From 79c8e29a7e404dbcf670df599fad6894f98ccab2 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 22 May 2012 14:43:28 -0700 Subject: [PATCH 01/16] aacdec: Turn PS off when switching to stereo and turn it to implicit when switching to mono. --- libavcodec/aacdec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index bd5ba00373..ddc7eef138 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -461,6 +461,7 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return NULL; ac->oc[1].m4ac.chan_config = 2; + ac->oc[1].m4ac.ps = 0; } // And vice-versa if (!ac->tags_mapped && type == TYPE_SCE && ac->oc[1].m4ac.chan_config == 2) { @@ -476,6 +477,8 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id) return NULL; ac->oc[1].m4ac.chan_config = 1; + if (ac->oc[1].m4ac.sbr) + ac->oc[1].m4ac.ps = -1; } // For indexed channel configurations map the channels solely based on position. switch (ac->oc[1].m4ac.chan_config) { From b56825c40ee1329b33aed34ff8a639fa18d263a0 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 4 Jun 2012 08:01:34 +0200 Subject: [PATCH 02/16] mpc8: fix maximum bands handling In Musepack SV8 codec property tell the maximum nonzero band, but every frame codes maximum band as a limit (i.e. strictly less than given value). Synthesis also expects maximum nonzero band, so there's a need to convert frame maximum band limit value. --- libavcodec/mpc8.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index f682edbed7..f2e8342dcb 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -270,7 +270,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); if(maxband > 32) maxband -= 33; } - if(maxband > c->maxbands) + if(maxband > c->maxbands + 1) return AVERROR_INVALIDDATA; c->last_max_band = maxband; @@ -405,7 +405,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, } } - ff_mpc_dequantize_and_synth(c, maxband, c->frame.data[0], avctx->channels); + ff_mpc_dequantize_and_synth(c, maxband - 1, c->frame.data[0], + avctx->channels); c->cur_frame++; From e58b75f7ff4733b0de17b2b91d1dac364627cb9d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 4 Jun 2012 20:01:55 +0200 Subject: [PATCH 03/16] avconv: fix exiting when max frames is reached. frame number should never be strictly larger than max frames, so the if() was never triggered. --- avconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv.c b/avconv.c index 3cbdfab143..f01dad0b2b 100644 --- a/avconv.c +++ b/avconv.c @@ -2871,7 +2871,7 @@ static int need_output(void) if (ost->is_past_recording_time || (os->pb && avio_tell(os->pb) >= of->limit_filesize)) continue; - if (ost->frame_number > ost->max_frames) { + if (ost->frame_number >= ost->max_frames) { int j; for (j = 0; j < of->ctx->nb_streams; j++) output_streams[of->ost_index + j]->is_past_recording_time = 1; From 3ffa233595fbf1b85841a55c8886e6942f8648d8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 07:32:43 +0200 Subject: [PATCH 04/16] avconv: don't use InputStream in the buffer management code. Use just the pointer to the head of the buffer pool. This will allow sharing the code with avplay. --- avconv.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/avconv.c b/avconv.c index f01dad0b2b..045fb27d48 100644 --- a/avconv.c +++ b/avconv.c @@ -180,7 +180,7 @@ typedef struct FrameBuffer { enum PixelFormat pix_fmt; int refcount; - struct InputStream *ist; + struct FrameBuffer **pool; ///< head of the buffer pool struct FrameBuffer *next; } FrameBuffer; @@ -449,7 +449,7 @@ static void reset_options(OptionsContext *o) init_opts(); } -static int alloc_buffer(InputStream *ist, AVCodecContext *s, FrameBuffer **pbuf) +static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf) { FrameBuffer *buf = av_mallocz(sizeof(*buf)); int i, ret; @@ -493,49 +493,51 @@ static int alloc_buffer(InputStream *ist, AVCodecContext *s, FrameBuffer **pbuf) buf->w = s->width; buf->h = s->height; buf->pix_fmt = s->pix_fmt; - buf->ist = ist; + buf->pool = pool; *pbuf = buf; return 0; } -static void free_buffer_pool(InputStream *ist) +static void free_buffer_pool(FrameBuffer **pool) { - FrameBuffer *buf = ist->buffer_pool; + FrameBuffer *buf = *pool; while (buf) { - ist->buffer_pool = buf->next; + *pool = buf->next; av_freep(&buf->base[0]); av_free(buf); - buf = ist->buffer_pool; + buf = *pool; } } -static void unref_buffer(InputStream *ist, FrameBuffer *buf) +static void unref_buffer(FrameBuffer *buf) { + FrameBuffer **pool = buf->pool; + av_assert0(buf->refcount); buf->refcount--; if (!buf->refcount) { - buf->next = ist->buffer_pool; - ist->buffer_pool = buf; + buf->next = *pool; + *pool = buf; } } static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) { - InputStream *ist = s->opaque; + FrameBuffer **pool = s->opaque; FrameBuffer *buf; int ret, i; - if (!ist->buffer_pool && (ret = alloc_buffer(ist, s, &ist->buffer_pool)) < 0) + if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0) return ret; - buf = ist->buffer_pool; - ist->buffer_pool = buf->next; + 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(ist, s, &buf)) < 0) + if ((ret = alloc_buffer(pool, s, &buf)) < 0) return ret; } buf->refcount++; @@ -560,21 +562,20 @@ static int codec_get_buffer(AVCodecContext *s, AVFrame *frame) static void codec_release_buffer(AVCodecContext *s, AVFrame *frame) { - InputStream *ist = s->opaque; FrameBuffer *buf = frame->opaque; int i; for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++) frame->data[i] = NULL; - unref_buffer(ist, buf); + unref_buffer(buf); } static void filter_release_buffer(AVFilterBuffer *fb) { FrameBuffer *buf = fb->priv; av_free(fb); - unref_buffer(buf->ist, buf); + unref_buffer(buf); } /** @@ -1205,7 +1206,7 @@ void exit_program(int ret) for (i = 0; i < nb_input_streams; i++) { av_freep(&input_streams[i]->decoded_frame); av_dict_free(&input_streams[i]->opts); - free_buffer_pool(input_streams[i]); + free_buffer_pool(&input_streams[i]->buffer_pool); av_freep(&input_streams[i]->filters); av_freep(&input_streams[i]); } @@ -2420,7 +2421,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; + ist->st->codec->opaque = &ist->buffer_pool; } if (!av_dict_get(ist->opts, "threads", NULL, 0)) From d55c2e05b5d07154ce374e159bbc1a6cf40e57d3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 07:57:59 +0200 Subject: [PATCH 05/16] avtools: move buffer management code from avconv to cmdutils. It will be used by avplay. --- avconv.c | 142 ----------------------------------------------------- cmdutils.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ cmdutils.h | 42 ++++++++++++++++ 3 files changed, 172 insertions(+), 142 deletions(-) diff --git a/avconv.c b/avconv.c index 045fb27d48..23ee164676 100644 --- a/avconv.c +++ b/avconv.c @@ -171,19 +171,6 @@ typedef struct FilterGraph { int nb_outputs; } FilterGraph; -typedef struct FrameBuffer { - uint8_t *base[4]; - uint8_t *data[4]; - int linesize[4]; - - int h, w; - enum PixelFormat pix_fmt; - - int refcount; - struct FrameBuffer **pool; ///< head of the buffer pool - struct FrameBuffer *next; -} FrameBuffer; - typedef struct InputStream { int file_index; AVStream *st; @@ -449,135 +436,6 @@ static void reset_options(OptionsContext *o) init_opts(); } -static int alloc_buffer(FrameBuffer **pool, AVCodecContext *s, FrameBuffer **pbuf) -{ - FrameBuffer *buf = av_mallocz(sizeof(*buf)); - int i, ret; - const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1; - 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 (!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; - } - /* XXX this shouldn't be needed, but some tests break without this line - * those decoders are buggy and need to be fixed. - * the following tests fail: - * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit - */ - memset(buf->base[0], 128, ret); - - avcodec_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 - 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; -} - -static void free_buffer_pool(FrameBuffer **pool) -{ - FrameBuffer *buf = *pool; - while (buf) { - *pool = buf->next; - av_freep(&buf->base[0]); - av_free(buf); - buf = *pool; - } -} - -static void unref_buffer(FrameBuffer *buf) -{ - FrameBuffer **pool = buf->pool; - - av_assert0(buf->refcount); - buf->refcount--; - if (!buf->refcount) { - buf->next = *pool; - *pool = buf; - } -} - -static 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; - frame->pkt_pts = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE; - frame->width = buf->w; - frame->height = buf->h; - frame->format = buf->pix_fmt; - frame->sample_aspect_ratio = s->sample_aspect_ratio; - - 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 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); -} - -static void filter_release_buffer(AVFilterBuffer *fb) -{ - FrameBuffer *buf = fb->priv; - av_free(fb); - unref_buffer(buf); -} - /** * Define a function for building a string containing a list of * allowed formats, diff --git a/cmdutils.c b/cmdutils.c index bd07d2ad89..abf89a3e43 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -37,6 +37,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/mathematics.h" +#include "libavutil/imgutils.h" #include "libavutil/parseutils.h" #include "libavutil/pixdesc.h" #include "libavutil/eval.h" @@ -1041,3 +1042,132 @@ 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) +{ + FrameBuffer *buf = av_mallocz(sizeof(*buf)); + int i, ret; + const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1; + 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 (!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; + } + /* XXX this shouldn't be needed, but some tests break without this line + * those decoders are buggy and need to be fixed. + * the following tests fail: + * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit + */ + memset(buf->base[0], 128, ret); + + avcodec_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 + 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; + frame->pkt_pts = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE; + frame->width = buf->w; + frame->height = buf->h; + frame->format = buf->pix_fmt; + frame->sample_aspect_ratio = s->sample_aspect_ratio; + + 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 6fff47ddeb..5dac13037a 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -383,4 +383,46 @@ void exit_program(int ret); */ void *grow_array(void *array, int elem_size, int *size, int new_size); +typedef struct FrameBuffer { + uint8_t *base[4]; + uint8_t *data[4]; + int linesize[4]; + + int h, w; + enum PixelFormat 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); #endif /* LIBAV_CMDUTILS_H */ From 67339f6eb41299096dd7de94f557b487ec3477ff Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 08:53:08 +0200 Subject: [PATCH 06/16] avplay: use buffersrc instead of custom input filter. We do not allow user filters, so avtools shouldn't use them either. It also allows to reuse buffer management code from avconv, thus reducing duplication. --- avplay.c | 297 ++++++++++++++----------------------------------------- 1 file changed, 76 insertions(+), 221 deletions(-) diff --git a/avplay.c b/avplay.c index d291ba384a..c01e446ab0 100644 --- a/avplay.c +++ b/avplay.c @@ -42,6 +42,7 @@ # include "libavfilter/avfilter.h" # include "libavfilter/avfiltergraph.h" # include "libavfilter/buffersink.h" +# include "libavfilter/buffersrc.h" #endif #include "cmdutils.h" @@ -212,7 +213,10 @@ typedef struct VideoState { PtsCorrectionContext pts_ctx; #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; @@ -1517,206 +1521,27 @@ static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacke } #if CONFIG_AVFILTER -typedef struct { - VideoState *is; - AVFrame *frame; - int use_dr1; -} FilterPriv; - -static int input_get_buffer(AVCodecContext *codec, AVFrame *pic) -{ - AVFilterContext *ctx = codec->opaque; - AVFilterBufferRef *ref; - int perms = AV_PERM_WRITE; - int i, w, h, stride[AV_NUM_DATA_POINTERS]; - unsigned edge; - int pixel_size; - - if (codec->codec->capabilities & CODEC_CAP_NEG_LINESIZES) - perms |= AV_PERM_NEG_LINESIZES; - - if (pic->buffer_hints & FF_BUFFER_HINTS_VALID) { - if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE) perms |= AV_PERM_READ; - if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE) perms |= AV_PERM_PRESERVE; - if (pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) perms |= AV_PERM_REUSE2; - } - if (pic->reference) perms |= AV_PERM_READ | AV_PERM_PRESERVE; - - w = codec->width; - h = codec->height; - avcodec_align_dimensions2(codec, &w, &h, stride); - edge = codec->flags & CODEC_FLAG_EMU_EDGE ? 0 : avcodec_get_edge_width(); - w += edge << 1; - h += edge << 1; - - if (!(ref = avfilter_get_video_buffer(ctx->outputs[0], perms, w, h))) - return -1; - - pixel_size = av_pix_fmt_descriptors[ref->format].comp[0].step_minus1 + 1; - ref->video->w = codec->width; - ref->video->h = codec->height; - for (i = 0; i < 4; i ++) { - unsigned hshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_w : 0; - unsigned vshift = (i == 1 || i == 2) ? av_pix_fmt_descriptors[ref->format].log2_chroma_h : 0; - - if (ref->data[i]) { - ref->data[i] += ((edge * pixel_size) >> hshift) + ((edge * ref->linesize[i]) >> vshift); - } - pic->data[i] = ref->data[i]; - pic->linesize[i] = ref->linesize[i]; - } - pic->opaque = ref; - pic->type = FF_BUFFER_TYPE_USER; - pic->reordered_opaque = codec->reordered_opaque; - pic->width = codec->width; - pic->height = codec->height; - pic->format = codec->pix_fmt; - pic->sample_aspect_ratio = codec->sample_aspect_ratio; - if (codec->pkt) pic->pkt_pts = codec->pkt->pts; - else pic->pkt_pts = AV_NOPTS_VALUE; - return 0; -} - -static void input_release_buffer(AVCodecContext *codec, AVFrame *pic) -{ - memset(pic->data, 0, sizeof(pic->data)); - avfilter_unref_buffer(pic->opaque); -} - -static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic) -{ - AVFilterBufferRef *ref = pic->opaque; - - if (pic->data[0] == NULL) { - pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return codec->get_buffer(codec, pic); - } - - if ((codec->width != ref->video->w) || (codec->height != ref->video->h) || - (codec->pix_fmt != ref->format)) { - av_log(codec, AV_LOG_ERROR, "Picture properties changed.\n"); - return -1; - } - - pic->reordered_opaque = codec->reordered_opaque; - if (codec->pkt) pic->pkt_pts = codec->pkt->pts; - else pic->pkt_pts = AV_NOPTS_VALUE; - return 0; -} - -static int input_init(AVFilterContext *ctx, const char *args, void *opaque) -{ - FilterPriv *priv = ctx->priv; - AVCodecContext *codec; - if (!opaque) return -1; - - priv->is = opaque; - codec = priv->is->video_st->codec; - codec->opaque = ctx; - if (codec->codec->capabilities & CODEC_CAP_DR1) { - priv->use_dr1 = 1; - codec->get_buffer = input_get_buffer; - codec->release_buffer = input_release_buffer; - codec->reget_buffer = input_reget_buffer; - codec->thread_safe_callbacks = 1; - } - - priv->frame = avcodec_alloc_frame(); - - return 0; -} - -static void input_uninit(AVFilterContext *ctx) -{ - FilterPriv *priv = ctx->priv; - av_free(priv->frame); -} - -static int input_request_frame(AVFilterLink *link) -{ - FilterPriv *priv = link->src->priv; - AVFilterBufferRef *picref; - int64_t pts = 0; - AVPacket pkt; - int ret; - - while (!(ret = get_video_frame(priv->is, priv->frame, &pts, &pkt))) - av_free_packet(&pkt); - if (ret < 0) - return -1; - - if (priv->use_dr1) { - picref = avfilter_ref_buffer(priv->frame->opaque, ~0); - } else { - picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, link->w, link->h); - av_image_copy(picref->data, picref->linesize, - priv->frame->data, priv->frame->linesize, - picref->format, link->w, link->h); - } - av_free_packet(&pkt); - - avfilter_copy_frame_props(picref, priv->frame); - picref->pts = pts; - - avfilter_start_frame(link, picref); - avfilter_draw_slice(link, 0, link->h, 1); - avfilter_end_frame(link); - - return 0; -} - -static int input_query_formats(AVFilterContext *ctx) -{ - FilterPriv *priv = ctx->priv; - enum PixelFormat pix_fmts[] = { - priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE - }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - return 0; -} - -static int input_config_props(AVFilterLink *link) -{ - FilterPriv *priv = link->src->priv; - AVCodecContext *c = priv->is->video_st->codec; - - link->w = c->width; - link->h = c->height; - link->time_base = priv->is->video_st->time_base; - - return 0; -} - -static AVFilter input_filter = -{ - .name = "avplay_input", - - .priv_size = sizeof(FilterPriv), - - .init = input_init, - .uninit = input_uninit, - - .query_formats = input_query_formats, - - .inputs = (AVFilterPad[]) {{ .name = NULL }}, - .outputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = input_request_frame, - .config_props = input_config_props, }, - { .name = NULL }}, -}; - static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters) { char sws_flags_str[128]; + char buffersrc_args[256]; int ret; AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format; + AVCodecContext *codec = is->video_st->codec; + snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags); graph->scale_sws_opts = av_strdup(sws_flags_str); - if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src", - NULL, is, graph)) < 0) + snprintf(buffersrc_args, sizeof(buffersrc_args), "%d:%d:%d:%d:%d:%d:%d", + codec->width, codec->height, codec->pix_fmt, + is->video_st->time_base.num, is->video_st->time_base.den, + codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den); + + + if ((ret = avfilter_graph_create_filter(&filt_src, + avfilter_get_by_name("buffer"), + "src", buffersrc_args, NULL, + graph)) < 0) return ret; if ((ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), @@ -1755,8 +1580,16 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c if ((ret = avfilter_graph_config(graph, NULL)) < 0) return ret; + 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; } @@ -1772,25 +1605,34 @@ static int video_thread(void *arg) #if CONFIG_AVFILTER AVFilterGraph *graph = avfilter_graph_alloc(); - AVFilterContext *filt_out = NULL; + 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; if ((ret = configure_video_filters(graph, is, vfilters)) < 0) goto the_end; + filt_in = is->in_video_filter; filt_out = is->out_video_filter; #endif for (;;) { -#if !CONFIG_AVFILTER AVPacket pkt; -#else +#if CONFIG_AVFILTER AVFilterBufferRef *picref; AVRational tb; #endif while (is->paused && !is->videoq.abort_request) SDL_Delay(10); + + ret = get_video_frame(is, frame, &pts_int, &pkt); + if (ret < 0) + goto the_end; + av_free_packet(&pkt); + + if (!ret) + continue; + #if CONFIG_AVFILTER if ( last_w != is->video_st->codec->width || last_h != is->video_st->codec->height) { @@ -1804,8 +1646,33 @@ static int video_thread(void *arg) last_w = is->video_st->codec->width; last_h = is->video_st->codec->height; } - ret = av_buffersink_read(filt_out, &picref); - if (picref) { + + 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); + + while (ret >= 0) { + ret = av_buffersink_read(filt_out, &picref); + if (ret < 0) { + ret = 0; + break; + } + avfilter_copy_buf_props(frame, picref); pts_int = picref->pts; @@ -1813,35 +1680,22 @@ static int video_thread(void *arg) pos = picref->pos; frame->opaque = picref; - ret = 1; - } - - if (ret >= 0 && 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); - av_dlog(NULL, "video_thread(): " - "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n", - tb.num, tb.den, pts1, - is->video_st->time_base.num, is->video_st->time_base.den, pts_int); + 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); + av_dlog(NULL, "video_thread(): " + "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n", + tb.num, tb.den, pts1, + 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); } #else - ret = get_video_frame(is, frame, &pts_int, &pkt); -#endif - - if (ret < 0) - goto the_end; - - if (!ret) - continue; - pts = pts_int * av_q2d(is->video_st->time_base); - -#if CONFIG_AVFILTER - ret = output_picture2(is, frame, pts, pos); -#else ret = output_picture2(is, frame, pts, pkt.pos); - av_free_packet(&pkt); #endif + if (ret < 0) goto the_end; @@ -2386,6 +2240,7 @@ static void stream_component_close(VideoState *is, int stream_index) ic->streams[stream_index]->discard = AVDISCARD_ALL; avcodec_close(avctx); + free_buffer_pool(&is->buffer_pool); switch (avctx->codec_type) { case AVMEDIA_TYPE_AUDIO: is->audio_st = NULL; From b74a1da49db5ebed51aceae6cacc2329288a92c1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 10:12:55 +0200 Subject: [PATCH 07/16] lavfi: make formats API private on next bump. It is only useful inside filters and we don't allow user filters for now. --- libavfilter/af_aformat.c | 8 +-- libavfilter/af_amix.c | 4 +- libavfilter/af_resample.c | 12 ++-- libavfilter/avfilter.c | 20 +++--- libavfilter/avfilter.h | 140 ++++++------------------------------ libavfilter/avfiltergraph.c | 18 ++--- libavfilter/buffersrc.c | 10 +-- libavfilter/formats.c | 58 +++++++++++---- libavfilter/formats.h | 138 +++++++++++++++++++++++++++++++++++ libavfilter/vf_blackframe.c | 3 +- libavfilter/vf_boxblur.c | 3 +- libavfilter/vf_crop.c | 3 +- libavfilter/vf_cropdetect.c | 3 +- libavfilter/vf_delogo.c | 3 +- libavfilter/vf_drawbox.c | 3 +- libavfilter/vf_drawtext.c | 3 +- libavfilter/vf_fade.c | 3 +- libavfilter/vf_fieldorder.c | 9 +-- libavfilter/vf_format.c | 5 +- libavfilter/vf_frei0r.c | 9 +-- libavfilter/vf_gradfun.c | 3 +- libavfilter/vf_hflip.c | 3 +- libavfilter/vf_hqdn3d.c | 3 +- libavfilter/vf_libopencv.c | 2 +- libavfilter/vf_lut.c | 3 +- libavfilter/vf_overlay.c | 11 +-- libavfilter/vf_pad.c | 3 +- libavfilter/vf_scale.c | 13 ++-- libavfilter/vf_transpose.c | 3 +- libavfilter/vf_unsharp.c | 3 +- libavfilter/vf_yadif.c | 3 +- libavfilter/vsrc_color.c | 3 +- libavfilter/vsrc_movie.c | 3 +- libavfilter/vsrc_nullsrc.c | 1 + libavfilter/vsrc_testsrc.c | 5 +- 35 files changed, 307 insertions(+), 210 deletions(-) diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c index 84442d379e..3a75b925dd 100644 --- a/libavfilter/af_aformat.c +++ b/libavfilter/af_aformat.c @@ -105,8 +105,8 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) } PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats, - avfilter_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); - PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, avfilter_add_format, + ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format"); + PARSE_FORMATS(s->sample_rates_str, int, s->sample_rates, ff_add_format, get_sample_rate, 0, "sample rate"); PARSE_FORMATS(s->channel_layouts_str, uint64_t, s->channel_layouts, ff_add_channel_layout, av_get_channel_layout, 0, @@ -121,8 +121,8 @@ static int query_formats(AVFilterContext *ctx) { AFormatContext *s = ctx->priv; - avfilter_set_common_formats(ctx, s->formats ? s->formats : - avfilter_all_formats(AVMEDIA_TYPE_AUDIO)); + ff_set_common_formats(ctx, s->formats ? s->formats : + ff_all_formats(AVMEDIA_TYPE_AUDIO)); ff_set_common_samplerates(ctx, s->sample_rates ? s->sample_rates : ff_all_samplerates()); ff_set_common_channel_layouts(ctx, s->channel_layouts ? s->channel_layouts : diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index d4af9a4234..d33d96ba6e 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -525,8 +525,8 @@ static void uninit(AVFilterContext *ctx) static int query_formats(AVFilterContext *ctx) { AVFilterFormats *formats = NULL; - avfilter_add_format(&formats, AV_SAMPLE_FMT_FLT); - avfilter_set_common_formats(ctx, formats); + ff_add_format(&formats, AV_SAMPLE_FMT_FLT); + ff_set_common_formats(ctx, formats); ff_set_common_channel_layouts(ctx, ff_all_channel_layouts()); ff_set_common_samplerates(ctx, ff_all_samplerates()); return 0; diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c index 1fc8c04b4a..6b1dfbc085 100644 --- a/libavfilter/af_resample.c +++ b/libavfilter/af_resample.c @@ -55,18 +55,18 @@ static int query_formats(AVFilterContext *ctx) AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; - AVFilterFormats *in_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *out_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); + AVFilterFormats *in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); + AVFilterFormats *out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); AVFilterFormats *in_samplerates = ff_all_samplerates(); AVFilterFormats *out_samplerates = ff_all_samplerates(); AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts(); AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts(); - avfilter_formats_ref(in_formats, &inlink->out_formats); - avfilter_formats_ref(out_formats, &outlink->in_formats); + ff_formats_ref(in_formats, &inlink->out_formats); + ff_formats_ref(out_formats, &outlink->in_formats); - avfilter_formats_ref(in_samplerates, &inlink->out_samplerates); - avfilter_formats_ref(out_samplerates, &outlink->in_samplerates); + ff_formats_ref(in_samplerates, &inlink->out_samplerates); + ff_formats_ref(out_samplerates, &outlink->in_samplerates); ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts); diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 2f5c37d3af..8594b8365c 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -120,10 +120,10 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, /* if any information on supported media formats already exists on the * link, we need to preserve that */ if (link->out_formats) - avfilter_formats_changeref(&link->out_formats, + ff_formats_changeref(&link->out_formats, &filt->outputs[filt_dstpad_idx]->out_formats); if (link->out_samplerates) - avfilter_formats_changeref(&link->out_samplerates, + ff_formats_changeref(&link->out_samplerates, &filt->outputs[filt_dstpad_idx]->out_samplerates); if (link->out_channel_layouts) ff_channel_layouts_changeref(&link->out_channel_layouts, @@ -380,10 +380,10 @@ void avfilter_free(AVFilterContext *filter) if ((link = filter->inputs[i])) { if (link->src) link->src->outputs[link->srcpad - link->src->output_pads] = NULL; - avfilter_formats_unref(&link->in_formats); - avfilter_formats_unref(&link->out_formats); - avfilter_formats_unref(&link->in_samplerates); - avfilter_formats_unref(&link->out_samplerates); + ff_formats_unref(&link->in_formats); + ff_formats_unref(&link->out_formats); + ff_formats_unref(&link->in_samplerates); + ff_formats_unref(&link->out_samplerates); ff_channel_layouts_unref(&link->in_channel_layouts); ff_channel_layouts_unref(&link->out_channel_layouts); } @@ -393,10 +393,10 @@ void avfilter_free(AVFilterContext *filter) if ((link = filter->outputs[i])) { if (link->dst) link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL; - avfilter_formats_unref(&link->in_formats); - avfilter_formats_unref(&link->out_formats); - avfilter_formats_unref(&link->in_samplerates); - avfilter_formats_unref(&link->out_samplerates); + ff_formats_unref(&link->in_formats); + ff_formats_unref(&link->out_formats); + ff_formats_unref(&link->in_samplerates); + ff_formats_unref(&link->out_samplerates); ff_channel_layouts_unref(&link->in_channel_layouts); ff_channel_layouts_unref(&link->out_channel_layouts); } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 289c06c331..37e783e41e 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -52,6 +52,7 @@ const char *avfilter_license(void); typedef struct AVFilterContext AVFilterContext; typedef struct AVFilterLink AVFilterLink; typedef struct AVFilterPad AVFilterPad; +typedef struct AVFilterFormats AVFilterFormats; /** * A reference-counted buffer data type used by the filter system. Filters @@ -197,134 +198,42 @@ AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask); */ void avfilter_unref_buffer(AVFilterBufferRef *ref); +#if FF_API_FILTERS_PUBLIC /** - * A list of supported formats for one end of a filter link. This is used - * during the format negotiation process to try to pick the best format to - * use to minimize the number of necessary conversions. Each filter gives a - * list of the formats supported by each input and output pad. The list - * given for each pad need not be distinct - they may be references to the - * same list of formats, as is often the case when a filter supports multiple - * formats, but will always output the same format as it is given in input. - * - * In this way, a list of possible input formats and a list of possible - * output formats are associated with each link. When a set of formats is - * negotiated over a link, the input and output lists are merged to form a - * new list containing only the common elements of each list. In the case - * that there were no common elements, a format conversion is necessary. - * Otherwise, the lists are merged, and all other links which reference - * either of the format lists involved in the merge are also affected. - * - * For example, consider the filter chain: - * filter (a) --> (b) filter (b) --> (c) filter - * - * where the letters in parenthesis indicate a list of formats supported on - * the input or output of the link. Suppose the lists are as follows: - * (a) = {A, B} - * (b) = {A, B, C} - * (c) = {B, C} - * - * First, the first link's lists are merged, yielding: - * filter (a) --> (a) filter (a) --> (c) filter - * - * Notice that format list (b) now refers to the same list as filter list (a). - * Next, the lists for the second link are merged, yielding: - * filter (a) --> (a) filter (a) --> (a) filter - * - * where (a) = {B}. - * - * Unfortunately, when the format lists at the two ends of a link are merged, - * we must ensure that all links which reference either pre-merge format list - * get updated as well. Therefore, we have the format list structure store a - * pointer to each of the pointers to itself. + * @addtogroup lavfi_deprecated + * @deprecated Those functions are only useful inside filters and + * user filters are not supported at this point. + * @{ */ -typedef struct AVFilterFormats { +struct AVFilterFormats { unsigned format_count; ///< number of formats int *formats; ///< list of media formats unsigned refcount; ///< number of references to this list struct AVFilterFormats ***refs; ///< references to this list -} AVFilterFormats; +}; -/** - * Create a list of supported formats. This is intended for use in - * AVFilter->query_formats(). - * - * @param fmts list of media formats, terminated by -1 - * @return the format list, with no existing references - */ +attribute_deprecated AVFilterFormats *avfilter_make_format_list(const int *fmts); - -/** - * Add fmt to the list of media formats contained in *avff. - * If *avff is NULL the function allocates the filter formats struct - * and puts its pointer in *avff. - * - * @return a non negative value in case of success, or a negative - * value corresponding to an AVERROR code in case of error - */ +attribute_deprecated int avfilter_add_format(AVFilterFormats **avff, int fmt); - -/** - * Return a list of all formats supported by Libav for the given media type. - */ +attribute_deprecated AVFilterFormats *avfilter_all_formats(enum AVMediaType type); - -/** - * Return a format list which contains the intersection of the formats of - * a and b. Also, all the references of a, all the references of b, and - * a and b themselves will be deallocated. - * - * If a and b do not share any common formats, neither is modified, and NULL - * is returned. - */ +attribute_deprecated AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b); - -/** - * Add *ref as a new reference to formats. - * That is the pointers will point like in the ascii art below: - * ________ - * |formats |<--------. - * | ____ | ____|___________________ - * | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| - * | |____| | | |____| - * |________| |________________________ - */ +attribute_deprecated void avfilter_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref); - -/** - * If *ref is non-NULL, remove *ref as a reference to the format list - * it currently points to, deallocates that list if this was the last - * reference, and sets *ref to NULL. - * - * Before After - * ________ ________ NULL - * |formats |<--------. |formats | ^ - * | ____ | ____|________________ | ____ | ____|________________ - * | |refs| | | __|_ | |refs| | | __|_ - * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink - * | |* *--------->|*ref| | |* | | | |*ref| - * | |____| | | |____| | |____| | | |____| - * |________| |_____________________ |________| |_____________________ - */ +attribute_deprecated void avfilter_formats_unref(AVFilterFormats **ref); - -/** - * - * Before After - * ________ ________ - * |formats |<---------. |formats |<---------. - * | ____ | ___|___ | ____ | ___|___ - * | |refs| | | | | | |refs| | | | | NULL - * | |* *--------->|*oldref| | |* *--------->|*newref| ^ - * | |* * | | |_______| | |* * | | |_______| ___|___ - * | |____| | | |____| | | | | - * |________| |________| |*oldref| - * |_______| - */ +attribute_deprecated void avfilter_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref); +attribute_deprecated +void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); +/** + * @} + */ +#endif /** * A filter pad used for either input or output. @@ -479,13 +388,6 @@ attribute_deprecated int avfilter_default_query_formats(AVFilterContext *ctx); #endif -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); - #if FF_API_FILTERS_PUBLIC /** start_frame() handler for filters which simply pass video along */ attribute_deprecated diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index bc275142d2..42bf1f7547 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -189,7 +189,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) continue; if (link->in_formats != link->out_formats && - !avfilter_merge_formats(link->in_formats, + !ff_merge_formats(link->in_formats, link->out_formats)) convert_needed = 1; if (link->type == AVMEDIA_TYPE_AUDIO) { @@ -246,8 +246,8 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) convert->filter->query_formats(convert); inlink = convert->inputs[0]; outlink = convert->outputs[0]; - if (!avfilter_merge_formats( inlink->in_formats, inlink->out_formats) || - !avfilter_merge_formats(outlink->in_formats, outlink->out_formats)) + if (!ff_merge_formats( inlink->in_formats, inlink->out_formats) || + !ff_merge_formats(outlink->in_formats, outlink->out_formats)) ret |= AVERROR(ENOSYS); if (inlink->type == AVMEDIA_TYPE_AUDIO && (!ff_merge_samplerates(inlink->in_samplerates, @@ -303,10 +303,10 @@ static int pick_format(AVFilterLink *link) link->channel_layout = link->in_channel_layouts->channel_layouts[0]; } - avfilter_formats_unref(&link->in_formats); - avfilter_formats_unref(&link->out_formats); - avfilter_formats_unref(&link->in_samplerates); - avfilter_formats_unref(&link->out_samplerates); + ff_formats_unref(&link->in_formats); + ff_formats_unref(&link->out_formats); + ff_formats_unref(&link->in_samplerates); + ff_formats_unref(&link->out_samplerates); ff_channel_layouts_unref(&link->in_channel_layouts); ff_channel_layouts_unref(&link->out_channel_layouts); @@ -353,9 +353,9 @@ static int reduce_formats_on_filter(AVFilterContext *filter) int i, j, k, ret = 0; REDUCE_FORMATS(int, AVFilterFormats, formats, formats, - format_count, avfilter_add_format); + format_count, ff_add_format); REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats, - format_count, avfilter_add_format); + format_count, ff_add_format); REDUCE_FORMATS(uint64_t, AVFilterChannelLayouts, channel_layouts, channel_layouts, nb_channel_layouts, ff_add_channel_layout); diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index ca9390aa5a..f78b8f6eff 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -284,14 +284,14 @@ static int query_formats(AVFilterContext *ctx) switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: - avfilter_add_format(&formats, c->pix_fmt); - avfilter_set_common_formats(ctx, formats); + ff_add_format(&formats, c->pix_fmt); + ff_set_common_formats(ctx, formats); break; case AVMEDIA_TYPE_AUDIO: - avfilter_add_format(&formats, c->sample_fmt); - avfilter_set_common_formats(ctx, formats); + ff_add_format(&formats, c->sample_fmt); + ff_set_common_formats(ctx, formats); - avfilter_add_format(&samplerates, c->sample_rate); + ff_add_format(&samplerates, c->sample_rate); ff_set_common_samplerates(ctx, samplerates); ff_add_channel_layout(&channel_layouts, c->channel_layout); diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 63c63e32b4..83bdcd7a7a 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -76,7 +76,7 @@ do { MERGE_REF(ret, b, fmts, type, fail); \ } while (0) -AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) +AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b) { AVFilterFormats *ret = NULL; @@ -161,7 +161,7 @@ int ff_fmt_is_in(int fmt, const int *fmts) return 0; } -AVFilterFormats *avfilter_make_format_list(const int *fmts) +AVFilterFormats *ff_make_format_list(const int *fmts) { AVFilterFormats *formats; int count; @@ -195,7 +195,7 @@ do { \ return 0; \ } while (0) -int avfilter_add_format(AVFilterFormats **avff, int fmt) +int ff_add_format(AVFilterFormats **avff, int fmt) { ADD_FORMAT(avff, fmt, int, formats, format_count); } @@ -205,7 +205,7 @@ int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts); } -AVFilterFormats *avfilter_all_formats(enum AVMediaType type) +AVFilterFormats *ff_all_formats(enum AVMediaType type) { AVFilterFormats *ret = NULL; int fmt; @@ -215,7 +215,7 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type) for (fmt = 0; fmt < num_formats; fmt++) if ((type != AVMEDIA_TYPE_VIDEO) || (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL))) - avfilter_add_format(&ret, fmt); + ff_add_format(&ret, fmt); return ret; } @@ -244,7 +244,7 @@ void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts ** FORMATS_REF(f, ref); } -void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) +void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) { FORMATS_REF(f, ref); } @@ -280,7 +280,7 @@ do { \ *ref = NULL; \ } while (0) -void avfilter_formats_unref(AVFilterFormats **ref) +void ff_formats_unref(AVFilterFormats **ref) { FORMATS_UNREF(ref, formats); } @@ -309,8 +309,7 @@ void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, FORMATS_CHANGEREF(oldref, newref); } -void avfilter_formats_changeref(AVFilterFormats **oldref, - AVFilterFormats **newref) +void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) { FORMATS_CHANGEREF(oldref, newref); } @@ -350,7 +349,7 @@ void ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates) { SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates, - avfilter_formats_ref, formats); + ff_formats_ref, formats); } /** @@ -358,10 +357,10 @@ void ff_set_common_samplerates(AVFilterContext *ctx, * formats. If there are no links hooked to this filter, the list of formats is * freed. */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) +void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) { SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats, - avfilter_formats_ref, formats); + ff_formats_ref, formats); } int ff_default_query_formats(AVFilterContext *ctx) @@ -370,7 +369,7 @@ int ff_default_query_formats(AVFilterContext *ctx) ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : AVMEDIA_TYPE_VIDEO; - avfilter_set_common_formats(ctx, avfilter_all_formats(type)); + ff_set_common_formats(ctx, ff_all_formats(type)); if (type == AVMEDIA_TYPE_AUDIO) { ff_set_common_channel_layouts(ctx, ff_all_channel_layouts()); ff_set_common_samplerates(ctx, ff_all_samplerates()); @@ -384,4 +383,37 @@ int avfilter_default_query_formats(AVFilterContext *ctx) { return ff_default_query_formats(ctx); } +void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) +{ + ff_set_common_formats(ctx, formats); +} +AVFilterFormats *avfilter_make_format_list(const int *fmts) +{ + return ff_make_format_list(fmts); +} +int avfilter_add_format(AVFilterFormats **avff, int fmt) +{ + return ff_add_format(avff, fmt); +} +AVFilterFormats *avfilter_all_formats(enum AVMediaType type) +{ + return ff_all_formats(type); +} +AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) +{ + return ff_merge_formats(a, b); +} +void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) +{ + ff_formats_ref(f, ref); +} +void avfilter_formats_unref(AVFilterFormats **ref) +{ + ff_formats_unref(ref); +} +void avfilter_formats_changeref(AVFilterFormats **oldref, + AVFilterFormats **newref) +{ + ff_formats_changeref(oldref, newref); +} #endif diff --git a/libavfilter/formats.h b/libavfilter/formats.h index 9acd31f38a..8961cb1a65 100644 --- a/libavfilter/formats.h +++ b/libavfilter/formats.h @@ -21,6 +21,56 @@ #include "avfilter.h" +/** + * A list of supported formats for one end of a filter link. This is used + * during the format negotiation process to try to pick the best format to + * use to minimize the number of necessary conversions. Each filter gives a + * list of the formats supported by each input and output pad. The list + * given for each pad need not be distinct - they may be references to the + * same list of formats, as is often the case when a filter supports multiple + * formats, but will always output the same format as it is given in input. + * + * In this way, a list of possible input formats and a list of possible + * output formats are associated with each link. When a set of formats is + * negotiated over a link, the input and output lists are merged to form a + * new list containing only the common elements of each list. In the case + * that there were no common elements, a format conversion is necessary. + * Otherwise, the lists are merged, and all other links which reference + * either of the format lists involved in the merge are also affected. + * + * For example, consider the filter chain: + * filter (a) --> (b) filter (b) --> (c) filter + * + * where the letters in parenthesis indicate a list of formats supported on + * the input or output of the link. Suppose the lists are as follows: + * (a) = {A, B} + * (b) = {A, B, C} + * (c) = {B, C} + * + * First, the first link's lists are merged, yielding: + * filter (a) --> (a) filter (a) --> (c) filter + * + * Notice that format list (b) now refers to the same list as filter list (a). + * Next, the lists for the second link are merged, yielding: + * filter (a) --> (a) filter (a) --> (a) filter + * + * where (a) = {B}. + * + * Unfortunately, when the format lists at the two ends of a link are merged, + * we must ensure that all links which reference either pre-merge format list + * get updated as well. Therefore, we have the format list structure store a + * pointer to each of the pointers to itself. + */ +#if !FF_API_FILTERS_PUBLIC +struct AVFilterFormats { + unsigned format_count; ///< number of formats + int *formats; ///< list of media formats + + unsigned refcount; ///< number of references to this list + struct AVFilterFormats ***refs; ///< references to this list +}; +#endif + typedef struct AVFilterChannelLayouts { uint64_t *channel_layouts; ///< list of channel layouts int nb_channel_layouts; ///< number of channel layouts @@ -59,6 +109,13 @@ void ff_set_common_channel_layouts(AVFilterContext *ctx, void ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates); +/** + * A helper for query_formats() which sets all links to the same list of + * formats. If there are no links hooked to this filter, the list of formats is + * freed. + */ +void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); + int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout); /** @@ -77,4 +134,85 @@ void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, int ff_default_query_formats(AVFilterContext *ctx); + +/** + * Create a list of supported formats. This is intended for use in + * AVFilter->query_formats(). + * + * @param fmts list of media formats, terminated by -1 + * @return the format list, with no existing references + */ +AVFilterFormats *ff_make_format_list(const int *fmts); + +/** + * Add fmt to the list of media formats contained in *avff. + * If *avff is NULL the function allocates the filter formats struct + * and puts its pointer in *avff. + * + * @return a non negative value in case of success, or a negative + * value corresponding to an AVERROR code in case of error + */ +int ff_add_format(AVFilterFormats **avff, int fmt); + +/** + * Return a list of all formats supported by Libav for the given media type. + */ +AVFilterFormats *ff_all_formats(enum AVMediaType type); + +/** + * Return a format list which contains the intersection of the formats of + * a and b. Also, all the references of a, all the references of b, and + * a and b themselves will be deallocated. + * + * If a and b do not share any common formats, neither is modified, and NULL + * is returned. + */ +AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b); + +/** + * Add *ref as a new reference to formats. + * That is the pointers will point like in the ascii art below: + * ________ + * |formats |<--------. + * | ____ | ____|___________________ + * | |refs| | | __|_ + * | |* * | | | | | | AVFilterLink + * | |* *--------->|*ref| + * | |____| | | |____| + * |________| |________________________ + */ +void ff_formats_ref(AVFilterFormats *formats, AVFilterFormats **ref); + +/** + * If *ref is non-NULL, remove *ref as a reference to the format list + * it currently points to, deallocates that list if this was the last + * reference, and sets *ref to NULL. + * + * Before After + * ________ ________ NULL + * |formats |<--------. |formats | ^ + * | ____ | ____|________________ | ____ | ____|________________ + * | |refs| | | __|_ | |refs| | | __|_ + * | |* * | | | | | | AVFilterLink | |* * | | | | | | AVFilterLink + * | |* *--------->|*ref| | |* | | | |*ref| + * | |____| | | |____| | |____| | | |____| + * |________| |_____________________ |________| |_____________________ + */ +void ff_formats_unref(AVFilterFormats **ref); + +/** + * + * Before After + * ________ ________ + * |formats |<---------. |formats |<---------. + * | ____ | ___|___ | ____ | ___|___ + * | |refs| | | | | | |refs| | | | | NULL + * | |* *--------->|*oldref| | |* *--------->|*newref| ^ + * | |* * | | |_______| | |* * | | |_______| ___|___ + * | |____| | | |____| | | | | + * |________| |________| |*oldref| + * |_______| + */ +void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref); + #endif // AVFILTER_FORMATS_H diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 7e69ccb1f6..bdc132285e 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -28,6 +28,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "video.h" typedef struct { @@ -45,7 +46,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c index fa739de48d..04486ce1a8 100644 --- a/libavfilter/vf_boxblur.c +++ b/libavfilter/vf_boxblur.c @@ -29,6 +29,7 @@ #include "libavutil/eval.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" static const char *const var_names[] = { "w", @@ -129,7 +130,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 5452601068..cb8b94ef7e 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -26,6 +26,7 @@ /* #define DEBUG */ #include "avfilter.h" +#include "formats.h" #include "video.h" #include "libavutil/eval.h" #include "libavutil/avstring.h" @@ -106,7 +107,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index d321afdd40..20bc219d81 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -25,6 +25,7 @@ #include "libavutil/imgutils.h" #include "avfilter.h" +#include "formats.h" #include "video.h" typedef struct { @@ -47,7 +48,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index a54abe1a79..3410982b63 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "video.h" /** @@ -165,7 +166,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index fc80402f60..46ce6979a0 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -28,6 +28,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/parseutils.h" #include "avfilter.h" +#include "formats.h" #include "video.h" enum { Y, U, V, A }; @@ -71,7 +72,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 5ef0d8c1ca..92f14a7ba8 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -41,6 +41,7 @@ #include "libavutil/lfg.h" #include "avfilter.h" #include "drawutils.h" +#include "formats.h" #include "video.h" #undef time @@ -396,7 +397,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index a0f37d2ad5..8bd4074592 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -27,6 +27,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "video.h" typedef struct { @@ -79,7 +80,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index 444dffb52c..d975aab974 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -28,6 +28,7 @@ #include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" typedef struct { @@ -76,12 +77,12 @@ static int query_formats(AVFilterContext *ctx) || av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_BITSTREAM) && av_pix_fmt_descriptors[pix_fmt].nb_components && !av_pix_fmt_descriptors[pix_fmt].log2_chroma_h - && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) { - avfilter_formats_unref(&formats); + && (ret = ff_add_format(&formats, pix_fmt)) < 0) { + ff_formats_unref(&formats); return ret; } - avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats); - avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats); + ff_formats_ref(formats, &ctx->inputs[0]->out_formats); + ff_formats_ref(formats, &ctx->outputs[0]->in_formats); } return 0; diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c index aaaca277df..fff616b06a 100644 --- a/libavfilter/vf_format.c +++ b/libavfilter/vf_format.c @@ -25,6 +25,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "video.h" typedef struct { @@ -89,7 +90,7 @@ static AVFilterFormats *make_format_list(FormatContext *format, int flag) #if CONFIG_FORMAT_FILTER static int query_formats_format(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); + ff_set_common_formats(ctx, make_format_list(ctx->priv, 1)); return 0; } @@ -119,7 +120,7 @@ AVFilter avfilter_vf_format = { #if CONFIG_NOFORMAT_FILTER static int query_formats_noformat(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); + ff_set_common_formats(ctx, make_format_list(ctx->priv, 0)); return 0; } diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 455e24a7f1..4dd6fbef09 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -31,6 +31,7 @@ #include "libavutil/mathematics.h" #include "libavutil/parseutils.h" #include "avfilter.h" +#include "formats.h" typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height); typedef void (*f0r_destruct_f)(f0r_instance_t instance); @@ -320,20 +321,20 @@ static int query_formats(AVFilterContext *ctx) AVFilterFormats *formats = NULL; if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) { - avfilter_add_format(&formats, PIX_FMT_BGRA); + ff_add_format(&formats, PIX_FMT_BGRA); } else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) { - avfilter_add_format(&formats, PIX_FMT_RGBA); + ff_add_format(&formats, PIX_FMT_RGBA); } else { /* F0R_COLOR_MODEL_PACKED32 */ static const enum PixelFormat pix_fmts[] = { PIX_FMT_BGRA, PIX_FMT_ARGB, PIX_FMT_ABGR, PIX_FMT_ARGB, PIX_FMT_NONE }; - formats = avfilter_make_format_list(pix_fmts); + formats = ff_make_format_list(pix_fmts); } if (!formats) return AVERROR(ENOMEM); - avfilter_set_common_formats(ctx, formats); + ff_set_common_formats(ctx, formats); return 0; } diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 9da9b20a70..b61c06317c 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -36,6 +36,7 @@ #include "libavutil/cpu.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "gradfun.h" DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = { @@ -160,7 +161,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index c92296e61a..5e87a7dc13 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -25,6 +25,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/pixdesc.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" @@ -62,7 +63,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 2e9a89510b..51de0d8de6 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -27,6 +27,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" typedef struct { int Coefs[4][512*16]; @@ -268,7 +269,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 6e343af7ef..2bbbb6a373 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -61,7 +61,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_BGR24, PIX_FMT_BGRA, PIX_FMT_GRAY8, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index b4950f4e36..29f8b3ce78 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "internal.h" static const char *const var_names[] = { @@ -163,7 +164,7 @@ static int query_formats(AVFilterContext *ctx) enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts : lut->is_yuv ? yuv_pix_fmts : all_pix_fmts; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index e8171e0069..571d48dfad 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -26,6 +26,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/eval.h" #include "libavutil/avstring.h" #include "libavutil/pixdesc.h" @@ -94,12 +95,12 @@ static int query_formats(AVFilterContext *ctx) { const enum PixelFormat inout_pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; const enum PixelFormat blend_pix_fmts[] = { PIX_FMT_YUVA420P, PIX_FMT_NONE }; - AVFilterFormats *inout_formats = avfilter_make_format_list(inout_pix_fmts); - AVFilterFormats *blend_formats = avfilter_make_format_list(blend_pix_fmts); + AVFilterFormats *inout_formats = ff_make_format_list(inout_pix_fmts); + AVFilterFormats *blend_formats = ff_make_format_list(blend_pix_fmts); - avfilter_formats_ref(inout_formats, &ctx->inputs [MAIN ]->out_formats); - avfilter_formats_ref(blend_formats, &ctx->inputs [OVERLAY]->out_formats); - avfilter_formats_ref(inout_formats, &ctx->outputs[MAIN ]->in_formats ); + ff_formats_ref(inout_formats, &ctx->inputs [MAIN ]->out_formats); + ff_formats_ref(blend_formats, &ctx->inputs [OVERLAY]->out_formats); + ff_formats_ref(inout_formats, &ctx->outputs[MAIN ]->in_formats ); return 0; } diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index fdadb1a7c7..1091a212d0 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -25,6 +25,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/pixdesc.h" @@ -84,7 +85,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 85095b78d7..82a3181cb5 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -24,6 +24,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/mathematics.h" @@ -123,21 +124,21 @@ static int query_formats(AVFilterContext *ctx) formats = NULL; for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) if ( sws_isSupportedInput(pix_fmt) - && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) { - avfilter_formats_unref(&formats); + && (ret = ff_add_format(&formats, pix_fmt)) < 0) { + ff_formats_unref(&formats); return ret; } - avfilter_formats_ref(formats, &ctx->inputs[0]->out_formats); + ff_formats_ref(formats, &ctx->inputs[0]->out_formats); } if (ctx->outputs[0]) { formats = NULL; for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) if ( sws_isSupportedOutput(pix_fmt) - && (ret = avfilter_add_format(&formats, pix_fmt)) < 0) { - avfilter_formats_unref(&formats); + && (ret = ff_add_format(&formats, pix_fmt)) < 0) { + ff_formats_unref(&formats); return ret; } - avfilter_formats_ref(formats, &ctx->outputs[0]->in_formats); + ff_formats_ref(formats, &ctx->outputs[0]->in_formats); } return 0; diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index a0ec67c426..7801066824 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -29,6 +29,7 @@ #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" #include "avfilter.h" +#include "formats.h" typedef struct { int hsub, vsub; @@ -83,7 +84,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 7aca2cf32f..9c0809f331 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -37,6 +37,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/common.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" @@ -162,7 +163,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 0c72444bee..694b984764 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -23,6 +23,7 @@ #include "libavutil/common.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "formats.h" #include "video.h" #include "yadif.h" @@ -387,7 +388,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 94b5a29719..803196ebf7 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -24,6 +24,7 @@ */ #include "avfilter.h" +#include "formats.h" #include "libavutil/pixdesc.h" #include "libavutil/colorspace.h" #include "libavutil/imgutils.h" @@ -100,7 +101,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 4ac079c5a2..45772319c6 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -36,6 +36,7 @@ #include "libavutil/imgutils.h" #include "libavformat/avformat.h" #include "avfilter.h" +#include "formats.h" typedef struct { const AVClass *class; @@ -202,7 +203,7 @@ static int query_formats(AVFilterContext *ctx) MovieContext *movie = ctx->priv; enum PixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_nullsrc.c b/libavfilter/vsrc_nullsrc.c index 4f9dd79346..d145b0b277 100644 --- a/libavfilter/vsrc_nullsrc.c +++ b/libavfilter/vsrc_nullsrc.c @@ -26,6 +26,7 @@ #include "libavutil/mathematics.h" #include "libavutil/parseutils.h" #include "avfilter.h" +#include "formats.h" static const char *const var_names[] = { "E", diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 0f5596b715..43495d6fd4 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -37,6 +37,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/parseutils.h" #include "avfilter.h" +#include "formats.h" typedef struct { const AVClass *class; @@ -348,7 +349,7 @@ static int test_query_formats(AVFilterContext *ctx) static const enum PixelFormat pix_fmts[] = { PIX_FMT_RGB24, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } @@ -459,7 +460,7 @@ static int rgbtest_query_formats(AVFilterContext *ctx) PIX_FMT_RGB555, PIX_FMT_BGR555, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); return 0; } From fa417fcd278a003530fe6bf851f8194177a5e71f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 10:31:48 +0200 Subject: [PATCH 08/16] lavfi: make avfilter_insert_pad and pals private on next bump. They are only useful inside filters and we don't allow user filters for now. --- libavfilter/af_amix.c | 2 +- libavfilter/avfilter.c | 24 +++++++++++++++++++++--- libavfilter/avfilter.h | 37 +++++++++---------------------------- libavfilter/internal.h | 33 +++++++++++++++++++++++++++++++++ libavfilter/split.c | 3 ++- 5 files changed, 66 insertions(+), 33 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index d33d96ba6e..8f8ae3e340 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -497,7 +497,7 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque) pad.name = av_strdup(name); pad.filter_samples = filter_samples; - avfilter_insert_inpad(ctx, i, &pad); + ff_insert_inpad(ctx, i, &pad); } return 0; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 8594b8365c..6b73e48d81 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -44,9 +44,9 @@ const char *avfilter_license(void) return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1; } -void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, - AVFilterPad **pads, AVFilterLink ***links, - AVFilterPad *newpad) +void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, + AVFilterPad **pads, AVFilterLink ***links, + AVFilterPad *newpad) { unsigned i; @@ -426,4 +426,22 @@ int avfilter_default_config_output_link(AVFilterLink *link) { return 0; } +void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, + AVFilterPad **pads, AVFilterLink ***links, + AVFilterPad *newpad) +{ + ff_insert_pad(idx, count, padidx_off, pads, links, newpad); +} +void avfilter_insert_inpad(AVFilterContext *f, unsigned index, + AVFilterPad *p) +{ + ff_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), + &f->input_pads, &f->inputs, p); +} +void avfilter_insert_outpad(AVFilterContext *f, unsigned index, + AVFilterPad *p) +{ + ff_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), + &f->output_pads, &f->outputs, p); +} #endif diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 37e783e41e..0f5a35fc73 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -749,38 +749,19 @@ void avfilter_free(AVFilterContext *filter); int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, unsigned filt_srcpad_idx, unsigned filt_dstpad_idx); -/** - * Insert a new pad. - * - * @param idx Insertion point. Pad is inserted at the end if this point - * is beyond the end of the list of pads. - * @param count Pointer to the number of pads in the list - * @param padidx_off Offset within an AVFilterLink structure to the element - * to increment when inserting a new pad causes link - * numbering to change - * @param pads Pointer to the pointer to the beginning of the list of pads - * @param links Pointer to the pointer to the beginning of the list of links - * @param newpad The new pad to add. A copy is made when adding. - */ +#if FF_API_FILTERS_PUBLIC +attribute_deprecated void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, AVFilterPad **pads, AVFilterLink ***links, AVFilterPad *newpad); -/** Insert a new input pad for the filter. */ -static inline void avfilter_insert_inpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), - &f->input_pads, &f->inputs, p); -} - -/** Insert a new output pad for the filter. */ -static inline void avfilter_insert_outpad(AVFilterContext *f, unsigned index, - AVFilterPad *p) -{ - avfilter_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), - &f->output_pads, &f->outputs, p); -} +attribute_deprecated +void avfilter_insert_inpad(AVFilterContext *f, unsigned index, + AVFilterPad *p); +attribute_deprecated +void avfilter_insert_outpad(AVFilterContext *f, unsigned index, + AVFilterPad *p); +#endif /** * Copy the frame properties of src to dst, without copying the actual diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 4eb65305f9..7f7cf45771 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -36,4 +36,37 @@ int ff_fmt_is_in(int fmt, const int *fmts); void ff_dlog_link(void *ctx, AVFilterLink *link, int end); +/** + * Insert a new pad. + * + * @param idx Insertion point. Pad is inserted at the end if this point + * is beyond the end of the list of pads. + * @param count Pointer to the number of pads in the list + * @param padidx_off Offset within an AVFilterLink structure to the element + * to increment when inserting a new pad causes link + * numbering to change + * @param pads Pointer to the pointer to the beginning of the list of pads + * @param links Pointer to the pointer to the beginning of the list of links + * @param newpad The new pad to add. A copy is made when adding. + */ +void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, + AVFilterPad **pads, AVFilterLink ***links, + AVFilterPad *newpad); + +/** Insert a new input pad for the filter. */ +static inline void ff_insert_inpad(AVFilterContext *f, unsigned index, + AVFilterPad *p) +{ + ff_insert_pad(index, &f->input_count, offsetof(AVFilterLink, dstpad), + &f->input_pads, &f->inputs, p); +} + +/** Insert a new output pad for the filter. */ +static inline void ff_insert_outpad(AVFilterContext *f, unsigned index, + AVFilterPad *p) +{ + ff_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), + &f->output_pads, &f->outputs, p); +} + #endif /* AVFILTER_INTERNAL_H */ diff --git a/libavfilter/split.c b/libavfilter/split.c index da33b7d183..9f7890cde6 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -25,6 +25,7 @@ #include "avfilter.h" #include "audio.h" +#include "internal.h" #include "video.h" static int split_init(AVFilterContext *ctx, const char *args, void *opaque) @@ -48,7 +49,7 @@ static int split_init(AVFilterContext *ctx, const char *args, void *opaque) pad.type = ctx->filter->inputs[0].type; pad.name = av_strdup(name); - avfilter_insert_outpad(ctx, i, &pad); + ff_insert_outpad(ctx, i, &pad); } return 0; From 803391f7195ba37a553026009ff989d6e2625d8f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 30 May 2012 11:20:32 +0200 Subject: [PATCH 09/16] lavfi: remove request/poll and drawing functions from public API on next bump They are only useful inside filters and we don't allow user filters for now. --- libavfilter/af_amix.c | 4 +-- libavfilter/af_asyncts.c | 3 ++- libavfilter/af_resample.c | 2 +- libavfilter/avfilter.c | 16 ++++++++--- libavfilter/avfilter.h | 51 +++++------------------------------- libavfilter/buffersink.c | 5 ++-- libavfilter/buffersrc.c | 7 ++--- libavfilter/internal.h | 17 ++++++++++++ libavfilter/split.c | 8 +++--- libavfilter/vf_aspect.c | 2 +- libavfilter/vf_blackframe.c | 4 +-- libavfilter/vf_boxblur.c | 3 ++- libavfilter/vf_crop.c | 6 ++--- libavfilter/vf_cropdetect.c | 2 +- libavfilter/vf_delogo.c | 6 ++--- libavfilter/vf_drawbox.c | 2 +- libavfilter/vf_drawtext.c | 6 ++--- libavfilter/vf_fade.c | 4 +-- libavfilter/vf_fieldorder.c | 9 ++++--- libavfilter/vf_fifo.c | 9 ++++--- libavfilter/vf_fps.c | 16 ++++++----- libavfilter/vf_frei0r.c | 11 ++++---- libavfilter/vf_gradfun.c | 7 ++--- libavfilter/vf_hflip.c | 3 ++- libavfilter/vf_hqdn3d.c | 5 ++-- libavfilter/vf_libopencv.c | 4 +-- libavfilter/vf_lut.c | 3 ++- libavfilter/vf_overlay.c | 13 ++++----- libavfilter/vf_pad.c | 9 ++++--- libavfilter/vf_pixdesctest.c | 5 ++-- libavfilter/vf_scale.c | 9 ++++--- libavfilter/vf_select.c | 19 +++++++------- libavfilter/vf_setpts.c | 2 +- libavfilter/vf_settb.c | 2 +- libavfilter/vf_showinfo.c | 2 +- libavfilter/vf_slicify.c | 10 +++---- libavfilter/vf_transpose.c | 7 ++--- libavfilter/vf_unsharp.c | 5 ++-- libavfilter/vf_vflip.c | 4 +-- libavfilter/vf_yadif.c | 23 ++++++++-------- libavfilter/video.c | 30 ++++++++++++++------- libavfilter/video.h | 35 +++++++++++++++++++++++++ libavfilter/vsrc_color.c | 7 ++--- libavfilter/vsrc_movie.c | 7 ++--- libavfilter/vsrc_testsrc.c | 7 ++--- 45 files changed, 235 insertions(+), 176 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 8f8ae3e340..3fc2e8499a 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -349,7 +349,7 @@ static int request_samples(AVFilterContext *ctx, int min_samples) if (s->input_state[i] == INPUT_OFF) continue; while (!ret && av_audio_fifo_size(s->fifos[i]) < min_samples) - ret = avfilter_request_frame(ctx->inputs[i]); + ret = ff_request_frame(ctx->inputs[i]); if (ret == AVERROR_EOF) { if (av_audio_fifo_size(s->fifos[i]) == 0) { s->input_state[i] = INPUT_OFF; @@ -410,7 +410,7 @@ static int request_frame(AVFilterLink *outlink) } if (s->frame_list->nb_frames == 0) { - ret = avfilter_request_frame(ctx->inputs[0]); + ret = ff_request_frame(ctx->inputs[0]); if (ret == AVERROR_EOF) { s->input_state[0] = INPUT_OFF; if (s->nb_inputs == 1) diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c index adb5347a80..252b32278d 100644 --- a/libavfilter/af_asyncts.c +++ b/libavfilter/af_asyncts.c @@ -24,6 +24,7 @@ #include "audio.h" #include "avfilter.h" +#include "internal.h" typedef struct ASyncContext { const AVClass *class; @@ -116,7 +117,7 @@ static int request_frame(AVFilterLink *link) { AVFilterContext *ctx = link->src; ASyncContext *s = ctx->priv; - int ret = avfilter_request_frame(ctx->inputs[0]); + int ret = ff_request_frame(ctx->inputs[0]); int nb_samples; /* flush the fifo */ diff --git a/libavfilter/af_resample.c b/libavfilter/af_resample.c index 6b1dfbc085..8a02cfe976 100644 --- a/libavfilter/af_resample.c +++ b/libavfilter/af_resample.c @@ -130,7 +130,7 @@ static int request_frame(AVFilterLink *outlink) { AVFilterContext *ctx = outlink->src; ResampleContext *s = ctx->priv; - int ret = avfilter_request_frame(ctx->inputs[0]); + int ret = ff_request_frame(ctx->inputs[0]); /* flush the lavr delay buffer */ if (ret == AVERROR_EOF && s->avr) { diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 6b73e48d81..3dbb6920ee 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -223,18 +223,18 @@ void ff_dlog_link(void *ctx, AVFilterLink *link, int end) } } -int avfilter_request_frame(AVFilterLink *link) +int ff_request_frame(AVFilterLink *link) { FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1); if (link->srcpad->request_frame) return link->srcpad->request_frame(link); else if (link->src->inputs[0]) - return avfilter_request_frame(link->src->inputs[0]); + return ff_request_frame(link->src->inputs[0]); else return -1; } -int avfilter_poll_frame(AVFilterLink *link) +int ff_poll_frame(AVFilterLink *link) { int i, min = INT_MAX; @@ -245,7 +245,7 @@ int avfilter_poll_frame(AVFilterLink *link) int val; if (!link->src->inputs[i]) return -1; - val = avfilter_poll_frame(link->src->inputs[i]); + val = ff_poll_frame(link->src->inputs[i]); min = FFMIN(min, val); } @@ -444,4 +444,12 @@ void avfilter_insert_outpad(AVFilterContext *f, unsigned index, ff_insert_pad(index, &f->output_count, offsetof(AVFilterLink, srcpad), &f->output_pads, &f->outputs, p); } +int avfilter_poll_frame(AVFilterLink *link) +{ + return ff_poll_frame(link); +} +int avfilter_request_frame(AVFilterLink *link) +{ + return ff_request_frame(link); +} #endif diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 0f5a35fc73..c592372ced 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -620,57 +620,20 @@ AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_arrays(uint8_t **data, enum AVSampleFormat sample_fmt, uint64_t channel_layout); -/** - * Request an input frame from the filter at the other end of the link. - * - * @param link the input link - * @return zero on success - */ +#if FF_API_FILTERS_PUBLIC +attribute_deprecated int avfilter_request_frame(AVFilterLink *link); -/** - * Poll a frame from the filter chain. - * - * @param link the input link - * @return the number of immediately available frames, a negative - * number in case of error - */ +attribute_deprecated int avfilter_poll_frame(AVFilterLink *link); -/** - * Notify the next filter of the start of a frame. - * - * @param link the output link the frame will be sent over - * @param picref A reference to the frame about to be sent. The data for this - * frame need only be valid once draw_slice() is called for that - * portion. The receiving filter will free this reference when - * it no longer needs it. - */ +attribute_deprecated void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); - -/** - * Notifie the next filter that the current frame has finished. - * - * @param link the output link the frame was sent over - */ +attribute_deprecated void avfilter_end_frame(AVFilterLink *link); - -/** - * Send a slice to the next filter. - * - * Slices have to be provided in sequential order, either in - * top-bottom or bottom-top order. If slices are provided in - * non-sequential order the behavior of the function is undefined. - * - * @param link the output link over which the frame is being sent - * @param y offset in pixels from the top of the image for this slice - * @param h height of this slice in pixels - * @param slice_dir the assumed direction for sending slices, - * from the top slice to the bottom slice if the value is 1, - * from the bottom slice to the top slice if the value is -1, - * for other values the behavior of the function is undefined. - */ +attribute_deprecated void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); +#endif /** Initialize the filter system. Register all builtin filters. */ void avfilter_register_all(void); diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c index 8787268f4c..13fb2558c1 100644 --- a/libavfilter/buffersink.c +++ b/libavfilter/buffersink.c @@ -31,6 +31,7 @@ #include "audio.h" #include "avfilter.h" #include "buffersink.h" +#include "internal.h" typedef struct { AVFifoBuffer *fifo; ///< FIFO buffer of frame references @@ -102,11 +103,11 @@ int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf) if (av_fifo_size(sink->fifo)) return av_fifo_size(sink->fifo)/sizeof(*buf); else - return avfilter_poll_frame(ctx->inputs[0]); + return ff_poll_frame(ctx->inputs[0]); } if (!av_fifo_size(sink->fifo) && - (ret = avfilter_request_frame(link)) < 0) + (ret = ff_request_frame(link)) < 0) return ret; if (!av_fifo_size(sink->fifo)) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index f78b8f6eff..7af9f6c571 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -27,6 +27,7 @@ #include "avfilter.h" #include "buffersrc.h" #include "formats.h" +#include "video.h" #include "vsrc_buffer.h" #include "libavutil/audioconvert.h" @@ -340,9 +341,9 @@ static int request_frame(AVFilterLink *link) switch (link->type) { case AVMEDIA_TYPE_VIDEO: - avfilter_start_frame(link, avfilter_ref_buffer(buf, ~0)); - avfilter_draw_slice(link, 0, link->h, 1); - avfilter_end_frame(link); + ff_start_frame(link, avfilter_ref_buffer(buf, ~0)); + ff_draw_slice(link, 0, link->h, 1); + ff_end_frame(link); break; case AVMEDIA_TYPE_AUDIO: ff_filter_samples(link, avfilter_ref_buffer(buf, ~0)); diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 7f7cf45771..4b53831063 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -69,4 +69,21 @@ static inline void ff_insert_outpad(AVFilterContext *f, unsigned index, &f->output_pads, &f->outputs, p); } +/** + * Poll a frame from the filter chain. + * + * @param link the input link + * @return the number of immediately available frames, a negative + * number in case of error + */ +int ff_poll_frame(AVFilterLink *link); + +/** + * Request an input frame from the filter at the other end of the link. + * + * @param link the input link + * @return zero on success + */ +int ff_request_frame(AVFilterLink *link); + #endif /* AVFILTER_INTERNAL_H */ diff --git a/libavfilter/split.c b/libavfilter/split.c index 9f7890cde6..95c1b9aa1f 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -69,8 +69,8 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) int i; for (i = 0; i < ctx->output_count; i++) - avfilter_start_frame(ctx->outputs[i], - avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); + ff_start_frame(ctx->outputs[i], + avfilter_ref_buffer(picref, ~AV_PERM_WRITE)); } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) @@ -79,7 +79,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) int i; for (i = 0; i < ctx->output_count; i++) - avfilter_draw_slice(ctx->outputs[i], y, h, slice_dir); + ff_draw_slice(ctx->outputs[i], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) @@ -88,7 +88,7 @@ static void end_frame(AVFilterLink *inlink) int i; for (i = 0; i < ctx->output_count; i++) - avfilter_end_frame(ctx->outputs[i]); + ff_end_frame(ctx->outputs[i]); avfilter_unref_buffer(inlink->cur_buf); } diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c index 4e1fdac90e..0555afe4c0 100644 --- a/libavfilter/vf_aspect.c +++ b/libavfilter/vf_aspect.c @@ -68,7 +68,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) AspectContext *aspect = link->dst->priv; picref->video->pixel_aspect = aspect->aspect; - avfilter_start_frame(link->dst->outputs[0], picref); + ff_start_frame(link->dst->outputs[0], picref); } #if CONFIG_SETDAR_FILTER diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index bdc132285e..1d9a75d502 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -87,7 +87,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) p += picref->linesize[0]; } - avfilter_draw_slice(ctx->outputs[0], y, h, slice_dir); + ff_draw_slice(ctx->outputs[0], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) @@ -105,7 +105,7 @@ static void end_frame(AVFilterLink *inlink) blackframe->frame++; blackframe->nblack = 0; - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_blackframe = { diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c index 04486ce1a8..21a0173ccb 100644 --- a/libavfilter/vf_boxblur.c +++ b/libavfilter/vf_boxblur.c @@ -30,6 +30,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" +#include "video.h" static const char *const var_names[] = { "w", @@ -328,7 +329,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir) w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane], boxblur->temp); - avfilter_draw_slice(outlink, y0, h0, slice_dir); + ff_draw_slice(outlink, y0, h0, slice_dir); } AVFilter avfilter_vf_boxblur = { diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index cb8b94ef7e..f25278e79e 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -290,7 +290,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) ref2->data[3] += crop->x * crop->max_step[3]; } - avfilter_start_frame(link->dst->outputs[0], ref2); + ff_start_frame(link->dst->outputs[0], ref2); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) @@ -308,7 +308,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (y + h > crop->y + crop->h) h = crop->y + crop->h - y; - avfilter_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); + ff_draw_slice(ctx->outputs[0], y - crop->y, h, slice_dir); } static void end_frame(AVFilterLink *link) @@ -317,7 +317,7 @@ static void end_frame(AVFilterLink *link) crop->var_values[VAR_N] += 1.0; avfilter_unref_buffer(link->cur_buf); - avfilter_end_frame(link->dst->outputs[0]); + ff_end_frame(link->dst->outputs[0]); } AVFilter avfilter_vf_crop = { diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 20bc219d81..38fd5c1355 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -190,7 +190,7 @@ static void end_frame(AVFilterLink *inlink) w, h, x, y); } - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_cropdetect = { diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c index 3410982b63..6fe47306ea 100644 --- a/libavfilter/vf_delogo.c +++ b/libavfilter/vf_delogo.c @@ -228,7 +228,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref = inpicref; outlink->out_buf = outpicref; - avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); } static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } @@ -257,8 +257,8 @@ static void end_frame(AVFilterLink *inlink) delogo->show, direct); } - avfilter_draw_slice(outlink, 0, inlink->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, inlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(inpicref); if (!direct) avfilter_unref_buffer(outpicref); diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 46ce6979a0..47db0490a7 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -119,7 +119,7 @@ static void draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir) } } - avfilter_draw_slice(inlink->dst->outputs[0], y0, h, 1); + ff_draw_slice(inlink->dst->outputs[0], y0, h, 1); } AVFilter avfilter_vf_drawbox = { diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 92f14a7ba8..411bcbc781 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -849,7 +849,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) (int)dtext->var_values[VAR_N], dtext->var_values[VAR_T], dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h); - avfilter_start_frame(inlink->dst->outputs[0], inpicref); + ff_start_frame(inlink->dst->outputs[0], inpicref); } static void end_frame(AVFilterLink *inlink) @@ -863,8 +863,8 @@ static void end_frame(AVFilterLink *inlink) dtext->var_values[VAR_N] += 1.0; - avfilter_draw_slice(outlink, 0, picref->video->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, picref->video->h, 1); + ff_end_frame(outlink); } AVFilter avfilter_vf_drawtext = { diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 8bd4074592..6b9cb66fe6 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -133,14 +133,14 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) { FadeContext *fade = inlink->dst->priv; - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); if (fade->frame_index >= fade->start_frame && fade->frame_index <= fade->stop_frame) diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c index d975aab974..ff1e332572 100644 --- a/libavfilter/vf_fieldorder.c +++ b/libavfilter/vf_fieldorder.c @@ -29,6 +29,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef struct { @@ -124,7 +125,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref = avfilter_ref_buffer(inpicref, ~0); outlink->out_buf = outpicref; - avfilter_start_frame(outlink, outpicref); + ff_start_frame(outlink, outpicref); } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) @@ -141,7 +142,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) * and that complexity will be added later */ if ( !inpicref->video->interlaced || inpicref->video->top_field_first == fieldorder->dst_tff) { - avfilter_draw_slice(outlink, y, h, slice_dir); + ff_draw_slice(outlink, y, h, slice_dir); } } @@ -203,13 +204,13 @@ static void end_frame(AVFilterLink *inlink) } } outpicref->video->top_field_first = fieldorder->dst_tff; - avfilter_draw_slice(outlink, 0, h, 1); + ff_draw_slice(outlink, 0, h, 1); } else { av_dlog(ctx, "not interlaced or field order already correct\n"); } - avfilter_end_frame(outlink); + ff_end_frame(outlink); avfilter_unref_buffer(inpicref); } diff --git a/libavfilter/vf_fifo.c b/libavfilter/vf_fifo.c index b99cec38dc..1785946a4f 100644 --- a/libavfilter/vf_fifo.c +++ b/libavfilter/vf_fifo.c @@ -24,6 +24,7 @@ */ #include "avfilter.h" +#include "internal.h" #include "video.h" typedef struct BufPic { @@ -77,15 +78,15 @@ static int request_frame(AVFilterLink *outlink) int ret; if (!fifo->root.next) { - if ((ret = avfilter_request_frame(outlink->src->inputs[0]) < 0)) + if ((ret = ff_request_frame(outlink->src->inputs[0]) < 0)) return ret; } /* by doing this, we give ownership of the reference to the next filter, * so we don't have to worry about dereferencing it ourselves. */ - avfilter_start_frame(outlink, fifo->root.next->picref); - avfilter_draw_slice (outlink, 0, outlink->h, 1); - avfilter_end_frame (outlink); + ff_start_frame(outlink, fifo->root.next->picref); + ff_draw_slice (outlink, 0, outlink->h, 1); + ff_end_frame (outlink); if (fifo->last == fifo->root.next) fifo->last = &fifo->root; diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c index da38af299b..18cd51a9a8 100644 --- a/libavfilter/vf_fps.c +++ b/libavfilter/vf_fps.c @@ -27,6 +27,8 @@ #include "libavutil/parseutils.h" #include "avfilter.h" +#include "internal.h" +#include "video.h" typedef struct FPSContext { const AVClass *class; @@ -129,7 +131,7 @@ static int request_frame(AVFilterLink *outlink) int ret = 0; while (ret >= 0 && s->frames_out == frames_out) - ret = avfilter_request_frame(ctx->inputs[0]); + ret = ff_request_frame(ctx->inputs[0]); /* flush the fifo */ if (ret == AVERROR_EOF && av_fifo_size(s->fifo)) { @@ -141,9 +143,9 @@ static int request_frame(AVFilterLink *outlink) buf->pts = av_rescale_q(s->first_pts, ctx->inputs[0]->time_base, outlink->time_base) + s->frames_out; - avfilter_start_frame(outlink, buf); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_start_frame(outlink, buf); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); s->frames_out++; } return 0; @@ -229,9 +231,9 @@ static void end_frame(AVFilterLink *inlink) buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base, outlink->time_base) + s->frames_out; - avfilter_start_frame(outlink, buf_out); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_start_frame(outlink, buf_out); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); s->frames_out++; } flush_fifo(s->fifo); diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 4dd6fbef09..85b4205559 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -32,6 +32,7 @@ #include "libavutil/parseutils.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height); typedef void (*f0r_destruct_f)(f0r_instance_t instance); @@ -351,8 +352,8 @@ static void end_frame(AVFilterLink *inlink) (const uint32_t *)inpicref->data[0], (uint32_t *)outpicref->data[0]); avfilter_unref_buffer(inpicref); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(outpicref); } @@ -436,11 +437,11 @@ static int source_request_frame(AVFilterLink *outlink) picref->pts = frei0r->pts++; picref->pos = -1; - avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}), NULL, (uint32_t *)picref->data[0]); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(picref); return 0; diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index b61c06317c..7fde16d41b 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -38,6 +38,7 @@ #include "avfilter.h" #include "formats.h" #include "gradfun.h" +#include "video.h" DECLARE_ALIGNED(16, static const uint16_t, dither)[8][8] = { {0x00,0x60,0x18,0x78,0x06,0x66,0x1E,0x7E}, @@ -197,7 +198,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref = inpicref; outlink->out_buf = outpicref; - avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); } static void null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { } @@ -226,8 +227,8 @@ static void end_frame(AVFilterLink *inlink) av_image_copy_plane(outpic->data[p], outpic->linesize[p], inpic->data[p], inpic->linesize[p], w, h); } - avfilter_draw_slice(outlink, 0, inlink->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, inlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(inpic); if (outpic != inpic) avfilter_unref_buffer(outpic); diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index 5e87a7dc13..aff0f8c5d3 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -26,6 +26,7 @@ #include "avfilter.h" #include "formats.h" +#include "video.h" #include "libavutil/pixdesc.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" @@ -140,7 +141,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } AVFilter avfilter_vf_hflip = { diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 51de0d8de6..0a26dd0017 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -28,6 +28,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef struct { int Coefs[4][512*16]; @@ -318,8 +319,8 @@ static void end_frame(AVFilterLink *inlink) hqdn3d->Coefs[2], hqdn3d->Coefs[3]); - avfilter_draw_slice(outlink, 0, inpic->video->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, inpic->video->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(inpic); avfilter_unref_buffer(outpic); } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 2bbbb6a373..b6dcd191ae 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -364,8 +364,8 @@ static void end_frame(AVFilterLink *inlink) fill_picref_from_iplimage(outpicref, &outimg, inlink->format); avfilter_unref_buffer(inpicref); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(outpicref); } diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 29f8b3ce78..3817228960 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -31,6 +31,7 @@ #include "avfilter.h" #include "formats.h" #include "internal.h" +#include "video.h" static const char *const var_names[] = { "E", @@ -338,7 +339,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - avfilter_draw_slice(outlink, y, h, slice_dir); + ff_draw_slice(outlink, y, h, slice_dir); } #define DEFINE_LUT_FILTER(name_, description_, init_) \ diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 571d48dfad..55f1cc3a14 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -33,6 +33,7 @@ #include "libavutil/imgutils.h" #include "libavutil/mathematics.h" #include "internal.h" +#include "video.h" static const char *const var_names[] = { "E", @@ -220,7 +221,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) if (!over->overpicref || over->overpicref->pts < outpicref->pts) { AVFilterBufferRef *old = over->overpicref; over->overpicref = NULL; - avfilter_request_frame(ctx->inputs[OVERLAY]); + ff_request_frame(ctx->inputs[OVERLAY]); if (over->overpicref) { if (old) avfilter_unref_buffer(old); @@ -228,7 +229,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) over->overpicref = old; } - avfilter_start_frame(inlink->dst->outputs[0], outpicref); + ff_start_frame(inlink->dst->outputs[0], outpicref); } static void start_frame_overlay(AVFilterLink *inlink, AVFilterBufferRef *inpicref) @@ -333,12 +334,12 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) over->overpicref->video->w, over->overpicref->video->h, y, outpicref->video->w, h); } - avfilter_draw_slice(outlink, y, h, slice_dir); + ff_draw_slice(outlink, y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) { - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); avfilter_unref_buffer(inlink->cur_buf); } @@ -350,12 +351,12 @@ static int poll_frame(AVFilterLink *link) { AVFilterContext *s = link->src; OverlayContext *over = s->priv; - int ret = avfilter_poll_frame(s->inputs[OVERLAY]); + int ret = ff_poll_frame(s->inputs[OVERLAY]); if (ret == AVERROR_EOF) ret = !!over->overpicref; - return ret && avfilter_poll_frame(s->inputs[MAIN]); + return ret && ff_poll_frame(s->inputs[MAIN]); } AVFilter avfilter_vf_overlay = { diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 1091a212d0..2e98aea028 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -26,6 +26,7 @@ #include "avfilter.h" #include "formats.h" +#include "video.h" #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/pixdesc.h" @@ -337,12 +338,12 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref->video->w = pad->w; outpicref->video->h = pad->h; - avfilter_start_frame(inlink->dst->outputs[0], outpicref); + ff_start_frame(inlink->dst->outputs[0], outpicref); } static void end_frame(AVFilterLink *link) { - avfilter_end_frame(link->dst->outputs[0]); + ff_end_frame(link->dst->outputs[0]); avfilter_unref_buffer(link->cur_buf); } @@ -366,7 +367,7 @@ static void draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, link->dst->outputs[0]->out_buf->linesize, pad->line, pad->line_step, pad->hsub, pad->vsub, 0, bar_y, pad->w, bar_h); - avfilter_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir); + ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir); } } @@ -400,7 +401,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step, pad->hsub, pad->vsub, pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h); - avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); draw_send_bar_slice(link, y, h, slice_dir, -1); } diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c index cf7dfeda3e..7eecdc0bb1 100644 --- a/libavfilter/vf_pixdesctest.c +++ b/libavfilter/vf_pixdesctest.c @@ -25,6 +25,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "video.h" typedef struct { const AVPixFmtDescriptor *pix_desc; @@ -76,7 +77,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) priv->pix_desc->flags & PIX_FMT_PSEUDOPAL) memcpy(outpicref->data[1], outpicref->data[1], 256*4); - avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); } static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) @@ -106,7 +107,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) } } - avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } AVFilter avfilter_vf_pixdesctest = { diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 82a3181cb5..6f33848f20 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -25,6 +25,7 @@ #include "avfilter.h" #include "formats.h" +#include "video.h" #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/mathematics.h" @@ -257,7 +258,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) AVFilterBufferRef *outpicref; if (!scale->sws) { - avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); return; } @@ -277,7 +278,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) INT_MAX); scale->slice_y = 0; - avfilter_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outpicref, ~0)); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) @@ -288,7 +289,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) const uint8_t *data[4]; if (!scale->sws) { - avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); return; } @@ -308,7 +309,7 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (slice_dir == -1) scale->slice_y -= out_h; - avfilter_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); + ff_draw_slice(link->dst->outputs[0], scale->slice_y, out_h, slice_dir); if (slice_dir == 1) scale->slice_y += out_h; } diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index 2b6b49c153..dab47ced85 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -27,6 +27,7 @@ #include "libavutil/fifo.h" #include "libavutil/mathematics.h" #include "avfilter.h" +#include "internal.h" #include "video.h" static const char *const var_names[] = { @@ -242,7 +243,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) sizeof(picref), NULL); return; } - avfilter_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); + ff_start_frame(inlink->dst->outputs[0], avfilter_ref_buffer(picref, ~0)); } } @@ -251,7 +252,7 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) SelectContext *select = inlink->dst->priv; if (select->select && !select->cache_frames) - avfilter_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir); } static void end_frame(AVFilterLink *inlink) @@ -262,7 +263,7 @@ static void end_frame(AVFilterLink *inlink) if (select->select) { if (select->cache_frames) return; - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); } avfilter_unref_buffer(picref); } @@ -277,15 +278,15 @@ static int request_frame(AVFilterLink *outlink) if (av_fifo_size(select->pending_frames)) { AVFilterBufferRef *picref; av_fifo_generic_read(select->pending_frames, &picref, sizeof(picref), NULL); - avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(picref); return 0; } while (!select->select) { - int ret = avfilter_request_frame(inlink); + int ret = ff_request_frame(inlink); if (ret < 0) return ret; } @@ -300,12 +301,12 @@ static int poll_frame(AVFilterLink *outlink) int count, ret; if (!av_fifo_size(select->pending_frames)) { - if ((count = avfilter_poll_frame(inlink)) <= 0) + if ((count = ff_poll_frame(inlink)) <= 0) return count; /* request frame from input, and apply select condition to it */ select->cache_frames = 1; while (count-- && av_fifo_space(select->pending_frames)) { - ret = avfilter_request_frame(inlink); + ret = ff_request_frame(inlink); if (ret < 0) break; } diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c index 103f265782..d303851686 100644 --- a/libavfilter/vf_setpts.c +++ b/libavfilter/vf_setpts.c @@ -129,7 +129,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) setpts->var_values[VAR_N] += 1.0; setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts); setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts); - avfilter_start_frame(inlink->dst->outputs[0], outpicref); + ff_start_frame(inlink->dst->outputs[0], outpicref); } static av_cold void uninit(AVFilterContext *ctx) diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c index b40ede87cb..78d4617526 100644 --- a/libavfilter/vf_settb.c +++ b/libavfilter/vf_settb.c @@ -119,7 +119,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) avfilter_unref_buffer(picref); } - avfilter_start_frame(outlink, picref2); + ff_start_frame(outlink, picref2); } AVFilter avfilter_vf_settb = { diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 0475f9bf90..1a8f16e2c3 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -75,7 +75,7 @@ static void end_frame(AVFilterLink *inlink) checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]); showinfo->frame++; - avfilter_end_frame(inlink->dst->outputs[0]); + ff_end_frame(inlink->dst->outputs[0]); } AVFilter avfilter_vf_showinfo = { diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c index 31d74979af..fdc10bea9d 100644 --- a/libavfilter/vf_slicify.c +++ b/libavfilter/vf_slicify.c @@ -73,7 +73,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) av_log(link->dst, AV_LOG_DEBUG, "h:%d\n", slice->h); - avfilter_start_frame(link->dst->outputs[0], picref); + ff_start_frame(link->dst->outputs[0], picref); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) @@ -83,16 +83,16 @@ static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) if (slice_dir == 1) { for (y2 = y; y2 + slice->h <= y + h; y2 += slice->h) - avfilter_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); + ff_draw_slice(link->dst->outputs[0], y2, slice->h, slice_dir); if (y2 < y + h) - avfilter_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); + ff_draw_slice(link->dst->outputs[0], y2, y + h - y2, slice_dir); } else if (slice_dir == -1) { for (y2 = y + h; y2 - slice->h >= y; y2 -= slice->h) - avfilter_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); + ff_draw_slice(link->dst->outputs[0], y2 - slice->h, slice->h, slice_dir); if (y2 > y) - avfilter_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); + ff_draw_slice(link->dst->outputs[0], y, y2 - y, slice_dir); } } diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index 7801066824..5e5feda85f 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -30,6 +30,7 @@ #include "libavutil/imgutils.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef struct { int hsub, vsub; @@ -130,7 +131,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num; } - avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); } static void end_frame(AVFilterLink *inlink) @@ -191,8 +192,8 @@ static void end_frame(AVFilterLink *inlink) } avfilter_unref_buffer(inpic); - avfilter_draw_slice(outlink, 0, outpic->video->h, 1); - avfilter_end_frame(outlink); + ff_draw_slice(outlink, 0, outpic->video->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(outpic); } diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index 9c0809f331..a5d301cd72 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -38,6 +38,7 @@ #include "avfilter.h" #include "formats.h" +#include "video.h" #include "libavutil/common.h" #include "libavutil/mem.h" #include "libavutil/pixdesc.h" @@ -224,8 +225,8 @@ static void end_frame(AVFilterLink *link) apply_unsharp(out->data[2], out->linesize[2], in->data[2], in->linesize[2], cw, ch, &unsharp->chroma); avfilter_unref_buffer(in); - avfilter_draw_slice(link->dst->outputs[0], 0, link->h, 1); - avfilter_end_frame(link->dst->outputs[0]); + ff_draw_slice(link->dst->outputs[0], 0, link->h, 1); + ff_end_frame(link->dst->outputs[0]); avfilter_unref_buffer(out); } diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c index a7f14c0775..6d2f42ed5d 100644 --- a/libavfilter/vf_vflip.c +++ b/libavfilter/vf_vflip.c @@ -78,14 +78,14 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) } } - avfilter_start_frame(link->dst->outputs[0], outpicref); + ff_start_frame(link->dst->outputs[0], outpicref); } static void draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { AVFilterContext *ctx = link->dst; - avfilter_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); + ff_draw_slice(ctx->outputs[0], link->h - (y+h), h, -1 * slice_dir); } AVFilter avfilter_vf_vflip = { diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 694b984764..b498ab9d39 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -24,6 +24,7 @@ #include "libavutil/pixdesc.h" #include "avfilter.h" #include "formats.h" +#include "internal.h" #include "video.h" #include "yadif.h" @@ -229,10 +230,10 @@ static void return_frame(AVFilterContext *ctx, int is_second) } else { yadif->out->pts = AV_NOPTS_VALUE; } - avfilter_start_frame(ctx->outputs[0], yadif->out); + ff_start_frame(ctx->outputs[0], yadif->out); } - avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1); - avfilter_end_frame(ctx->outputs[0]); + ff_draw_slice(ctx->outputs[0], 0, link->h, 1); + ff_end_frame(ctx->outputs[0]); yadif->frame_pending = (yadif->mode&1) && !is_second; } @@ -260,7 +261,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->prev = NULL; if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; - avfilter_start_frame(ctx->outputs[0], yadif->out); + ff_start_frame(ctx->outputs[0], yadif->out); return; } @@ -274,7 +275,7 @@ static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref) yadif->out->video->interlaced = 0; if (yadif->out->pts != AV_NOPTS_VALUE) yadif->out->pts *= 2; - avfilter_start_frame(ctx->outputs[0], yadif->out); + ff_start_frame(ctx->outputs[0], yadif->out); } static void end_frame(AVFilterLink *link) @@ -286,8 +287,8 @@ static void end_frame(AVFilterLink *link) return; if (yadif->auto_enable && !yadif->cur->video->interlaced) { - avfilter_draw_slice(ctx->outputs[0], 0, link->h, 1); - avfilter_end_frame(ctx->outputs[0]); + ff_draw_slice(ctx->outputs[0], 0, link->h, 1); + ff_end_frame(ctx->outputs[0]); return; } @@ -310,7 +311,7 @@ static int request_frame(AVFilterLink *link) if (yadif->eof) return AVERROR_EOF; - ret = avfilter_request_frame(link->src->inputs[0]); + ret = ff_request_frame(link->src->inputs[0]); if (ret == AVERROR_EOF && yadif->next) { AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, AV_PERM_READ); @@ -335,14 +336,14 @@ static int poll_frame(AVFilterLink *link) if (yadif->frame_pending) return 1; - val = avfilter_poll_frame(link->src->inputs[0]); + val = ff_poll_frame(link->src->inputs[0]); if (val <= 0) return val; if (val==1 && !yadif->next) { //FIXME change API to not requre this red tape - if ((ret = avfilter_request_frame(link->src->inputs[0])) < 0) + if ((ret = ff_request_frame(link->src->inputs[0])) < 0) return ret; - val = avfilter_poll_frame(link->src->inputs[0]); + val = ff_poll_frame(link->src->inputs[0]); if (val <= 0) return val; } diff --git a/libavfilter/video.c b/libavfilter/video.c index 6a19388f6e..33082a1482 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -162,7 +162,7 @@ AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { - avfilter_start_frame(link->dst->outputs[0], picref); + ff_start_frame(link->dst->outputs[0], picref); } static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) @@ -175,13 +175,13 @@ static void default_start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) if (outlink) { outlink->out_buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); avfilter_copy_buffer_ref_props(outlink->out_buf, picref); - avfilter_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); + ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0)); } } /* XXX: should we do the duplicating of the picture ref here, instead of * forcing the source filter to do it? */ -void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { void (*start_frame)(AVFilterLink *, AVFilterBufferRef *); AVFilterPad *dst = link->dstpad; @@ -213,7 +213,7 @@ void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) void ff_null_end_frame(AVFilterLink *link) { - avfilter_end_frame(link->dst->outputs[0]); + ff_end_frame(link->dst->outputs[0]); } static void default_end_frame(AVFilterLink *inlink) @@ -231,11 +231,11 @@ static void default_end_frame(AVFilterLink *inlink) avfilter_unref_buffer(outlink->out_buf); outlink->out_buf = NULL; } - avfilter_end_frame(outlink); + ff_end_frame(outlink); } } -void avfilter_end_frame(AVFilterLink *link) +void ff_end_frame(AVFilterLink *link) { void (*end_frame)(AVFilterLink *); @@ -254,7 +254,7 @@ void avfilter_end_frame(AVFilterLink *link) void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { - avfilter_draw_slice(link->dst->outputs[0], y, h, slice_dir); + ff_draw_slice(link->dst->outputs[0], y, h, slice_dir); } static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) @@ -265,10 +265,10 @@ static void default_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir outlink = inlink->dst->outputs[0]; if (outlink) - avfilter_draw_slice(outlink, y, h, slice_dir); + ff_draw_slice(outlink, y, h, slice_dir); } -void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { uint8_t *src[4], *dst[4]; int i, j, vsub; @@ -342,4 +342,16 @@ void avfilter_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { ff_null_draw_slice(link, y, h, slice_dir); } +void avfilter_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) +{ + ff_start_frame(link, picref); +} +void avfilter_end_frame(AVFilterLink *link) +{ + ff_end_frame(link); +} +void avfilter_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) +{ + ff_draw_slice(link, y, h, slice_dir); +} #endif diff --git a/libavfilter/video.h b/libavfilter/video.h index 2256482eee..7c9f9a0d28 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -29,4 +29,39 @@ void ff_null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); void ff_null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); void ff_null_end_frame(AVFilterLink *link); +/** + * Notify the next filter of the start of a frame. + * + * @param link the output link the frame will be sent over + * @param picref A reference to the frame about to be sent. The data for this + * frame need only be valid once draw_slice() is called for that + * portion. The receiving filter will free this reference when + * it no longer needs it. + */ +void ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref); + +/** + * Notify the next filter that the current frame has finished. + * + * @param link the output link the frame was sent over + */ +void ff_end_frame(AVFilterLink *link); + +/** + * Send a slice to the next filter. + * + * Slices have to be provided in sequential order, either in + * top-bottom or bottom-top order. If slices are provided in + * non-sequential order the behavior of the function is undefined. + * + * @param link the output link over which the frame is being sent + * @param y offset in pixels from the top of the image for this slice + * @param h height of this slice in pixels + * @param slice_dir the assumed direction for sending slices, + * from the top slice to the bottom slice if the value is 1, + * from the bottom slice to the top slice if the value is -1, + * for other values the behavior of the function is undefined. + */ +void ff_draw_slice(AVFilterLink *link, int y, int h, int slice_dir); + #endif /* AVFILTER_VIDEO_H */ diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 803196ebf7..99ea0ad5c1 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -25,6 +25,7 @@ #include "avfilter.h" #include "formats.h" +#include "video.h" #include "libavutil/pixdesc.h" #include "libavutil/colorspace.h" #include "libavutil/imgutils.h" @@ -144,12 +145,12 @@ static int color_request_frame(AVFilterLink *link) picref->pts = color->pts++; picref->pos = -1; - avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0)); + ff_start_frame(link, avfilter_ref_buffer(picref, ~0)); ff_draw_rectangle(picref->data, picref->linesize, color->line, color->line_step, color->hsub, color->vsub, 0, 0, color->w, color->h); - avfilter_draw_slice(link, 0, color->h, 1); - avfilter_end_frame(link); + ff_draw_slice(link, 0, color->h, 1); + ff_end_frame(link); avfilter_unref_buffer(picref); return 0; diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 45772319c6..ff3022cdd6 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -37,6 +37,7 @@ #include "libavformat/avformat.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef struct { const AVClass *class; @@ -287,9 +288,9 @@ static int request_frame(AVFilterLink *outlink) return ret; outpicref = avfilter_ref_buffer(movie->picref, ~0); - avfilter_start_frame(outlink, outpicref); - avfilter_draw_slice(outlink, 0, outlink->h, 1); - avfilter_end_frame(outlink); + ff_start_frame(outlink, outpicref); + ff_draw_slice(outlink, 0, outlink->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(movie->picref); movie->picref = NULL; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 43495d6fd4..7187241136 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -38,6 +38,7 @@ #include "libavutil/parseutils.h" #include "avfilter.h" #include "formats.h" +#include "video.h" typedef struct { const AVClass *class; @@ -142,9 +143,9 @@ static int request_frame(AVFilterLink *outlink) test->nb_frame++; test->fill_picture_fn(outlink->src, picref); - avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); - avfilter_draw_slice(outlink, 0, picref->video->h, 1); - avfilter_end_frame(outlink); + ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0)); + ff_draw_slice(outlink, 0, picref->video->h, 1); + ff_end_frame(outlink); avfilter_unref_buffer(picref); return 0; From c45e2da617d74b6f0d82208efd017d66139eabe2 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 2 Jun 2012 20:30:23 +0200 Subject: [PATCH 10/16] imc: move channel-specific data into separate context This will be useful for Indeo Audio decoder which is almost the same but supports stereo. --- libavcodec/imc.c | 404 +++++++++++++++++++++++++---------------------- 1 file changed, 217 insertions(+), 187 deletions(-) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 44e15f0bca..d53693c848 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -49,9 +49,7 @@ #define BANDS 32 #define COEFFS 256 -typedef struct { - AVFrame frame; - +typedef struct IMCChannel { float old_floor[BANDS]; float flcoeffs1[BANDS]; float flcoeffs2[BANDS]; @@ -61,16 +59,6 @@ typedef struct { float flcoeffs6[BANDS]; float CWdecoded[COEFFS]; - /** MDCT tables */ - //@{ - float mdct_sine_window[COEFFS]; - float post_cos[COEFFS]; - float post_sin[COEFFS]; - float pre_coef1[COEFFS]; - float pre_coef2[COEFFS]; - float last_fft_im[COEFFS]; - //@} - int bandWidthT[BANDS]; ///< codewords per band int bitsBandT[BANDS]; ///< how many bits per codeword in band int CWlengthT[COEFFS]; ///< how many bits in each codeword @@ -82,9 +70,28 @@ typedef struct { int skipFlagCount[BANDS]; ///< skipped coeffients per band int skipFlags[COEFFS]; ///< skip coefficient decoding or not int codewords[COEFFS]; ///< raw codewords read from bitstream + + float last_fft_im[COEFFS]; + + int decoder_reset; +} IMCChannel; + +typedef struct { + AVFrame frame; + + IMCChannel chctx[1]; + + /** MDCT tables */ + //@{ + float mdct_sine_window[COEFFS]; + float post_cos[COEFFS]; + float post_sin[COEFFS]; + float pre_coef1[COEFFS]; + float pre_coef2[COEFFS]; + //@} + float sqrt_tab[30]; GetBitContext gb; - int decoder_reset; float one_div_log2; DSPContext dsp; @@ -115,10 +122,15 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } - q->decoder_reset = 1; + for (j = 0; j < avctx->channels; j++) { + q->chctx[j].decoder_reset = 1; - for (i = 0; i < BANDS; i++) - q->old_floor[i] = 1.0; + for (i = 0; i < BANDS; i++) + q->chctx[j].old_floor[i] = 1.0; + + for (i = 0; i < COEFFS / 2; i++) + q->chctx[j].last_fft_im[i] = 0; + } /* Build mdct window, a simple sine window normalized with sqrt(2) */ ff_sine_window_init(q->mdct_sine_window, COEFFS); @@ -138,8 +150,6 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) q->pre_coef1[i] = -(r1 + r2) * sqrt(2.0); q->pre_coef2[i] = (r1 - r2) * sqrt(2.0); } - - q->last_fft_im[i] = 0; } /* Generate a square root table */ @@ -164,8 +174,9 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) return ret; } ff_dsputil_init(&q->dsp, avctx); - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; - avctx->channel_layout = AV_CH_LAYOUT_MONO; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO + : AV_CH_LAYOUT_STEREO; avcodec_get_frame_defaults(&q->frame); avctx->coded_frame = &q->frame; @@ -313,8 +324,8 @@ static void imc_decode_level_coefficients2(IMCContext *q, int *levlCoeffBuf, /** * Perform bit allocation depending on bits available */ -static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, - int flag) +static int bit_allocation(IMCContext *q, IMCChannel *chctx, + int stream_format_code, int freebits, int flag) { int i, j; const float limit = -1.e20; @@ -333,43 +344,43 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, int found_indx = 0; for (i = 0; i < BANDS; i++) - highest = FFMAX(highest, q->flcoeffs1[i]); + highest = FFMAX(highest, chctx->flcoeffs1[i]); for (i = 0; i < BANDS - 1; i++) - q->flcoeffs4[i] = q->flcoeffs3[i] - log(q->flcoeffs5[i]) / log(2); - q->flcoeffs4[BANDS - 1] = limit; + chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log(chctx->flcoeffs5[i]) / log(2); + chctx->flcoeffs4[BANDS - 1] = limit; highest = highest * 0.25; for (i = 0; i < BANDS; i++) { indx = -1; - if ((band_tab[i + 1] - band_tab[i]) == q->bandWidthT[i]) + if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i]) indx = 0; - if ((band_tab[i + 1] - band_tab[i]) > q->bandWidthT[i]) + if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i]) indx = 1; - if (((band_tab[i + 1] - band_tab[i]) / 2) >= q->bandWidthT[i]) + if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i]) indx = 2; if (indx == -1) return AVERROR_INVALIDDATA; - q->flcoeffs4[i] += xTab[(indx * 2 + (q->flcoeffs1[i] < highest)) * 2 + flag]; + chctx->flcoeffs4[i] += xTab[(indx * 2 + (chctx->flcoeffs1[i] < highest)) * 2 + flag]; } if (stream_format_code & 0x2) { - q->flcoeffs4[0] = limit; - q->flcoeffs4[1] = limit; - q->flcoeffs4[2] = limit; - q->flcoeffs4[3] = limit; + chctx->flcoeffs4[0] = limit; + chctx->flcoeffs4[1] = limit; + chctx->flcoeffs4[2] = limit; + chctx->flcoeffs4[3] = limit; } for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) { - iacc += q->bandWidthT[i]; - summa += q->bandWidthT[i] * q->flcoeffs4[i]; + iacc += chctx->bandWidthT[i]; + summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i]; } - q->bandWidthT[BANDS - 1] = 0; + chctx->bandWidthT[BANDS - 1] = 0; summa = (summa * 0.5 - freebits) / iacc; @@ -382,13 +393,13 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, iacc = 0; for (j = (stream_format_code & 0x2) ? 4 : 0; j < BANDS; j++) { - cwlen = av_clipf(((q->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6); + cwlen = av_clipf(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6); - q->bitsBandT[j] = cwlen; - summer += q->bandWidthT[j] * cwlen; + chctx->bitsBandT[j] = cwlen; + summer += chctx->bandWidthT[j] * cwlen; if (cwlen > 0) - iacc += q->bandWidthT[j]; + iacc += chctx->bandWidthT[j]; } flg = t2; @@ -405,13 +416,13 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS; i++) { for (j = band_tab[i]; j < band_tab[i + 1]; j++) - q->CWlengthT[j] = q->bitsBandT[i]; + chctx->CWlengthT[j] = chctx->bitsBandT[i]; } if (freebits > summer) { for (i = 0; i < BANDS; i++) { - workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 - : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415); + workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20 + : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415); } highest = 0.0; @@ -432,11 +443,11 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, if (highest > -1.e20) { workT[found_indx] -= 2.0; - if (++q->bitsBandT[found_indx] == 6) + if (++chctx->bitsBandT[found_indx] == 6) workT[found_indx] = -1.e20; for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) { - q->CWlengthT[j]++; + chctx->CWlengthT[j]++; summer++; } } @@ -444,7 +455,7 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, } if (freebits < summer) { for (i = 0; i < BANDS; i++) { - workT[i] = q->bitsBandT[i] ? (q->bitsBandT[i] * -2 + q->flcoeffs4[i] + 1.585) + workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] + 1.585) : 1.e20; } if (stream_format_code & 0x2) { @@ -466,12 +477,12 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, // break; workT[low_indx] = lowest + 2.0; - if (!--q->bitsBandT[low_indx]) + if (!--chctx->bitsBandT[low_indx]) workT[low_indx] = 1.e20; for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) { - if (q->CWlengthT[j] > 0) { - q->CWlengthT[j]--; + if (chctx->CWlengthT[j] > 0) { + chctx->CWlengthT[j]--; summer--; } } @@ -480,54 +491,54 @@ static int bit_allocation(IMCContext *q, int stream_format_code, int freebits, return 0; } -static void imc_get_skip_coeff(IMCContext *q) +static void imc_get_skip_coeff(IMCContext *q, IMCChannel *chctx) { int i, j; - memset(q->skipFlagBits, 0, sizeof(q->skipFlagBits)); - memset(q->skipFlagCount, 0, sizeof(q->skipFlagCount)); + memset(chctx->skipFlagBits, 0, sizeof(chctx->skipFlagBits)); + memset(chctx->skipFlagCount, 0, sizeof(chctx->skipFlagCount)); for (i = 0; i < BANDS; i++) { - if (!q->bandFlagsBuf[i] || !q->bandWidthT[i]) + if (!chctx->bandFlagsBuf[i] || !chctx->bandWidthT[i]) continue; - if (!q->skipFlagRaw[i]) { - q->skipFlagBits[i] = band_tab[i + 1] - band_tab[i]; + if (!chctx->skipFlagRaw[i]) { + chctx->skipFlagBits[i] = band_tab[i + 1] - band_tab[i]; for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - q->skipFlags[j] = get_bits1(&q->gb); - if (q->skipFlags[j]) - q->skipFlagCount[i]++; + chctx->skipFlags[j] = get_bits1(&q->gb); + if (chctx->skipFlags[j]) + chctx->skipFlagCount[i]++; } } else { for (j = band_tab[i]; j < band_tab[i + 1] - 1; j += 2) { if (!get_bits1(&q->gb)) { // 0 - q->skipFlagBits[i]++; - q->skipFlags[j] = 1; - q->skipFlags[j + 1] = 1; - q->skipFlagCount[i] += 2; + chctx->skipFlagBits[i]++; + chctx->skipFlags[j] = 1; + chctx->skipFlags[j + 1] = 1; + chctx->skipFlagCount[i] += 2; } else { if (get_bits1(&q->gb)) { // 11 - q->skipFlagBits[i] += 2; - q->skipFlags[j] = 0; - q->skipFlags[j + 1] = 1; - q->skipFlagCount[i]++; + chctx->skipFlagBits[i] += 2; + chctx->skipFlags[j] = 0; + chctx->skipFlags[j + 1] = 1; + chctx->skipFlagCount[i]++; } else { - q->skipFlagBits[i] += 3; - q->skipFlags[j + 1] = 0; + chctx->skipFlagBits[i] += 3; + chctx->skipFlags[j + 1] = 0; if (!get_bits1(&q->gb)) { // 100 - q->skipFlags[j] = 1; - q->skipFlagCount[i]++; + chctx->skipFlags[j] = 1; + chctx->skipFlagCount[i]++; } else { // 101 - q->skipFlags[j] = 0; + chctx->skipFlags[j] = 0; } } } } if (j < band_tab[i + 1]) { - q->skipFlagBits[i]++; - if ((q->skipFlags[j] = get_bits1(&q->gb))) - q->skipFlagCount[i]++; + chctx->skipFlagBits[i]++; + if ((chctx->skipFlags[j] = get_bits1(&q->gb))) + chctx->skipFlagCount[i]++; } } } @@ -536,7 +547,8 @@ static void imc_get_skip_coeff(IMCContext *q) /** * Increase highest' band coefficient sizes as some bits won't be used */ -static void imc_adjust_bit_allocation(IMCContext *q, int summer) +static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx, + int summer) { float workT[32]; int corrected = 0; @@ -545,8 +557,8 @@ static void imc_adjust_bit_allocation(IMCContext *q, int summer) int found_indx = 0; for (i = 0; i < BANDS; i++) { - workT[i] = (q->bitsBandT[i] == 6) ? -1.e20 - : (q->bitsBandT[i] * -2 + q->flcoeffs4[i] - 0.415); + workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20 + : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415); } while (corrected < summer) { @@ -564,12 +576,12 @@ static void imc_adjust_bit_allocation(IMCContext *q, int summer) if (highest > -1.e20) { workT[found_indx] -= 2.0; - if (++(q->bitsBandT[found_indx]) == 6) + if (++(chctx->bitsBandT[found_indx]) == 6) workT[found_indx] = -1.e20; for (j = band_tab[found_indx]; j < band_tab[found_indx+1] && (corrected < summer); j++) { - if (!q->skipFlags[j] && (q->CWlengthT[j] < 6)) { - q->CWlengthT[j]++; + if (!chctx->skipFlags[j] && (chctx->CWlengthT[j] < 6)) { + chctx->CWlengthT[j]++; corrected++; } } @@ -577,17 +589,17 @@ static void imc_adjust_bit_allocation(IMCContext *q, int summer) } } -static void imc_imdct256(IMCContext *q) +static void imc_imdct256(IMCContext *q, IMCChannel *chctx) { int i; float re, im; /* prerotation */ for (i = 0; i < COEFFS / 2; i++) { - q->samples[i].re = -(q->pre_coef1[i] * q->CWdecoded[COEFFS - 1 - i * 2]) - - (q->pre_coef2[i] * q->CWdecoded[i * 2]); - q->samples[i].im = (q->pre_coef2[i] * q->CWdecoded[COEFFS - 1 - i * 2]) - - (q->pre_coef1[i] * q->CWdecoded[i * 2]); + q->samples[i].re = -(q->pre_coef1[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) - + (q->pre_coef2[i] * chctx->CWdecoded[i * 2]); + q->samples[i].im = (q->pre_coef2[i] * chctx->CWdecoded[COEFFS - 1 - i * 2]) - + (q->pre_coef1[i] * chctx->CWdecoded[i * 2]); } /* FFT */ @@ -598,15 +610,16 @@ static void imc_imdct256(IMCContext *q) for (i = 0; i < COEFFS / 2; i++) { re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]); im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]); - q->out_samples[i * 2] = (q->mdct_sine_window[COEFFS - 1 - i * 2] * q->last_fft_im[i]) + q->out_samples[i * 2] = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i]) + (q->mdct_sine_window[i * 2] * re); - q->out_samples[COEFFS - 1 - i * 2] = (q->mdct_sine_window[i * 2] * q->last_fft_im[i]) + q->out_samples[COEFFS - 1 - i * 2] = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i]) - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re); - q->last_fft_im[i] = im; + chctx->last_fft_im[i] = im; } } -static int inverse_quant_coeff(IMCContext *q, int stream_format_code) +static int inverse_quant_coeff(IMCContext *q, IMCChannel *chctx, + int stream_format_code) { int i, j; int middle_value, cw_len, max_size; @@ -614,30 +627,30 @@ static int inverse_quant_coeff(IMCContext *q, int stream_format_code) for (i = 0; i < BANDS; i++) { for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - q->CWdecoded[j] = 0; - cw_len = q->CWlengthT[j]; + chctx->CWdecoded[j] = 0; + cw_len = chctx->CWlengthT[j]; - if (cw_len <= 0 || q->skipFlags[j]) + if (cw_len <= 0 || chctx->skipFlags[j]) continue; max_size = 1 << cw_len; middle_value = max_size >> 1; - if (q->codewords[j] >= max_size || q->codewords[j] < 0) + if (chctx->codewords[j] >= max_size || chctx->codewords[j] < 0) return AVERROR_INVALIDDATA; if (cw_len >= 4) { quantizer = imc_quantizer2[(stream_format_code & 2) >> 1]; - if (q->codewords[j] >= middle_value) - q->CWdecoded[j] = quantizer[q->codewords[j] - 8] * q->flcoeffs6[i]; + if (chctx->codewords[j] >= middle_value) + chctx->CWdecoded[j] = quantizer[chctx->codewords[j] - 8] * chctx->flcoeffs6[i]; else - q->CWdecoded[j] = -quantizer[max_size - q->codewords[j] - 8 - 1] * q->flcoeffs6[i]; + chctx->CWdecoded[j] = -quantizer[max_size - chctx->codewords[j] - 8 - 1] * chctx->flcoeffs6[i]; }else{ - quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (q->bandFlagsBuf[i] << 1)]; - if (q->codewords[j] >= middle_value) - q->CWdecoded[j] = quantizer[q->codewords[j] - 1] * q->flcoeffs6[i]; + quantizer = imc_quantizer1[((stream_format_code & 2) >> 1) | (chctx->bandFlagsBuf[i] << 1)]; + if (chctx->codewords[j] >= middle_value) + chctx->CWdecoded[j] = quantizer[chctx->codewords[j] - 1] * chctx->flcoeffs6[i]; else - q->CWdecoded[j] = -quantizer[max_size - 2 - q->codewords[j]] * q->flcoeffs6[i]; + chctx->CWdecoded[j] = -quantizer[max_size - 2 - chctx->codewords[j]] * chctx->flcoeffs6[i]; } } } @@ -645,16 +658,16 @@ static int inverse_quant_coeff(IMCContext *q, int stream_format_code) } -static int imc_get_coeffs(IMCContext *q) +static int imc_get_coeffs(IMCContext *q, IMCChannel *chctx) { int i, j, cw_len, cw; for (i = 0; i < BANDS; i++) { - if (!q->sumLenArr[i]) + if (!chctx->sumLenArr[i]) continue; - if (q->bandFlagsBuf[i] || q->bandWidthT[i]) { + if (chctx->bandFlagsBuf[i] || chctx->bandWidthT[i]) { for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - cw_len = q->CWlengthT[j]; + cw_len = chctx->CWlengthT[j]; cw = 0; if (get_bits_count(&q->gb) + cw_len > 512) { @@ -662,47 +675,25 @@ static int imc_get_coeffs(IMCContext *q) return AVERROR_INVALIDDATA; } - if (cw_len && (!q->bandFlagsBuf[i] || !q->skipFlags[j])) + if (cw_len && (!chctx->bandFlagsBuf[i] || !chctx->skipFlags[j])) cw = get_bits(&q->gb, cw_len); - q->codewords[j] = cw; + chctx->codewords[j] = cw; } } } return 0; } -static int imc_decode_frame(AVCodecContext *avctx, void *data, - int *got_frame_ptr, AVPacket *avpkt) +static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - - IMCContext *q = avctx->priv_data; - int stream_format_code; int imc_hdr, i, j, ret; int flag; int bits, summer; int counter, bitscount; - LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]); + IMCChannel *chctx = q->chctx + ch; - if (buf_size < IMC_BLOCK_SIZE) { - av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); - return AVERROR_INVALIDDATA; - } - - /* get output buffer */ - q->frame.nb_samples = COEFFS; - if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return ret; - } - q->out_samples = (float*)q->frame.data[0]; - - q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2); - - init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); /* Check the frame header */ imc_hdr = get_bits(&q->gb, 9); @@ -721,90 +712,90 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, // av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code); if (stream_format_code & 0x04) - q->decoder_reset = 1; + chctx->decoder_reset = 1; - if (q->decoder_reset) { + if (chctx->decoder_reset) { memset(q->out_samples, 0, sizeof(q->out_samples)); for (i = 0; i < BANDS; i++) - q->old_floor[i] = 1.0; + chctx->old_floor[i] = 1.0; for (i = 0; i < COEFFS; i++) - q->CWdecoded[i] = 0; - q->decoder_reset = 0; + chctx->CWdecoded[i] = 0; + chctx->decoder_reset = 0; } flag = get_bits1(&q->gb); - imc_read_level_coeffs(q, stream_format_code, q->levlCoeffBuf); + imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf); if (stream_format_code & 0x4) - imc_decode_level_coefficients(q, q->levlCoeffBuf, - q->flcoeffs1, q->flcoeffs2); + imc_decode_level_coefficients(q, chctx->levlCoeffBuf, + chctx->flcoeffs1, chctx->flcoeffs2); else - imc_decode_level_coefficients2(q, q->levlCoeffBuf, q->old_floor, - q->flcoeffs1, q->flcoeffs2); + imc_decode_level_coefficients2(q, chctx->levlCoeffBuf, chctx->old_floor, + chctx->flcoeffs1, chctx->flcoeffs2); - memcpy(q->old_floor, q->flcoeffs1, 32 * sizeof(float)); + memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float)); counter = 0; for (i = 0; i < BANDS; i++) { - if (q->levlCoeffBuf[i] == 16) { - q->bandWidthT[i] = 0; + if (chctx->levlCoeffBuf[i] == 16) { + chctx->bandWidthT[i] = 0; counter++; } else - q->bandWidthT[i] = band_tab[i + 1] - band_tab[i]; + chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i]; } - memset(q->bandFlagsBuf, 0, BANDS * sizeof(int)); + memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int)); for (i = 0; i < BANDS - 1; i++) { - if (q->bandWidthT[i]) - q->bandFlagsBuf[i] = get_bits1(&q->gb); + if (chctx->bandWidthT[i]) + chctx->bandFlagsBuf[i] = get_bits1(&q->gb); } - imc_calculate_coeffs(q, q->flcoeffs1, q->flcoeffs2, q->bandWidthT, q->flcoeffs3, q->flcoeffs5); + imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5); bitscount = 0; /* first 4 bands will be assigned 5 bits per coefficient */ if (stream_format_code & 0x2) { bitscount += 15; - q->bitsBandT[0] = 5; - q->CWlengthT[0] = 5; - q->CWlengthT[1] = 5; - q->CWlengthT[2] = 5; + chctx->bitsBandT[0] = 5; + chctx->CWlengthT[0] = 5; + chctx->CWlengthT[1] = 5; + chctx->CWlengthT[2] = 5; for (i = 1; i < 4; i++) { - bits = (q->levlCoeffBuf[i] == 16) ? 0 : 5; - q->bitsBandT[i] = bits; + bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5; + chctx->bitsBandT[i] = bits; for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - q->CWlengthT[j] = bits; + chctx->CWlengthT[j] = bits; bitscount += bits; } } } - if ((ret = bit_allocation(q, stream_format_code, + if ((ret = bit_allocation(q, chctx, stream_format_code, 512 - bitscount - get_bits_count(&q->gb), flag)) < 0) { av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n"); - q->decoder_reset = 1; + chctx->decoder_reset = 1; return ret; } for (i = 0; i < BANDS; i++) { - q->sumLenArr[i] = 0; - q->skipFlagRaw[i] = 0; + chctx->sumLenArr[i] = 0; + chctx->skipFlagRaw[i] = 0; for (j = band_tab[i]; j < band_tab[i + 1]; j++) - q->sumLenArr[i] += q->CWlengthT[j]; - if (q->bandFlagsBuf[i]) - if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > q->sumLenArr[i]) && (q->sumLenArr[i] > 0)) - q->skipFlagRaw[i] = 1; + chctx->sumLenArr[i] += chctx->CWlengthT[j]; + if (chctx->bandFlagsBuf[i]) + if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0)) + chctx->skipFlagRaw[i] = 1; } - imc_get_skip_coeff(q); + imc_get_skip_coeff(q, chctx); for (i = 0; i < BANDS; i++) { - q->flcoeffs6[i] = q->flcoeffs1[i]; + chctx->flcoeffs6[i] = chctx->flcoeffs1[i]; /* band has flag set and at least one coded coefficient */ - if (q->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != q->skipFlagCount[i]) { - q->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] / - q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - q->skipFlagCount[i])]; + if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) { + chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] / + q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])]; } } @@ -812,49 +803,88 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, bits = summer = 0; for (i = 0; i < BANDS; i++) { - if (q->bandFlagsBuf[i]) { + if (chctx->bandFlagsBuf[i]) { for (j = band_tab[i]; j < band_tab[i + 1]; j++) { - if (q->skipFlags[j]) { - summer += q->CWlengthT[j]; - q->CWlengthT[j] = 0; + if (chctx->skipFlags[j]) { + summer += chctx->CWlengthT[j]; + chctx->CWlengthT[j] = 0; } } - bits += q->skipFlagBits[i]; - summer -= q->skipFlagBits[i]; + bits += chctx->skipFlagBits[i]; + summer -= chctx->skipFlagBits[i]; } } - imc_adjust_bit_allocation(q, summer); + imc_adjust_bit_allocation(q, chctx, summer); for (i = 0; i < BANDS; i++) { - q->sumLenArr[i] = 0; + chctx->sumLenArr[i] = 0; for (j = band_tab[i]; j < band_tab[i + 1]; j++) - if (!q->skipFlags[j]) - q->sumLenArr[i] += q->CWlengthT[j]; + if (!chctx->skipFlags[j]) + chctx->sumLenArr[i] += chctx->CWlengthT[j]; } - memset(q->codewords, 0, sizeof(q->codewords)); + memset(chctx->codewords, 0, sizeof(chctx->codewords)); - if (imc_get_coeffs(q) < 0) { + if (imc_get_coeffs(q, chctx) < 0) { av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n"); - q->decoder_reset = 1; + chctx->decoder_reset = 1; return AVERROR_INVALIDDATA; } - if (inverse_quant_coeff(q, stream_format_code) < 0) { + if (inverse_quant_coeff(q, chctx, stream_format_code) < 0) { av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n"); - q->decoder_reset = 1; + chctx->decoder_reset = 1; return AVERROR_INVALIDDATA; } - memset(q->skipFlags, 0, sizeof(q->skipFlags)); + memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags)); - imc_imdct256(q); + imc_imdct256(q, chctx); + + return 0; +} + +static int imc_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int ret, i; + + IMCContext *q = avctx->priv_data; + + LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]); + + if (buf_size < IMC_BLOCK_SIZE) { + av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); + return AVERROR_INVALIDDATA; + } + + /* get output buffer */ + q->frame.nb_samples = COEFFS; + if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + + for (i = 0; i < avctx->channels; i++) { + q->out_samples = (float*)q->frame.data[0] + i; + + q->dsp.bswap16_buf(buf16, (const uint16_t*)buf, IMC_BLOCK_SIZE / 2); + + init_get_bits(&q->gb, (const uint8_t*)buf16, IMC_BLOCK_SIZE * 8); + + buf += IMC_BLOCK_SIZE; + + if ((ret = imc_decode_block(avctx, q, i)) < 0) + return ret; + } *got_frame_ptr = 1; *(AVFrame *)data = q->frame; - return IMC_BLOCK_SIZE; + return IMC_BLOCK_SIZE * avctx->channels; } From 34271cabacb20f24ad07bff818e3447330cdd851 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 2 Jun 2012 20:35:41 +0200 Subject: [PATCH 11/16] imc: make IMDCT support stereo output This will be useful for Indeo Audio decoder which is almost the same but supports stereo. --- libavcodec/imc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libavcodec/imc.c b/libavcodec/imc.c index d53693c848..4b8ad7c536 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -589,10 +589,12 @@ static void imc_adjust_bit_allocation(IMCContext *q, IMCChannel *chctx, } } -static void imc_imdct256(IMCContext *q, IMCChannel *chctx) +static void imc_imdct256(IMCContext *q, IMCChannel *chctx, int channels) { int i; float re, im; + float *dst1 = q->out_samples; + float *dst2 = q->out_samples + (COEFFS - 1) * channels; /* prerotation */ for (i = 0; i < COEFFS / 2; i++) { @@ -610,10 +612,12 @@ static void imc_imdct256(IMCContext *q, IMCChannel *chctx) for (i = 0; i < COEFFS / 2; i++) { re = ( q->samples[i].re * q->post_cos[i]) + (-q->samples[i].im * q->post_sin[i]); im = (-q->samples[i].im * q->post_cos[i]) - ( q->samples[i].re * q->post_sin[i]); - q->out_samples[i * 2] = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i]) - + (q->mdct_sine_window[i * 2] * re); - q->out_samples[COEFFS - 1 - i * 2] = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i]) - - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re); + *dst1 = (q->mdct_sine_window[COEFFS - 1 - i * 2] * chctx->last_fft_im[i]) + + (q->mdct_sine_window[i * 2] * re); + *dst2 = (q->mdct_sine_window[i * 2] * chctx->last_fft_im[i]) + - (q->mdct_sine_window[COEFFS - 1 - i * 2] * re); + dst1 += channels * 2; + dst2 -= channels * 2; chctx->last_fft_im[i] = im; } } @@ -840,7 +844,7 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags)); - imc_imdct256(q, chctx); + imc_imdct256(q, chctx, avctx->channels); return 0; } From c6061443f766b31b6601c36a832760ebd917c8ad Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 2 Jun 2012 21:07:02 +0200 Subject: [PATCH 12/16] Indeo Audio decoder --- Changelog | 2 ++ doc/general.texi | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/imc.c | 72 ++++++++++++++++++++++++++++++++++-------- libavcodec/imcdata.h | 19 +++++++++++ libavcodec/version.h | 4 +-- libavformat/riff.c | 1 + 9 files changed, 87 insertions(+), 15 deletions(-) diff --git a/Changelog b/Changelog index 358662bfed..898a2473e8 100644 --- a/Changelog +++ b/Changelog @@ -23,6 +23,8 @@ version : - audio mix filter - avprobe output is now standard INI or JSON. The old format can still be used with -of old. +- Indeo Audio decoder + version 0.8: diff --git a/doc/general.texi b/doc/general.texi index 680b971bc7..dee8f9e096 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -706,6 +706,7 @@ following image formats are supported: @tab encoding supported through external library libgsm @item GSM Microsoft variant @tab E @tab X @tab encoding supported through external library libgsm +@item IAC (Indeo Audio Coder) @tab @tab X @item IMC (Intel Music Coder) @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index da8aa8ac20..3bfd78bc63 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -197,6 +197,7 @@ OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_HUFFYUV_DECODER) += huffyuv.o OBJS-$(CONFIG_HUFFYUV_ENCODER) += huffyuv.o +OBJS-$(CONFIG_IAC_DECODER) += imc.o OBJS-$(CONFIG_IDCIN_DECODER) += idcinvideo.o OBJS-$(CONFIG_IFF_BYTERUN1_DECODER) += iff.o OBJS-$(CONFIG_IFF_ILBM_DECODER) += iff.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index a1df47af69..01d13d5348 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -260,6 +260,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (FLAC, flac); REGISTER_DECODER (GSM, gsm); REGISTER_DECODER (GSM_MS, gsm_ms); + REGISTER_DECODER (IAC, iac); REGISTER_DECODER (IMC, imc); REGISTER_DECODER (MACE3, mace3); REGISTER_DECODER (MACE6, mace6); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 102df3a7a0..4a07d6dd57 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -393,6 +393,7 @@ enum CodecID { CODEC_ID_8SVX_FIB, CODEC_ID_BMV_AUDIO, CODEC_ID_RALF, + CODEC_ID_IAC, /* subtitle codecs */ CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 4b8ad7c536..3856f4a851 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -79,7 +79,7 @@ typedef struct IMCChannel { typedef struct { AVFrame frame; - IMCChannel chctx[1]; + IMCChannel chctx[2]; /** MDCT tables */ //@{ @@ -98,6 +98,9 @@ typedef struct { FFTContext fft; DECLARE_ALIGNED(32, FFTComplex, samples)[COEFFS / 2]; float *out_samples; + + int8_t cyclTab[32], cyclTab2[32]; + float weights1[31], weights2[31]; } IMCContext; static VLC huffman_vlc[4][4]; @@ -117,7 +120,8 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) IMCContext *q = avctx->priv_data; double r1, r2; - if (avctx->channels != 1) { + if ((avctx->codec_id == CODEC_ID_IMC && avctx->channels != 1) + || (avctx->codec_id == CODEC_ID_IAC && avctx->channels > 2)) { av_log_ask_for_sample(avctx, "Number of channels is not supported\n"); return AVERROR_PATCHWELCOME; } @@ -169,6 +173,18 @@ static av_cold int imc_decode_init(AVCodecContext *avctx) } q->one_div_log2 = 1 / log(2); + memcpy(q->cyclTab, cyclTab, sizeof(cyclTab)); + memcpy(q->cyclTab2, cyclTab2, sizeof(cyclTab2)); + if (avctx->codec_id == CODEC_ID_IAC) { + q->cyclTab[29] = 31; + q->cyclTab2[31] = 28; + memcpy(q->weights1, iac_weights1, sizeof(iac_weights1)); + memcpy(q->weights2, iac_weights2, sizeof(iac_weights2)); + } else { + memcpy(q->weights1, imc_weights1, sizeof(imc_weights1)); + memcpy(q->weights2, imc_weights2, sizeof(imc_weights2)); + } + if ((ret = ff_fft_init(&q->fft, 7, 1))) { av_log(avctx, AV_LOG_INFO, "FFT init failed\n"); return ret; @@ -210,13 +226,13 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1, } for (i = 0; i < BANDS; i++) { - for (cnt2 = i; cnt2 < cyclTab[i]; cnt2++) + for (cnt2 = i; cnt2 < q->cyclTab[i]; cnt2++) flcoeffs5[cnt2] = flcoeffs5[cnt2] + workT3[i]; workT2[cnt2 - 1] = workT2[cnt2 - 1] + workT3[i]; } for (i = 1; i < BANDS; i++) { - accum = (workT2[i - 1] + accum) * imc_weights1[i - 1]; + accum = (workT2[i - 1] + accum) * q->weights1[i - 1]; flcoeffs5[i] += accum; } @@ -224,7 +240,7 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1, workT2[i] = 0.0; for (i = 0; i < BANDS; i++) { - for (cnt2 = i - 1; cnt2 > cyclTab2[i]; cnt2--) + for (cnt2 = i - 1; cnt2 > q->cyclTab2[i]; cnt2--) flcoeffs5[cnt2] += workT3[i]; workT2[cnt2+1] += workT3[i]; } @@ -232,7 +248,7 @@ static void imc_calculate_coeffs(IMCContext *q, float *flcoeffs1, accum = 0.0; for (i = BANDS-2; i >= 0; i--) { - accum = (workT2[i+1] + accum) * imc_weights2[i]; + accum = (workT2[i+1] + accum) * q->weights2[i]; flcoeffs5[i] += accum; // there is missing code here, but it seems to never be triggered } @@ -701,16 +717,17 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) /* Check the frame header */ imc_hdr = get_bits(&q->gb, 9); - if (imc_hdr != IMC_FRAME_ID) { - av_log(avctx, AV_LOG_ERROR, "imc frame header check failed!\n"); - av_log(avctx, AV_LOG_ERROR, "got %x instead of 0x21.\n", imc_hdr); + if (imc_hdr & 0x18) { + av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n"); + av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr); return AVERROR_INVALIDDATA; } stream_format_code = get_bits(&q->gb, 3); if (stream_format_code & 1) { - av_log(avctx, AV_LOG_ERROR, "Stream code format %X is not supported\n", stream_format_code); - return AVERROR_INVALIDDATA; + av_log_ask_for_sample(avctx, "Stream format %X is not supported\n", + stream_format_code); + return AVERROR_PATCHWELCOME; } // av_log(avctx, AV_LOG_DEBUG, "stream_format_code = %d\n", stream_format_code); @@ -773,6 +790,11 @@ static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch) } } } + if (avctx->codec_id == CODEC_ID_IAC) { + bitscount += !!chctx->bandWidthT[BANDS - 1]; + if (!(stream_format_code & 0x2)) + bitscount += 16; + } if ((ret = bit_allocation(q, chctx, stream_format_code, 512 - bitscount - get_bits_count(&q->gb), @@ -860,8 +882,8 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, LOCAL_ALIGNED_16(uint16_t, buf16, [IMC_BLOCK_SIZE / 2]); - if (buf_size < IMC_BLOCK_SIZE) { - av_log(avctx, AV_LOG_ERROR, "imc frame too small!\n"); + if (buf_size < IMC_BLOCK_SIZE * avctx->channels) { + av_log(avctx, AV_LOG_ERROR, "frame too small!\n"); return AVERROR_INVALIDDATA; } @@ -885,6 +907,18 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data, return ret; } + if (avctx->channels == 2) { + float *src = (float*)q->frame.data[0], t1, t2; + + for (i = 0; i < COEFFS; i++) { + t1 = src[0]; + t2 = src[1]; + src[0] = t1 + t2; + src[1] = t1 - t2; + src += 2; + } + } + *got_frame_ptr = 1; *(AVFrame *)data = q->frame; @@ -913,3 +947,15 @@ AVCodec ff_imc_decoder = { .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("IMC (Intel Music Coder)"), }; + +AVCodec ff_iac_decoder = { + .name = "iac", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_IAC, + .priv_data_size = sizeof(IMCContext), + .init = imc_decode_init, + .close = imc_decode_close, + .decode = imc_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("IAC (Indeo Audio Coder)"), +}; diff --git a/libavcodec/imcdata.h b/libavcodec/imcdata.h index 8e99391d61..ea9b3747fc 100644 --- a/libavcodec/imcdata.h +++ b/libavcodec/imcdata.h @@ -44,6 +44,25 @@ static const int8_t cyclTab2[32] = { 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; +static const float iac_weights1[31] = { + 0.0538585, 0.0576251, 0.0645592, 0.0494032, 0.0428915, 0.0592188, + 0.0604145, 0.0673549, 0.0797351, 0.0972911, 0.119376, 0.144777, + 0.17181, 0.198625, 0.242918, 0.262113, 0.278434, 0.310752, + 0.319978, 0.328482, 0.354631, 0.380212, 0.388783, 0.400428, + 0.43096, 0.462397, 0.479469, 0.499329, 0.534526, 0.568631, + 0.589218 +}; + +static const float iac_weights2[31] = { + 0.000375307, 0.000450455, 0.000612191, 0.000297262, 0.000202956, + 0.000484887, 0.000511777, 0.000686431, 0.00108256, 0.00185267, + 0.00321869, 0.00541861, 0.00860266, 0.012726, 0.0219151, + 0.0269104, 0.0316774, 0.0426107, 0.046113, 0.0494974, + 0.0608692, 0.0734633, 0.0780208, 0.0844921, 0.103034, + 0.124606, 0.137421, 0.153336, 0.184296, 0.217792, + 0.239742 +}; + static const float imc_weights1[31] = { 0.119595, 0.123124, 0.129192, 9.97377e-2, 8.1923e-2, 9.61153e-2, 8.77885e-2, 8.61174e-2, 9.00882e-2, 9.91658e-2, 0.112991, 0.131126, 0.152886, 0.177292, 0.221782, 0.244917, 0.267386, diff --git a/libavcodec/version.h b/libavcodec/version.h index da7796abb0..e8f0b5cb84 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -27,8 +27,8 @@ */ #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 13 -#define LIBAVCODEC_VERSION_MICRO 1 +#define LIBAVCODEC_VERSION_MINOR 14 +#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/riff.c b/libavformat/riff.c index 8a913452a7..922a863a84 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -322,6 +322,7 @@ const AVCodecTag ff_codec_wav_tags[] = { { CODEC_ID_ATRAC3, 0x0270 }, { CODEC_ID_ADPCM_G722, 0x028F }, { CODEC_ID_IMC, 0x0401 }, + { CODEC_ID_IAC, 0x0402 }, { CODEC_ID_GSM_MS, 0x1500 }, { CODEC_ID_TRUESPEECH, 0x1501 }, { CODEC_ID_AAC, 0x1600 }, /* ADTS AAC */ From 62bebf6edbbccab013062f74a3093ed3ddbe04d8 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 4 Jun 2012 16:07:48 -0700 Subject: [PATCH 13/16] avformat: Factorize codec probing. --- libavformat/utils.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 438752174e..60ba984066 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -612,6 +612,30 @@ fail: /*******************************************************/ +static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) +{ + if(st->codec->codec_id == CODEC_ID_PROBE){ + AVProbeData *pd = &st->probe_data; + av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index); + --st->probe_packets; + + pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); + memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); + pd->buf_size += pkt->size; + memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); + + if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ + //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes + set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0); + if(st->codec->codec_id != CODEC_ID_PROBE){ + pd->buf_size=0; + av_freep(&pd->buf); + av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); + } + } + } +} + int ff_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, i; @@ -675,26 +699,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end); s->raw_packet_buffer_remaining_size -= pkt->size; - if(st->codec->codec_id == CODEC_ID_PROBE){ - AVProbeData *pd = &st->probe_data; - av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index); - --st->probe_packets; - - pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); - memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); - pd->buf_size += pkt->size; - memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); - - if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ - //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes - set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0); - if(st->codec->codec_id != CODEC_ID_PROBE){ - pd->buf_size=0; - av_freep(&pd->buf); - av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); - } - } - } + probe_codec(s, st, pkt); } } From f0ff9eb49394d4ba06eff30e0dac2f3ce590e311 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 4 Jun 2012 16:58:48 -0700 Subject: [PATCH 14/16] avformat: Probe codecs at score 0 on buffer exhaustion conditions. --- libavformat/utils.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 60ba984066..d7ba5a7405 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -619,13 +619,17 @@ static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index); --st->probe_packets; - pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); - memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); - pd->buf_size += pkt->size; - memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); + if (pkt) { + pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); + memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); + pd->buf_size += pkt->size; + memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); + } else { + st->probe_packets = 0; + } - if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ - //FIXME we do not reduce score to 0 for the case of running out of buffer space in bytes + if (!st->probe_packets || + av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) { set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0); if(st->codec->codec_id != CODEC_ID_PROBE){ pd->buf_size=0; @@ -646,10 +650,14 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (pktl) { *pkt = pktl->pkt; - if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE || - !s->streams[pkt->stream_index]->probe_packets || - s->raw_packet_buffer_remaining_size < pkt->size){ - AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data; + st = s->streams[pkt->stream_index]; + if (st->codec->codec_id != CODEC_ID_PROBE || !st->probe_packets || + s->raw_packet_buffer_remaining_size < pkt->size) { + AVProbeData *pd; + if (st->probe_packets) { + probe_codec(s, st, NULL); + } + pd = &st->probe_data; av_freep(&pd->buf); pd->buf_size = 0; s->raw_packet_buffer = pktl->next; @@ -664,8 +672,12 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) { if (!pktl || ret == AVERROR(EAGAIN)) return ret; - for (i = 0; i < s->nb_streams; i++) - s->streams[i]->probe_packets = 0; + for (i = 0; i < s->nb_streams; i++) { + st = s->streams[i]; + if (st->probe_packets) { + probe_codec(s, st, NULL); + } + } continue; } From 503f2feb143b58bf9b7850ef00ec0bb02d509f78 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 4 Jun 2012 17:35:51 -0700 Subject: [PATCH 15/16] avprobe: Identify codec probe failures rather than calling them unsupported codecs. --- avprobe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/avprobe.c b/avprobe.c index 2464f8623a..8e93d05ae9 100644 --- a/avprobe.c +++ b/avprobe.c @@ -733,7 +733,10 @@ static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) AVStream *stream = fmt_ctx->streams[i]; AVCodec *codec; - if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) { + if (stream->codec->codec_id == CODEC_ID_PROBE) { + fprintf(stderr, "Failed to probe codec for input stream %d\n", + stream->index); + } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) { fprintf(stderr, "Unsupported codec with id %d for input stream %d\n", stream->codec->codec_id, stream->index); From ecf79c4d3e8baaf2f303278ef81db6f8407656bc Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 4 Jun 2012 18:27:03 -0700 Subject: [PATCH 16/16] vorbis: Validate that the floor 1 X values contain no duplicates. Duplicate values in this vector are explicitly banned by the Vorbis I spec and cause divide-by-zero crashes later on. --- libavcodec/vorbis.c | 9 ++++++++- libavcodec/vorbis.h | 3 ++- libavcodec/vorbisdec.c | 6 +++++- libavcodec/vorbisenc.c | 3 ++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c index 52ded8b0a8..16fb998fab 100644 --- a/libavcodec/vorbis.c +++ b/libavcodec/vorbis.c @@ -119,7 +119,8 @@ int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) return 0; } -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values) { int i; list[0].sort = 0; @@ -143,6 +144,11 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) for (i = 0; i < values - 1; i++) { int j; for (j = i + 1; j < values; j++) { + if (list[i].x == list[j].x) { + av_log(avccontext, AV_LOG_ERROR, + "Duplicate value found in floor 1 X coordinates\n"); + return AVERROR_INVALIDDATA; + } if (list[list[i].sort].x > list[list[j].sort].x) { int tmp = list[i].sort; list[i].sort = list[j].sort; @@ -150,6 +156,7 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) } } } + return 0; } static inline void render_line_unrolled(intptr_t x, int y, int x1, diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h index 924ca800b2..ee4967cdfe 100644 --- a/libavcodec/vorbis.h +++ b/libavcodec/vorbis.h @@ -36,7 +36,8 @@ typedef struct { uint16_t high; } vorbis_floor1_entry; -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values); +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values); unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n) int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num); void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 36db356f27..3489b8f029 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -574,7 +574,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) } // Precalculate order of x coordinates - needed for decode - ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); + if (ff_vorbis_ready_floor1_list(vc->avccontext, + floor_setup->data.t1.list, + floor_setup->data.t1.x_list_dim)) { + return AVERROR_INVALIDDATA; + } } else if (floor_setup->floor_type == 0) { unsigned max_codebook_dim = 0; diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 0b0caccb7c..173619ae4b 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -340,7 +340,8 @@ static int create_vorbis_context(vorbis_enc_context *venc, }; fc->list[i].x = a[i - 2]; } - ff_vorbis_ready_floor1_list(fc->list, fc->values); + if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values)) + return AVERROR_BUG; venc->nresidues = 1; venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues);