当前位置:网站首页>AVFrame related api memory management

AVFrame related api memory management

2022-08-10 17:49:00 Audio and video development old man

注意:If memory is allocated by stack

AVFrame frame
....Pseudocode setupframe相关参数...
avcodec_receive_frame(decodec_ctx, &frame)

则会发生段错误,Not found so farAVPacket的api av_init_packetsimilar function to initializeAVFrame,And if the video is stored1080i50,1s中就6M左右,而一个进程LinuxThe total allocated stack memory is only8M,The recommended heap method is as follows:

构建AVFrame变量的api,其中av_frame_allocDisplays the application structure space,Then initialize the structure variable,设置默认值(后附源码).

Allocate structure space

AVFrame* frame = av_frame_alloc();

Set values ​​to its structure members

frame->width = 1920;
frame->height = 1080;
frame->format = AV_PIX_FMT_YUV420P;

//parameter setter0即可,Indicates according to the currentcpuType automatically selects the number of bytes to align,in audio0,Video must be press32位补齐,This is to allocate space for the pointer to the video data inside the structure,Allocate a reasonable space size according to the three parameters set earlier(Just configure these three to get one frame video size).

//alloc inner memory
av_frame_get_buffer(frame, 32);

For audio you need to set the bit depth,Number of samples and channels,Because of the size of one frame of audio:(format/8) x channels x nb_samples.

AVFrame* pcm = av_frame_alloc();
pcm->format = outSampleFmt;//位深 16/32位
pcm->channels = channels;
pcm->channel_layout = av_get_default_channel_layout(channels);
pcm->nb_samples = nbSample;//样本数
ret = av_frame_get_buffer(pcm, 0);
 av_frame_unref(praw_frame);

本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

释放praw_frame空间,and reset its various parameters,Not recommended every timeavcodec_receive_frame后调用av_frame_unref,因为AVFrameThe video or audio stored in a fixed size,after each release,再次调用avcodec_receive_frame,还需要为praw_frame分配内存.

另一篇文章,From the codec interfaceAVPacket和AVFramememory allocation and release issues,avcodec_send_frame和avcodec_receive_packet

Only deals with videoapi:

(1)此apiThe first two parameters are output parameters,Used to give pointerspointersRequest a space in the specified format,它和av_frame_get_bufferAllocated memory space,And none of them are filled with video data.

/**
 * 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);

(2)when you get a pointerptr,这个ptrOne frame of video data is stored in it,I want to put him inAVFrame中可以使用以下api.

/**
 * @deprecated use av_image_fill_arrays() instead.
 */
attribute_deprecated
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
         enum AVPixelFormat pix_fmt, int width, int height);

使用举例:

avpicture_fill((AVPicture *)frame, (const uint8_t *)ptr,
 (enum AVPixelFormat)frame->format, in_width, in_height);

可以看出AVFrame类型的frame需要用AVPicture强制转换.

Note that it doesn't giveframe->data分配内存空间,而是将frame->data与ptr指针关联起来,frame中的视频数据,是ptrThe video data in the memory pointed to,因此是浅拷贝.

(3)这个是上面api的升级版,使用场景相同.笔者为ffmpeg4.3,The above is marked as a deprecated version,但不影响使用,No notification will be reported.在源码中avpicture_fill()内部就是调用av_image_fill_arrays实现的,Hence it is also a shallow copy,并没有给dst_data分配内存空间.

The following twoapiAll are for video storageAVFrame填充数据,No new space is allocated.

/**
 * 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);
AVFrame *av_frame_alloc(void)
{
    //申请一块AVFrame大小的内存
    AVFrame *frame = av_mallocz(sizeof(*frame));
 
    if (!frame)
        return NULL;
 
    frame->extended_data = NULL;
    //设置默认的值
    get_frame_defaults(frame);
 
    return frame;
}

本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs↓↓↓↓↓↓见下面↓↓文章底部点击领取↓↓

原网站

版权声明
本文为[Audio and video development old man]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208101722585600.html