Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
openSUSE:Leap:15.5:Update
ffmpeg.21544
ffmpeg-CVE-2018-13301.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ffmpeg-CVE-2018-13301.patch of Package ffmpeg.21544
diff -Nura ffmpeg-3.4.2/fftools/ffmpeg.c ffmpeg-3.4.2_new/fftools/ffmpeg.c --- ffmpeg-3.4.2/fftools/ffmpeg.c 2019-07-06 16:42:23.008212683 +0800 +++ ffmpeg-3.4.2_new/fftools/ffmpeg.c 2019-07-08 00:26:34.653219658 +0800 @@ -2910,7 +2910,7 @@ /* Useful for subtitles retiming by lavf (FIXME), skipping samples in * audio, and video decoders such as cuvid or mediacodec */ - av_codec_set_pkt_timebase(ist->dec_ctx, ist->st->time_base); + ist->dec_ctx->pkt_timebase = ist->st->time_base; if (!av_dict_get(ist->decoder_opts, "threads", NULL, 0)) av_dict_set(&ist->decoder_opts, "threads", "auto", 0); diff -Nura ffmpeg-3.4.2/fftools/ffmpeg_opt.c ffmpeg-3.4.2_new/fftools/ffmpeg_opt.c --- ffmpeg-3.4.2/fftools/ffmpeg_opt.c 2019-07-06 16:42:23.009212693 +0800 +++ ffmpeg-3.4.2_new/fftools/ffmpeg_opt.c 2019-07-08 00:26:43.109297918 +0800 @@ -792,8 +792,8 @@ if(!ist->dec) ist->dec = avcodec_find_decoder(par->codec_id); #if FF_API_LOWRES - if (av_codec_get_lowres(st->codec)) { - av_codec_set_lowres(ist->dec_ctx, av_codec_get_lowres(st->codec)); + if (st->codec->lowres) { + ist->dec_ctx->lowres = st->codec->lowres; ist->dec_ctx->width = st->codec->width; ist->dec_ctx->height = st->codec->height; ist->dec_ctx->coded_width = st->codec->coded_width; @@ -1663,7 +1663,7 @@ av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n"); exit_program(1); } - av_codec_set_chroma_intra_matrix(video_enc, p); + video_enc->chroma_intra_matrix = p; parse_matrix_coeffs(p, chroma_intra_matrix); } MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st); diff -Nura ffmpeg-3.4.2/libavcodec/bit_depth_template.c ffmpeg-3.4.2_new/libavcodec/bit_depth_template.c --- ffmpeg-3.4.2/libavcodec/bit_depth_template.c 2016-03-29 10:25:11.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/bit_depth_template.c 2019-07-08 00:27:16.981611423 +0800 @@ -29,6 +29,7 @@ # undef pixel2 # undef pixel4 # undef dctcoef +# undef idctin # undef INIT_CLIP # undef no_rnd_avg_pixel4 # undef rnd_avg_pixel4 @@ -53,6 +54,16 @@ # define pixel4 uint64_t # define dctcoef int32_t +#ifdef IN_IDCT_DEPTH +#if IN_IDCT_DEPTH == 32 +# define idctin int32_t +#else +# define idctin int16_t +#endif +#else +# define idctin int16_t +#endif + # define INIT_CLIP # define no_rnd_avg_pixel4 no_rnd_avg64 # define rnd_avg_pixel4 rnd_avg64 @@ -71,6 +82,7 @@ # define pixel2 uint16_t # define pixel4 uint32_t # define dctcoef int16_t +# define idctin int16_t # define INIT_CLIP # define no_rnd_avg_pixel4 no_rnd_avg32 @@ -87,7 +99,10 @@ # define CLIP(a) av_clip_uint8(a) #endif -#define FUNC3(a, b, c) a ## _ ## b ## c +#define FUNC3(a, b, c) a ## _ ## b ## c #define FUNC2(a, b, c) FUNC3(a, b, c) #define FUNC(a) FUNC2(a, BIT_DEPTH,) #define FUNCC(a) FUNC2(a, BIT_DEPTH, _c) +#define FUNC4(a, b, c) a ## _int ## b ## _ ## c ## bit +#define FUNC5(a, b, c) FUNC4(a, b, c) +#define FUNC6(a) FUNC5(a, IN_IDCT_DEPTH, BIT_DEPTH) diff -Nura ffmpeg-3.4.2/libavcodec/error_resilience.c ffmpeg-3.4.2_new/libavcodec/error_resilience.c --- ffmpeg-3.4.2/libavcodec/error_resilience.c 2018-02-12 08:29:04.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/error_resilience.c 2019-07-08 00:27:34.805776383 +0800 @@ -818,7 +818,8 @@ s->avctx->codec->capabilities&AV_CODEC_CAP_HWACCEL_VDPAU || #endif !s->cur_pic.f || - s->cur_pic.field_picture + s->cur_pic.field_picture || + s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO ) return 0; return 1; diff -Nura ffmpeg-3.4.2/libavcodec/h263dec.c ffmpeg-3.4.2_new/libavcodec/h263dec.c --- ffmpeg-3.4.2/libavcodec/h263dec.c 2018-02-12 08:29:04.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/h263dec.c 2019-07-08 00:27:48.781905730 +0800 @@ -47,6 +47,12 @@ static enum AVPixelFormat h263_get_format(AVCodecContext *avctx) { + /* MPEG-4 Studio Profile only, not supported by hardware */ + if (avctx->bits_per_raw_sample > 8) { + av_assert1(avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO); + return avctx->pix_fmt; + } + if (avctx->codec->id == AV_CODEC_ID_MSS2) return AV_PIX_FMT_YUV420P; @@ -197,6 +203,11 @@ ff_set_qscale(s, s->qscale); + if (s->studio_profile) { + if ((ret = ff_mpeg4_decode_studio_slice_header(s->avctx->priv_data)) < 0) + return ret; + } + if (s->avctx->hwaccel) { const uint8_t *start = s->gb.buffer + get_bits_count(&s->gb) / 8; ret = s->avctx->hwaccel->decode_slice(s->avctx, start, s->gb.buffer_end - start); diff -Nura ffmpeg-3.4.2/libavcodec/idctdsp.c ffmpeg-3.4.2_new/libavcodec/idctdsp.c --- ffmpeg-3.4.2/libavcodec/idctdsp.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/idctdsp.c 2019-07-08 00:28:00.854017456 +0800 @@ -256,14 +256,20 @@ c->perm_type = FF_IDCT_PERM_NONE; } else { if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) { - c->idct_put = ff_simple_idct_put_10; - c->idct_add = ff_simple_idct_add_10; - c->idct = ff_simple_idct_10; + /* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT + However, it only uses idct_put */ + if (avctx->codec_id == AV_CODEC_ID_MPEG4 && avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO) + c->idct_put = ff_simple_idct_put_int32_10bit; + else { + c->idct_put = ff_simple_idct_put_int16_10bit; + c->idct_add = ff_simple_idct_add_int16_10bit; + c->idct = ff_simple_idct_int16_10bit; + } c->perm_type = FF_IDCT_PERM_NONE; } else if (avctx->bits_per_raw_sample == 12) { - c->idct_put = ff_simple_idct_put_12; - c->idct_add = ff_simple_idct_add_12; - c->idct = ff_simple_idct_12; + c->idct_put = ff_simple_idct_put_int16_12bit; + c->idct_add = ff_simple_idct_add_int16_12bit; + c->idct = ff_simple_idct_int16_12bit; c->perm_type = FF_IDCT_PERM_NONE; } else { if (avctx->idct_algo == FF_IDCT_INT) { @@ -280,9 +286,9 @@ #endif /* CONFIG_FAANIDCT */ } else { // accurate/default /* Be sure FF_IDCT_NONE will select this one, since it uses FF_IDCT_PERM_NONE */ - c->idct_put = ff_simple_idct_put_8; - c->idct_add = ff_simple_idct_add_8; - c->idct = ff_simple_idct_8; + c->idct_put = ff_simple_idct_put_int16_8bit; + c->idct_add = ff_simple_idct_add_int16_8bit; + c->idct = ff_simple_idct_int16_8bit; c->perm_type = FF_IDCT_PERM_NONE; } } diff -Nura ffmpeg-3.4.2/libavcodec/ituh263dec.c ffmpeg-3.4.2_new/libavcodec/ituh263dec.c --- ffmpeg-3.4.2/libavcodec/ituh263dec.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/ituh263dec.c 2019-07-08 00:28:14.238141324 +0800 @@ -207,12 +207,27 @@ } /** - * Decode the group of blocks / video packet header. + * Decode the group of blocks / video packet header / slice header (MPEG-4 Studio). * @return bit position of the resync_marker, or <0 if none was found */ int ff_h263_resync(MpegEncContext *s){ int left, pos, ret; + /* In MPEG-4 studio mode look for a new slice startcode + * and decode slice header */ + if(s->codec_id==AV_CODEC_ID_MPEG4 && s->studio_profile) { + align_get_bits(&s->gb); + + while (get_bits_left(&s->gb) >= 32 && show_bits_long(&s->gb, 32) != SLICE_START_CODE) { + get_bits(&s->gb, 8); + } + + if (show_bits_long(&s->gb, 32) == SLICE_START_CODE) + return get_bits_count(&s->gb); + else + return -1; + } + if(s->codec_id==AV_CODEC_ID_MPEG4){ skip_bits1(&s->gb); align_get_bits(&s->gb); diff -Nura ffmpeg-3.4.2/libavcodec/me_cmp.c ffmpeg-3.4.2_new/libavcodec/me_cmp.c --- ffmpeg-3.4.2/libavcodec/me_cmp.c 2018-01-01 06:35:47.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/me_cmp.c 2019-07-08 00:28:27.022259639 +0800 @@ -721,7 +721,7 @@ s->block_last_index[0 /* FIXME */] = s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i); s->dct_unquantize_inter(s, temp, 0, s->qscale); - ff_simple_idct_8(temp); // FIXME + ff_simple_idct_int16_8bit(temp); // FIXME for (i = 0; i < 64; i++) sum += (temp[i] - bak[i]) * (temp[i] - bak[i]); diff -Nura ffmpeg-3.4.2/libavcodec/mpeg12dec.c ffmpeg-3.4.2_new/libavcodec/mpeg12dec.c --- ffmpeg-3.4.2/libavcodec/mpeg12dec.c 2018-02-12 08:29:18.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpeg12dec.c 2019-07-08 00:28:39.095371373 +0800 @@ -649,16 +649,6 @@ return 0; } -static inline int get_qscale(MpegEncContext *s) -{ - int qscale = get_bits(&s->gb, 5); - if (s->q_scale_type) - return ff_mpeg2_non_linear_qscale[qscale]; - else - return qscale << 1; -} - - /* motion type (for MPEG-2) */ #define MT_FIELD 1 #define MT_FRAME 2 @@ -751,7 +741,7 @@ s->interlaced_dct = get_bits1(&s->gb); if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); + s->qscale = mpeg_get_qscale(s); if (s->concealment_motion_vectors) { /* just parse them */ @@ -819,7 +809,7 @@ } if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); + s->qscale = mpeg_get_qscale(s); s->last_mv[0][0][0] = 0; s->last_mv[0][0][1] = 0; @@ -840,7 +830,7 @@ } if (IS_QUANT(mb_type)) - s->qscale = get_qscale(s); + s->qscale = mpeg_get_qscale(s); /* motion vectors */ s->mv_dir = (mb_type >> 13) & 3; @@ -1743,7 +1733,7 @@ ff_mpeg1_clean_buffers(s); s->interlaced_dct = 0; - s->qscale = get_qscale(s); + s->qscale = mpeg_get_qscale(s); if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n"); diff -Nura ffmpeg-3.4.2/libavcodec/mpeg4data.h ffmpeg-3.4.2_new/libavcodec/mpeg4data.h --- ffmpeg-3.4.2/libavcodec/mpeg4data.h 2018-01-01 06:35:47.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpeg4data.h 2019-07-08 00:28:51.126482719 +0800 @@ -373,4 +373,120 @@ 99, 13, 15, 17, 19, 21, 23, 0 }; +/* Note these are different in studio mode */ +const uint16_t ff_mpeg4_studio_dc_luma[19][2]={ + {0x0e, 6}, {0x06, 5}, {0x00, 4}, {0x02, 4}, + {0x07, 3}, {0x05, 3}, {0x03, 3}, {0x02, 3}, + {0x04, 3}, {0x06, 3}, {0x01, 4}, {0x1e, 7}, + {0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11}, + {0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13} +}; + +const uint16_t ff_mpeg4_studio_dc_chroma[19][2]={ + {0x00, 4}, {0x02, 4}, {0x07, 3}, {0x05, 3}, + {0x03, 3}, {0x02, 3}, {0x04, 3}, {0x06, 3}, + {0x01, 4}, {0x06, 5}, {0x0e, 6}, {0x1e, 7}, + {0x3e, 8}, {0x7e, 9}, {0xfe, 10}, {0x1fe, 11}, + {0x3fe, 12}, {0x7fe, 13}, {0x7ff, 13} +}; + +const uint16_t ff_mpeg4_studio_intra[12][22][2]={ + { + {0x05, 4}, {0x04, 4}, {0x05, 7}, {0x09, 9}, + {0x21, 11}, {0x41, 12}, {0x81, 13}, {0x03, 4}, + {0x03, 5}, {0x05, 6}, {0x04, 7}, {0x03, 7}, + {0x05, 8}, {0x03, 2}, {0x05, 3}, {0x04, 3}, + {0x03, 3}, {0x02, 4}, {0x04, 6}, {0x03, 6}, + {0x11, 10}, {0x80, 13} + }, + { + {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, + {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, + {0x00, 0}, {0x00, 0}, {0x00, 0}, {0x00, 0}, + {0x00, 0}, {0x00, 0}, {0x01, 1}, {0x01, 2}, + {0x01, 3}, {0x01, 4}, {0x01, 5}, {0x03, 7}, + {0x05, 8}, {0x04, 8} + }, + { + {0x05, 3}, {0x03, 5}, {0x02, 5}, {0x03, 7}, + {0x09, 9}, {0x103, 14}, {0x102, 14}, {0x04, 3}, + {0x03, 3}, {0x03, 4}, {0x02, 4}, {0x03, 6}, + {0x11, 10}, {0x03, 2}, {0x02, 3}, {0x02, 6}, + {0x05, 8}, {0x21, 11}, {0x83, 13}, {0x101, 14}, + {0x201, 15}, {0x82, 13} + }, + { + {0x05, 5}, {0x05, 4}, {0x04, 5}, {0x03, 6}, + {0x09, 9}, {0x83, 13}, {0x82, 13}, {0x03, 3}, + {0x04, 4}, {0x03, 4}, {0x03, 5}, {0x05, 8}, + {0x81, 13}, {0x03, 2}, {0x02, 2}, {0x02, 5}, + {0x02, 6}, {0x03, 7}, {0x11, 10}, {0x43, 12}, + {0x80, 13}, {0x42, 12} + }, + { + {0x05, 7}, {0x03, 4}, {0x03, 5}, {0x04, 7}, + {0x09, 9}, {0x83, 13}, {0x101, 14}, {0x03, 3}, + {0x02, 4}, {0x05, 6}, {0x03, 7}, {0x11, 10}, + {0x201, 15}, {0x03, 2}, {0x02, 2}, {0x02, 3}, + {0x04, 6}, {0x03, 6}, {0x05, 8}, {0x21, 11}, + {0x82, 13}, {0x81, 13} + }, + { + {0x13, 10}, {0x03, 5}, {0x05, 7}, {0x12, 10}, + {0x43, 12}, {0x83, 13}, {0x82, 13}, {0x02, 5}, + {0x04, 7}, {0x05, 8}, {0x23, 11}, {0x81, 13}, + {0x101, 14}, {0x03, 2}, {0x02, 2}, {0x01, 2}, + {0x01, 3}, {0x03, 6}, {0x03, 7}, {0x22, 11}, + {0x201, 15}, {0x42, 12} + }, + { + {0x23, 11}, {0x01, 4}, {0x07, 8}, {0x13, 10}, + {0x22, 11}, {0x103, 14}, {0x102, 14}, {0x03, 6}, + {0x06, 8}, {0x12, 10}, {0x43, 12}, {0x101, 14}, + {0x201, 15}, {0x03, 3}, {0x02, 3}, {0x03, 2}, + {0x02, 2}, {0x01, 3}, {0x02, 6}, {0x05, 8}, + {0x42, 12}, {0x41, 12} + }, + { + {0x0b, 9}, {0x03, 5}, {0x07, 8}, {0x07, 7}, + {0x06, 7}, {0x23, 11}, {0x41, 12}, {0x05, 7}, + {0x06, 8}, {0x0a, 9}, {0x13, 10}, {0x22, 11}, + {0x40, 12}, {0x03, 4}, {0x02, 4}, {0x03, 2}, + {0x02, 2}, {0x01, 2}, {0x02, 5}, {0x04, 7}, + {0x12, 10}, {0x21, 11} + }, + { + {0x15, 10}, {0x03, 6}, {0x14, 10}, {0x23, 11}, + {0x07, 8}, {0x43, 12}, {0x81, 13}, {0x06, 8}, + {0x0b, 9}, {0x13, 10}, {0x12, 10}, {0x42, 12}, + {0x80, 13}, {0x01, 4}, {0x03, 3}, {0x02, 3}, + {0x03, 2}, {0x02, 2}, {0x01, 3}, {0x02, 6}, + {0x22, 11}, {0x41, 12} + }, + { + {0x43, 12}, {0x05, 6}, {0x07, 8}, {0x04, 6}, + {0x03, 6}, {0x13, 10}, {0x42, 12}, {0x05, 7}, + {0x04, 7}, {0x06, 8}, {0x12, 10}, {0x41, 12}, + {0x40, 12}, {0x03, 5}, {0x03, 4}, {0x03, 3}, + {0x02, 3}, {0x03, 2}, {0x02, 2}, {0x02, 4}, + {0x05, 8}, {0x11, 10} + }, + { + {0x83, 13}, {0x05, 7}, {0x07, 8}, {0x03, 4}, + {0x21, 11}, {0x82, 13}, {0x81, 13}, {0x04, 7}, + {0x06, 8}, {0x0b, 9}, {0x0a, 9}, {0x11, 10}, + {0x80, 13}, {0x03, 5}, {0x02, 5}, {0x02, 4}, + {0x03, 3}, {0x02, 3}, {0x03, 2}, {0x02, 2}, + {0x03, 6}, {0x09, 9} + }, + { + {0x13, 10}, {0x03, 5}, {0x03, 6}, {0x0d, 9}, + {0x0c, 9}, {0x21, 11}, {0x20, 11}, {0x02, 5}, + {0x02, 6}, {0x07, 8}, {0x0b, 9}, {0x12, 10}, + {0x11, 10}, {0x05, 3}, {0x04, 3}, {0x05, 4}, + {0x04, 4}, {0x03, 4}, {0x02, 4}, {0x03, 3}, + {0x03, 2}, {0x0a, 9} + } +}; + #endif /* AVCODEC_MPEG4DATA_H */ diff -Nura ffmpeg-3.4.2/libavcodec/mpeg4videodec.c ffmpeg-3.4.2_new/libavcodec/mpeg4videodec.c --- ffmpeg-3.4.2/libavcodec/mpeg4videodec.c 2018-02-12 08:29:18.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpeg4videodec.c 2019-07-08 00:29:04.158603338 +0800 @@ -43,6 +43,7 @@ #define SPRITE_TRAJ_VLC_BITS 6 #define DC_VLC_BITS 9 #define MB_TYPE_B_VLC_BITS 4 +#define STUDIO_INTRA_BITS 9 static VLC dc_lum, dc_chrom; static VLC sprite_trajectory; @@ -523,6 +524,55 @@ return 0; } +static void reset_studio_dc_predictors(MpegEncContext *s) +{ + /* Reset DC Predictors */ + s->last_dc[0] = + s->last_dc[1] = + s->last_dc[2] = 1 << (s->avctx->bits_per_raw_sample + s->dct_precision + s->intra_dc_precision - 1); +} + +/** + * Decode the next video packet. + * @return <0 if something went wrong + */ +int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx) +{ + MpegEncContext *s = &ctx->m; + GetBitContext *gb = &s->gb; + unsigned vlc_len; + uint16_t mb_num; + + if (get_bits_left(gb) >= 32 && get_bits_long(gb, 32) == SLICE_START_CODE) { + vlc_len = av_log2(s->mb_width * s->mb_height) + 1; + mb_num = get_bits(gb, vlc_len); + + if (mb_num >= s->mb_num) + return AVERROR_INVALIDDATA; + + s->mb_x = mb_num % s->mb_width; + s->mb_y = mb_num / s->mb_width; + + if (ctx->shape != BIN_ONLY_SHAPE) + s->qscale = mpeg_get_qscale(s); + + if (get_bits1(gb)) { /* slice_extension_flag */ + skip_bits1(gb); /* intra_slice */ + skip_bits1(gb); /* slice_VOP_id_enable */ + skip_bits(gb, 6); /* slice_VOP_id */ + while (get_bits1(gb)) /* extra_bit_slice */ + skip_bits(gb, 8); /* extra_information_slice */ + } + + reset_studio_dc_predictors(s); + } + else { + return AVERROR_INVALIDDATA; + } + + return 0; +} + /** * Get the average motion vector for a GMC MB. * @param n either 0 for the x component or 1 for y @@ -1716,6 +1766,189 @@ return SLICE_OK; } +/* As per spec, studio start code search isn't the same as the old type of start code */ +static void next_start_code_studio(GetBitContext *gb) +{ + align_get_bits(gb); + + while (get_bits_left(gb) >= 24 && show_bits_long(gb, 24) != 0x1) { + get_bits(gb, 8); + } +} + +/* additional_code, vlc index */ +static const uint8_t ac_state_tab[22][2] = +{ + {0, 0}, + {0, 1}, + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + {5, 1}, + {1, 2}, + {2, 2}, + {3, 2}, + {4, 2}, + {5, 2}, + {6, 2}, + {1, 3}, + {2, 4}, + {3, 5}, + {4, 6}, + {5, 7}, + {6, 8}, + {7, 9}, + {8, 10}, + {0, 11} +}; + +static int mpeg4_decode_studio_block(MpegEncContext *s, int32_t block[64], int n) +{ + Mpeg4DecContext *ctx = s->avctx->priv_data; + + int cc, dct_dc_size, dct_diff, code, j, idx = 1, group = 0, run = 0, + additional_code_len, sign, mismatch; + VLC *cur_vlc = &ctx->studio_intra_tab[0]; + uint8_t *const scantable = s->intra_scantable.permutated; + const uint16_t *quant_matrix; + uint32_t flc; + const int min = -1 * (1 << (s->avctx->bits_per_raw_sample + 6)); + const int max = ((1 << (s->avctx->bits_per_raw_sample + 6)) - 1); + + mismatch = 1; + + memset(block, 0, 64 * sizeof(int32_t)); + + if (n < 4) { + cc = 0; + dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + quant_matrix = s->intra_matrix; + } else { + cc = (n & 1) + 1; + if (ctx->rgb) + dct_dc_size = get_vlc2(&s->gb, ctx->studio_luma_dc.table, STUDIO_INTRA_BITS, 2); + else + dct_dc_size = get_vlc2(&s->gb, ctx->studio_chroma_dc.table, STUDIO_INTRA_BITS, 2); + quant_matrix = s->chroma_intra_matrix; + } + + if (dct_dc_size < 0) { + av_log(s->avctx, AV_LOG_ERROR, "illegal dct_dc_size vlc\n"); + return AVERROR_INVALIDDATA; + } else if (dct_dc_size == 0) { + dct_diff = 0; + } else { + dct_diff = get_xbits(&s->gb, dct_dc_size); + + if (dct_dc_size > 8) { + if(!check_marker(s->avctx, &s->gb, "dct_dc_size > 8")) + return AVERROR_INVALIDDATA; + } + + } + + s->last_dc[cc] += dct_diff; + + if (s->mpeg_quant) + block[0] = s->last_dc[cc] * (8 >> s->intra_dc_precision); + else + block[0] = s->last_dc[cc] * (8 >> s->intra_dc_precision) * (8 >> s->dct_precision); + /* TODO: support mpeg_quant for AC coefficients */ + + block[0] = av_clip(block[0], min, max); + mismatch ^= block[0]; + + /* AC Coefficients */ + while (1) { + group = get_vlc2(&s->gb, cur_vlc->table, STUDIO_INTRA_BITS, 2); + + if (group < 0) { + av_log(s->avctx, AV_LOG_ERROR, "illegal ac coefficient group vlc\n"); + return AVERROR_INVALIDDATA; + } + + additional_code_len = ac_state_tab[group][0]; + cur_vlc = &ctx->studio_intra_tab[ac_state_tab[group][1]]; + + if (group == 0) { + /* End of Block */ + break; + } else if (group >= 1 && group <= 6) { + /* Zero run length (Table B.47) */ + run = 1 << additional_code_len; + if (additional_code_len) + run += get_bits(&s->gb, additional_code_len); + idx += run; + continue; + } else if (group >= 7 && group <= 12) { + /* Zero run length and +/-1 level (Table B.48) */ + code = get_bits(&s->gb, additional_code_len); + sign = code & 1; + code >>= 1; + run = (1 << (additional_code_len - 1)) + code; + idx += run; + j = scantable[idx++]; + block[j] = sign ? 1 : -1; + } else if (group >= 13 && group <= 20) { + /* Level value (Table B.49) */ + j = scantable[idx++]; + block[j] = get_xbits(&s->gb, additional_code_len); + } else if (group == 21) { + /* Escape */ + j = scantable[idx++]; + additional_code_len = s->avctx->bits_per_raw_sample + s->dct_precision + 4; + flc = get_bits(&s->gb, additional_code_len); + if (flc >> (additional_code_len-1)) + block[j] = -1 * (( flc ^ ((1 << additional_code_len) -1)) + 1); + else + block[j] = flc; + } + block[j] = ((8 * 2 * block[j] * quant_matrix[j] * s->qscale) >> s->dct_precision) / 32; + block[j] = av_clip(block[j], min, max); + mismatch ^= block[j]; + } + + block[63] ^= mismatch & 1; + + return 0; +} + +static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64]) +{ + int i; + + /* StudioMacroblock */ + /* Assumes I-VOP */ + s->mb_intra = 1; + if (get_bits1(&s->gb)) { /* compression_mode */ + /* DCT */ + /* macroblock_type, 1 or 2-bit VLC */ + if (!get_bits1(&s->gb)) { + skip_bits1(&s->gb); + s->qscale = mpeg_get_qscale(s); + } + + for (i = 0; i < mpeg4_block_count[s->chroma_format]; i++) { + if (mpeg4_decode_studio_block(s, (*s->block32)[i], i) < 0) + return AVERROR_INVALIDDATA; + } + } else { + /* DPCM */ + check_marker(s->avctx, &s->gb, "DPCM block start"); + avpriv_request_sample(s->avctx, "DPCM encoded block"); + next_start_code_studio(&s->gb); + return SLICE_ERROR; + } + + if (get_bits_left(&s->gb) >= 24 && show_bits(&s->gb, 23) == 0) { + next_start_code_studio(&s->gb); + return SLICE_END; + } + + return SLICE_OK; +} + static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb) { int hours, minutes, seconds; @@ -1738,20 +1971,68 @@ return 0; } -static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb) +static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb, int *profile, int *level) { - s->avctx->profile = get_bits(gb, 4); - s->avctx->level = get_bits(gb, 4); + *profile = get_bits(gb, 4); + *level = get_bits(gb, 4); // for Simple profile, level 0 - if (s->avctx->profile == 0 && s->avctx->level == 8) { - s->avctx->level = 0; + if (*profile == 0 && *level == 8) { + *level = 0; } return 0; } +static int mpeg4_decode_visual_object(MpegEncContext *s, GetBitContext *gb) +{ + int visual_object_type; + int is_visual_object_identifier = get_bits1(gb); + + if (is_visual_object_identifier) { + skip_bits(gb, 4+3); + } + visual_object_type = get_bits(gb, 4); + + if (visual_object_type == VOT_VIDEO_ID || + visual_object_type == VOT_STILL_TEXTURE_ID) { + int video_signal_type = get_bits1(gb); + if (video_signal_type) { + int video_format = get_bits(gb, 3); + int video_range = get_bits1(gb); + int color_description = get_bits1(gb); + + s->avctx->color_range = video_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; + + if (color_description) { + s->avctx->color_primaries = get_bits(gb, 8); + s->avctx->color_trc = get_bits(gb, 8); + s->avctx->colorspace = get_bits(gb, 8); + } + } + } + + return 0; +} + +static void mpeg4_load_default_matrices(MpegEncContext *s) +{ + int i, v; + + /* load default matrices */ + for (i = 0; i < 64; i++) { + int j = s->idsp.idct_permutation[i]; + v = ff_mpeg4_default_intra_matrix[i]; + s->intra_matrix[j] = v; + s->chroma_intra_matrix[j] = v; + + v = ff_mpeg4_default_non_intra_matrix[i]; + s->inter_matrix[j] = v; + s->chroma_inter_matrix[j] = v; + } +} + static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; @@ -1915,17 +2196,7 @@ if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */ int i, v; - /* load default matrixes */ - for (i = 0; i < 64; i++) { - int j = s->idsp.idct_permutation[i]; - v = ff_mpeg4_default_intra_matrix[i]; - s->intra_matrix[j] = v; - s->chroma_intra_matrix[j] = v; - - v = ff_mpeg4_default_non_intra_matrix[i]; - s->inter_matrix[j] = v; - s->chroma_inter_matrix[j] = v; - } + mpeg4_load_default_matrices(s); /* load custom intra matrix */ if (get_bits1(gb)) { @@ -2569,6 +2840,232 @@ return 0; } +static void read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) +{ + int i, j, v; + + if (get_bits1(gb)) { + /* intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + v = get_bits(gb, 8); + j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; + s->intra_matrix[j] = v; + s->chroma_intra_matrix[j] = v; + } + } + + if (get_bits1(gb)) { + /* non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + if (get_bits1(gb)) { + /* chroma_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + v = get_bits(gb, 8); + j = s->idsp.idct_permutation[ff_zigzag_direct[i]]; + s->chroma_intra_matrix[j] = v; + } + } + + if (get_bits1(gb)) { + /* chroma_non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + next_start_code_studio(gb); +} + +static void extension_and_user_data(MpegEncContext *s, GetBitContext *gb, int id) +{ + uint32_t startcode; + uint8_t extension_type; + + startcode = show_bits_long(gb, 32); + if (startcode == USER_DATA_STARTCODE || startcode == EXT_STARTCODE) { + + if ((id == 2 || id == 4) && startcode == EXT_STARTCODE) { + skip_bits_long(gb, 32); + extension_type = get_bits(gb, 4); + if (extension_type == QUANT_MATRIX_EXT_ID) + read_quant_matrix_ext(s, gb); + } + } +} + +static void decode_smpte_tc(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; + + skip_bits(gb, 16); /* Time_code[63..48] */ + check_marker(s->avctx, gb, "after Time_code[63..48]"); + skip_bits(gb, 16); /* Time_code[47..32] */ + check_marker(s->avctx, gb, "after Time_code[47..32]"); + skip_bits(gb, 16); /* Time_code[31..16] */ + check_marker(s->avctx, gb, "after Time_code[31..16]"); + skip_bits(gb, 16); /* Time_code[15..0] */ + check_marker(s->avctx, gb, "after Time_code[15..0]"); + skip_bits(gb, 4); /* reserved_bits */ +} + +/** + * Decode the next studio vop header. + * @return <0 if something went wrong + */ +static int decode_studio_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; + + if (get_bits_left(gb) <= 32) + return 0; + + if (get_bits_long(gb, 32) != VOP_STARTCODE) + return AVERROR_INVALIDDATA; + + s->decode_mb = mpeg4_decode_studio_mb; + + decode_smpte_tc(ctx, gb); + + skip_bits(gb, 10); /* temporal_reference */ + skip_bits(gb, 2); /* vop_structure */ + s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* vop_coding_type */ + if (get_bits1(gb)) { /* vop_coded */ + skip_bits1(gb); /* top_field_first */ + skip_bits1(gb); /* repeat_first_field */ + s->progressive_frame = get_bits1(gb) ^ 1; /* progressive_frame */ + } + + if (s->pict_type == AV_PICTURE_TYPE_I) { + if (get_bits1(gb)) + reset_studio_dc_predictors(s); + } + + if (ctx->shape != BIN_ONLY_SHAPE) { + s->alternate_scan = get_bits1(gb); + s->frame_pred_frame_dct = get_bits1(gb); + s->dct_precision = get_bits(gb, 2); + s->intra_dc_precision = get_bits(gb, 2); + s->q_scale_type = get_bits1(gb); + } + + if (s->alternate_scan) { + ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } else { + ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); + ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); + } + + mpeg4_load_default_matrices(s); + + next_start_code_studio(gb); + extension_and_user_data(s, gb, 4); + + return 0; +} + +static int decode_studiovisualobject(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + uint32_t startcode; + MpegEncContext *s = &ctx->m; + int visual_object_type, width, height; + + startcode = get_bits_long(gb, 32); + + /* StudioVisualObject() */ + if (startcode == VISUAL_OBJ_STARTCODE) { + skip_bits(gb, 4); /* visual_object_verid */ + visual_object_type = get_bits(gb, 4); + + next_start_code_studio(gb); + extension_and_user_data(s, gb, 1); + + if (visual_object_type == VOT_VIDEO_ID) { + /* StudioVideoObjectLayer */ + skip_bits_long(gb, 32); /* video_object_start_code */ + skip_bits_long(gb, 32); /* video_object_layer_start_code */ + skip_bits1(gb); /* random_accessible_vol */ + skip_bits(gb, 8); /* video_object_type_indication */ + skip_bits(gb, 4); /* video_object_layer_verid */ + ctx->shape = get_bits(gb, 2); /* video_object_layer_shape */ + skip_bits(gb, 4); /* video_object_layer_shape_extension */ + skip_bits1(gb); /* progressive_sequence */ + if (ctx->shape != BIN_ONLY_SHAPE) { + ctx->rgb = get_bits1(gb); /* rgb_components */ + s->chroma_format = get_bits(gb, 2); /* chroma_format */ + if (!s->chroma_format) { + av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n"); + return AVERROR_INVALIDDATA; + } + + s->avctx->bits_per_raw_sample = get_bits(gb, 4); /* bit_depth */ + if (s->avctx->bits_per_raw_sample == 10) { + if (ctx->rgb) { + s->avctx->pix_fmt = AV_PIX_FMT_GBRP10; + } + else { + s->avctx->pix_fmt = s->chroma_format == CHROMA_422 ? AV_PIX_FMT_YUV422P10 : AV_PIX_FMT_YUV444P10; + } + } + else { + avpriv_request_sample(s->avctx, "MPEG-4 Studio profile bit-depth %u", s->avctx->bits_per_raw_sample); + return AVERROR_PATCHWELCOME; + } + } + if (ctx->shape == RECT_SHAPE) { + check_marker(s->avctx, gb, "before video_object_layer_width"); + width = get_bits(gb, 14); /* video_object_layer_width */ + check_marker(s->avctx, gb, "before video_object_layer_height"); + height = get_bits(gb, 14); /* video_object_layer_height */ + check_marker(s->avctx, gb, "after video_object_layer_height"); + + /* Do the same check as non-studio profile */ + if (width && height) { + if (s->width && s->height && + (s->width != width || s->height != height)) + s->context_reinit = 1; + s->width = width; + s->height = height; + } + } + s->aspect_ratio_info = get_bits(gb, 4); + if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) { + s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width + s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height + } else { + s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info]; + } + skip_bits(gb, 4); /* frame_rate_code */ + skip_bits(gb, 15); /* first_half_bit_rate */ + check_marker(s->avctx, gb, "after first_half_bit_rate"); + skip_bits(gb, 15); /* latter_half_bit_rate */ + check_marker(s->avctx, gb, "after latter_half_bit_rate"); + skip_bits(gb, 15); /* first_half_vbv_buffer_size */ + check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); + skip_bits(gb, 3); /* latter_half_vbv_buffer_size */ + skip_bits(gb, 11); /* first_half_vbv_buffer_size */ + check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); + skip_bits(gb, 15); /* latter_half_vbv_occupancy */ + check_marker(s->avctx, gb, "after latter_half_vbv_occupancy"); + s->low_delay = get_bits1(gb); + s->mpeg_quant = get_bits1(gb); /* mpeg2_stream */ + + next_start_code_studio(gb); + extension_and_user_data(s, gb, 2); + } + } + + return 0; +} + /** * Decode MPEG-4 headers. * @return <0 if no VOP found (or a damaged one) @@ -2681,7 +3178,27 @@ } else if (startcode == GOP_STARTCODE) { mpeg4_decode_gop_header(s, gb); } else if (startcode == VOS_STARTCODE) { - mpeg4_decode_profile_level(s, gb); + int profile, level; + mpeg4_decode_profile_level(s, gb, &profile, &level); + if (profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO && + (level > 0 && level < 9)) { + s->studio_profile = 1; + next_start_code_studio(gb); + extension_and_user_data(s, gb, 0); + } else if (s->studio_profile) { + avpriv_request_sample(s->avctx, "Mixes studio and non studio profile\n"); + return AVERROR_PATCHWELCOME; + } + s->avctx->profile = profile; + s->avctx->level = level; + } else if (startcode == VISUAL_OBJ_STARTCODE) { + if (s->studio_profile) { + if ((ret = decode_studiovisualobject(ctx, gb)) < 0) + return ret; + break; + } + } else if (startcode == VISUAL_OBJ_STARTCODE) { + mpeg4_decode_visual_object(s, gb); } else if (startcode == VOP_STARTCODE) { break; } @@ -2695,7 +3212,15 @@ s->low_delay = 1; s->avctx->has_b_frames = !s->low_delay; - return decode_vop_header(ctx, gb); + if (s->studio_profile) { + av_assert0(s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO); + if (!s->avctx->bits_per_raw_sample) { + av_log(s->avctx, AV_LOG_ERROR, "Missing VOL header\n"); + return AVERROR_INVALIDDATA; + } + return decode_studio_vop_header(ctx, gb); + } else + return decode_vop_header(ctx, gb); } av_cold void ff_mpeg4videodec_static_init(void) { @@ -2795,6 +3320,37 @@ } #endif +static av_cold int init_studio_vlcs(Mpeg4DecContext *ctx) +{ + int i, ret; + + for (i = 0; i < 12; i++) { + ret = init_vlc(&ctx->studio_intra_tab[i], STUDIO_INTRA_BITS, 22, + &ff_mpeg4_studio_intra[i][0][1], 4, 2, + &ff_mpeg4_studio_intra[i][0][0], 4, 2, + 0); + + if (ret < 0) + return ret; + } + + ret = init_vlc(&ctx->studio_luma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_luma[0][1], 4, 2, + &ff_mpeg4_studio_dc_luma[0][0], 4, 2, + 0); + if (ret < 0) + return ret; + + ret = init_vlc(&ctx->studio_chroma_dc, STUDIO_INTRA_BITS, 19, + &ff_mpeg4_studio_dc_chroma[0][1], 4, 2, + &ff_mpeg4_studio_dc_chroma[0][0], 4, 2, + 0); + if (ret < 0) + return ret; + + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx) { Mpeg4DecContext *ctx = avctx->priv_data; @@ -2810,6 +3366,8 @@ return ret; ff_mpeg4videodec_static_init(); + if ((ret = init_studio_vlcs(ctx)) < 0) + return ret; s->h263_pred = 1; s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */ diff -Nura ffmpeg-3.4.2/libavcodec/mpeg4video.h ffmpeg-3.4.2_new/libavcodec/mpeg4video.h --- ffmpeg-3.4.2/libavcodec/mpeg4video.h 2018-01-01 06:35:47.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpeg4video.h 2019-07-08 00:29:17.774729353 +0800 @@ -43,6 +43,9 @@ #define ACE_VO_TYPE 12 #define ADV_SIMPLE_VO_TYPE 17 +#define VOT_VIDEO_ID 1 +#define VOT_STILL_TEXTURE_ID 2 + // aspect_ratio_info #define EXTENDED_PAR 15 @@ -58,6 +61,10 @@ #define GOP_STARTCODE 0x1B3 #define VISUAL_OBJ_STARTCODE 0x1B5 #define VOP_STARTCODE 0x1B6 +#define SLICE_STARTCODE 0x1B7 +#define EXT_STARTCODE 0x1B8 + +#define QUANT_MATRIX_EXT_ID 0x3 /* smaller packets likely don't contain a real frame */ #define MAX_NVOP_SIZE 19 @@ -105,8 +112,16 @@ int cplx_estimation_trash_i; int cplx_estimation_trash_p; int cplx_estimation_trash_b; + + VLC studio_intra_tab[12]; + VLC studio_luma_dc; + VLC studio_chroma_dc; + + int rgb; } Mpeg4DecContext; +static const uint8_t mpeg4_block_count[4] = {0, 6, 8, 12}; + /* dc encoding for MPEG-4 */ extern const uint8_t ff_mpeg4_DCtab_lum[13][2]; extern const uint8_t ff_mpeg4_DCtab_chrom[13][2]; @@ -134,6 +149,10 @@ extern const uint8_t ff_mpeg4_dc_threshold[8]; +extern const uint16_t ff_mpeg4_studio_dc_luma[19][2]; +extern const uint16_t ff_mpeg4_studio_dc_chroma[19][2]; +extern const uint16_t ff_mpeg4_studio_intra[12][22][2]; + void ff_mpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], int motion_x, int motion_y); @@ -152,6 +171,7 @@ int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx); int ff_mpeg4_get_video_packet_prefix_length(MpegEncContext *s); int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx); +int ff_mpeg4_decode_studio_slice_header(Mpeg4DecContext *ctx); void ff_mpeg4_init_direct_mv(MpegEncContext *s); void ff_mpeg4videodec_static_init(void); int ff_mpeg4_workaround_bugs(AVCodecContext *avctx); diff -Nura ffmpeg-3.4.2/libavcodec/mpegvideo.c ffmpeg-3.4.2_new/libavcodec/mpegvideo.c --- ffmpeg-3.4.2/libavcodec/mpegvideo.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpegvideo.c 2019-07-08 00:29:30.551847603 +0800 @@ -386,6 +386,9 @@ for (i = 0; i < 12; i++) { s->pblocks[i] = &s->block[i]; } + + FF_ALLOCZ_OR_GOTO(s->avctx, s->block32, sizeof(*s->block32), fail) + if (s->avctx->codec_tag == AV_RL32("VCR2")) { // exchange uv FFSWAP(void *, s->pblocks[4], s->pblocks[5]); @@ -421,6 +424,7 @@ av_freep(&s->me.map); av_freep(&s->me.score_map); av_freep(&s->blocks); + av_freep(&s->block32); av_freep(&s->ac_val_base); s->block = NULL; } @@ -438,6 +442,7 @@ COPY(me.score_map); COPY(blocks); COPY(block); + COPY(block32); COPY(start_mb_y); COPY(end_mb_y); COPY(me.map_generation); @@ -811,6 +816,7 @@ s->dct_error_sum = NULL; s->block = NULL; s->blocks = NULL; + s->block32 = NULL; memset(s->pblocks, 0, sizeof(s->pblocks)); s->ac_val_base = NULL; s->ac_val[0] = @@ -2657,8 +2663,31 @@ ff_wmv2_add_mb(s, block, dest_y, dest_cb, dest_cr); } } else { + /* Only MPEG-4 Simple Studio Profile is supported in > 8-bit mode. + TODO: Integrate 10-bit properly into mpegvideo.c so that ER works properly */ + if (s->avctx->bits_per_raw_sample > 8){ + const int act_block_size = block_size * 2; + s->idsp.idct_put(dest_y, dct_linesize, (int16_t*)(*s->block32)[0]); + s->idsp.idct_put(dest_y + act_block_size, dct_linesize, (int16_t*)(*s->block32)[1]); + s->idsp.idct_put(dest_y + dct_offset, dct_linesize, (int16_t*)(*s->block32)[2]); + s->idsp.idct_put(dest_y + dct_offset + act_block_size, dct_linesize, (int16_t*)(*s->block32)[3]); + + dct_linesize = uvlinesize << s->interlaced_dct; + dct_offset = s->interlaced_dct ? uvlinesize : uvlinesize*block_size; + + s->idsp.idct_put(dest_cb, dct_linesize, (int16_t*)(*s->block32)[4]); + s->idsp.idct_put(dest_cr, dct_linesize, (int16_t*)(*s->block32)[5]); + s->idsp.idct_put(dest_cb + dct_offset, dct_linesize, (int16_t*)(*s->block32)[6]); + s->idsp.idct_put(dest_cr + dct_offset, dct_linesize, (int16_t*)(*s->block32)[7]); + if(!s->chroma_x_shift){//Chroma444 + s->idsp.idct_put(dest_cb + act_block_size, dct_linesize, (int16_t*)(*s->block32)[8]); + s->idsp.idct_put(dest_cr + act_block_size, dct_linesize, (int16_t*)(*s->block32)[9]); + s->idsp.idct_put(dest_cb + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[10]); + s->idsp.idct_put(dest_cr + act_block_size + dct_offset, dct_linesize, (int16_t*)(*s->block32)[11]); + } + } /* dct only in intra block */ - if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){ + else if(s->encoding || !(s->codec_id==AV_CODEC_ID_MPEG1VIDEO || s->codec_id==AV_CODEC_ID_MPEG2VIDEO)){ put_dct(s, block[0], 0, dest_y , dct_linesize, s->qscale); put_dct(s, block[1], 1, dest_y + block_size, dct_linesize, s->qscale); put_dct(s, block[2], 2, dest_y + dct_offset , dct_linesize, s->qscale); @@ -2739,7 +2768,8 @@ void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename const int linesize = s->current_picture.f->linesize[0]; //not s->linesize as this would be wrong for field pics const int uvlinesize = s->current_picture.f->linesize[1]; - const int mb_size= 4 - s->avctx->lowres; + const int width_of_mb = (4 + (s->avctx->bits_per_raw_sample > 8)) - s->avctx->lowres; + const int height_of_mb = 4 - s->avctx->lowres; s->block_index[0]= s->b8_stride*(s->mb_y*2 ) - 2 + s->mb_x*2; s->block_index[1]= s->b8_stride*(s->mb_y*2 ) - 1 + s->mb_x*2; @@ -2749,20 +2779,20 @@ s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1; //block_index is not used by mpeg2, so it is not affected by chroma_format - s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << mb_size); - s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (mb_size - s->chroma_x_shift)); - s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (mb_size - s->chroma_x_shift)); + s->dest[0] = s->current_picture.f->data[0] + (int)((s->mb_x - 1U) << width_of_mb); + s->dest[1] = s->current_picture.f->data[1] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift)); + s->dest[2] = s->current_picture.f->data[2] + (int)((s->mb_x - 1U) << (width_of_mb - s->chroma_x_shift)); if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME)) { if(s->picture_structure==PICT_FRAME){ - s->dest[0] += s->mb_y * linesize << mb_size; - s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); - s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift); + s->dest[0] += s->mb_y * linesize << height_of_mb; + s->dest[1] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift); + s->dest[2] += s->mb_y * uvlinesize << (height_of_mb - s->chroma_y_shift); }else{ - s->dest[0] += (s->mb_y>>1) * linesize << mb_size; - s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); - s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift); + s->dest[0] += (s->mb_y>>1) * linesize << height_of_mb; + s->dest[1] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift); + s->dest[2] += (s->mb_y>>1) * uvlinesize << (height_of_mb - s->chroma_y_shift); av_assert1((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD)); } } diff -Nura ffmpeg-3.4.2/libavcodec/mpegvideo.h ffmpeg-3.4.2_new/libavcodec/mpegvideo.h --- ffmpeg-3.4.2/libavcodec/mpegvideo.h 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/mpegvideo.h 2019-07-08 00:29:40.806942512 +0800 @@ -45,6 +45,7 @@ #include "mpegpicture.h" #include "mpegvideodsp.h" #include "mpegvideoencdsp.h" +#include "mpegvideodata.h" #include "pixblockdsp.h" #include "put_bits.h" #include "ratecontrol.h" @@ -71,6 +72,8 @@ #define SLICE_MAX_START_CODE 0x000001af #define EXT_START_CODE 0x000001b5 #define USER_START_CODE 0x000001b2 +#define SLICE_START_CODE 0x000001b7 + /** * MpegEncContext. @@ -381,6 +384,8 @@ int custom_pcf; /* MPEG-4 specific */ + int studio_profile; + int dct_precision; ///< number of bits to represent the fractional part of time (encoder only) int time_increment_bits; int last_time_base; @@ -497,7 +502,10 @@ int16_t (*block)[64]; ///< points to one of the following blocks int16_t (*blocks)[12][64]; // for HQ mode we need to keep the best block - int (*decode_mb)(struct MpegEncContext *s, int16_t block[6][64]); // used by some codecs to avoid a switch() + int (*decode_mb)(struct MpegEncContext *s, int16_t block[12][64]); // used by some codecs to avoid a switch() + + int32_t (*block32)[12][64]; + #define SLICE_OK 0 #define SLICE_ERROR -1 #define SLICE_END -2 ///<end marker found @@ -729,7 +737,8 @@ qpel_mc_func (*qpix_op)[16]); static inline void ff_update_block_index(MpegEncContext *s){ - const int block_size= 8 >> s->avctx->lowres; + const int bytes_per_pixel = 1 + (s->avctx->bits_per_raw_sample > 8); + const int block_size= (8*bytes_per_pixel) >> s->avctx->lowres; s->block_index[0]+=2; s->block_index[1]+=2; @@ -738,8 +747,8 @@ s->block_index[4]++; s->block_index[5]++; s->dest[0]+= 2*block_size; - s->dest[1]+= block_size; - s->dest[2]+= block_size; + s->dest[1]+= (2 >> s->chroma_x_shift) * block_size; + s->dest[2]+= (2 >> s->chroma_x_shift) * block_size; } static inline int get_bits_diff(MpegEncContext *s){ @@ -751,4 +760,13 @@ return bits - last; } +static inline int mpeg_get_qscale(MpegEncContext *s) +{ + int qscale = get_bits(&s->gb, 5); + if (s->q_scale_type) + return ff_mpeg2_non_linear_qscale[qscale]; + else + return qscale << 1; +} + #endif /* AVCODEC_MPEGVIDEO_H */ diff -Nura ffmpeg-3.4.2/libavcodec/simple_idct.c ffmpeg-3.4.2_new/libavcodec/simple_idct.c --- ffmpeg-3.4.2/libavcodec/simple_idct.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/simple_idct.c 2019-07-08 00:29:53.919063861 +0800 @@ -30,6 +30,8 @@ #include "mathops.h" #include "simple_idct.h" +#define IN_IDCT_DEPTH 16 + #define BIT_DEPTH 8 #include "simple_idct_template.c" #undef BIT_DEPTH @@ -46,6 +48,13 @@ #define BIT_DEPTH 12 #include "simple_idct_template.c" #undef BIT_DEPTH +#undef IN_IDCT_DEPTH + +#define IN_IDCT_DEPTH 32 +#define BIT_DEPTH 10 +#include "simple_idct_template.c" +#undef BIT_DEPTH +#undef IN_IDCT_DEPTH /* 2x4x8 idct */ @@ -115,7 +124,7 @@ /* IDCT8 on each line */ for(i=0; i<8; i++) { - idctRowCondDC_8(block + i*8, 0); + idctRowCondDC_int16_8bit(block + i*8, 0); } /* IDCT4 and store */ @@ -188,7 +197,7 @@ /* IDCT8 on each line */ for(i=0; i<4; i++) { - idctRowCondDC_8(block + i*8, 0); + idctRowCondDC_int16_8bit(block + i*8, 0); } /* IDCT4 and store */ @@ -208,7 +217,7 @@ /* IDCT8 and store */ for(i=0; i<4; i++){ - idctSparseColAdd_8(dest + i, line_size, block + i); + idctSparseColAdd_int16_8bit(dest + i, line_size, block + i); } } diff -Nura ffmpeg-3.4.2/libavcodec/simple_idct.h ffmpeg-3.4.2_new/libavcodec/simple_idct.h --- ffmpeg-3.4.2/libavcodec/simple_idct.h 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/simple_idct.h 2019-07-08 00:30:00.279122632 +0800 @@ -31,20 +31,24 @@ #include <stddef.h> #include <stdint.h> -void ff_simple_idct_put_8(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_add_8(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_8(int16_t *block); +void ff_simple_idct_put_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_int16_8bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_int16_8bit(int16_t *block); -void ff_simple_idct_put_10(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_add_10(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_10(int16_t *block); +void ff_simple_idct_put_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_int16_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_int16_10bit(int16_t *block); -void ff_simple_idct_put_12(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_add_12(uint8_t *dest, ptrdiff_t line_size, int16_t *block); -void ff_simple_idct_12(int16_t *block); +void ff_simple_idct_put_int32_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_int32_10bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_int32_10bit(int16_t *block); + +void ff_simple_idct_put_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_add_int16_12bit(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_int16_12bit(int16_t *block); /** - * Special version of ff_simple_idct_10() which does dequantization + * Special version of ff_simple_idct_int16_10bit() which does dequantization * and scales by a factor of 2 more between the two IDCTs to account * for larger scale of input coefficients. */ diff -Nura ffmpeg-3.4.2/libavcodec/simple_idct_template.c ffmpeg-3.4.2_new/libavcodec/simple_idct_template.c --- ffmpeg-3.4.2/libavcodec/simple_idct_template.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/simple_idct_template.c 2019-07-08 00:30:13.463244461 +0800 @@ -77,6 +77,10 @@ #define ROW_SHIFT 13 #define COL_SHIFT 18 #define DC_SHIFT 1 +# elif IN_IDCT_DEPTH == 32 +#define ROW_SHIFT 13 +#define COL_SHIFT 21 +#define DC_SHIFT 2 # else #define ROW_SHIFT 12 #define COL_SHIFT 19 @@ -109,11 +113,13 @@ #ifdef EXTRA_SHIFT static inline void FUNC(idctRowCondDC_extrashift)(int16_t *row, int extra_shift) #else -static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift) +static inline void FUNC6(idctRowCondDC)(idctin *row, int extra_shift) #endif { SUINT a0, a1, a2, a3, b0, b1, b2, b3; +// TODO: Add DC-only support for int32_t input +#if IN_IDCT_DEPTH == 16 #if HAVE_FAST_64BIT #define ROW0_MASK (0xffffLL << 48 * HAVE_BIGENDIAN) if (((AV_RN64A(row) & ~ROW0_MASK) | AV_RN64A(row+4)) == 0) { @@ -148,6 +154,7 @@ return; } #endif +#endif a0 = (W4 * row[0]) + (1 << (ROW_SHIFT + extra_shift - 1)); a1 = a0; @@ -168,7 +175,11 @@ b3 = MUL(W7, row[1]); MAC(b3, -W5, row[3]); +#if IN_IDCT_DEPTH == 32 + if (AV_RN64A(row + 4) | AV_RN64A(row + 6)) { +#else if (AV_RN64A(row + 4)) { +#endif a0 += W4*row[4] + W6*row[6]; a1 += - W4*row[4] - W2*row[6]; a2 += - W4*row[4] + W2*row[6]; @@ -250,8 +261,8 @@ #ifdef EXTRA_SHIFT static inline void FUNC(idctSparseCol_extrashift)(int16_t *col) #else -static inline void FUNC(idctSparseColPut)(pixel *dest, ptrdiff_t line_size, - int16_t *col) +static inline void FUNC6(idctSparseColPut)(pixel *dest, ptrdiff_t line_size, + idctin *col) { SUINT a0, a1, a2, a3, b0, b1, b2, b3; @@ -274,8 +285,8 @@ dest[0] = av_clip_pixel((int)(a0 - b0) >> COL_SHIFT); } -static inline void FUNC(idctSparseColAdd)(pixel *dest, ptrdiff_t line_size, - int16_t *col) +static inline void FUNC6(idctSparseColAdd)(pixel *dest, ptrdiff_t line_size, + idctin *col) { int a0, a1, a2, a3, b0, b1, b2, b3; @@ -298,7 +309,7 @@ dest[0] = av_clip_pixel(dest[0] + ((a0 - b0) >> COL_SHIFT)); } -static inline void FUNC(idctSparseCol)(int16_t *col) +static inline void FUNC6(idctSparseCol)(idctin *col) #endif { int a0, a1, a2, a3, b0, b1, b2, b3; @@ -316,21 +327,23 @@ } #ifndef EXTRA_SHIFT -void FUNC(ff_simple_idct_put)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block) +void FUNC6(ff_simple_idct_put)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block_) { + idctin *block = (idctin *)block_; pixel *dest = (pixel *)dest_; int i; line_size /= sizeof(pixel); for (i = 0; i < 8; i++) - FUNC(idctRowCondDC)(block + i*8, 0); + FUNC6(idctRowCondDC)(block + i*8, 0); for (i = 0; i < 8; i++) - FUNC(idctSparseColPut)(dest + i, line_size, block + i); + FUNC6(idctSparseColPut)(dest + i, line_size, block + i); } -void FUNC(ff_simple_idct_add)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block) +#if IN_IDCT_DEPTH == 16 +void FUNC6(ff_simple_idct_add)(uint8_t *dest_, ptrdiff_t line_size, int16_t *block) { pixel *dest = (pixel *)dest_; int i; @@ -338,20 +351,21 @@ line_size /= sizeof(pixel); for (i = 0; i < 8; i++) - FUNC(idctRowCondDC)(block + i*8, 0); + FUNC6(idctRowCondDC)(block + i*8, 0); for (i = 0; i < 8; i++) - FUNC(idctSparseColAdd)(dest + i, line_size, block + i); + FUNC6(idctSparseColAdd)(dest + i, line_size, block + i); } -void FUNC(ff_simple_idct)(int16_t *block) +void FUNC6(ff_simple_idct)(int16_t *block) { int i; for (i = 0; i < 8; i++) - FUNC(idctRowCondDC)(block + i*8, 0); + FUNC6(idctRowCondDC)(block + i*8, 0); for (i = 0; i < 8; i++) - FUNC(idctSparseCol)(block + i); + FUNC6(idctSparseCol)(block + i); } #endif +#endif diff -Nura ffmpeg-3.4.2/libavcodec/tests/dct.c ffmpeg-3.4.2_new/libavcodec/tests/dct.c --- ffmpeg-3.4.2/libavcodec/tests/dct.c 2018-02-12 08:29:05.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/tests/dct.c 2019-07-08 00:30:34.348437454 +0800 @@ -82,9 +82,9 @@ static const struct algo idct_tab[] = { { "REF-DBL", ff_ref_idct, FF_IDCT_PERM_NONE }, { "INT", ff_j_rev_dct, FF_IDCT_PERM_LIBMPEG2 }, - { "SIMPLE-C", ff_simple_idct_8, FF_IDCT_PERM_NONE }, - { "SIMPLE-C10", ff_simple_idct_10, FF_IDCT_PERM_NONE }, - { "SIMPLE-C12", ff_simple_idct_12, FF_IDCT_PERM_NONE, 0, 1 }, + { "SIMPLE-C", ff_simple_idct_int16_8bit, FF_IDCT_PERM_NONE }, + { "SIMPLE-C10", ff_simple_idct_int16_10bit, FF_IDCT_PERM_NONE }, + { "SIMPLE-C12", ff_simple_idct_int16_12bit, FF_IDCT_PERM_NONE, 0, 1 }, { "PR-C", ff_prores_idct_wrap, FF_IDCT_PERM_NONE, 0, 1 }, #if CONFIG_FAANIDCT { "FAANI", ff_faanidct, FF_IDCT_PERM_NONE }, diff -Nura ffmpeg-3.4.2/libavcodec/vc1.c ffmpeg-3.4.2_new/libavcodec/vc1.c --- ffmpeg-3.4.2/libavcodec/vc1.c 2018-01-01 06:35:48.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/vc1.c 2019-07-08 00:30:47.014554498 +0800 @@ -314,11 +314,11 @@ v->multires = get_bits1(gb); v->res_fasttx = get_bits1(gb); if (!v->res_fasttx) { - v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_8; + v->vc1dsp.vc1_inv_trans_8x8 = ff_simple_idct_int16_8bit; v->vc1dsp.vc1_inv_trans_8x4 = ff_simple_idct84_add; v->vc1dsp.vc1_inv_trans_4x8 = ff_simple_idct48_add; v->vc1dsp.vc1_inv_trans_4x4 = ff_simple_idct44_add; - v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add_8; + v->vc1dsp.vc1_inv_trans_8x8_dc = ff_simple_idct_add_int16_8bit; v->vc1dsp.vc1_inv_trans_8x4_dc = ff_simple_idct84_add; v->vc1dsp.vc1_inv_trans_4x8_dc = ff_simple_idct48_add; v->vc1dsp.vc1_inv_trans_4x4_dc = ff_simple_idct44_add; diff -Nura ffmpeg-3.4.2/libavcodec/x86/idctdsp_init.c ffmpeg-3.4.2_new/libavcodec/x86/idctdsp_init.c --- ffmpeg-3.4.2/libavcodec/x86/idctdsp_init.c 2018-02-12 08:29:06.000000000 +0800 +++ ffmpeg-3.4.2_new/libavcodec/x86/idctdsp_init.c 2019-07-08 00:31:09.583763051 +0800 @@ -123,6 +123,7 @@ } if (avctx->bits_per_raw_sample == 10 && + avctx->codec_id != AV_CODEC_ID_MPEG4 && (avctx->idct_algo == FF_IDCT_AUTO || avctx->idct_algo == FF_IDCT_SIMPLEAUTO || avctx->idct_algo == FF_IDCT_SIMPLE)) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor