From 9b2dc29534b35d9e337274214853bc8d795f53c4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 21 Jan 2013 21:10:18 +0100 Subject: [PATCH 1/2] avconv: convert to new refcounted AVFrame API --- avconv.c | 128 +++++++++++++++++++++++++++++-------------------------- avconv.h | 4 +- 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/avconv.c b/avconv.c index 900f49afe7..1a18ad336d 100644 --- a/avconv.c +++ b/avconv.c @@ -193,9 +193,9 @@ static void exit_program(void) av_freep(&input_files[i]); } for (i = 0; i < nb_input_streams; i++) { - avcodec_free_frame(&input_streams[i]->decoded_frame); + av_frame_free(&input_streams[i]->decoded_frame); + av_frame_free(&input_streams[i]->filter_frame); av_dict_free(&input_streams[i]->opts); - free_buffer_pool(&input_streams[i]->buffer_pool); av_freep(&input_streams[i]->filters); av_freep(&input_streams[i]); } @@ -332,7 +332,10 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) pkt->flags & AV_PKT_FLAG_KEY); if (a > 0) { av_free_packet(pkt); - new_pkt.destruct = av_destruct_packet; + new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, + av_buffer_default_free, NULL, 0); + if (!new_pkt.buf) + exit(1); } else if (a < 0) { av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s", bsfc->filter->name, pkt->stream_index, @@ -566,28 +569,20 @@ static void do_video_out(AVFormatContext *s, write_frame(s, &pkt, ost); } else { int got_packet; - AVFrame big_picture; - big_picture = *in_picture; - /* better than nothing: use input picture interlaced - settings */ - big_picture.interlaced_frame = in_picture->interlaced_frame; - if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) { - if (ost->top_field_first == -1) - big_picture.top_field_first = in_picture->top_field_first; - else - big_picture.top_field_first = !!ost->top_field_first; - } + if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) && + ost->top_field_first >= 0) + in_picture->top_field_first = !!ost->top_field_first; - big_picture.quality = ost->st->codec->global_quality; + in_picture->quality = ost->st->codec->global_quality; if (!enc->me_threshold) - big_picture.pict_type = 0; + in_picture->pict_type = 0; if (ost->forced_kf_index < ost->forced_kf_count && - big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) { - big_picture.pict_type = AV_PICTURE_TYPE_I; + in_picture->pts >= ost->forced_kf_pts[ost->forced_kf_index]) { + in_picture->pict_type = AV_PICTURE_TYPE_I; ost->forced_kf_index++; } - ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet); + ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet); if (ret < 0) { av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); exit(1); @@ -665,7 +660,6 @@ static void do_video_stats(OutputStream *ost, int frame_size) static int poll_filter(OutputStream *ost) { OutputFile *of = output_files[ost->file_index]; - AVFilterBufferRef *picref; AVFrame *filtered_frame = NULL; int frame_size, ret; @@ -677,17 +671,16 @@ static int poll_filter(OutputStream *ost) if (ost->enc->type == AVMEDIA_TYPE_AUDIO && !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) - ret = av_buffersink_read_samples(ost->filter->filter, &picref, + ret = av_buffersink_get_samples(ost->filter->filter, filtered_frame, ost->st->codec->frame_size); else - ret = av_buffersink_read(ost->filter->filter, &picref); + ret = av_buffersink_get_frame(ost->filter->filter, filtered_frame); if (ret < 0) return ret; - avfilter_copy_buf_props(filtered_frame, picref); - if (picref->pts != AV_NOPTS_VALUE) { - filtered_frame->pts = av_rescale_q(picref->pts, + if (filtered_frame->pts != AV_NOPTS_VALUE) { + filtered_frame->pts = av_rescale_q(filtered_frame->pts, ost->filter->filter->inputs[0]->time_base, ost->st->codec->time_base) - av_rescale_q(of->start_time, @@ -695,7 +688,7 @@ static int poll_filter(OutputStream *ost) ost->st->codec->time_base); if (of->start_time && filtered_frame->pts < 0) { - avfilter_unref_buffer(picref); + av_frame_unref(filtered_frame); return 0; } } @@ -703,7 +696,7 @@ static int poll_filter(OutputStream *ost) switch (ost->filter->filter->inputs[0]->type) { case AVMEDIA_TYPE_VIDEO: if (!ost->frame_aspect_ratio) - ost->st->codec->sample_aspect_ratio = picref->video->pixel_aspect; + ost->st->codec->sample_aspect_ratio = filtered_frame->sample_aspect_ratio; do_video_out(of->ctx, ost, filtered_frame, &frame_size); if (vstats_filename && frame_size) @@ -717,7 +710,7 @@ static int poll_filter(OutputStream *ost) av_assert0(0); } - avfilter_unref_buffer(picref); + av_frame_unref(filtered_frame); return 0; } @@ -1040,8 +1033,11 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO && ost->st->codec->codec_id != AV_CODEC_ID_VC1 ) { - if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) - opkt.destruct = av_destruct_packet; + if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) { + opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0); + if (!opkt.buf) + exit(1); + } } else { opkt.data = pkt->data; opkt.size = pkt->size; @@ -1081,19 +1077,21 @@ int guess_input_channel_layout(InputStream *ist) static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) { - AVFrame *decoded_frame; + AVFrame *decoded_frame, *f; AVCodecContext *avctx = ist->st->codec; - int i, ret, resample_changed; + int i, ret, err = 0, resample_changed; if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) return AVERROR(ENOMEM); + if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc())) + return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt); if (!*got_output || ret < 0) { if (!pkt->size) { for (i = 0; i < ist->nb_filters; i++) - av_buffersrc_buffer(ist->filters[i]->filter, NULL); + av_buffersrc_add_frame(ist->filters[i]->filter, NULL); } return ret; } @@ -1154,19 +1152,34 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) decoded_frame->pts = av_rescale_q(decoded_frame->pts, ist->st->time_base, (AVRational){1, ist->st->codec->sample_rate}); - for (i = 0; i < ist->nb_filters; i++) - av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame); + for (i = 0; i < ist->nb_filters; i++) { + if (i < ist->nb_filters - 1) { + f = ist->filter_frame; + err = av_frame_ref(f, decoded_frame); + if (err < 0) + break; + } else + f = decoded_frame; - return ret; + err = av_buffersrc_add_frame(ist->filters[i]->filter, f); + if (err < 0) + break; + } + + av_frame_unref(ist->filter_frame); + av_frame_unref(decoded_frame); + return err < 0 ? err : ret; } static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) { - AVFrame *decoded_frame; + AVFrame *decoded_frame, *f; void *buffer_to_free = NULL; - int i, ret = 0, resample_changed; + int i, ret = 0, err = 0, resample_changed; - if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame())) + if (!ist->decoded_frame && !(ist->decoded_frame = av_frame_alloc())) + return AVERROR(ENOMEM); + if (!ist->filter_frame && !(ist->filter_frame = av_frame_alloc())) return AVERROR(ENOMEM); decoded_frame = ist->decoded_frame; @@ -1175,7 +1188,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) if (!*got_output || ret < 0) { if (!pkt->size) { for (i = 0; i < ist->nb_filters; i++) - av_buffersrc_buffer(ist->filters[i]->filter, NULL); + av_buffersrc_add_frame(ist->filters[i]->filter, NULL); } return ret; } @@ -1219,26 +1232,23 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) } for (i = 0; i < ist->nb_filters; i++) { - if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1) { - FrameBuffer *buf = decoded_frame->opaque; - AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( - decoded_frame->data, decoded_frame->linesize, - AV_PERM_READ | AV_PERM_PRESERVE, - ist->st->codec->width, ist->st->codec->height, - ist->st->codec->pix_fmt); - - avfilter_copy_frame_props(fb, decoded_frame); - fb->buf->priv = buf; - fb->buf->free = filter_release_buffer; - - buf->refcount++; - av_buffersrc_buffer(ist->filters[i]->filter, fb); + if (i < ist->nb_filters - 1) { + f = ist->filter_frame; + err = av_frame_ref(f, decoded_frame); + if (err < 0) + break; } else - av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame); + f = decoded_frame; + + err = av_buffersrc_add_frame(ist->filters[i]->filter, f); + if (err < 0) + break; } + av_frame_unref(ist->filter_frame); + av_frame_unref(decoded_frame); av_free(buffer_to_free); - return ret; + return err < 0 ? err : ret; } static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) @@ -1408,11 +1418,7 @@ static int init_input_stream(int ist_index, char *error, int error_len) } } - if (codec->type == AVMEDIA_TYPE_VIDEO && codec->capabilities & CODEC_CAP_DR1) { - ist->st->codec->get_buffer = codec_get_buffer; - ist->st->codec->release_buffer = codec_release_buffer; - ist->st->codec->opaque = &ist->buffer_pool; - } + av_opt_set_int(ist->st->codec, "refcounted_frames", 1, 0); if (!av_dict_get(ist->opts, "threads", NULL, 0)) av_dict_set(&ist->opts, "threads", "auto", 0); diff --git a/avconv.h b/avconv.h index da7259e292..eb9df9b16a 100644 --- a/avconv.h +++ b/avconv.h @@ -200,6 +200,7 @@ typedef struct InputStream { int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */ AVCodec *dec; AVFrame *decoded_frame; + AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */ int64_t start; /* time when read started */ /* predicted dts of the next packet read for this stream or (when there are @@ -223,9 +224,6 @@ typedef struct InputStream { int resample_channels; uint64_t resample_channel_layout; - /* a pool of free buffers for decoded data */ - FrameBuffer *buffer_pool; - /* decoded data from this stream goes into all those filters * currently video and audio only */ InputFilter **filters; From 354468fc12dcf93e7fb4af552e18906771913273 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Feb 2013 16:06:16 +0100 Subject: [PATCH 2/2] avplay: switch to new refcounted frames API Remove now unused cmdutils get_buffer() implementation. --- avplay.c | 76 ++++++++------------------------ cmdutils.c | 126 ----------------------------------------------------- cmdutils.h | 43 ------------------ 3 files changed, 19 insertions(+), 226 deletions(-) diff --git a/avplay.c b/avplay.c index c45ec55b2a..b87e270e74 100644 --- a/avplay.c +++ b/avplay.c @@ -108,9 +108,7 @@ typedef struct VideoPicture { int reallocate; enum AVPixelFormat pix_fmt; -#if CONFIG_AVFILTER - AVFilterBufferRef *picref; -#endif + AVRational sar; } VideoPicture; typedef struct SubPicture { @@ -217,8 +215,6 @@ typedef struct VideoState { #if CONFIG_AVFILTER AVFilterContext *in_video_filter; // the first filter in the video chain AVFilterContext *out_video_filter; // the last filter in the video chain - int use_dr1; - FrameBuffer *buffer_pool; #endif float skip_frames; @@ -656,10 +652,10 @@ static void video_image_display(VideoState *is) vp = &is->pictq[is->pictq_rindex]; if (vp->bmp) { #if CONFIG_AVFILTER - if (vp->picref->video->pixel_aspect.num == 0) + if (!vp->sar.num) aspect_ratio = 0; else - aspect_ratio = av_q2d(vp->picref->video->pixel_aspect); + aspect_ratio = av_q2d(vp->sar); #else /* XXX: use variable in the frame */ @@ -1229,9 +1225,6 @@ static void stream_close(VideoState *is) /* free all pictures */ for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) { vp = &is->pictq[i]; -#if CONFIG_AVFILTER - avfilter_unref_bufferp(&vp->picref); -#endif if (vp->bmp) { SDL_FreeYUVOverlay(vp->bmp); vp->bmp = NULL; @@ -1279,8 +1272,6 @@ static void alloc_picture(void *opaque) SDL_FreeYUVOverlay(vp->bmp); #if CONFIG_AVFILTER - avfilter_unref_bufferp(&vp->picref); - vp->width = is->out_video_filter->inputs[0]->w; vp->height = is->out_video_filter->inputs[0]->h; vp->pix_fmt = is->out_video_filter->inputs[0]->format; @@ -1369,10 +1360,6 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t /* if the frame is not skipped, then display it */ if (vp->bmp) { AVPicture pict = { { 0 } }; -#if CONFIG_AVFILTER - avfilter_unref_bufferp(&vp->picref); - vp->picref = src_frame->opaque; -#endif /* get a pointer on the bitmap */ SDL_LockYUVOverlay (vp->bmp); @@ -1432,6 +1419,7 @@ static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos) { double frame_delay, pts; + int ret; pts = pts1; @@ -1448,7 +1436,9 @@ static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int6 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5); is->video_clock += frame_delay; - return queue_picture(is, src_frame, pts, pos); + ret = queue_picture(is, src_frame, pts, pos); + av_frame_unref(src_frame); + return ret; } static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt) @@ -1504,7 +1494,7 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke is->skip_frames_index -= FFMAX(is->skip_frames, 1.0); return 1; } - + av_frame_unref(frame); } return 0; } @@ -1572,13 +1562,6 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c is->in_video_filter = filt_src; is->out_video_filter = filt_out; - if (codec->codec->capabilities & CODEC_CAP_DR1) { - is->use_dr1 = 1; - codec->get_buffer = codec_get_buffer; - codec->release_buffer = codec_release_buffer; - codec->opaque = &is->buffer_pool; - } - return ret; } @@ -1588,7 +1571,7 @@ static int video_thread(void *arg) { AVPacket pkt = { 0 }; VideoState *is = arg; - AVFrame *frame = avcodec_alloc_frame(); + AVFrame *frame = av_frame_alloc(); int64_t pts_int; double pts; int ret; @@ -1596,7 +1579,6 @@ static int video_thread(void *arg) #if CONFIG_AVFILTER AVFilterGraph *graph = avfilter_graph_alloc(); AVFilterContext *filt_out = NULL, *filt_in = NULL; - int64_t pos; int last_w = is->video_st->codec->width; int last_h = is->video_st->codec->height; @@ -1608,7 +1590,6 @@ static int video_thread(void *arg) for (;;) { #if CONFIG_AVFILTER - AVFilterBufferRef *picref; AVRational tb; #endif while (is->paused && !is->videoq.abort_request) @@ -1639,38 +1620,19 @@ static int video_thread(void *arg) } frame->pts = pts_int; - if (is->use_dr1) { - FrameBuffer *buf = frame->opaque; - AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( - frame->data, frame->linesize, - AV_PERM_READ | AV_PERM_PRESERVE, - frame->width, frame->height, - frame->format); - - avfilter_copy_frame_props(fb, frame); - fb->buf->priv = buf; - fb->buf->free = filter_release_buffer; - - buf->refcount++; - av_buffersrc_buffer(filt_in, fb); - - } else - av_buffersrc_write_frame(filt_in, frame); + ret = av_buffersrc_add_frame(filt_in, frame); + if (ret < 0) + goto the_end; while (ret >= 0) { - ret = av_buffersink_read(filt_out, &picref); + ret = av_buffersink_get_frame(filt_out, frame); if (ret < 0) { ret = 0; break; } - avfilter_copy_buf_props(frame, picref); - - pts_int = picref->pts; + pts_int = frame->pts; tb = filt_out->inputs[0]->time_base; - pos = picref->pos; - frame->opaque = picref; - if (av_cmp_q(tb, is->video_st->time_base)) { av_unused int64_t pts1 = pts_int; pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base); @@ -1680,7 +1642,7 @@ static int video_thread(void *arg) is->video_st->time_base.num, is->video_st->time_base.den, pts_int); } pts = pts_int * av_q2d(is->video_st->time_base); - ret = output_picture2(is, frame, pts, pos); + ret = output_picture2(is, frame, pts, 0); } #else pts = pts_int * av_q2d(is->video_st->time_base); @@ -1690,6 +1652,7 @@ static int video_thread(void *arg) if (ret < 0) goto the_end; + if (step) if (cur_stream) stream_pause(cur_stream); @@ -1700,7 +1663,7 @@ static int video_thread(void *arg) avfilter_graph_free(&graph); #endif av_free_packet(&pkt); - avcodec_free_frame(&frame); + av_frame_free(&frame); return 0; } @@ -2090,6 +2053,8 @@ static int stream_component_open(VideoState *is, int stream_index) if (!av_dict_get(opts, "threads", NULL, 0)) av_dict_set(&opts, "threads", "auto", 0); + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) + av_dict_set(&opts, "refcounted_frames", "1", 0); if (!codec || avcodec_open2(avctx, codec, &opts) < 0) return -1; @@ -2235,9 +2200,6 @@ static void stream_component_close(VideoState *is, int stream_index) ic->streams[stream_index]->discard = AVDISCARD_ALL; avcodec_close(avctx); -#if CONFIG_AVFILTER - free_buffer_pool(&is->buffer_pool); -#endif switch (avctx->codec_type) { case AVMEDIA_TYPE_AUDIO: is->audio_st = NULL; diff --git a/cmdutils.c b/cmdutils.c index 3dbb722d21..4655681e4a 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -1543,129 +1543,3 @@ void *grow_array(void *array, int elem_size, int *size, int new_size) } return array; } - -static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf) -{ - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt); - FrameBuffer *buf; - int i, ret; - int pixel_size; - int h_chroma_shift, v_chroma_shift; - int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1 - int w = s->width, h = s->height; - - if (!desc) - return AVERROR(EINVAL); - pixel_size = desc->comp[0].step_minus1 + 1; - - buf = av_mallocz(sizeof(*buf)); - if (!buf) - return AVERROR(ENOMEM); - - if (!(s->flags & CODEC_FLAG_EMU_EDGE)) { - w += 2*edge; - h += 2*edge; - } - - avcodec_align_dimensions(s, &w, &h); - if ((ret = av_image_alloc(buf->base, buf->linesize, w, h, - s->pix_fmt, 32)) < 0) { - av_freep(&buf); - return ret; - } - - av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, - &h_chroma_shift, &v_chroma_shift); - - for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) { - const int h_shift = i==0 ? 0 : h_chroma_shift; - const int v_shift = i==0 ? 0 : v_chroma_shift; - if (s->flags & CODEC_FLAG_EMU_EDGE) - buf->data[i] = buf->base[i]; - else if (buf->base[i]) - buf->data[i] = buf->base[i] + - FFALIGN((buf->linesize[i]*edge >> v_shift) + - (pixel_size*edge >> h_shift), 32); - } - buf->w = s->width; - buf->h = s->height; - buf->pix_fmt = s->pix_fmt; - buf->pool = pool; - - *pbuf = buf; - return 0; -} - -int codec_get_buffer(AVCodecContext *s, AVFrame *frame) -{ - FrameBuffer **pool = s->opaque; - FrameBuffer *buf; - int ret, i; - - if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0) - return ret; - - buf = *pool; - *pool = buf->next; - buf->next = NULL; - if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) { - av_freep(&buf->base[0]); - av_free(buf); - if ((ret = alloc_buffer(pool, s, &buf)) < 0) - return ret; - } - buf->refcount++; - - frame->opaque = buf; - frame->type = FF_BUFFER_TYPE_USER; - frame->extended_data = frame->data; - - for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) { - frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't - frame->data[i] = buf->data[i]; - frame->linesize[i] = buf->linesize[i]; - } - - return 0; -} - -static void unref_buffer(FrameBuffer *buf) -{ - FrameBuffer **pool = buf->pool; - - av_assert0(buf->refcount); - buf->refcount--; - if (!buf->refcount) { - buf->next = *pool; - *pool = buf; - } -} - -void codec_release_buffer(AVCodecContext *s, AVFrame *frame) -{ - FrameBuffer *buf = frame->opaque; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++) - frame->data[i] = NULL; - - unref_buffer(buf); -} - -void filter_release_buffer(AVFilterBuffer *fb) -{ - FrameBuffer *buf = fb->priv; - av_free(fb); - unref_buffer(buf); -} - -void free_buffer_pool(FrameBuffer **pool) -{ - FrameBuffer *buf = *pool; - while (buf) { - *pool = buf->next; - av_freep(&buf->base[0]); - av_free(buf); - buf = *pool; - } -} diff --git a/cmdutils.h b/cmdutils.h index 84d906855b..cdcfc0728e 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -510,49 +510,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size); #define GROW_ARRAY(array, nb_elems)\ array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1) -typedef struct FrameBuffer { - uint8_t *base[4]; - uint8_t *data[4]; - int linesize[4]; - - int h, w; - enum AVPixelFormat pix_fmt; - - int refcount; - struct FrameBuffer **pool; ///< head of the buffer pool - struct FrameBuffer *next; -} FrameBuffer; - -/** - * Get a frame from the pool. This is intended to be used as a callback for - * AVCodecContext.get_buffer. - * - * @param s codec context. s->opaque must be a pointer to the head of the - * buffer pool. - * @param frame frame->opaque will be set to point to the FrameBuffer - * containing the frame data. - */ -int codec_get_buffer(AVCodecContext *s, AVFrame *frame); - -/** - * A callback to be used for AVCodecContext.release_buffer along with - * codec_get_buffer(). - */ -void codec_release_buffer(AVCodecContext *s, AVFrame *frame); - -/** - * A callback to be used for AVFilterBuffer.free. - * @param fb buffer to free. fb->priv must be a pointer to the FrameBuffer - * containing the buffer data. - */ -void filter_release_buffer(AVFilterBuffer *fb); - -/** - * Free all the buffers in the pool. This must be called after all the - * buffers have been released. - */ -void free_buffer_pool(FrameBuffer **pool); - #define GET_PIX_FMT_NAME(pix_fmt)\ const char *name = av_get_pix_fmt_name(pix_fmt);