diff options
Diffstat (limited to 'libavcodec/mpeg4videodec.c')
-rw-r--r-- | libavcodec/mpeg4videodec.c | 1712 |
1 files changed, 1332 insertions, 380 deletions
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 566fd3a..b6f2ae7 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -3,23 +3,28 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#define UNCHECKED_BITSTREAM_READER 1 + +#include "libavutil/internal.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" #include "error_resilience.h" #include "hwaccel.h" #include "idctdsp.h" @@ -32,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 @@ -40,6 +46,9 @@ #define SPRITE_TRAJ_VLC_BITS 6 #define DC_VLC_BITS 9 #define MB_TYPE_B_VLC_BITS 4 +#define STUDIO_INTRA_BITS 9 + +static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb); static VLC dc_lum, dc_chrom; static VLC sprite_trajectory; @@ -52,15 +61,6 @@ static const int mb_type_b_map[4] = { MB_TYPE_L0 | MB_TYPE_16x16, }; -static inline int check_marker(AVCodecContext *avctx, GetBitContext *s, const char *msg) -{ - int bit = get_bits1(s); - if (!bit) - av_log(avctx, AV_LOG_INFO, "Marker bit missing %s\n", msg); - - return bit; -} - /** * Predict the ac. * @param n block index (0-3 are luma, 4-5 are chroma) @@ -73,7 +73,7 @@ void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir) int8_t *const qscale_table = s->current_picture.qscale_table; /* find prediction */ - ac_val = s->ac_val[0][0] + s->block_index[n] * 16; + ac_val = &s->ac_val[0][0][0] + s->block_index[n] * 16; ac_val1 = ac_val; if (s->ac_pred) { if (dir == 0) { @@ -121,12 +121,13 @@ void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir) * check if the next stuff is a resync marker or the end. * @return 0 if not */ -static inline int mpeg4_is_resync(MpegEncContext *s) +static inline int mpeg4_is_resync(Mpeg4DecContext *ctx) { + MpegEncContext *s = &ctx->m; int bits_count = get_bits_count(&s->gb); int v = show_bits(&s->gb, 16); - if (s->workaround_bugs & FF_BUG_NO_PADDING) + if (s->workaround_bugs & FF_BUG_NO_PADDING && !ctx->resync_marker) return 0; while (v <= 0xFF) { @@ -143,10 +144,11 @@ static inline int mpeg4_is_resync(MpegEncContext *s) v |= 0x7F >> (7 - (bits_count & 7)); if (v == 0x7F) - return 1; + return s->mb_num; } else { if (v == ff_mpeg4_resync_prefix[bits_count & 7]) { - int len; + int len, mb_num; + int mb_num_bits = av_log2(s->mb_num - 1) + 1; GetBitContext gb = s->gb; skip_bits(&s->gb, 1); @@ -156,10 +158,14 @@ static inline int mpeg4_is_resync(MpegEncContext *s) if (get_bits1(&s->gb)) break; + mb_num = get_bits(&s->gb, mb_num_bits); + if (!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits) + mb_num= -1; + s->gb = gb; if (len >= ff_mpeg4_get_video_packet_prefix_length(s)) - return 1; + return mb_num; } } return 0; @@ -171,13 +177,15 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g int a = 2 << s->sprite_warping_accuracy; int rho = 3 - s->sprite_warping_accuracy; int r = 16 / a; - int alpha = 0; + int alpha = 1; int beta = 0; int w = s->width; int h = s->height; int min_ab, i, w2, h2, w3, h3; int sprite_ref[4][2]; int virtual_ref[2][2]; + int64_t sprite_offset[2][2]; + int64_t sprite_delta[2][2]; // only true for rectangle shapes const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 }, @@ -196,17 +204,17 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g int x = 0, y = 0; length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if (length) + if (length > 0) x = get_xbits(gb, length); if (!(ctx->divx_version == 500 && ctx->divx_build == 413)) - skip_bits1(gb); /* marker bit */ + check_marker(s->avctx, gb, "before sprite_trajectory"); length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if (length) + if (length > 0) y = get_xbits(gb, length); - skip_bits1(gb); /* marker bit */ + check_marker(s->avctx, gb, "after sprite_trajectory"); ctx->sprite_traj[i][0] = d[i][0] = x; ctx->sprite_traj[i][1] = d[i][1] = y; } @@ -246,71 +254,71 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g * from w&h based to w2&h2 based which are of the 2^x form. */ virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) + ROUNDED_DIV(((w - w2) * - (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + - w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w); + (r * sprite_ref[0][0] - 16LL * vop_ref[0][0]) + + w2 * (r * sprite_ref[1][0] - 16LL * vop_ref[1][0])), w); virtual_ref[0][1] = 16 * vop_ref[0][1] + ROUNDED_DIV(((w - w2) * - (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + - w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w); + (r * sprite_ref[0][1] - 16LL * vop_ref[0][1]) + + w2 * (r * sprite_ref[1][1] - 16LL * vop_ref[1][1])), w); virtual_ref[1][0] = 16 * vop_ref[0][0] + - ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + - h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h); + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16LL * vop_ref[0][0]) + + h2 * (r * sprite_ref[2][0] - 16LL * vop_ref[2][0])), h); virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) + - ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + - h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h); + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16LL * vop_ref[0][1]) + + h2 * (r * sprite_ref[2][1] - 16LL * vop_ref[2][1])), h); switch (ctx->num_sprite_warping_points) { case 0: - s->sprite_offset[0][0] = - s->sprite_offset[0][1] = - s->sprite_offset[1][0] = - s->sprite_offset[1][1] = 0; - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + sprite_offset[0][0] = + sprite_offset[0][1] = + sprite_offset[1][0] = + sprite_offset[1][1] = 0; + sprite_delta[0][0] = a; + sprite_delta[0][1] = + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; case 1: // GMC only - s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0]; - s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1]; - s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) - + sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0]; + sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1]; + sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) - a * (vop_ref[0][0] / 2); - s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) - + sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) - a * (vop_ref[0][1] / 2); - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + sprite_delta[0][0] = a; + sprite_delta[0][1] = + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; case 2: - s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) + - (-r * sprite_ref[0][0] + virtual_ref[0][0]) * - (-vop_ref[0][0]) + - (r * sprite_ref[0][1] - virtual_ref[0][1]) * - (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); - s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) + - (-r * sprite_ref[0][1] + virtual_ref[0][1]) * - (-vop_ref[0][0]) + - (-r * sprite_ref[0][0] + virtual_ref[0][0]) * - (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); - s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) * - (-2 * vop_ref[0][0] + 1) + - (r * sprite_ref[0][1] - virtual_ref[0][1]) * - (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * - sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1))); - s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) * - (-2 * vop_ref[0][0] + 1) + - (-r * sprite_ref[0][0] + virtual_ref[0][0]) * - (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * - sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1))); - s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); - s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); - s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); - s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + sprite_offset[0][0] = ((int64_t) sprite_ref[0][0] * (1 << alpha + rho)) + + ((int64_t) -r * sprite_ref[0][0] + virtual_ref[0][0]) * + ((int64_t) -vop_ref[0][0]) + + ((int64_t) r * sprite_ref[0][1] - virtual_ref[0][1]) * + ((int64_t) -vop_ref[0][1]) + (1 << (alpha + rho - 1)); + sprite_offset[0][1] = ((int64_t) sprite_ref[0][1] * (1 << alpha + rho)) + + ((int64_t) -r * sprite_ref[0][1] + virtual_ref[0][1]) * + ((int64_t) -vop_ref[0][0]) + + ((int64_t) -r * sprite_ref[0][0] + virtual_ref[0][0]) * + ((int64_t) -vop_ref[0][1]) + (1 << (alpha + rho - 1)); + sprite_offset[1][0] = (((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * + ((int64_t)-2 * vop_ref[0][0] + 1) + + ((int64_t) r * sprite_ref[0][1] - virtual_ref[0][1]) * + ((int64_t)-2 * vop_ref[0][1] + 1) + 2 * w2 * r * + (int64_t) sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1))); + sprite_offset[1][1] = (((int64_t)-r * sprite_ref[0][1] + virtual_ref[0][1]) * + ((int64_t)-2 * vop_ref[0][0] + 1) + + ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * + ((int64_t)-2 * vop_ref[0][1] + 1) + 2 * w2 * r * + (int64_t) sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1))); + sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); + sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); + sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); + sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); ctx->sprite_shift[0] = alpha + rho; ctx->sprite_shift[1] = alpha + rho + 2; @@ -319,68 +327,116 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g min_ab = FFMIN(alpha, beta); w3 = w2 >> min_ab; h3 = h2 >> min_ab; - s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + beta + rho - min_ab)) + - (-r * sprite_ref[0][0] + virtual_ref[0][0]) * - h3 * (-vop_ref[0][0]) + - (-r * sprite_ref[0][0] + virtual_ref[1][0]) * - w3 * (-vop_ref[0][1]) + - (1 << (alpha + beta + rho - min_ab - 1)); - s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + beta + rho - min_ab)) + - (-r * sprite_ref[0][1] + virtual_ref[0][1]) * - h3 * (-vop_ref[0][0]) + - (-r * sprite_ref[0][1] + virtual_ref[1][1]) * - w3 * (-vop_ref[0][1]) + - (1 << (alpha + beta + rho - min_ab - 1)); - s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * - h3 * (-2 * vop_ref[0][0] + 1) + - (-r * sprite_ref[0][0] + virtual_ref[1][0]) * - w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * - r * sprite_ref[0][0] - 16 * w2 * h3 + - (1 << (alpha + beta + rho - min_ab + 1)); - s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * - h3 * (-2 * vop_ref[0][0] + 1) + - (-r * sprite_ref[0][1] + virtual_ref[1][1]) * - w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * - r * sprite_ref[0][1] - 16 * w2 * h3 + - (1 << (alpha + beta + rho - min_ab + 1)); - s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3; - s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3; - s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3; - s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3; + sprite_offset[0][0] = ((int64_t)sprite_ref[0][0] * (1 << (alpha + beta + rho - min_ab))) + + ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-vop_ref[0][0]) + + ((int64_t)-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-vop_ref[0][1]) + + ((int64_t)1 << (alpha + beta + rho - min_ab - 1)); + sprite_offset[0][1] = ((int64_t)sprite_ref[0][1] * (1 << (alpha + beta + rho - min_ab))) + + ((int64_t)-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-vop_ref[0][0]) + + ((int64_t)-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-vop_ref[0][1]) + + ((int64_t)1 << (alpha + beta + rho - min_ab - 1)); + sprite_offset[1][0] = ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-2 * vop_ref[0][0] + 1) + + ((int64_t)-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-2 * vop_ref[0][1] + 1) + + (int64_t)2 * w2 * h3 * r * sprite_ref[0][0] - 16 * w2 * h3 + + ((int64_t)1 << (alpha + beta + rho - min_ab + 1)); + sprite_offset[1][1] = ((int64_t)-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-2 * vop_ref[0][0] + 1) + + ((int64_t)-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-2 * vop_ref[0][1] + 1) + + (int64_t)2 * w2 * h3 * r * sprite_ref[0][1] - 16 * w2 * h3 + + ((int64_t)1 << (alpha + beta + rho - min_ab + 1)); + sprite_delta[0][0] = (-r * (int64_t)sprite_ref[0][0] + virtual_ref[0][0]) * h3; + sprite_delta[0][1] = (-r * (int64_t)sprite_ref[0][0] + virtual_ref[1][0]) * w3; + sprite_delta[1][0] = (-r * (int64_t)sprite_ref[0][1] + virtual_ref[0][1]) * h3; + sprite_delta[1][1] = (-r * (int64_t)sprite_ref[0][1] + virtual_ref[1][1]) * w3; ctx->sprite_shift[0] = alpha + beta + rho - min_ab; ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2; break; } /* try to simplify the situation */ - if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] && - s->sprite_delta[0][1] == 0 && - s->sprite_delta[1][0] == 0 && - s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) { - s->sprite_offset[0][0] >>= ctx->sprite_shift[0]; - s->sprite_offset[0][1] >>= ctx->sprite_shift[0]; - s->sprite_offset[1][0] >>= ctx->sprite_shift[1]; - s->sprite_offset[1][1] >>= ctx->sprite_shift[1]; - s->sprite_delta[0][0] = a; - s->sprite_delta[0][1] = 0; - s->sprite_delta[1][0] = 0; - s->sprite_delta[1][1] = a; + if (sprite_delta[0][0] == a << ctx->sprite_shift[0] && + sprite_delta[0][1] == 0 && + sprite_delta[1][0] == 0 && + sprite_delta[1][1] == a << ctx->sprite_shift[0]) { + sprite_offset[0][0] >>= ctx->sprite_shift[0]; + sprite_offset[0][1] >>= ctx->sprite_shift[0]; + sprite_offset[1][0] >>= ctx->sprite_shift[1]; + sprite_offset[1][1] >>= ctx->sprite_shift[1]; + sprite_delta[0][0] = a; + sprite_delta[0][1] = 0; + sprite_delta[1][0] = 0; + sprite_delta[1][1] = a; ctx->sprite_shift[0] = 0; ctx->sprite_shift[1] = 0; s->real_sprite_warping_points = 1; } else { int shift_y = 16 - ctx->sprite_shift[0]; int shift_c = 16 - ctx->sprite_shift[1]; + for (i = 0; i < 2; i++) { - s->sprite_offset[0][i] <<= shift_y; - s->sprite_offset[1][i] <<= shift_c; - s->sprite_delta[0][i] <<= shift_y; - s->sprite_delta[1][i] <<= shift_y; + if (shift_c < 0 || shift_y < 0 || + FFABS( sprite_offset[0][i]) >= INT_MAX >> shift_y || + FFABS( sprite_offset[1][i]) >= INT_MAX >> shift_c || + FFABS( sprite_delta[0][i]) >= INT_MAX >> shift_y || + FFABS( sprite_delta[1][i]) >= INT_MAX >> shift_y + ) { + avpriv_request_sample(s->avctx, "Too large sprite shift, delta or offset"); + goto overflow; + } + } + + for (i = 0; i < 2; i++) { + sprite_offset[0][i] *= 1 << shift_y; + sprite_offset[1][i] *= 1 << shift_c; + sprite_delta[0][i] *= 1 << shift_y; + sprite_delta[1][i] *= 1 << shift_y; ctx->sprite_shift[i] = 16; + + } + for (i = 0; i < 2; i++) { + int64_t sd[2] = { + sprite_delta[i][0] - a * (1LL<<16), + sprite_delta[i][1] - a * (1LL<<16) + }; + + if (llabs(sprite_offset[0][i] + sprite_delta[i][0] * (w+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sprite_delta[i][0] * (w+16LL) + sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(sprite_delta[i][0] * (w+16LL)) >= INT_MAX || + llabs(sprite_delta[i][1] * (h+16LL)) >= INT_MAX || + llabs(sd[0]) >= INT_MAX || + llabs(sd[1]) >= INT_MAX || + llabs(sprite_offset[0][i] + sd[0] * (w+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sd[1] * (h+16LL)) >= INT_MAX || + llabs(sprite_offset[0][i] + sd[0] * (w+16LL) + sd[1] * (h+16LL)) >= INT_MAX + ) { + avpriv_request_sample(s->avctx, "Overflow on sprite points"); + goto overflow; + } } s->real_sprite_warping_points = ctx->num_sprite_warping_points; } + for (i = 0; i < 4; i++) { + s->sprite_offset[i&1][i>>1] = sprite_offset[i&1][i>>1]; + s->sprite_delta [i&1][i>>1] = sprite_delta [i&1][i>>1]; + } + + return 0; +overflow: + memset(s->sprite_offset, 0, sizeof(s->sprite_offset)); + memset(s->sprite_delta, 0, sizeof(s->sprite_delta)); + return AVERROR_PATCHWELCOME; +} + +static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) { + MpegEncContext *s = &ctx->m; + int len = FFMIN(ctx->time_increment_bits + 3, 15); + + get_bits(gb, len); + if (get_bits1(gb)) + get_bits(gb, len); + check_marker(s->avctx, gb, "after new_pred"); + return 0; } @@ -397,7 +453,7 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) /* is there enough space left for a video packet + header */ if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20) - return -1; + return AVERROR_INVALIDDATA; for (len = 0; len < 32; len++) if (get_bits1(&s->gb)) @@ -405,7 +461,7 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) if (len != ff_mpeg4_get_video_packet_prefix_length(s)) { av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n"); - return -1; + return AVERROR_INVALIDDATA; } if (ctx->shape != RECT_SHAPE) { @@ -414,23 +470,10 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) } mb_num = get_bits(&s->gb, mb_num_bits); - if (mb_num >= s->mb_num) { + if (mb_num >= s->mb_num || !mb_num) { av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num); - return -1; - } - if (s->pict_type == AV_PICTURE_TYPE_B) { - int mb_x = 0, mb_y = 0; - - while (s->next_picture.mbskip_table[s->mb_index2xy[mb_num]]) { - if (!mb_x) - ff_thread_await_progress(&s->next_picture_ptr->tf, mb_y++, 0); - mb_num++; - if (++mb_x == s->mb_width) - mb_x = 0; - } - if (mb_num >= s->mb_num) - return -1; // slice contains just skipped MBs (already decoded) + return AVERROR_INVALIDDATA; } s->mb_x = mb_num % s->mb_width; @@ -484,7 +527,57 @@ int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx) } } } - // FIXME new-pred stuff + if (ctx->new_pred) + decode_new_pred(ctx, &s->gb); + + 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; } @@ -505,10 +598,10 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n) len >>= s->quarter_sample; if (s->real_sprite_warping_points == 1) { - if (ctx->divx_version == 500 && ctx->divx_build == 413) + if (ctx->divx_version == 500 && ctx->divx_build == 413 && a >= s->quarter_sample) sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample)); else - sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a); + sum = RSHIFT(s->sprite_offset[0][n] * (1 << s->quarter_sample), a); } else { dx = s->sprite_delta[n][0]; dy = s->sprite_delta[n][1]; @@ -558,7 +651,7 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) if (code < 0 || code > 9 /* && s->nbit < 9 */) { av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n"); - return -1; + return AVERROR_INVALIDDATA; } if (code == 0) { @@ -579,9 +672,9 @@ static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr) if (code > 8) { if (get_bits1(&s->gb) == 0) { /* marker */ - if (s->avctx->err_recognition & AV_EF_BITSTREAM) { + if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) { av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n"); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -624,8 +717,8 @@ static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx) cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2); if (cbpc < 0) { av_log(s->avctx, AV_LOG_ERROR, - "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; } } while (cbpc == 8); @@ -645,7 +738,7 @@ static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx) if (dc < 0) { av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + return dc; } dir <<= 1; if (dc_pred_dir) @@ -696,8 +789,8 @@ try_again: cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); if (cbpc < 0) { av_log(s->avctx, AV_LOG_ERROR, - "cbpc corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; } if (cbpc == 20) goto try_again; @@ -735,11 +828,11 @@ try_again: if (!s->mcsel) { mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; } else { @@ -766,11 +859,11 @@ try_again: int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; mot_val[0] = mx; mot_val[1] = my; } @@ -811,7 +904,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count) if (cbpy < 0) { av_log(s->avctx, AV_LOG_ERROR, "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } s->cbp_table[xy] |= cbpy << 2; @@ -826,7 +919,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count) if (cbpy < 0) { av_log(s->avctx, AV_LOG_ERROR, "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } if (s->cbp_table[xy] & 8) @@ -839,7 +932,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count) if (dc < 0) { av_log(s->avctx, AV_LOG_ERROR, "DC corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + return dc; } dir <<= 1; if (dc_pred_dir) @@ -858,7 +951,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count) if (cbpy < 0) { av_log(s->avctx, AV_LOG_ERROR, "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } if (s->cbp_table[xy] & 8) @@ -885,21 +978,22 @@ int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx) { MpegEncContext *s = &ctx->m; int mb_num; + int ret; const int part_a_error = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_ERROR | ER_MV_ERROR) : ER_MV_ERROR; const int part_a_end = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END | ER_MV_END) : ER_MV_END; mb_num = mpeg4_decode_partition_a(ctx); - if (mb_num < 0) { + if (mb_num <= 0) { ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); - return -1; + return mb_num ? mb_num : AVERROR_INVALIDDATA; } if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) { av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n"); ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); - return -1; + return AVERROR_INVALIDDATA; } s->mb_num_left = mb_num; @@ -911,7 +1005,7 @@ int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx) av_log(s->avctx, AV_LOG_ERROR, "marker missing after first I partition at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } } else { while (show_bits(&s->gb, 10) == 1) @@ -920,17 +1014,18 @@ int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx) av_log(s->avctx, AV_LOG_ERROR, "marker missing after first P partition at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } } ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x - 1, s->mb_y, part_a_end); - if (mpeg4_decode_partition_b(s, mb_num) < 0) { + ret = mpeg4_decode_partition_b(s, mb_num); + if (ret < 0) { if (s->pict_type == AV_PICTURE_TYPE_P) ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_DC_ERROR); - return -1; + return ret; } else { if (s->pict_type == AV_PICTURE_TYPE_P) ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, @@ -948,7 +1043,8 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, int n, int coded, int intra, int rvlc) { MpegEncContext *s = &ctx->m; - int level, i, last, run, qmul, qadd, dc_pred_dir; + int level, i, last, run, qmul, qadd; + int av_uninit(dc_pred_dir); RLTable *rl; RL_VLC_ELEM *rl_vlc; const uint8_t *scan_table; @@ -968,7 +1064,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, } else { level = mpeg4_decode_dc(s, n, &dc_pred_dir); if (level < 0) - return -1; + return level; } block[0] = level; i = 0; @@ -1036,7 +1132,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in rvlc esc\n"); - return -1; + return AVERROR_INVALIDDATA; } SKIP_CACHE(re, &s->gb, 1); @@ -1049,7 +1145,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in rvlc esc\n"); - return -1; + return AVERROR_INVALIDDATA; } SKIP_CACHE(re, &s->gb, 1); @@ -1058,7 +1154,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 5) != 0x10) { av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n"); - return -1; + return AVERROR_INVALIDDATA; } SKIP_CACHE(re, &s->gb, 5); @@ -1093,7 +1189,8 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); - return -1; + if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR)) + return AVERROR_INVALIDDATA; } SKIP_CACHE(re, &s->gb, 1); @@ -1103,24 +1200,47 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); - return -1; + if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR)) + return AVERROR_INVALIDDATA; } SKIP_COUNTER(re, &s->gb, 1 + 12 + 1); } +#if 0 + if (s->error_recognition >= FF_ER_COMPLIANT) { + const int abs_level= FFABS(level); + if (abs_level<=MAX_LEVEL && run<=MAX_RUN) { + const int run1= run - rl->max_run[last][abs_level] - 1; + if (abs_level <= rl->max_level[last][run]) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n"); + return AVERROR_INVALIDDATA; + } + if (s->error_recognition > FF_ER_COMPLIANT) { + if (abs_level <= rl->max_level[last][run]*2) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n"); + return AVERROR_INVALIDDATA; + } + if (run1 >= 0 && abs_level <= rl->max_level[last][run1]) { + av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n"); + return AVERROR_INVALIDDATA; + } + } + } + } +#endif if (level > 0) level = level * qmul + qadd; else level = level * qmul - qadd; if ((unsigned)(level + 2048) > 4095) { - if (s->avctx->err_recognition & AV_EF_BITSTREAM) { + if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)) { if (level > 2560 || level < -2560) { av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale); - return -1; + return AVERROR_INVALIDDATA; } } level = level < 0 ? -2048 : 2047; @@ -1152,12 +1272,13 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); } + ff_tlog(s->avctx, "dct[%d][%d] = %- 4d end?:%d\n", scan_table[i&63]&7, scan_table[i&63] >> 3, level, i>62); if (i > 62) { i -= 192; if (i & (~63)) { av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } block[scan_table[i]] = level; @@ -1191,10 +1312,12 @@ not_coded: */ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) { - Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; + Mpeg4DecContext *ctx = s->avctx->priv_data; int cbp, mb_type; const int xy = s->mb_x + s->mb_y * s->mb_stride; + av_assert2(s == (void*)ctx); + mb_type = s->current_picture.mb_type[xy]; cbp = s->cbp_table[xy]; @@ -1252,7 +1375,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) av_log(s->avctx, AV_LOG_ERROR, "texture corrupted at %d %d %d\n", s->mb_x, s->mb_y, s->mb_intra); - return -1; + return AVERROR_INVALIDDATA; } cbp += cbp; } @@ -1260,12 +1383,12 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) /* per-MB end of slice check */ if (--s->mb_num_left <= 0) { - if (mpeg4_is_resync(s)) + if (mpeg4_is_resync(ctx)) return SLICE_END; else return SLICE_NOEND; } else { - if (mpeg4_is_resync(s)) { + if (mpeg4_is_resync(ctx)) { const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1; if (s->cbp_table[xy + delta]) return SLICE_END; @@ -1276,13 +1399,14 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64]) static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) { - Mpeg4DecContext *ctx = (Mpeg4DecContext *)s; + Mpeg4DecContext *ctx = s->avctx->priv_data; int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; int16_t *mot_val; static const int8_t quant_tab[4] = { -1, -2, 1, 2 }; const int xy = s->mb_x + s->mb_y * s->mb_stride; - assert(s->h263_pred); + av_assert2(s == (void*)ctx); + av_assert2(s->h263_pred); if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_S) { @@ -1318,8 +1442,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2); if (cbpc < 0) { av_log(s->avctx, AV_LOG_ERROR, - "cbpc damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; + "mcbpc damaged at %d %d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; } } while (cbpc == 20); @@ -1335,6 +1459,11 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) else s->mcsel = 0; cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F; + if (cbpy < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "P cbpy damaged at %d %d\n", s->mb_x, s->mb_y); + return AVERROR_INVALIDDATA; + } cbp = (cbpc & 3) | (cbpy << 2); if (dquant) @@ -1370,11 +1499,11 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) for (i = 0; i < 2; i++) { mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; my = ff_h263_decode_motion(s, pred_y / 2, s->f_code); if (my >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; s->mv[0][i][0] = mx; s->mv[0][i][1] = my; @@ -1387,12 +1516,12 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; s->mv[0][0][0] = mx; s->mv[0][0][1] = my; } @@ -1403,11 +1532,11 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) - return -1; + return AVERROR_INVALIDDATA; s->mv[0][i][0] = mx; s->mv[0][i][1] = my; mot_val[0] = mx; @@ -1463,7 +1592,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1); if (mb_type < 0) { av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n"); - return -1; + return AVERROR_INVALIDDATA; } mb_type = mb_type_b_map[mb_type]; if (modb2) { @@ -1574,7 +1703,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64]) if (cbpc < 0) { av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } } while (cbpc == 8); @@ -1592,7 +1721,7 @@ intra: if (cbpy < 0) { av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; + return AVERROR_INVALIDDATA; } cbp = (cbpc & 3) | (cbpy << 2); @@ -1608,7 +1737,7 @@ intra: /* decode each block */ for (i = 0; i < 6; i++) { if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0) - return -1; + return AVERROR_INVALIDDATA; cbp += cbp; } goto end; @@ -1617,27 +1746,30 @@ intra: /* decode each block */ for (i = 0; i < 6; i++) { if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0) - return -1; + return AVERROR_INVALIDDATA; cbp += cbp; } end: /* per-MB end of slice check */ if (s->codec_id == AV_CODEC_ID_MPEG4) { - if (mpeg4_is_resync(s)) { - const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1; + int next = mpeg4_is_resync(ctx); + if (next) { + if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) { + return AVERROR_INVALIDDATA; + } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next) + return SLICE_END; - if (s->pict_type == AV_PICTURE_TYPE_B && - s->next_picture.mbskip_table[xy + delta]) { + if (s->pict_type == AV_PICTURE_TYPE_B) { + const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; ff_thread_await_progress(&s->next_picture_ptr->tf, (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y + 1, s->mb_height - 1) : s->mb_y, 0); + if (s->next_picture.mbskip_table[xy + delta]) + return SLICE_OK; } - if (s->pict_type == AV_PICTURE_TYPE_B && - s->next_picture.mbskip_table[xy + delta]) - return SLICE_OK; return SLICE_END; } } @@ -1645,41 +1777,375 @@ end: return SLICE_OK; } -static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb) +/* 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) { - int hours, minutes, seconds; - unsigned time_code = show_bits(gb, 18); - - if (time_code & 0x40) { /* marker_bit */ - hours = time_code >> 13; - minutes = time_code >> 7 & 0x3f; - seconds = time_code & 0x3f; - s->time_base = seconds + 60 * (minutes + 60 * hours); - skip_bits(gb, 20); /* time_code, closed_gov, broken_link */ + 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 { - av_log(s->avctx, AV_LOG_WARNING, "GOP header missing marker_bit\n"); + 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; + if (idx > 63) + return AVERROR_INVALIDDATA; + j = scantable[idx++]; + block[j] = sign ? 1 : -1; + } else if (group >= 13 && group <= 20) { + /* Level value (Table B.49) */ + if (idx > 63) + return AVERROR_INVALIDDATA; + j = scantable[idx++]; + block[j] = get_xbits(&s->gb, additional_code_len); + } else if (group == 21) { + /* Escape */ + if (idx > 63) + return AVERROR_INVALIDDATA; + 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_profile_level(MpegEncContext *s, GetBitContext *gb) +static int mpeg4_decode_dpcm_macroblock(MpegEncContext *s, int16_t macroblock[256], int n) { - int profile_and_level_indication; + int i, j, w, h, idx = 0; + int block_mean, rice_parameter, rice_prefix_code, rice_suffix_code, + dpcm_residual, left, top, topleft, min_left_top, max_left_top, p, p2, output; + h = 16 >> (n ? s->chroma_y_shift : 0); + w = 16 >> (n ? s->chroma_x_shift : 0); + + 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)); - profile_and_level_indication = get_bits(gb, 8); + 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; + } - s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4; - s->avctx->level = (profile_and_level_indication & 0x0f); + 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++) { + output = 1 << (s->avctx->bits_per_raw_sample - 1); + top = 1 << (s->avctx->bits_per_raw_sample - 1); + + for (j = 0; j < w; j++) { + left = output; + topleft = top; + + 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 { + if (rice_prefix_code == 12) { + av_log(s->avctx, AV_LOG_ERROR, "Forbidden rice_prefix_code\n"); + return AVERROR_INVALIDDATA; + } + 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); + + if (i != 0) + top = macroblock[idx-w]; + + p = left + top - topleft; + min_left_top = FFMIN(left, top); + if (p < min_left_top) + p = min_left_top; + + max_left_top = FFMAX(left, top); + if (p > max_left_top) + p = max_left_top; + + p2 = (FFMIN(min_left_top, topleft) + FFMAX(max_left_top, topleft)) >> 1; + if (p2 == p) + p2 = block_mean; + + if (p2 > p) + dpcm_residual *= -1; + + macroblock[idx++] = output = (dpcm_residual + p) & ((1 << s->avctx->bits_per_raw_sample) - 1); + } + } + + return 0; +} + +static int mpeg4_decode_studio_mb(MpegEncContext *s, int16_t block_[12][64]) +{ + int i; + + s->dpcm_direction = 0; + + /* 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"); + s->dpcm_direction = get_bits1(&s->gb) ? -1 : 1; + for (i = 0; i < 3; i++) { + if (mpeg4_decode_dpcm_macroblock(s, (*s->dpcm_macroblock)[i], i) < 0) + return AVERROR_INVALIDDATA; + } + } + + if (get_bits_left(&s->gb) >= 24 && show_bits(&s->gb, 23) == 0) { + next_start_code_studio(&s->gb); + return SLICE_END; + } + + //vcon-stp9L1.bits (first frame) + if (get_bits_left(&s->gb) == 0) + return SLICE_END; + + //vcon-stp2L1.bits, vcon-stp3L1.bits, vcon-stp6L1.bits, vcon-stp7L1.bits, vcon-stp8L1.bits, vcon-stp10L1.bits (first frame) + if (get_bits_left(&s->gb) < 8U && show_bits(&s->gb, get_bits_left(&s->gb)) == 0) + return SLICE_END; + + return SLICE_OK; +} + +static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb) +{ + int hours, minutes, seconds; + + if (!show_bits(gb, 23)) { + av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n"); + return AVERROR_INVALIDDATA; + } + + hours = get_bits(gb, 5); + minutes = get_bits(gb, 6); + check_marker(s->avctx, gb, "in gop_header"); + seconds = get_bits(gb, 6); + + s->time_base = seconds + 60*(minutes + 60*hours); + + skip_bits1(gb); + skip_bits1(gb); + + return 0; +} + +static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb, int *profile, int *level) +{ + + *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_range, color_description; + skip_bits(gb, 3); // video_format + video_range = get_bits1(gb); + 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; @@ -1688,6 +2154,23 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) /* vol header */ skip_bits(gb, 1); /* random access */ s->vo_type = get_bits(gb, 8); + + /* If we are in studio profile (per vo_type), check if its all consistent + * and if so continue pass control to decode_studio_vol_header(). + * elIf something is inconsistent, error out + * else continue with (non studio) vol header decpoding. + */ + if (s->vo_type == CORE_STUDIO_VO_TYPE || + s->vo_type == SIMPLE_STUDIO_VO_TYPE) { + if (s->avctx->profile != FF_PROFILE_UNKNOWN && s->avctx->profile != FF_PROFILE_MPEG4_SIMPLE_STUDIO) + return AVERROR_INVALIDDATA; + s->studio_profile = 1; + s->avctx->profile = FF_PROFILE_MPEG4_SIMPLE_STUDIO; + return decode_studio_vol_header(ctx, gb); + } else if (s->studio_profile) { + return AVERROR_PATCHWELCOME; + } + if (get_bits1(gb) != 0) { /* is_ol_id */ vo_ver_id = get_bits(gb, 4); /* vo_ver_id */ skip_bits(gb, 3); /* vo_priority */ @@ -1710,22 +2193,30 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) s->low_delay = get_bits1(gb); if (get_bits1(gb)) { /* vbv parameters */ get_bits(gb, 15); /* first_half_bitrate */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after first_half_bitrate"); get_bits(gb, 15); /* latter_half_bitrate */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after latter_half_bitrate"); get_bits(gb, 15); /* first_half_vbv_buffer_size */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after first_half_vbv_buffer_size"); get_bits(gb, 3); /* latter_half_vbv_buffer_size */ get_bits(gb, 11); /* first_half_vbv_occupancy */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after first_half_vbv_occupancy"); get_bits(gb, 15); /* latter_half_vbv_occupancy */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after latter_half_vbv_occupancy"); } } else { /* is setting low delay flag only once the smartest thing to do? * low delay detection will not be overridden. */ - if (s->picture_number == 0) - s->low_delay = 0; + if (s->picture_number == 0) { + switch(s->vo_type) { + case SIMPLE_VO_TYPE: + case ADV_SIMPLE_VO_TYPE: + s->low_delay = 1; + break; + default: + s->low_delay = 0; + } + } } ctx->shape = get_bits(gb, 2); /* vol shape */ @@ -1741,7 +2232,7 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) s->avctx->framerate.num = get_bits(gb, 16); if (!s->avctx->framerate.num) { av_log(s->avctx, AV_LOG_ERROR, "framerate==0\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->time_increment_bits = av_log2(s->avctx->framerate.num - 1) + 1; @@ -1755,15 +2246,17 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) else s->avctx->framerate.den = 1; + s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1})); + ctx->t_frame = 0; if (ctx->shape != BIN_ONLY_SHAPE) { if (ctx->shape == RECT_SHAPE) { - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "before width"); width = get_bits(gb, 13); - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "before height"); height = get_bits(gb, 13); - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after height"); if (width && height && /* they should be non zero but who knows */ !(s->width && s->codec_tag == AV_RL32("MP4S"))) { if (s->width && s->height && @@ -1791,13 +2284,13 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) ctx->vol_sprite_usage == GMC_SPRITE) { if (ctx->vol_sprite_usage == STATIC_SPRITE) { skip_bits(gb, 13); // sprite_width - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after sprite_width"); skip_bits(gb, 13); // sprite_height - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after sprite_height"); skip_bits(gb, 13); // sprite_left - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after sprite_left"); skip_bits(gb, 13); // sprite_top - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after sprite_top"); } ctx->num_sprite_warping_points = get_bits(gb, 6); if (ctx->num_sprite_warping_points > 3) { @@ -1805,7 +2298,7 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) "%d sprite_warping_points\n", ctx->num_sprite_warping_points); ctx->num_sprite_warping_points = 0; - return -1; + return AVERROR_INVALIDDATA; } s->sprite_warping_accuracy = get_bits(gb, 2); ctx->sprite_brightness_change = get_bits1(gb); @@ -1821,6 +2314,9 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (s->quant_precision != 5) av_log(s->avctx, AV_LOG_ERROR, "quant precision %d\n", s->quant_precision); + if (s->quant_precision<3 || s->quant_precision>9) { + s->quant_precision = 5; + } } else { s->quant_precision = 5; } @@ -1830,23 +2326,17 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) 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)) { int last = 0; for (i = 0; i < 64; i++) { int j; + if (get_bits_left(gb) < 8) { + av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n"); + return AVERROR_INVALIDDATA; + } v = get_bits(gb, 8); if (v == 0) break; @@ -1870,6 +2360,10 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) int last = 0; for (i = 0; i < 64; i++) { int j; + if (get_bits_left(gb) < 8) { + av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n"); + return AVERROR_INVALIDDATA; + } v = get_bits(gb, 8); if (v == 0) break; @@ -1896,6 +2390,11 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) else s->quarter_sample = 0; + if (get_bits_left(gb) < 4) { + av_log(s->avctx, AV_LOG_ERROR, "VOL Header truncated\n"); + return AVERROR_INVALIDDATA; + } + if (!get_bits1(gb)) { int pos = get_bits_count(gb); int estimation_method = get_bits(gb, 2); @@ -2003,6 +2502,18 @@ no_cplx_est: } } + if (s->avctx->debug&FF_DEBUG_PICT_INFO) { + av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, low_delay:%d %s%s%s%s\n", + s->avctx->framerate.den, s->avctx->framerate.num, + ctx->time_increment_bits, + s->quant_precision, + s->progressive_sequence, + s->low_delay, + ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "", + s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : "" + ); + } + return 0; } @@ -2034,11 +2545,6 @@ static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb) ctx->divx_version = ver; ctx->divx_build = build; s->divx_packed = e == 3 && last == 'p'; - if (s->divx_packed && !ctx->showed_packed_warning) { - av_log(s->avctx, AV_LOG_WARNING, - "Invalid and inefficient vfw-avi packed B-frames detected\n"); - ctx->showed_packed_warning = 1; - } } /* libavcodec detection */ @@ -2047,8 +2553,15 @@ static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb) e = sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); if (e != 4) { e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1; - if (e > 1) - build = (ver << 16) + (ver2 << 8) + ver3; + if (e > 1) { + if (ver > 0xFFU || ver2 > 0xFFU || ver3 > 0xFFU) { + av_log(s->avctx, AV_LOG_WARNING, + "Unknown Lavc version string encountered, %d.%d.%d; " + "clamping sub-version values to 8-bits.\n", + ver, ver2, ver3); + } + build = ((ver & 0xFF) << 16) + ((ver2 & 0xFF) << 8) + (ver3 & 0xFF); + } } if (e != 4) { if (strcmp(buf, "ffmpeg") == 0) @@ -2062,6 +2575,14 @@ static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb) if (e == 1) ctx->xvid_build = build; + return 0; +} + +int ff_mpeg4_workaround_bugs(AVCodecContext *avctx) +{ + Mpeg4DecContext *ctx = avctx->priv_data; + MpegEncContext *s = &ctx->m; + if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) { if (s->codec_tag == AV_RL32("XVID") || s->codec_tag == AV_RL32("XVIX") || @@ -2081,8 +2602,96 @@ static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb) ctx->divx_build = -1; } - if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0) - ff_xvid_idct_init(&s->idsp, s->avctx); + if (s->workaround_bugs & FF_BUG_AUTODETECT) { + if (s->codec_tag == AV_RL32("XVIX")) + s->workaround_bugs |= FF_BUG_XVID_ILACE; + + if (s->codec_tag == AV_RL32("UMP4")) + s->workaround_bugs |= FF_BUG_UMP4; + + if (ctx->divx_version >= 500 && ctx->divx_build < 1814) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA; + + if (ctx->divx_version > 502 && ctx->divx_build < 1814) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA2; + + if (ctx->xvid_build <= 3U) + s->padding_bug_score = 256 * 256 * 256 * 64; + + if (ctx->xvid_build <= 1U) + s->workaround_bugs |= FF_BUG_QPEL_CHROMA; + + if (ctx->xvid_build <= 12U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->xvid_build <= 32U) + s->workaround_bugs |= FF_BUG_DC_CLIP; + +#define SET_QPEL_FUNC(postfix1, postfix2) \ + s->qdsp.put_ ## postfix1 = ff_put_ ## postfix2; \ + s->qdsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \ + s->qdsp.avg_ ## postfix1 = ff_avg_ ## postfix2; + + if (ctx->lavc_build < 4653U) + s->workaround_bugs |= FF_BUG_STD_QPEL; + + if (ctx->lavc_build < 4655U) + s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; + + if (ctx->lavc_build < 4670U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->lavc_build <= 4712U) + s->workaround_bugs |= FF_BUG_DC_CLIP; + + if ((ctx->lavc_build&0xFF) >= 100) { + if (ctx->lavc_build > 3621476 && ctx->lavc_build < 3752552 && + (ctx->lavc_build < 3752037 || ctx->lavc_build > 3752191) // 3.2.1+ + ) + s->workaround_bugs |= FF_BUG_IEDGE; + } + + if (ctx->divx_version >= 0) + s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; + if (ctx->divx_version == 501 && ctx->divx_build == 20020416) + s->padding_bug_score = 256 * 256 * 256 * 64; + + if (ctx->divx_version < 500U) + s->workaround_bugs |= FF_BUG_EDGE; + + if (ctx->divx_version >= 0) + s->workaround_bugs |= FF_BUG_HPEL_CHROMA; + } + + if (s->workaround_bugs & FF_BUG_STD_QPEL) { + SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c) + + SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c) + SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c) + } + + if (avctx->debug & FF_DEBUG_BUGS) + av_log(s->avctx, AV_LOG_DEBUG, + "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n", + s->workaround_bugs, ctx->lavc_build, ctx->xvid_build, + ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : ""); + + if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 && + s->codec_id == AV_CODEC_ID_MPEG4 && + avctx->idct_algo == FF_IDCT_AUTO) { + avctx->idct_algo = FF_IDCT_XVID; + ff_mpv_idct_init(s); + return 1; + } return 0; } @@ -2091,7 +2700,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; int time_incr, time_increment; + int64_t pts; + s->mcsel = 0; s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */ if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay && ctx->vol_control_parameters == 0 && !(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)) { @@ -2113,7 +2724,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (ctx->time_increment_bits == 0 || !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) { - /* Headers seem incomplete; try to guess time_increment_bits. */ + av_log(s->avctx, AV_LOG_WARNING, + "time_increment_bits %d is invalid in relation to the current bitstream, this is likely caused by a missing VOL header\n", ctx->time_increment_bits); + for (ctx->time_increment_bits = 1; ctx->time_increment_bits < 16; ctx->time_increment_bits++) { @@ -2125,6 +2738,13 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18) break; } + + av_log(s->avctx, AV_LOG_WARNING, + "time_increment_bits set to %d bits, based on bitstream analysis\n", ctx->time_increment_bits); + if (s->avctx->framerate.num && 4*s->avctx->framerate.num < 1<<ctx->time_increment_bits) { + s->avctx->framerate.num = 1<<ctx->time_increment_bits; + s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1})); + } } if (IS_3IV1) @@ -2135,7 +2755,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (s->pict_type != AV_PICTURE_TYPE_B) { s->last_time_base = s->time_base; s->time_base += time_incr; - s->time = s->time_base * s->avctx->framerate.num + time_increment; + s->time = s->time_base * (int64_t)s->avctx->framerate.num + time_increment; if (s->workaround_bugs & FF_BUG_UMP4) { if (s->time < s->last_non_b_time) { /* header is not mpeg-4-compatible, broken encoder, @@ -2147,7 +2767,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) s->pp_time = s->time - s->last_non_b_time; s->last_non_b_time = s->time; } else { - s->time = (s->last_time_base + time_incr) * s->avctx->framerate.num + time_increment; + s->time = (s->last_time_base + time_incr) * (int64_t)s->avctx->framerate.num + time_increment; s->pb_time = s->pp_time - (s->last_non_b_time - s->time); if (s->pp_time <= s->pb_time || s->pp_time <= s->pp_time - s->pb_time || @@ -2165,12 +2785,20 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2; s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) - ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2; - if (!s->progressive_sequence) { - if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) + if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) { + s->pb_field_time = 2; + s->pp_field_time = 4; + if (!s->progressive_sequence) return FRAME_SKIPPED; } } + if (s->avctx->framerate.den) + pts = ROUNDED_DIV(s->time, s->avctx->framerate.den); + else + pts = AV_NOPTS_VALUE; + ff_dlog(s->avctx, "MPEG4 PTS: %"PRId64"\n", pts); + check_marker(s->avctx, gb, "before vop_coded"); /* vop coded */ @@ -2179,6 +2807,9 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n"); return FRAME_SKIPPED; } + if (ctx->new_pred) + decode_new_pred(ctx, gb); + if (ctx->shape != BIN_ONLY_SHAPE && (s->pict_type == AV_PICTURE_TYPE_P || (s->pict_type == AV_PICTURE_TYPE_S && @@ -2193,11 +2824,11 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (ctx->shape != RECT_SHAPE) { if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) { skip_bits(gb, 13); /* width */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after width"); skip_bits(gb, 13); /* height */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after height"); skip_bits(gb, 13); /* hor_spat_ref */ - skip_bits1(gb); /* marker */ + check_marker(s->avctx, gb, "after hor_spat_ref"); skip_bits(gb, 13); /* ver_spat_ref */ } skip_bits1(gb); /* change_CR_disable */ @@ -2215,6 +2846,10 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (s->pict_type == AV_PICTURE_TYPE_B) skip_bits_long(gb, ctx->cplx_estimation_trash_b); + if (get_bits_left(gb) < 3) { + av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n"); + return AVERROR_INVALIDDATA; + } ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)]; if (!s->progressive_sequence) { s->top_field_first = get_bits1(gb); @@ -2235,16 +2870,20 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); } - if (s->pict_type == AV_PICTURE_TYPE_S && - (ctx->vol_sprite_usage == STATIC_SPRITE || - ctx->vol_sprite_usage == GMC_SPRITE)) { - if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0) - return AVERROR_INVALIDDATA; - if (ctx->sprite_brightness_change) - av_log(s->avctx, AV_LOG_ERROR, - "sprite_brightness_change not supported\n"); - if (ctx->vol_sprite_usage == STATIC_SPRITE) - av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); + if (s->pict_type == AV_PICTURE_TYPE_S) { + if((ctx->vol_sprite_usage == STATIC_SPRITE || + ctx->vol_sprite_usage == GMC_SPRITE)) { + if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0) + return AVERROR_INVALIDDATA; + if (ctx->sprite_brightness_change) + av_log(s->avctx, AV_LOG_ERROR, + "sprite_brightness_change not supported\n"); + if (ctx->vol_sprite_usage == STATIC_SPRITE) + av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); + } else { + memset(s->sprite_offset, 0, sizeof(s->sprite_offset)); + memset(s->sprite_delta, 0, sizeof(s->sprite_delta)); + } } if (ctx->shape != BIN_ONLY_SHAPE) { @@ -2252,7 +2891,7 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (s->qscale == 0) { av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG-4 header (qscale=0)\n"); - return -1; // makes no sense to continue, as there is nothing left from the image then + return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then } if (s->pict_type != AV_PICTURE_TYPE_I) { @@ -2260,29 +2899,39 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) if (s->f_code == 0) { av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG-4 header (f_code=0)\n"); - return -1; // makes no sense to continue, as there is nothing left from the image then + s->f_code = 1; + return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then } } else s->f_code = 1; if (s->pict_type == AV_PICTURE_TYPE_B) { s->b_code = get_bits(gb, 3); + if (s->b_code == 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Error, header damaged or not MPEG4 header (b_code=0)\n"); + s->b_code=1; + return AVERROR_INVALIDDATA; // makes no sense to continue, as the MV decoding will break very quickly + } } else s->b_code = 1; if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, - "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d\n", + "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n", s->qscale, s->f_code, s->b_code, s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")), - gb->size_in_bits, s->progressive_sequence, s->alternate_scan, + gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first, s->quarter_sample ? "q" : "h", s->data_partitioning, ctx->resync_marker, ctx->num_sprite_warping_points, s->sprite_warping_accuracy, 1 - s->no_rounding, s->vo_type, ctx->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold, ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p, - ctx->cplx_estimation_trash_b); + ctx->cplx_estimation_trash_b, + s->time, + time_increment + ); } if (!ctx->scalability) { @@ -2321,20 +2970,267 @@ static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb) return 0; } +static int read_quant_matrix_ext(MpegEncContext *s, GetBitContext *gb) +{ + int i, j, v; + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* 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)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + if (get_bits1(gb)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* 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)) { + if (get_bits_left(gb) < 64*8) + return AVERROR_INVALIDDATA; + /* chroma_non_intra_quantiser_matrix */ + for (i = 0; i < 64; i++) { + get_bits(gb, 8); + } + } + + next_start_code_studio(gb); + return 0; +} + +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; + + s->partitioned_frame = 0; + s->interlaced_dct = 0; + 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) +{ + MpegEncContext *s = &ctx->m; + int visual_object_type; + + skip_bits(gb, 4); /* visual_object_verid */ + visual_object_type = get_bits(gb, 4); + if (visual_object_type != VOT_VIDEO_ID) { + avpriv_request_sample(s->avctx, "VO type %u", visual_object_type); + return AVERROR_PATCHWELCOME; + } + + next_start_code_studio(gb); + extension_and_user_data(s, gb, 1); + + return 0; +} + +static int decode_studio_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) +{ + MpegEncContext *s = &ctx->m; + int width, height; + int bits_per_raw_sample; + + // random_accessible_vol and video_object_type_indication have already + // been read by the caller decode_vol_header() + 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; + } + + bits_per_raw_sample = get_bits(gb, 4); /* bit_depth */ + if (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", bits_per_raw_sample); + return AVERROR_PATCHWELCOME; + } + s->avctx->bits_per_raw_sample = bits_per_raw_sample; + } + 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) + * + * @param header If set the absence of a VOP is not treated as error; otherwise, it is treated as such. + * @return <0 if an error occured * FRAME_SKIPPED if a not coded VOP is found - * 0 if a VOP is found + * 0 else */ -int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) +int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb, int header) { MpegEncContext *s = &ctx->m; unsigned startcode, v; + int ret; + int vol = 0; /* search next start code */ align_get_bits(gb); + // If we have not switched to studio profile than we also did not switch bps + // that means something else (like a previous instance) outside set bps which + // would be inconsistant with the currect state, thus reset it + if (!s->studio_profile && s->avctx->bits_per_raw_sample != 8) + s->avctx->bits_per_raw_sample = 0; + if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) { skip_bits(gb, 24); if (get_bits(gb, 8) == 0xF0) @@ -2345,11 +3241,13 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) for (;;) { if (get_bits_count(gb) >= gb->size_in_bits) { if (gb->size_in_bits == 8 && - (ctx->divx_version >= 0 || ctx->xvid_build >= 0)) { - av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits); + (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) { + av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits); return FRAME_SKIPPED; // divx bug + } else if (header && get_bits_count(gb) == gb->size_in_bits) { + return 0; // ordinary return value for parsing of extradata } else - return -1; // end of stream + return AVERROR_INVALIDDATA; // end of stream } /* use the bits after the test */ @@ -2419,14 +3317,37 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) } if (startcode >= 0x120 && startcode <= 0x12F) { - if (decode_vol_header(ctx, gb) < 0) - return -1; + if (vol) { + av_log(s->avctx, AV_LOG_WARNING, "Ignoring multiple VOL headers\n"); + continue; + } + vol++; + if ((ret = decode_vol_header(ctx, gb)) < 0) + return ret; } else if (startcode == USER_DATA_STARTCODE) { decode_user_data(ctx, gb); } 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; + } else + mpeg4_decode_visual_object(s, gb); } else if (startcode == VOP_STARTCODE) { break; } @@ -2440,64 +3361,40 @@ end: s->low_delay = 1; s->avctx->has_b_frames = !s->low_delay; - if (s->workaround_bugs & FF_BUG_AUTODETECT) { - if (s->codec_tag == AV_RL32("XVIX")) - s->workaround_bugs |= FF_BUG_XVID_ILACE; - - if (s->codec_tag == AV_RL32("UMP4")) - s->workaround_bugs |= FF_BUG_UMP4; - - if (ctx->divx_version >= 500 && ctx->divx_build < 1814) - s->workaround_bugs |= FF_BUG_QPEL_CHROMA; - - if (ctx->divx_version > 502 && ctx->divx_build < 1814) - s->workaround_bugs |= FF_BUG_QPEL_CHROMA2; - - if (ctx->xvid_build <= 3U) - s->padding_bug_score = 256 * 256 * 256 * 64; - - if (ctx->xvid_build <= 1U) - s->workaround_bugs |= FF_BUG_QPEL_CHROMA; - - if (ctx->xvid_build <= 12U) - s->workaround_bugs |= FF_BUG_EDGE; - - if (ctx->xvid_build <= 32U) - s->workaround_bugs |= FF_BUG_DC_CLIP; - - if (ctx->lavc_build < 4653U) - s->workaround_bugs |= FF_BUG_STD_QPEL; - - if (ctx->lavc_build < 4655U) - s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; - - if (ctx->lavc_build < 4670U) - s->workaround_bugs |= FF_BUG_EDGE; - - if (ctx->lavc_build <= 4712U) - s->workaround_bugs |= FF_BUG_DC_CLIP; - - if (ctx->divx_version >= 0) - s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE; - - if (ctx->divx_version == 501 && ctx->divx_build == 20020416) - s->padding_bug_score = 256 * 256 * 256 * 64; + if (s->studio_profile) { + 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); +} - if (ctx->divx_version < 500U) - s->workaround_bugs |= FF_BUG_EDGE; +av_cold void ff_mpeg4videodec_static_init(void) { + static int done = 0; - if (ctx->divx_version >= 0) - s->workaround_bugs |= FF_BUG_HPEL_CHROMA; + if (!done) { + ff_rl_init(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); + ff_rl_init(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); + ff_rl_init(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); + INIT_VLC_RL(ff_mpeg4_rl_intra, 554); + INIT_VLC_RL(ff_rvlc_rl_inter, 1072); + INIT_VLC_RL(ff_rvlc_rl_intra, 1072); + INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_lum[0][1], 2, 1, + &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); + INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, + &ff_mpeg4_DCtab_chrom[0][1], 2, 1, + &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); + INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, + &ff_sprite_trajectory_tab[0][1], 4, 2, + &ff_sprite_trajectory_tab[0][0], 4, 2, 128); + INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, + &ff_mb_type_b_tab[0][1], 2, 1, + &ff_mb_type_b_tab[0][0], 2, 1, 16); + done = 1; } - - - if (s->avctx->debug & FF_DEBUG_BUGS) - av_log(s->avctx, AV_LOG_DEBUG, - "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n", - s->workaround_bugs, ctx->lavc_build, ctx->xvid_build, - ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : ""); - - return decode_vop_header(ctx, gb); } int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size) @@ -2506,34 +3403,40 @@ int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size) MpegEncContext *s = &ctx->m; /* divx 5.01+ bitstream reorder stuff */ + /* Since this clobbers the input buffer and hwaccel codecs still need the + * data during hwaccel->end_frame we should not do this any earlier */ if (s->divx_packed) { - int current_pos = get_bits_count(&s->gb) >> 3; + int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3); int startcode_found = 0; - if (buf_size - current_pos > 5) { + if (buf_size - current_pos > 7) { + int i; - for (i = current_pos; i < buf_size - 3; i++) + for (i = current_pos; i < buf_size - 4; i++) + if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 && buf[i + 3] == 0xB6) { - startcode_found = 1; + startcode_found = !(buf[i + 4] & 0x40); break; } } - if (s->gb.buffer == s->bitstream_buffer && buf_size > 7 && - ctx->xvid_build >= 0) { // xvid style - startcode_found = 1; - current_pos = 0; - } if (startcode_found) { - av_fast_malloc(&s->bitstream_buffer, + if (!ctx->showed_packed_warning) { + av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and " + "wasteful way to store B-frames ('packed B-frames'). " + "Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.\n"); + ctx->showed_packed_warning = 1; + } + av_fast_padded_malloc(&s->bitstream_buffer, &s->allocated_bitstream_buffer_size, - buf_size - current_pos + - AV_INPUT_BUFFER_PADDING_SIZE); - if (!s->bitstream_buffer) + buf_size - current_pos); + if (!s->bitstream_buffer) { + s->bitstream_buffer_size = 0; return AVERROR(ENOMEM); + } memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos); s->bitstream_buffer_size = buf_size - current_pos; @@ -2543,6 +3446,7 @@ int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size) return 0; } +#if HAVE_THREADS static int mpeg4_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { @@ -2555,12 +3459,42 @@ static int mpeg4_update_thread_context(AVCodecContext *dst, if (ret < 0) return ret; + memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext)); + if (CONFIG_MPEG4_DECODER && !init && s1->xvid_build >= 0) ff_xvid_idct_init(&s->m.idsp, dst); - s->shape = s1->shape; - s->time_increment_bits = s1->time_increment_bits; - s->xvid_build = s1->xvid_build; + return 0; +} +#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; } @@ -2570,7 +3504,6 @@ static av_cold int decode_init(AVCodecContext *avctx) Mpeg4DecContext *ctx = avctx->priv_data; MpegEncContext *s = &ctx->m; int ret; - static int done = 0; ctx->divx_version = ctx->divx_build = @@ -2580,28 +3513,9 @@ static av_cold int decode_init(AVCodecContext *avctx) if ((ret = ff_h263_decode_init(avctx)) < 0) return ret; - if (!done) { - done = 1; - - ff_rl_init(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - ff_rl_init(&ff_rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); - ff_rl_init(&ff_rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); - INIT_VLC_RL(ff_mpeg4_rl_intra, 554); - INIT_VLC_RL(ff_rvlc_rl_inter, 1072); - INIT_VLC_RL(ff_rvlc_rl_intra, 1072); - INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_lum[0][1], 2, 1, - &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512); - INIT_VLC_STATIC(&dc_chrom, DC_VLC_BITS, 10 /* 13 */, - &ff_mpeg4_DCtab_chrom[0][1], 2, 1, - &ff_mpeg4_DCtab_chrom[0][0], 2, 1, 512); - INIT_VLC_STATIC(&sprite_trajectory, SPRITE_TRAJ_VLC_BITS, 15, - &ff_sprite_trajectory_tab[0][1], 4, 2, - &ff_sprite_trajectory_tab[0][0], 4, 2, 128); - INIT_VLC_STATIC(&mb_type_b_vlc, MB_TYPE_B_VLC_BITS, 4, - &ff_mb_type_b_tab[0][1], 2, 1, - &ff_mb_type_b_tab[0][0], 2, 1, 16); - } + 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 */ @@ -2614,6 +3528,35 @@ static av_cold int decode_init(AVCodecContext *avctx) return 0; } +static av_cold int decode_end(AVCodecContext *avctx) +{ + Mpeg4DecContext *ctx = avctx->priv_data; + int i; + + if (!avctx->internal->is_copy) { + for (i = 0; i < 12; i++) + ff_free_vlc(&ctx->studio_intra_tab[i]); + + ff_free_vlc(&ctx->studio_luma_dc); + ff_free_vlc(&ctx->studio_chroma_dc); + } + + return ff_h263_decode_end(avctx); +} + +static const AVOption mpeg4_options[] = { + {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, + {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, + {NULL} +}; + +static const AVClass mpeg4_class = { + .class_name = "MPEG4 Video Decoder", + .item_name = av_default_item_name, + .option = mpeg4_options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_mpeg4_decoder = { .name = "mpeg4", .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), @@ -2621,22 +3564,31 @@ AVCodec ff_mpeg4_decoder = { .id = AV_CODEC_ID_MPEG4, .priv_data_size = sizeof(Mpeg4DecContext), .init = decode_init, - .close = ff_h263_decode_end, + .close = decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, + .flush = ff_mpeg_flush, + .max_lowres = 3, + .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, + .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), + .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context), + .priv_class = &mpeg4_class, .hw_configs = (const AVCodecHWConfigInternal*[]) { +#if CONFIG_MPEG4_NVDEC_HWACCEL + HWACCEL_NVDEC(mpeg4), +#endif #if CONFIG_MPEG4_VAAPI_HWACCEL HWACCEL_VAAPI(mpeg4), #endif #if CONFIG_MPEG4_VDPAU_HWACCEL HWACCEL_VDPAU(mpeg4), #endif +#if CONFIG_MPEG4_VIDEOTOOLBOX_HWACCEL + HWACCEL_VIDEOTOOLBOX(mpeg4), +#endif NULL }, - .flush = ff_mpeg_flush, - .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, - .profiles = NULL_IF_CONFIG_SMALL(ff_mpeg4_video_profiles), - .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context), }; |