videos tamaño recortar para imagen gratis editar como app iphone ios opengl-es video-processing gpgpu

tamaño - Decodificar marcos de video en la GPU de iPhone



imovie (3)

Aparentemente, vImage podría ser apropiado, suponiendo que puedas usar iOS 5. Cada décimo frame parece estar dentro de lo razonable para usar un framework como vImage. Sin embargo, cualquier tipo de procesamiento real en tiempo real va a requerir OpenGL.

Estoy buscando la forma más rápida de decodificar los marcos de un video MPEG-4 local en el iPhone. Simplemente me interesan los valores de luminancia de los píxeles en cada 10º fotograma. No necesito renderizar el video en ningún lado.

He probado ffmpeg, AVAssetReader, ImageAssetGenerator, OpenCV y MPMoviePlayer, pero son demasiado lentos. La velocidad más rápida que puedo obtener es ~ 2x (2 minutos de video escaneados en un minuto). Me gustaría algo más cerca de 10x.

Suponiendo que mis intentos anteriores no utilizaron la GPU, ¿hay alguna forma de lograr mi objetivo con algo que se ejecute en la GPU? Parece que OpenGL es principalmente para renderizar resultados, pero lo he visto como filtros para video entrante. Tal vez esa es una opción?

¡Gracias por adelantado!


Si está dispuesto a utilizar una solución solo iOS 5, eche un vistazo a la aplicación de muestra ChromaKey de la sesión WWDC 2011 en AVCaputureSession.

Esa demostración captura 30 FPS de video de la cámara incorporada y pasa cada fotograma a OpenGL como una textura. A continuación, utiliza OpenGL para manipular el marco y, opcionalmente, escribe el resultado en un archivo de video de salida.

El código utiliza un poco de magia grave de bajo nivel para vincular un búfer de Core Video Pixel desde una sesión AVCaptureSession a OpenGL para que compartan memoria en el hardware de gráficos.

Sería bastante sencillo cambiar AVCaptureSession para usar un archivo de película como entrada en lugar de entrada de cámara.

Probablemente podría configurar la sesión para entregar marcos en formato Y / UV en lugar de RGB, donde el componente Y es la luminancia. De lo contrario, sería una cuestión bastante simple escribir un sombreador que convertiría los valores RGB para cada píxel en valores de luminancia.

Debería poder hacer todo esto en TODAS las tramas, no solo en cada 10º fotograma.


Suponiendo que el cuello de botella de su aplicación está en el código que convierte los marcos de video a un formato visualizable (como RGB), podría interesarle un código que compartí que se usó para convertir un marco .mp4 (codificado como YV12) a RGB usando Qt y OpenGL . Esta aplicación sube el marco a la GPU y activa un sombreador de fragmentos GLSL para hacer la conversión de YV12 a RGB, por lo que podría mostrarse en una 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);" "}"