From e43f56b205a6112451bba3da965f327850bf67a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 5 Jul 2012 09:47:29 +0300 Subject: [PATCH 01/10] flvdec: Treat all nellymoser versions as the same codec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids creating new AVStreams for them when switching between different variants of them, since we can handle changes between different sample rates of nellymoser within the same stream. Signed-off-by: Martin Storsjö --- libavformat/flvdec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 602cb9ebee..12c250437a 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -113,11 +113,7 @@ static int flv_same_audio_codec(AVCodecContext *acodec, int flags) case FLV_CODECID_MP3: return acodec->codec_id == CODEC_ID_MP3; case FLV_CODECID_NELLYMOSER_8KHZ_MONO: - return acodec->sample_rate == 8000 && - acodec->codec_id == CODEC_ID_NELLYMOSER; case FLV_CODECID_NELLYMOSER_16KHZ_MONO: - return acodec->sample_rate == 16000 && - acodec->codec_id == CODEC_ID_NELLYMOSER; case FLV_CODECID_NELLYMOSER: return acodec->codec_id == CODEC_ID_NELLYMOSER; case FLV_CODECID_PCM_MULAW: From 784514a4a8c621290fc5fa942ad286f9726475a9 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 3 Jul 2012 00:29:30 +0100 Subject: [PATCH 02/10] flacdec: add planar output support Signed-off-by: Mans Rullgard --- libavcodec/flacdec.c | 34 +++++++++++++++++++------ libavcodec/flacdsp.c | 35 +++++++++++++++++++++++--- libavcodec/flacdsp.h | 2 +- libavcodec/flacdsp_template.c | 47 ++++++++++++++++++++++++----------- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 7295e2e1ce..89819e31fb 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -104,11 +104,22 @@ int avpriv_flac_is_extradata_valid(AVCodecContext *avctx, static void flac_set_bps(FLACContext *s) { - if (s->bps > 16) { - s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; + enum AVSampleFormat req = s->avctx->request_sample_fmt; + int need32 = s->bps > 16; + int want32 = av_get_bytes_per_sample(req) > 2; + int planar = av_sample_fmt_is_planar(req); + + if (need32 || want32) { + if (planar) + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P; + else + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; s->sample_shift = 32 - s->bps; } else { - s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (planar) + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + else + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; s->sample_shift = 16 - s->bps; } } @@ -132,7 +143,7 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); allocate_buffers(s); flac_set_bps(s); - ff_flacdsp_init(&s->dsp, avctx->sample_fmt); + ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps); s->got_streaminfo = 1; avcodec_get_frame_defaults(&s->frame); @@ -233,7 +244,7 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); allocate_buffers(s); flac_set_bps(s); - ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; return 0; @@ -492,9 +503,11 @@ static int decode_frame(FLACContext *s) "supported\n"); return -1; } - s->bps = s->avctx->bits_per_raw_sample = fi.bps; - flac_set_bps(s); + if (!s->bps) { + s->bps = s->avctx->bits_per_raw_sample = fi.bps; + flac_set_bps(s); + } if (!s->max_blocksize) s->max_blocksize = FLAC_MAX_BLOCKSIZE; @@ -520,7 +533,7 @@ static int decode_frame(FLACContext *s) if (!s->got_streaminfo) { allocate_buffers(s); - ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt); + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; dump_headers(s->avctx, (FLACStreaminfo *)s); } @@ -628,4 +641,9 @@ AVCodec ff_flac_decoder = { .decode = flac_decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_S32P, + -1 }, }; diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c index fcee8e44c7..a2e335b4de 100644 --- a/libavcodec/flacdsp.c +++ b/libavcodec/flacdsp.c @@ -23,10 +23,21 @@ #include "flacdsp.h" #define SAMPLE_SIZE 16 +#define PLANAR 0 +#include "flacdsp_template.c" + +#undef PLANAR +#define PLANAR 1 #include "flacdsp_template.c" #undef SAMPLE_SIZE +#undef PLANAR #define SAMPLE_SIZE 32 +#define PLANAR 0 +#include "flacdsp_template.c" + +#undef PLANAR +#define PLANAR 1 #include "flacdsp_template.c" static void flac_lpc_16_c(int32_t *decoded, const int coeffs[32], @@ -72,15 +83,27 @@ static void flac_lpc_32_c(int32_t *decoded, const int coeffs[32], } -av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt) +av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, + int bps) { + if (bps > 16) + c->lpc = flac_lpc_32_c; + else + c->lpc = flac_lpc_16_c; + switch (fmt) { case AV_SAMPLE_FMT_S32: c->decorrelate[0] = flac_decorrelate_indep_c_32; c->decorrelate[1] = flac_decorrelate_ls_c_32; c->decorrelate[2] = flac_decorrelate_rs_c_32; c->decorrelate[3] = flac_decorrelate_ms_c_32; - c->lpc = flac_lpc_32_c; + break; + + case AV_SAMPLE_FMT_S32P: + c->decorrelate[0] = flac_decorrelate_indep_c_32p; + c->decorrelate[1] = flac_decorrelate_ls_c_32p; + c->decorrelate[2] = flac_decorrelate_rs_c_32p; + c->decorrelate[3] = flac_decorrelate_ms_c_32p; break; case AV_SAMPLE_FMT_S16: @@ -88,7 +111,13 @@ av_cold void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt) c->decorrelate[1] = flac_decorrelate_ls_c_16; c->decorrelate[2] = flac_decorrelate_rs_c_16; c->decorrelate[3] = flac_decorrelate_ms_c_16; - c->lpc = flac_lpc_16_c; + break; + + case AV_SAMPLE_FMT_S16P: + c->decorrelate[0] = flac_decorrelate_indep_c_16p; + c->decorrelate[1] = flac_decorrelate_ls_c_16p; + c->decorrelate[2] = flac_decorrelate_rs_c_16p; + c->decorrelate[3] = flac_decorrelate_ms_c_16p; break; } } diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h index fe5ca53177..16515539a6 100644 --- a/libavcodec/flacdsp.h +++ b/libavcodec/flacdsp.h @@ -29,6 +29,6 @@ typedef struct FLACDSPContext { int qlevel, int len); } FLACDSPContext; -void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt); +void ff_flacdsp_init(FLACDSPContext *c, enum AVSampleFormat fmt, int bps); #endif /* AVCODEC_FLACDSP_H */ diff --git a/libavcodec/flacdsp_template.c b/libavcodec/flacdsp_template.c index 34da5a6d25..0affe22ddb 100644 --- a/libavcodec/flacdsp_template.c +++ b/libavcodec/flacdsp_template.c @@ -19,68 +19,85 @@ */ #include +#include "libavutil/avutil.h" #undef FUNC +#undef FSUF #undef sample +#undef sample_type +#undef OUT +#undef S #if SAMPLE_SIZE == 32 -# define FUNC(n) n ## _32 -# define sample int32_t +# define sample_type int32_t #else -# define FUNC(n) n ## _16 -# define sample int16_t +# define sample_type int16_t #endif +#if PLANAR +# define FSUF AV_JOIN(SAMPLE_SIZE, p) +# define sample sample_type * +# define OUT(n) n +# define S(s, c, i) (s[c][i]) +#else +# define FSUF SAMPLE_SIZE +# define sample sample_type +# define OUT(n) n[0] +# define S(s, c, i) (*s++) +#endif + +#define FUNC(n) AV_JOIN(n ## _, FSUF) + static void FUNC(flac_decorrelate_indep_c)(uint8_t **out, int32_t **in, int channels, int len, int shift) { - sample *samples = (sample *) out[0]; + sample *samples = (sample *) OUT(out); int i, j; for (j = 0; j < len; j++) for (i = 0; i < channels; i++) - *samples++ = in[i][j] << shift; + S(samples, i, j) = in[i][j] << shift; } static void FUNC(flac_decorrelate_ls_c)(uint8_t **out, int32_t **in, int channels, int len, int shift) { - sample *samples = (sample *) out[0]; + sample *samples = (sample *) OUT(out); int i; for (i = 0; i < len; i++) { int a = in[0][i]; int b = in[1][i]; - *samples++ = a << shift; - *samples++ = (a - b) << shift; + S(samples, 0, i) = a << shift; + S(samples, 1, i) = (a - b) << shift; } } static void FUNC(flac_decorrelate_rs_c)(uint8_t **out, int32_t **in, int channels, int len, int shift) { - sample *samples = (sample *) out[0]; + sample *samples = (sample *) OUT(out); int i; for (i = 0; i < len; i++) { int a = in[0][i]; int b = in[1][i]; - *samples++ = (a + b) << shift; - *samples++ = b << shift; + S(samples, 0, i) = (a + b) << shift; + S(samples, 1, i) = b << shift; } } static void FUNC(flac_decorrelate_ms_c)(uint8_t **out, int32_t **in, int channels, int len, int shift) { - sample *samples = (sample *) out[0]; + sample *samples = (sample *) OUT(out); int i; for (i = 0; i < len; i++) { int a = in[0][i]; int b = in[1][i]; a -= b >> 1; - *samples++ = (a + b) << shift; - *samples++ = a << shift; + S(samples, 0, i) = (a + b) << shift; + S(samples, 1, i) = a << shift; } } From 0a19000da8d744ff64b902f9f3fede1d865b1ae7 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Fri, 29 Jun 2012 15:23:03 +0100 Subject: [PATCH 03/10] lavc: options: add planar names for request_sample_fmt Signed-off-by: Mans Rullgard --- libavcodec/options_table.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 5ecf4f7ee9..7f5b643150 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -391,6 +391,11 @@ static const AVOption options[]={ {"s32", "32-bit signed integer", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"flt", "32-bit float", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLT }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {"dbl", "64-bit double", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBL }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"u8p" , "8-bit unsigned integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_U8P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"s16p", "16-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S16P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"s32p", "32-bit signed integer planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"fltp", "32-bit float planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, +{"dblp", "64-bit double planar", 0, AV_OPT_TYPE_CONST, {.dbl = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"}, {NULL}, }; From 1f061da529f4dad617c31b788b92089be4114c48 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 6 Jul 2012 09:22:46 +0200 Subject: [PATCH 04/10] mss3: add forgotten 'static' qualifier for private table --- libavcodec/mss3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c index 37d8aee4ec..25163c660e 100644 --- a/libavcodec/mss3.c +++ b/libavcodec/mss3.c @@ -141,7 +141,7 @@ static const uint8_t mss3_chroma_quant[64] = { 99, 99, 99, 99, 99, 99, 99, 99 }; -const uint8_t zigzag_scan[64] = { +static const uint8_t zigzag_scan[64] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, From b98c8f4f2bf5879ba5393a439f0fccf76a65e448 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 4 Jul 2012 02:53:25 +0200 Subject: [PATCH 05/10] avconv: fix the check for -ss as an output option. start time is already substracted from the frame timestamp, so it needs to be checked against 0, not start time. --- avconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv.c b/avconv.c index 6517c4bcfc..c59916e3ed 100644 --- a/avconv.c +++ b/avconv.c @@ -1568,7 +1568,7 @@ static int poll_filters(void) AV_TIME_BASE_Q, ost->st->codec->time_base); - if (of->start_time && filtered_frame->pts < of->start_time) { + if (of->start_time && filtered_frame->pts < 0) { avfilter_unref_buffer(picref); continue; } From 53ddd43f0c9aa9d1060d70a7e921e1ae74601947 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 4 Jul 2012 02:56:38 +0200 Subject: [PATCH 06/10] avconv: use only meaningful timestamps in start time check. --- avconv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/avconv.c b/avconv.c index c59916e3ed..fad0626c91 100644 --- a/avconv.c +++ b/avconv.c @@ -1560,7 +1560,7 @@ static int poll_filters(void) break; avfilter_copy_buf_props(filtered_frame, picref); - if (picref->pts != AV_NOPTS_VALUE) + if (picref->pts != AV_NOPTS_VALUE) { filtered_frame->pts = av_rescale_q(picref->pts, ost->filter->filter->inputs[0]->time_base, ost->st->codec->time_base) - @@ -1568,9 +1568,10 @@ static int poll_filters(void) AV_TIME_BASE_Q, ost->st->codec->time_base); - if (of->start_time && filtered_frame->pts < 0) { - avfilter_unref_buffer(picref); - continue; + if (of->start_time && filtered_frame->pts < 0) { + avfilter_unref_buffer(picref); + continue; + } } switch (ost->filter->filter->inputs[0]->type) { From 428b369804d1a0ea7212409e800324ce284e9d55 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 4 Jul 2012 18:55:14 +0200 Subject: [PATCH 07/10] af_amix: only consider negative return codes as errors. --- libavfilter/af_amix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 8ceb179e58..a8ec8a194f 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -360,7 +360,7 @@ static int request_samples(AVFilterContext *ctx, int min_samples) s->input_state[i] = INPUT_OFF; continue; } - } else if (ret) + } else if (ret < 0) return ret; } return 0; @@ -422,7 +422,7 @@ static int request_frame(AVFilterLink *outlink) return AVERROR_EOF; else return AVERROR(EAGAIN); - } else if (ret) + } else if (ret < 0) return ret; } av_assert0(s->frame_list->nb_frames > 0); From 54bf88e65fe2d87a41abcbee33392725ebe2f0a0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 5 Jul 2012 20:28:10 +0200 Subject: [PATCH 08/10] af_amix: return AVERROR(EAGAIN) when request_frame didn't produce output. 0 should only be returned when there was at least one output frame. --- libavfilter/af_amix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index a8ec8a194f..deeaa036ac 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -409,7 +409,7 @@ static int request_frame(AVFilterLink *outlink) available_samples = get_available_samples(s); if (!available_samples) - return 0; + return AVERROR(EAGAIN); return output_frame(outlink, available_samples); } @@ -440,7 +440,7 @@ static int request_frame(AVFilterLink *outlink) available_samples = get_available_samples(s); if (!available_samples) - return 0; + return AVERROR(EAGAIN); available_samples = FFMIN(available_samples, wanted_samples); } else { available_samples = wanted_samples; From b7558ac293f199ac408117618a61567ee1ee7077 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 5 Jul 2012 21:51:44 +0200 Subject: [PATCH 09/10] af_amix: avoid spurious EAGAIN. Input on/off state can change in request_samples(), which can result in a state where only the first input is active. get_available_samples() will then return 0, and request_frame() will fail with EAGAIN even though there is data on the single active input. Take this into account and check the number of active inputs again after calling request_samples(). --- libavfilter/af_amix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index deeaa036ac..439231fbd1 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -437,7 +437,9 @@ static int request_frame(AVFilterLink *outlink) ret = calc_active_inputs(s); if (ret < 0) return ret; + } + if (s->active_inputs > 1) { available_samples = get_available_samples(s); if (!available_samples) return AVERROR(EAGAIN); From 5adc829eb0787682111ca063bfc2b31558999dff Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Wed, 4 Jul 2012 23:06:25 +0100 Subject: [PATCH 10/10] configure: add functions for testing code fragments This simplifies testing arbitrary code fragments within a function body. Signed-off-by: Mans Rullgard Signed-off-by: Luca Barbato --- configure | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/configure b/configure index 9f70a36f74..a08b3af79e 100755 --- a/configure +++ b/configure @@ -660,6 +660,20 @@ check_ld(){ check_cmd $ld $LDFLAGS $flags -o $TMPE $TMPO $libs $extralibs } +check_code(){ + log check_code "$@" + check=$1 + headers=$2 + code=$3 + shift 3 + { + for hdr in $headers; do + echo "#include <$hdr>" + done + echo "int main(void) { $code; return 0; }" + } | check_$check "$@" +} + check_cppflags(){ log check_cppflags "$@" set -- $($filter_cppflags "$@") @@ -817,15 +831,7 @@ check_type(){ type=$2 shift 2 disable_safe "$type" - incs="" - for hdr in $headers; do - incs="$incs -#include <$hdr>" - done - check_cc "$@" <$member; -EOF + check_code cc "$headers" "const void *p = &(($struct *)0)->$member" "$@" && + enable_safe "${struct}_${member}" } require(){ @@ -2399,9 +2398,7 @@ case "$arch" in ;; x86) subarch="x86_32" - check_cc <