代码片段一:
AVFrame *av_frame_alloc(void)
{
AVFrame *frame = av_mallocz(sizeof(*frame));
if (!frame)
return NULL;
frame->extended_data = NULL;
get_frame_defaults(frame);
return frame;
}
说明:
分配AVFrame结构体大小的内存,并将所有字段内容设置为0。
通过get_frame_defaults函数将AVFrame结构体中一些特殊的字段设置为特殊值。
这里并没有分配任何的视频或音频数据空间。
代码片段二:
与av_frame_alloc对应的函数
void av_frame_free(AVFrame **frame)
{
if (!frame || !*frame)
return;
av_frame_unref(*frame);
av_freep(frame);
}
说明:
av_freep(frame);完成的功能才是真正与av_frame_alloc对应。av_freep(frame)函数完成将av_frame_alloc分配的AVFrame结构体指针内存释放。
av_frame_unref(*frame);函数完成释放音视频数据。
代码片段三:
void av_frame_unref(AVFrame *frame)
{
int i;
for (i = 0; i < frame->nb_side_data; i++) {
av_freep(&frame->side_data[i]->data);
av_dict_free(&frame->side_data[i]->metadata);
av_freep(&frame->side_data[i]);
}
av_freep(&frame->side_data);
for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
av_buffer_unref(&frame->buf[i]);
for (i = 0; i < frame->nb_extended_buf; i++)
av_buffer_unref(&frame->extended_buf[i]);
av_freep(&frame->extended_buf);
av_dict_free(&frame->metadata);
av_buffer_unref(&frame->qp_table_buf);
get_frame_defaults(frame);
}
说明:
1、
函数av_buffer_unref(&frame->buf[i]);释放了真正的音视频数据。
依据:get_audio_buffer函数中调用frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
get_video_buffer函数中调用frame->data[1] = frame->buf[1]->data; frame->extended_data = frame->data;
从get_audio_buffer及get_video_buffer函数中可以看出extended_data 与data指向同一位置。
2、
当音频通道数超过AV_NUM_DATA_POINTERS(8)时,多余通道数据存放在extended_buf中。
代码片段四:
static int get_video_buffer(AVFrame *frame, int align)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
int ret, i;
if (!desc)
return AVERROR(EINVAL);
if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
return ret;
if (!frame->linesize[0]) {
for(i=1; i<=align; i+=i) {
ret = av_image_fill_linesizes(frame->linesize, frame->format,
FFALIGN(frame->width, i));
if (ret < 0)
return ret;
if (!(frame->linesize[0] & (align-1)))