8
votes

Meilleur chemin de AvplayerItemvideoOutPut de Texture OpenGL

En tirant mes cheveux en essayant de comprendre le meilleur chemin actuel des vidéos d'aviverse à une opengltexture, la plupart de ce que je trouve est lié à iOS, et je n'arrive pas à le faire fonctionner bien à OSX.

Tout d'abord, voici comment je configurais le videoOutput: p> xxx pré>

Je tente trois solutions différentes, dont seule une seule semble fonctionner de manière cohérente, mais pas sûr que ce soit le le plus rapide. On travaille pour un peu, puis se décompose avec des cadres sautant partout, et on produit simplement du noir. P>

premier off, solution de travail utilisant GltexImage2D P>

- (BOOL) renderByCVOpenGLTextureCacheForTime:(NSTimeInterval) time
{
    CMTime vTime = [self.playeroutput itemTimeForHostTime:CACurrentMediaTime()];

    if ([self.playeroutput hasNewPixelBufferForItemTime:vTime]) {
        _cvPixelBufferRef = [self.playeroutput copyPixelBufferForItemTime:vTime itemTimeForDisplay:NULL];
        if (!_textureCacheRef) {
            CVReturn error = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, cgl_ctx, CGLGetPixelFormat(cgl_ctx), NULL, &_textureCacheRef);
            if (error) {
                NSLog(@"Texture cache create failed");
            }
        }

        CVReturn error = CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _textureCacheRef, _cvPixelBufferRef, NULL, &_textureRef);
        if (error) {
            NSLog(@"Failed to copy video texture");
        }


        CVPixelBufferRelease(_cvPixelBufferRef);

        _textureName = CVOpenGLTextureGetName(_textureRef);

    }
    return YES;
}


0 commentaires

3 Réponses :


5
votes

Je commence le même voyage et j'en connais autant sur OpenGL que je le fais sur l'élevage des moutons, mais remarquez que vos pboptions ne contiennent pas kcvpixelbufferopenglcompatibilitykeybkey code> xxx pré>

Je demande le tampon de pixel comme kcvpixelformattype_32bgra plutôt que composant et cela fonctionne pour moi avec des variables locales pour _Currentsurface (iosurfaceref), Texturename (GLUINT), _sourceWidth (int) et _sourceheight (int) P>

IOSurfaceRef newSurface = CVPixelBufferGetIOSurface(pixelBuffer);
if (_currentSurface != newSurface) {
    CGLContextObj  cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];
    [[self openGLContext] makeCurrentContext];

    IOSurfaceDecrementUseCount(_currentSurface);
    _currentSurface = newSurface;
    IOSurfaceIncrementUseCount(_currentSurface);
    GLsizei texWidth = (int) IOSurfaceGetWidth(_currentSurface);
    GLsizei texHeight = (int) IOSurfaceGetHeight(_currentSurface);

    if (_sourceWidth == 0 && _sourceHeight == 0) {
        // used during drawing of texture
        _sourceWidth = texWidth;
        _sourceHeight = texHeight;
    }

    if (!_textureName) {
        GLuint name;
        glGenTextures(1, &name);
        _textureName = name;
    }

    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, _textureName);
    CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, texWidth, texHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, self.currentSurface, 0);        
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
}


7 commentaires

Merci, je l'ai essayé, mais je n'ai trouvé aucun avantage immédiat avec les exemples ci-dessus. Je reviendrai à cela dans la semaine prochaine alors que je range mon code vidéo et je joue un peu avec les choses.


Je viens de voir votre édition 'Je vais bientôt donner vos suggestions, merci!


Je viens de l'essayer et ça marche pour moi aussi. Semble changer le format de pixel loin de YCBR résolu le glitching que je recevais.


CVPIXELBUPERGETIOSURFACE est-il une API privée?


Pourquoi savez-vous tant d'élevage des moutons?


@jjxtra à partir de IOS 11, Iosurface est maintenant une API publique.


@LUCASTIZMA C'est une bonne nouvelle!



0
votes

Lorsque vous utilisez l'option n ° 2, avez-vous défini la propriété "conserve" "conserve" de l'eagllacheer à no? C'est peut-être la raison pour laquelle il semble utiliser le même cadre dans différents cycles. Il serait avantageux de voir comment vous avez configuré ou si vous avez configuré, le calque de manière appropriée pour la vue à laquelle vous rendant les embrouillards ...


9 commentaires

Je n'utilise pas du tout des calques dans cette application, les cadres vidéo sont téléchargés sur OpenGL et traités là-bas. Pour ma version iOS, j'ai réussi à obtenir le CVopenglTexTurEcache de travailler avec peu de problèmes.


Vous utilisez des couches; Ils font partie intégrante de tout UIView ou GLKView. De plus, vos textures sont rendues via un contexte à une couche. Ce que vous ne faites pas est de configurer la couche de la vue à laquelle vous rendu et dont le contexte rend le calque de cette vue.


C'était à l'origine une question OSX, je rendu en fait à ma propre sous-classe de NsopenglView, bien que cela puisse passer par un traitement supplémentaire dans une FBO par des contextes partagés. J'ai utilisé un code très similaire pour capturer l'affichage et le rendre exactement à la même vue en même temps et qui fonctionnerait en douceur (mais la vidéo serait toujours un problème).


Est-ce toujours une question OS X?


Je suppose que c'est, vous ne pouvez pas accéder à Iosurfaces dans iOS sans utiliser des API privées, la solution iosurface ne volerait pas si vous vouliez votre application dans le magasin. Pour iOS, j'ai trouvé que la cvopengleStexturecache est bien fonctionnée (codée similaire à ci-dessus) et je n'ai pas eu les mêmes problèmes que sur OSX. Je soupçonne que je n'ai pas configuré de l'aspect correctement pour OSX.


Vous pouvez utiliser iosurfaces dans votre application et le numéro d'option n ° 2 - à ce mesure que je ne connaisse qu'un seul correctif: initialisation du tampon de pixel vidéo principal en tant qu'objet de pointeur dangerable et mutable. De plus, vous devez créer le tampon de pixel avant d'attribuer une valeur. Lorsque vous le créez, vous pouvez utiliser la clé IOSURFACE correspondante dans le dictionnaire des propriétés; Le reste, vous avez raison, sauvegardez l'absence du support CAEAGLLAYER, que vous avez déjà informé. Voir Diapositives 107-108 chez Devrestreaming.Apple. Com / Vidéos / WWDC / 2015 / 510JICCQSZ / 510 / ...


Il convient de noter qu'avant IOS 11, Iosurface n'était disponible que pour être utilisé indirectement dans la fondation AV et l'image principale (peut-être d'autres) en spécifiant certains paramètres. Dans iOS 11, il apparaît qu'ils ont pleinement exposé le cadre de l'IOSurface réel, de sorte que cela ouvre des possibilités plus intéressantes lorsque vous travaillez avec le traitement du tampon de pixel de pixel multimédia.


Comme quelles possibilités?


Interopérabilité entre la fondation AV, l'image centrale, le métal, les gants, etc. Il existe de nouvelles API exposées pour ces différents cadres pour passer dans iosurface REFS, il faut donc ouvrir quelques autres voies de traitement de tampon direct sans avoir besoin de copier ou de perdre du temps / de la mémoire transfert de données de pixel d'un cadre à un autre.



1
votes

Il apparaît que la méthode correspondante de texturation vidéo rapide sur OSX consiste à utiliser BIPLANAR IOSURFaces où la planche à empletse [0] est la lumie (Y) et la planchode [1] est la chroma (UV). Mon code circule sur le profil de base, de sorte que les constantes de Glenum à CGLTEXIMAGIOSURFace2D reflètent la même chose. Assez sûr que seules les textures de rectangle sont prises en charge. J'utilise un shader GLSL pour les combiner et cela fonctionne bien sur la Sierra. Brièvement résumée: xxx pré>

glsl p>

uniform sampler2DRect textureSampler0;
uniform sampler2DRect textureSampler1;
// ...
vec3 YCrCb;
vec2 lumaCoords = texCoord0;
vec2 chromaCoords = lumaCoords*vec2(0.5,0.5);
vec2 chroma = texture(textureSampler1,chromaCoords).xy;
float luma = texture(textureSampler0,lumaCoords).x;
YCrCb.x = (luma-(16.0/255.0)); // video range
YCrCb.yz = (chroma-vec2(0.5,0.5));
vec4 rgbA = vec4(colorConversionMatrix * YCrCb,1.0);


0 commentaires