ffmpeg yuv

FFMPEG: volcado de datos YUV en la estructura de AVFrame



(2)

Estoy tratando de volcar datos de YUV420 en la estructura AVFrame de FFMPEG. Desde el siguiente enlace:

http://ffmpeg.org/doxygen/trunk/structAVFrame.html , puedo deducir que necesito poner mis datos en

data[AV_NUM_DATA_POINTERS]

utilizando

linesize [AV_NUM_DATA_POINTERS].

Los datos de YUV que trato de volcar son YUV420 y el tamaño de la imagen es 416x240. Entonces, ¿cómo puedo volcar / mapear estos datos yuv a la variable de estructuras AVFrame? Me doy cuenta de que linesize representa la zancada, es decir, supongo que el ancho de mi imagen, lo he intentado con algunas combinaciones pero no obtengo el resultado. Le solicito amablemente que me ayude a mapear el búfer. Gracias por adelantado.


AVFrame se puede interpretar como una imagen AV para rellenar los campos de data y de linesize . La forma más fácil de llenar estos campos es usar la función avpicture_fill .

Para rellenar los buffers YU y V del AVFrame, depende de los datos de entrada y de lo que quiera hacer con el fotograma (¿desea escribir en el AVFrame y borrar los datos iniciales? O conservar una copia).

Si el búfer es lo suficientemente grande (al menos linesize[0] * height para datos Y, linesize[1 or 2] * height/2 para datos U / V), puede usar directamente búferes de entrada:

// Initialize the AVFrame AVFrame* frame = avcodec_alloc_frame(); frame->width = width; frame->height = height; frame->format = AV_PIX_FMT_YUV420P; // Initialize frame->linesize avpicture_fill((AVPicture*)frame, NULL, frame->format, frame->width, frame->height); // Set frame->data pointers manually frame->data[0] = inputBufferY; frame->data[1] = inputBufferU; frame->data[2] = inputBufferV; // Or if your Y, U, V buffers are contiguous and have the correct size, simply use: // avpicture_fill((AVPicture*)frame, inputBufferYUV, frame->format, frame->width, frame->height);

Si desea / necesita manipular una copia de datos de entrada, necesita calcular el tamaño de búfer necesario y copiar datos de entrada en él.

// Initialize the AVFrame AVFrame* frame = avcodec_alloc_frame(); frame->width = width; frame->height = height; frame->format = AV_PIX_FMT_YUV420P; // Allocate a buffer large enough for all data int size = avpicture_get_size(frame->format, frame->width, frame->height); uint8_t* buffer = (uint8_t*)av_malloc(size); // Initialize frame->linesize and frame->data pointers avpicture_fill((AVPicture*)frame, buffer, frame->format, frame->width, frame->height); // Copy data from the 3 input buffers memcpy(frame->data[0], inputBufferY, frame->linesize[0] * frame->height); memcpy(frame->data[1], inputBufferU, frame->linesize[1] * frame->height / 2); memcpy(frame->data[2], inputBufferV, frame->linesize[2] * frame->height / 2);

Una vez que haya terminado con el AVFrame, no olvide liberarlo con av_frame_free (y cualquier búfer asignado por av_malloc ).


FF_API int ff_get_format_plane_size(int fmt, int plane, int scanLine, int height) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); if (desc) { int h = height; if (plane == 1 || plane == 2) { h = FF_CEIL_RSHIFT(height, desc->log2_chroma_h); } return h*scanLine; } else return AVERROR(EINVAL); }