Décoder les images vidéo sur GPU iPhone

je cherche le moyen le plus rapide de décoder les images d'une vidéo mpeg-4 locale sur l'iPhone. Je suis simplement intéressé par les valeurs de luminance des pixels dans chaque 10ème image. Je n'ai besoin de rendre la vidéo nulle part.

j'ai essayé ffmpeg, AVAssetReader, ImageAssetGenerator, OpenCV, et MPMoviePlayer mais ils sont tous trop lents. La vitesse la plus rapide que je peux obtenir est ~2x (2 minutes de vidéo scannée en une minute). J'aimerais quelque chose de plus de 10 fois.

en supposant mes tentatives ci-dessus n'a pas utilisé le GPU, y a-t-il un moyen d'Accomplir mon but avec quelque chose qui fonctionne sur le GPU? OpenGL semble comme il est principalement pour la production de rendu, mais je l'ai vu utilisé comme filtres pour la vidéo entrante. C'est peut-être une option?

Merci d'avance!

15
demandé sur Dmitry Shkuropatsky 2012-02-17 21:33:20

3 réponses

si vous êtes prêt à utiliser une solution iOS 5 uniquement, jetez un oeil à L'application ChromaKey échantillon de la session WWDC 2011 sur AVCaputureSession.

cette démo capture 30 FPS de vidéo de la caméra intégrée et passe chaque image à OpenGL comme une texture. Il utilise ensuite OpenGL pour manipuler le cadre, et écrit optionnellement le résultat dans un fichier vidéo de sortie.

le code utilise une magie de bas niveau pour lier un tampon de Pixel vidéo à partir D'une AVCaptureSession pour OpenGL afin qu'ils partagent la mémoire dans le matériel graphique.

il devrait être assez simple de changer la session AVCaptureSession pour utiliser un fichier film comme entrée plutôt que comme entrée caméra.

vous pourriez probablement configurer la session pour fournir des cadres en Y/UV plutôt qu'en RVB, où le composant Y est la luminance. Sinon, il serait assez simple d'écrire un shader qui convertirait les valeurs RVB pour chaque pixel en valeurs de luminance.

vous devriez être capable de faire tout cela sur tous les cadres, pas seulement tous les 10èmes cadres.

3
répondu Duncan C 2012-02-26 02:18:08

apparemment vImage pourrait être approprié, en supposant que vous pouvez utiliser iOS 5. Chaque dixième image semble être dans la raison d'utiliser un cadre comme vImage. Cependant, tout type de traitement réel en temps réel va presque certainement exiger OpenGL.

0
répondu LucasTizma 2012-02-20 00:41:32

en supposant que le goulot d'étranglement de votre application est dans le code qui convertit les cadres vidéo en un format affichable( comme RGB), vous pourriez être intéressé par un code que j'ai partagé qui a été utilisé pour convertir un .mp4 cadre (codé comme YV12) RVB à l'aide de Qt et OpenGL. Cette application télécharge le cadre sur le GPU et active un GLSL fragment shader pour faire la conversion de YV12 en RVB, de sorte qu'il puisse être affiché dans un QImage.

static const char *p_s_fragment_shader =
    "#extension GL_ARB_texture_rectangle : enable\n"
    "uniform sampler2DRect tex;"
    "uniform float ImgHeight, chromaHeight_Half, chromaWidth;"
    "void main()"
    "{"
    "    vec2 t = gl_TexCoord[0].xy;" // get texcoord from fixed-function pipeline
    "    float CbY = ImgHeight + floor(t.y / 4.0);"
    "    float CrY = ImgHeight + chromaHeight_Half + floor(t.y / 4.0);"
    "    float CbCrX = floor(t.x / 2.0) + chromaWidth * floor(mod(t.y, 2.0));"
    "    float Cb = texture2DRect(tex, vec2(CbCrX, CbY)).x - .5;"
    "    float Cr = texture2DRect(tex, vec2(CbCrX, CrY)).x - .5;"
    "    float y = texture2DRect(tex, t).x;" // redundant texture read optimized away by texture cache
    "    float r = y + 1.28033 * Cr;"
    "    float g = y - .21482 * Cb - .38059 * Cr;"
    "    float b = y + 2.12798 * Cb;"
    "    gl_FragColor = vec4(r, g, b, 1.0);"
    "}"
0
répondu karlphillip 2017-05-23 12:20:04