From 81cf53e13309bd58aeb10f3574807f66b25d0091 Mon Sep 17 00:00:00 2001 From: Can Wu Date: Tue, 26 Feb 2013 10:01:21 +0800 Subject: mpegts: add support for stream_type 0x42, which is CAVS This allows demuxing and muxing of CAVS TS streams. Signed-off-by: Anton Khirnov --- libavformat/mpeg.h | 1 + libavformat/mpegts.c | 1 + libavformat/mpegts.h | 1 + libavformat/mpegtsenc.c | 3 +++ 4 files changed, 6 insertions(+) diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h index 75dddf346b..629f2f061d 100644 --- a/libavformat/mpeg.h +++ b/libavformat/mpeg.h @@ -54,6 +54,7 @@ #define STREAM_TYPE_AUDIO_AAC 0x0f #define STREAM_TYPE_VIDEO_MPEG4 0x10 #define STREAM_TYPE_VIDEO_H264 0x1b +#define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_AUDIO_AC3 0x81 #define STREAM_TYPE_AUDIO_DTS 0x8a diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 2582c5b0bd..1540a8d118 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -523,6 +523,7 @@ static const StreamType ISO_types[] = { { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, { 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */ { 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, + { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, { 0 }, diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 89544f06f8..fafe98fcf8 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -52,6 +52,7 @@ #define STREAM_TYPE_AUDIO_AAC_LATM 0x11 #define STREAM_TYPE_VIDEO_MPEG4 0x10 #define STREAM_TYPE_VIDEO_H264 0x1b +#define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_VIDEO_VC1 0xea #define STREAM_TYPE_VIDEO_DIRAC 0xd1 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 29d83c668a..44a5e5b089 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -279,6 +279,9 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) case AV_CODEC_ID_H264: stream_type = STREAM_TYPE_VIDEO_H264; break; + case AV_CODEC_ID_CAVS: + stream_type = STREAM_TYPE_VIDEO_CAVS; + break; case AV_CODEC_ID_DIRAC: stream_type = STREAM_TYPE_VIDEO_DIRAC; break; -- cgit v1.2.3 From b164d66e35d349de414e2f0d7365a147aba8a620 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Tue, 12 Mar 2013 07:33:12 +0100 Subject: ape: make version-dependent decoding functions called via pointers This will help in supporting old versions, e.g. version 3.93 uses the same range coder but different predictor and version 3.82 uses different range coder and predictor. Also this should not make decoding newer versions slower by introducing additional checks on versions. --- libavcodec/apedec.c | 182 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 123 insertions(+), 59 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 83f8723241..0bef457eb8 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -161,8 +161,24 @@ typedef struct APEContext { const uint8_t *ptr; ///< current position in frame data int error; + + void (*entropy_decode_mono)(struct APEContext *ctx, int blockstodecode); + void (*entropy_decode_stereo)(struct APEContext *ctx, int blockstodecode); + void (*predictor_decode_mono)(struct APEContext *ctx, int count); + void (*predictor_decode_stereo)(struct APEContext *ctx, int count); } APEContext; +static void ape_apply_filters(APEContext *ctx, int32_t *decoded0, + int32_t *decoded1, int count); + +static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode); +static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode); +static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode); +static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode); + +static void predictor_decode_mono_3950(APEContext *ctx, int count); +static void predictor_decode_stereo_3950(APEContext *ctx, int count); + // TODO: dsputilize static av_cold int ape_decode_close(AVCodecContext *avctx) @@ -231,6 +247,17 @@ static av_cold int ape_decode_init(AVCodecContext *avctx) filter_alloc_fail); } + if (s->fileversion < 3990) { + s->entropy_decode_mono = entropy_decode_mono_3900; + s->entropy_decode_stereo = entropy_decode_stereo_3900; + } else { + s->entropy_decode_mono = entropy_decode_mono_3990; + s->entropy_decode_stereo = entropy_decode_stereo_3990; + } + + s->predictor_decode_mono = predictor_decode_mono_3950; + s->predictor_decode_stereo = predictor_decode_stereo_3950; + ff_dsputil_init(&s->dsp, avctx); avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; @@ -401,67 +428,76 @@ static inline void update_rice(APERice *rice, unsigned int x) rice->k++; } -static inline int ape_decode_value(APEContext *ctx, APERice *rice) +static inline int ape_decode_value_3900(APEContext *ctx, APERice *rice) { unsigned int x, overflow; + int tmpk; - if (ctx->fileversion < 3990) { - int tmpk; + overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); - overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970); + if (overflow == (MODEL_ELEMENTS - 1)) { + tmpk = range_decode_bits(ctx, 5); + overflow = 0; + } else + tmpk = (rice->k < 1) ? 0 : rice->k - 1; - if (overflow == (MODEL_ELEMENTS - 1)) { - tmpk = range_decode_bits(ctx, 5); - overflow = 0; - } else - tmpk = (rice->k < 1) ? 0 : rice->k - 1; - - if (tmpk <= 16) - x = range_decode_bits(ctx, tmpk); - else if (tmpk <= 32) { - x = range_decode_bits(ctx, 16); - x |= (range_decode_bits(ctx, tmpk - 16) << 16); - } else { - av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); - return AVERROR_INVALIDDATA; - } - x += overflow << tmpk; + if (tmpk <= 16) + x = range_decode_bits(ctx, tmpk); + else if (tmpk <= 32) { + x = range_decode_bits(ctx, 16); + x |= (range_decode_bits(ctx, tmpk - 16) << 16); } else { - int base, pivot; + av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); + return AVERROR_INVALIDDATA; + } + x += overflow << tmpk; + + update_rice(rice, x); + + /* Convert to signed */ + if (x & 1) + return (x >> 1) + 1; + else + return -(x >> 1); +} - pivot = rice->ksum >> 5; - if (pivot == 0) - pivot = 1; +static inline int ape_decode_value_3990(APEContext *ctx, APERice *rice) +{ + unsigned int x, overflow; + int base, pivot; - overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); + pivot = rice->ksum >> 5; + if (pivot == 0) + pivot = 1; - if (overflow == (MODEL_ELEMENTS - 1)) { - overflow = range_decode_bits(ctx, 16) << 16; - overflow |= range_decode_bits(ctx, 16); - } + overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980); - if (pivot < 0x10000) { - base = range_decode_culfreq(ctx, pivot); - range_decode_update(ctx, 1, base); - } else { - int base_hi = pivot, base_lo; - int bbits = 0; - - while (base_hi & ~0xFFFF) { - base_hi >>= 1; - bbits++; - } - base_hi = range_decode_culfreq(ctx, base_hi + 1); - range_decode_update(ctx, 1, base_hi); - base_lo = range_decode_culfreq(ctx, 1 << bbits); - range_decode_update(ctx, 1, base_lo); - - base = (base_hi << bbits) + base_lo; + if (overflow == (MODEL_ELEMENTS - 1)) { + overflow = range_decode_bits(ctx, 16) << 16; + overflow |= range_decode_bits(ctx, 16); + } + + if (pivot < 0x10000) { + base = range_decode_culfreq(ctx, pivot); + range_decode_update(ctx, 1, base); + } else { + int base_hi = pivot, base_lo; + int bbits = 0; + + while (base_hi & ~0xFFFF) { + base_hi >>= 1; + bbits++; } + base_hi = range_decode_culfreq(ctx, base_hi + 1); + range_decode_update(ctx, 1, base_hi); + base_lo = range_decode_culfreq(ctx, 1 << bbits); + range_decode_update(ctx, 1, base_lo); - x = base + overflow * pivot; + base = (base_hi << bbits) + base_lo; } + x = base + overflow * pivot; + update_rice(rice, x); /* Convert to signed */ @@ -471,15 +507,41 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice) return -(x >> 1); } -static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) +static void entropy_decode_mono_3900(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + + while (blockstodecode--) + *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY); +} + +static void entropy_decode_stereo_3900(APEContext *ctx, int blockstodecode) { int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; while (blockstodecode--) { - *decoded0++ = ape_decode_value(ctx, &ctx->riceY); - if (stereo) - *decoded1++ = ape_decode_value(ctx, &ctx->riceX); + *decoded0++ = ape_decode_value_3900(ctx, &ctx->riceY); + *decoded1++ = ape_decode_value_3900(ctx, &ctx->riceX); + } +} + +static void entropy_decode_mono_3990(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + + while (blockstodecode--) + *decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY); +} + +static void entropy_decode_stereo_3990(APEContext *ctx, int blockstodecode) +{ + int32_t *decoded0 = ctx->decoded[0]; + int32_t *decoded1 = ctx->decoded[1]; + + while (blockstodecode--) { + *decoded0++ = ape_decode_value_3990(ctx, &ctx->riceY); + *decoded1++ = ape_decode_value_3990(ctx, &ctx->riceX); } } @@ -588,12 +650,14 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, return p->filterA[filter]; } -static void predictor_decode_stereo(APEContext *ctx, int count) +static void predictor_decode_stereo_3950(APEContext *ctx, int count) { APEPredictor *p = &ctx->predictor; int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; + ape_apply_filters(ctx, ctx->decoded[0], ctx->decoded[1], count); + while (count--) { /* Predictor Y */ *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, @@ -615,12 +679,14 @@ static void predictor_decode_stereo(APEContext *ctx, int count) } } -static void predictor_decode_mono(APEContext *ctx, int count) +static void predictor_decode_mono_3950(APEContext *ctx, int count) { APEPredictor *p = &ctx->predictor; int32_t *decoded0 = ctx->decoded[0]; int32_t predictionA, currentA, A, sign; + ape_apply_filters(ctx, ctx->decoded[0], NULL, count); + currentA = p->lastA[0]; while (count--) { @@ -779,11 +845,10 @@ static void ape_unpack_mono(APEContext *ctx, int count) return; } - entropy_decode(ctx, count, 0); - ape_apply_filters(ctx, ctx->decoded[0], NULL, count); + ctx->entropy_decode_mono(ctx, count); /* Now apply the predictor decoding */ - predictor_decode_mono(ctx, count); + ctx->predictor_decode_mono(ctx, count); /* Pseudo-stereo - just copy left channel to right channel */ if (ctx->channels == 2) { @@ -803,11 +868,10 @@ static void ape_unpack_stereo(APEContext *ctx, int count) return; } - entropy_decode(ctx, count, 1); - ape_apply_filters(ctx, decoded0, decoded1, count); + ctx->entropy_decode_stereo(ctx, count); /* Now apply the predictor decoding */ - predictor_decode_stereo(ctx, count); + ctx->predictor_decode_stereo(ctx, count); /* Decorrelate and scale to output depth */ while (count--) { -- cgit v1.2.3