On Wed, Aug 22, 2018 at 12:29:57AM +0100, Kieran Kunhya wrote: > $subj > > Depends on Michael's patch. > I have a FATE sample frame.
> mpeg4videodec.c | 101 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > mpegvideo.c | 75 ++++++++++++++++++++++++++++++++--------- > mpegvideo.h | 2 + > 3 files changed, 158 insertions(+), 20 deletions(-) > 530459506bce209c83f6e3d477c2bbf77cd5d072 > 0001-mpeg4video-Add-Studio-DPCM-support.patch > From 909fba9afc7edc94a8fd043899ff44c022a32d17 Mon Sep 17 00:00:00 2001 > From: Kieran Kunhya <kie...@kunhya.com> > Date: Sun, 19 Aug 2018 02:31:42 +0100 > Subject: [PATCH] mpeg4video: Add Studio DPCM support > > --- > libavcodec/mpeg4videodec.c | 101 > +++++++++++++++++++++++++++++++++++++++++++-- > libavcodec/mpegvideo.c | 75 +++++++++++++++++++++++++-------- > libavcodec/mpegvideo.h | 2 + > 3 files changed, 158 insertions(+), 20 deletions(-) > > diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c > index 1686ed1001..dda462c2ea 100644 > --- a/libavcodec/mpeg4videodec.c > +++ b/libavcodec/mpeg4videodec.c > @@ -24,6 +24,7 @@ > > #include "libavutil/internal.h" > #include "libavutil/opt.h" > +#include "libavutil/pixdesc.h" > #include "error_resilience.h" > #include "hwaccel.h" > #include "idctdsp.h" > @@ -36,6 +37,7 @@ > #include "profiles.h" > #include "thread.h" > #include "xvididct.h" > +#include "unary.h" > > /* The defines below define the number of bits that are read at once for > * reading vlc values. Changing these may improve speed and data cache needs > @@ -1923,10 +1925,101 @@ static int mpeg4_decode_studio_block(MpegEncContext > *s, int32_t block[64], int n > return 0; > } > > +static int mpeg4_decode_dpcm_macroblock(MpegEncContext *s, int16_t > macroblock[256], int n) > +{ > + int i, j, w, h, idx = 0; > + int block_mean, rice_parameter, rice_prefix_code, rice_suffix_code; > + int dpcm_residual, a, b, c, p, p2; > + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); > + h = 16 >> (n ? desc->log2_chroma_h : 0); > + w = 16 >> (n ? desc->log2_chroma_w : 0); you can use chroma_x_shift, chroma_y_shift from the context, theres no need to obtain a AVPixFmtDescriptor > + > + block_mean = get_bits(&s->gb, s->avctx->bits_per_raw_sample); > + if (block_mean == 0){ > + av_log(s->avctx, AV_LOG_ERROR, "Forbidden block_mean\n"); > + return AVERROR_INVALIDDATA; > + } > + s->last_dc[n] = block_mean * (1 << (s->dct_precision + > s->intra_dc_precision)); > + > + rice_parameter = get_bits(&s->gb, 4); > + if (rice_parameter == 0) { > + av_log(s->avctx, AV_LOG_ERROR, "Forbidden rice_parameter\n"); > + return AVERROR_INVALIDDATA; > + } > + > + if (rice_parameter == 15) > + rice_parameter = 0; > + > + if (rice_parameter > 11) { > + av_log(s->avctx, AV_LOG_ERROR, "Forbidden rice_parameter\n"); > + return AVERROR_INVALIDDATA; > + } > + > + for (i = 0; i < h; i++) { > + for (j = 0; j < w; j++) { > + rice_prefix_code = get_unary(&s->gb, 1, 12); > + > + /* Escape */ > + if (rice_prefix_code == 11) > + dpcm_residual = get_bits(&s->gb, > s->avctx->bits_per_raw_sample); > + else { > + rice_suffix_code = get_bitsz(&s->gb, rice_parameter); > + dpcm_residual = (rice_prefix_code << rice_parameter) + > rice_suffix_code; > + } > + > + /* Map to a signed residual */ > + if (dpcm_residual & 1) > + dpcm_residual = (-1 * dpcm_residual) >> 1; > + else > + dpcm_residual = (dpcm_residual >> 1); This could be optimized, not sure how common DPCM blocks are so maybe this doesnt matter > + > + /* Calculate predictors > + a = left > + b = top > + c = top left > + */ > + if (j == 0) > + a = 1 << (s->avctx->bits_per_raw_sample - 1); > + else > + a = macroblock[idx-1]; you can move this out of the loop and just update "a" at the end of the loop, as its the previous value > + > + if (i == 0) > + b = 1 << (s->avctx->bits_per_raw_sample - 1); > + else > + b = macroblock[idx-w]; > + > + if ((j == 0) || (i == 0)) > + c = 1 << (s->avctx->bits_per_raw_sample - 1); > + else > + c = macroblock[idx-w-1]; this too can be avoided by simply updating "c" at the end of teh loop and setting it outside before the loop > + > + p = a + b - c; > + if (p < FFMIN(a, b)) > + p = FFMIN(a, b); > + > + if (p > FFMAX(a, b)) > + p = FFMAX(a, b); > + > + p2 = (FFMIN3(a, b, c) + FFMAX3(a, b, c)) / 2; using >> instead of /2 should be faster here also FFMIN(a, b) and FFMAX(a, b) have already been calculated, they could be reused to turn 3 argument MIN/MAX to 2 argument variants [...] > diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h > index e16deb64e7..5b316c6adb 100644 > --- a/libavcodec/mpegvideo.h > +++ b/libavcodec/mpegvideo.h > @@ -509,6 +509,8 @@ typedef struct MpegEncContext { > int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // > used by some codecs to avoid a switch() > > int32_t (*block32)[12][64]; > + int block_type; // 0 = DCT, 1 = DPCM top to bottom scan, 2 = > DPCM bottom to top scan i suggest a "dpcm_direction" instead that uses // 0 = DCT, 1 = DPCM top to bottom scan, -1 = DPCM bottom to top scan it would be more self explanatory thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB You can kill me, but you cannot change the truth.
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel