1. 程式人生 > >ffmpeg中av_image_alloc()函式的用法 以及 另一種同樣功能的函式用法

ffmpeg中av_image_alloc()函式的用法 以及 另一種同樣功能的函式用法

一、ffmpeg中av_image_alloc()是這樣定義的。此函式的功能是按照指定的寬、高、畫素格式來分析影象記憶體。

引數說明:

  pointers[4]:儲存影象通道的地址。如果是RGB,則前三個指標分別指向R,G,B的記憶體地址。第四個指標保留不用

  linesizes[4]:儲存影象每個通道的記憶體對齊的步長,即一行的對齊記憶體的寬度,此值大小等於影象寬度。

  w:                 要申請記憶體的影象寬度。

  h:                  要申請記憶體的影象高度。

  pix_fmt:        要申請記憶體的影象的畫素格式。

  align:            用於記憶體對齊的值。

  返回值:所申請的記憶體空間的總大小。如果是負值,表示申請失敗。

/**
 * Allocate an image with size w and h and pixel format pix_fmt, and
 * fill pointers and linesizes accordingly.
 * The allocated image buffer has to be freed by using
 * av_freep(&pointers[0]).
 *
 * @param align the value to use for buffer size alignment
 * @return the size in bytes required for the image buffer, a negative
 * error code in case of failure
 */
int av_image_alloc(uint8_t *pointers[4], int linesizes[4],

                   int w, int h, enum AVPixelFormat pix_fmt, int align);


(1)呼叫例項

參見本地工程  \vs2010cProjects\ffmpeg_yuv_file_show_sdl2\ffmpeg_yuv_file_show_sdl2。

具體程式碼:

ret= av_image_alloc(src_data, src_linesize,src_w, src_h, src_pixfmt, 1);   //按照長、寬、畫素格式分配各個通道的記憶體大小以及步長(linesize),記憶體地址儲存到src_data的指標陣列中
    if (ret< 0) {
        printf( "Could not allocate source image\n");
        return -1;
}

二、另一種同樣功能的函式呼叫方法

int image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height, 1);   //計算指定畫素格式、影象寬、高所需要的對齊的記憶體大小
out_buffer = (unsigned char *)av_malloc(image_buf_size);   //分配指定大小的記憶體空間

av_image_get_buffer_size()函式的作用是通過指定畫素格式、影象寬、影象高來計算所需的記憶體大小。

ffmpeg中關於av_image_get_buffer_size()的定義如下:

/**
 * Return the size in bytes of the amount of data required to store an
 * image with the given parameters.
 *
 * @param pix_fmt  the pixel format of the image
 * @param width    the width of the image in pixels
 * @param height   the height of the image in pixels
 * @param align    the assumed linesize alignment
 * @return the buffer size in bytes, a negative error code in case of failure
 */
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);

重點說明一個引數align:此引數是設定記憶體對齊的對齊數,也就是按多大的位元組進行記憶體對齊。比如設定為1,表示按1位元組對齊,那麼得到的結果就是與實際的記憶體大小一樣。再比如設定為4,表示按4位元組對齊。也就是記憶體的起始地址必須是4的整倍數。

ffmpeg中關於av_image_fill_array()函式的定義:

/**
 * Setup the data pointers and linesizes based on the specified image
 * parameters and the provided array.
 *
 * The fields of the given image are filled in by using the src
 * address which points to the image data buffer. Depending on the
 * specified pixel format, one or multiple image data pointers and
 * line sizes will be set.  If a planar format is specified, several
 * pointers will be set pointing to the different picture planes and
 * the line sizes of the different planes will be stored in the
 * lines_sizes array. Call with src == NULL to get the required
 * size for the src buffer.
 *
 * To allocate the buffer and fill in the dst_data and dst_linesize in
 * one call, use av_image_alloc().
 *
 * @param dst_data      data pointers to be filled in
 * @param dst_linesize  linesizes for the image in dst_data to be filled in
 * @param src           buffer which will contain or contains the actual image data, can be NULL
 * @param pix_fmt       the pixel format of the image
 * @param width         the width of the image in pixels
 * @param height        the height of the image in pixels
 * @param align         the value used in src for linesize alignment
 * @return the size in bytes required for src, a negative error code
 * in case of failure
 */
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
                         const uint8_t *src,
                         enum AVPixelFormat pix_fmt, int width, int height, int align);

av_image_fill_arrays()函式自身不具備記憶體申請的功能,此函式類似於格式化已經申請的記憶體,即通過av_malloc()函式申請的記憶體空間。

再者,av_image_fill_arrays()中引數具體說明:

  dst_data[4]:        [out]對申請的記憶體格式化為三個通道後,分別儲存其地址

  dst_linesize[4]:        [out]格式化的記憶體的步長(即記憶體對齊後的寬度)

  *src:        [in]av_alloc()函式申請的記憶體地址。

 pix_fmt:    [in] 申請 src記憶體時的畫素格式

width:        [in]申請src記憶體時指定的寬度

height:        [in]申請scr記憶體時指定的高度

align:        [in]申請src記憶體時指定的對齊位元組數。

(1)呼叫例項1

image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 1);  //按1位元組進行記憶體對齊,得到的記憶體大小最接近實際大小
	printf("image_buf_size:%d\n",image_buf_size);

	image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 0);  //按0位元組進行記憶體對齊,得到的記憶體大小是0
	printf("image_buf_size:%d\n",image_buf_size);

	image_buf_size = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, 11, 5, 4);   //按4位元組進行記憶體對齊,得到的記憶體大小稍微大一些
	printf("image_buf_size:%d\n",image_buf_size);

(2)呼叫例項2

img_convert_out_buffer = (unsigned char *)av_malloc(av_image_get_buffer_size(dst_pixfmt, dst_w, dst_h, 1));
av_image_fill_arrays(pFrameYUV->data,pFrameYUV->linesize, img_convert_out_buffer,dst_pixfmt, dst_w, dst_h, 1);                
img_convert_ctx = sws_getContext(src_w, src_h, src_pixfmt,
                                 dst_w, dst_h, dst_pixfmt,
                                 SWS_BICUBIC, NULL, NULL, NULL);	

(3)呼叫方法總結

通過以上例項可以看到,(a)計算所需記憶體大小av_image_get_bufferz_size() --> (b) 按計算的記憶體大小申請所需記憶體 av_malloc()  --> (c) 對申請的記憶體進行格式化 av_image_fill_arrays();