1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00
FFmpeg/libavcodec/rv10.c

717 lines
23 KiB
C
Raw Normal View History

/*
* RV10/RV20 decoder
* Copyright (c) 2000,2001 Fabrice Bellard
* Copyright (c) 2002-2004 Michael Niedermayer
*
* This file is part of FFmpeg.
*
* 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.
*
* 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 FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* RV10/RV20 decoder
*/
#include <inttypes.h>
#include "libavutil/imgutils.h"
#include "libavutil/thread.h"
#include "avcodec.h"
#include "error_resilience.h"
#include "h263.h"
#include "h263data.h"
#include "h263dec.h"
#include "internal.h"
#include "mpeg_er.h"
#include "mpegutils.h"
#include "mpegvideo.h"
#include "mpeg4video.h"
#include "mpegvideodata.h"
#include "rv10.h"
#define RV_GET_MAJOR_VER(x) ((x) >> 28)
#define RV_GET_MINOR_VER(x) (((x) >> 20) & 0xFF)
#define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
#define MAX_VLC_ENTRIES 1023 // Note: Does not include the skip entries.
#define DC_VLC_BITS 9
typedef struct RVDecContext {
MpegEncContext m;
int sub_id;
int orig_width, orig_height;
} RVDecContext;
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
/* (run, length) encoded value for the symbols table. The actual symbols
* are run..run - length (mod 256).
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
* The last two entries in the following table apply to luma only.
* The skip values are not included in this list. */
static const uint8_t rv_sym_run_len[][2] = {
{ 0, 0 }, { 1, 0 }, { 255, 0 }, { 3, 1 }, { 254, 1 },
{ 7, 3 }, { 252, 3 }, { 15, 7 }, { 248, 7 }, { 31, 15 },
{ 240, 15 }, { 63, 31 }, { 224, 31 }, { 127, 63 }, { 192, 63 },
{ 255, 127 }, { 128, 127 }, { 127, 255 }, { 128, 255 },
};
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
/* entry[i] of the following tables gives
* the number of VLC codes of length i + 2. */
static const uint16_t rv_lum_len_count[15] = {
1, 0, 2, 4, 8, 16, 32, 0, 64, 0, 128, 0, 256, 0, 512,
};
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
static const uint16_t rv_chrom_len_count[15] = {
1, 2, 4, 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 0, 256,
};
static VLC rv_dc_lum, rv_dc_chrom;
int ff_rv_decode_dc(MpegEncContext *s, int n)
{
int code;
if (n < 4) {
code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2);
} else {
code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2);
if (code < 0) {
av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
return -1;
}
}
return code;
}
/* read RV 1.0 compatible frame header */
static int rv10_decode_picture_header(MpegEncContext *s)
{
2011-06-01 19:26:27 +03:00
int mb_count, pb_frame, marker, mb_xy;
marker = get_bits1(&s->gb);
if (get_bits1(&s->gb))
s->pict_type = AV_PICTURE_TYPE_P;
else
s->pict_type = AV_PICTURE_TYPE_I;
2013-04-09 21:06:44 +03:00
if (!marker)
av_log(s->avctx, AV_LOG_ERROR, "marker missing\n");
pb_frame = get_bits1(&s->gb);
ff_dlog(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame);
2013-04-09 21:06:44 +03:00
if (pb_frame) {
avpriv_request_sample(s->avctx, "PB-frame");
return AVERROR_PATCHWELCOME;
}
s->qscale = get_bits(&s->gb, 5);
2013-04-09 21:06:44 +03:00
if (s->qscale == 0) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n");
return AVERROR_INVALIDDATA;
}
if (s->pict_type == AV_PICTURE_TYPE_I) {
if (s->rv10_version == 3) {
/* specific MPEG like DC coding not used */
s->last_dc[0] = get_bits(&s->gb, 8);
s->last_dc[1] = get_bits(&s->gb, 8);
s->last_dc[2] = get_bits(&s->gb, 8);
ff_dlog(s->avctx, "DC:%d %d %d\n", s->last_dc[0],
s->last_dc[1], s->last_dc[2]);
}
}
/* if multiple packets per frame are sent, the position at which
* to display the macroblocks is coded here */
2013-04-09 21:06:44 +03:00
mb_xy = s->mb_x + s->mb_y * s->mb_width;
if (show_bits(&s->gb, 12) == 0 || (mb_xy && mb_xy < s->mb_num)) {
s->mb_x = get_bits(&s->gb, 6); /* mb_x */
s->mb_y = get_bits(&s->gb, 6); /* mb_y */
mb_count = get_bits(&s->gb, 12);
} else {
2013-04-09 21:06:44 +03:00
s->mb_x = 0;
s->mb_y = 0;
mb_count = s->mb_width * s->mb_height;
}
2011-06-01 19:26:27 +03:00
skip_bits(&s->gb, 3); /* ignored */
s->f_code = 1;
return mb_count;
}
static int rv20_decode_picture_header(RVDecContext *rv, int whole_size)
{
MpegEncContext *s = &rv->m;
int seq, mb_pos, i, ret;
int rpr_max;
2013-04-09 21:06:44 +03:00
i = get_bits(&s->gb, 2);
switch (i) {
case 0:
s->pict_type = AV_PICTURE_TYPE_I;
break;
case 1:
s->pict_type = AV_PICTURE_TYPE_I;
break; // hmm ...
case 2:
s->pict_type = AV_PICTURE_TYPE_P;
break;
case 3:
s->pict_type = AV_PICTURE_TYPE_B;
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n");
return AVERROR_INVALIDDATA;
}
if (s->low_delay && s->pict_type == AV_PICTURE_TYPE_B) {
av_log(s->avctx, AV_LOG_ERROR, "low delay B\n");
return -1;
}
if (!s->last_picture_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n");
return AVERROR_INVALIDDATA;
}
2013-04-09 21:06:44 +03:00
if (get_bits1(&s->gb)) {
av_log(s->avctx, AV_LOG_ERROR, "reserved bit set\n");
return AVERROR_INVALIDDATA;
}
s->qscale = get_bits(&s->gb, 5);
2013-04-09 21:06:44 +03:00
if (s->qscale == 0) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n");
return AVERROR_INVALIDDATA;
}
2013-04-09 21:06:44 +03:00
if (RV_GET_MINOR_VER(rv->sub_id) >= 2)
s->loop_filter = get_bits1(&s->gb) && !s->avctx->lowres;
2013-04-09 21:06:44 +03:00
if (RV_GET_MINOR_VER(rv->sub_id) <= 1)
seq = get_bits(&s->gb, 8) << 7;
else
seq = get_bits(&s->gb, 13) << 2;
rpr_max = s->avctx->extradata[1] & 7;
if (rpr_max) {
int f, new_w, new_h;
int rpr_bits = av_log2(rpr_max) + 1;
f = get_bits(&s->gb, rpr_bits);
2013-04-09 21:06:44 +03:00
if (f) {
if (s->avctx->extradata_size < 8 + 2 * f) {
av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n");
return AVERROR_INVALIDDATA;
}
new_w = 4 * ((uint8_t *) s->avctx->extradata)[6 + 2 * f];
new_h = 4 * ((uint8_t *) s->avctx->extradata)[7 + 2 * f];
2013-04-09 21:06:44 +03:00
} else {
new_w = rv->orig_width;
new_h = rv->orig_height;
}
if (new_w != s->width || new_h != s->height || !s->context_initialized) {
AVRational old_aspect = s->avctx->sample_aspect_ratio;
2013-04-09 21:06:44 +03:00
av_log(s->avctx, AV_LOG_DEBUG,
"attempting to change resolution to %dx%d\n", new_w, new_h);
if (av_image_check_size(new_w, new_h, 0, s->avctx) < 0)
return AVERROR_INVALIDDATA;
if (whole_size < (new_w + 15)/16 * ((new_h + 15)/16) / 8)
return AVERROR_INVALIDDATA;
ff_mpv_common_end(s);
// attempt to keep aspect during typical resolution switches
if (!old_aspect.num)
old_aspect = (AVRational){1, 1};
if (2 * (int64_t)new_w * s->height == (int64_t)new_h * s->width)
s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){2, 1});
if ((int64_t)new_w * s->height == 2 * (int64_t)new_h * s->width)
s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){1, 2});
ret = ff_set_dimensions(s->avctx, new_w, new_h);
if (ret < 0)
return ret;
s->width = new_w;
s->height = new_h;
if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
}
2013-04-09 21:06:44 +03:00
if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d/%d\n", f, rpr_bits, rpr_max);
}
}
if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)
return AVERROR_INVALIDDATA;
mb_pos = ff_h263_decode_mba(s);
2013-04-09 21:06:44 +03:00
seq |= s->time & ~0x7FFF;
if (seq - s->time > 0x4000)
seq -= 0x8000;
if (seq - s->time < -0x4000)
seq += 0x8000;
if (seq != s->time) {
if (s->pict_type != AV_PICTURE_TYPE_B) {
s->time = seq;
s->pp_time = s->time - s->last_non_b_time;
s->last_non_b_time = s->time;
} else {
s->time = seq;
s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
}
}
if (s->pict_type == AV_PICTURE_TYPE_B) {
if (s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0) {
av_log(s->avctx, AV_LOG_DEBUG,
"messed up order, possible from seeking? skipping current B-frame\n");
#define ERROR_SKIP_FRAME -123
return ERROR_SKIP_FRAME;
}
ff_mpeg4_init_direct_mv(s);
}
2013-04-09 21:06:44 +03:00
s->no_rounding = get_bits1(&s->gb);
2013-04-09 21:06:44 +03:00
if (RV_GET_MINOR_VER(rv->sub_id) <= 1 && s->pict_type == AV_PICTURE_TYPE_B)
// binary decoder reads 3+2 bits here but they don't seem to be used
skip_bits(&s->gb, 5);
2013-04-09 21:06:44 +03:00
s->f_code = 1;
s->h263_aic = s->pict_type == AV_PICTURE_TYPE_I;
s->modified_quant = 1;
if (!s->avctx->lowres)
s->loop_filter = 1;
2013-04-09 21:06:44 +03:00
if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
av_log(s->avctx, AV_LOG_INFO,
"num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n",
seq, s->mb_x, s->mb_y, s->pict_type, s->qscale,
s->no_rounding);
}
av_assert0(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
return s->mb_width * s->mb_height - mb_pos;
}
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
static av_cold void rv10_build_vlc(VLC *vlc, const uint16_t len_count[15],
const uint8_t sym_rl[][2], int sym_rl_elems)
{
uint16_t syms[MAX_VLC_ENTRIES];
uint8_t lens[MAX_VLC_ENTRIES];
unsigned nb_syms = 0, nb_lens = 0;
for (unsigned i = 0; i < sym_rl_elems; i++) {
unsigned cur_sym = sym_rl[i][0];
for (unsigned tmp = nb_syms + sym_rl[i][1]; nb_syms <= tmp; nb_syms++)
syms[nb_syms] = 0xFF & cur_sym--;
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
}
for (unsigned i = 0; i < 15; i++)
for (unsigned tmp = nb_lens + len_count[i]; nb_lens < tmp; nb_lens++)
lens[nb_lens] = i + 2;
av_assert1(nb_lens == nb_syms);
ff_init_vlc_from_lengths(vlc, DC_VLC_BITS, nb_lens, lens, 1,
syms, 2, 2, 0, INIT_VLC_STATIC_OVERLONG, NULL);
}
static av_cold void rv10_init_static(void)
{
static VLC_TYPE table[1472 + 992][2];
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
rv_dc_lum.table = table;
rv_dc_lum.table_allocated = 1472;
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
rv10_build_vlc(&rv_dc_lum, rv_lum_len_count,
rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len));
for (int i = 0; i < 1 << (DC_VLC_BITS - 7 /* Length of skip prefix */); i++) {
/* All codes beginning with 0x7F have the same length and value.
* Modifying the table directly saves us the useless subtables. */
rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][0] = 255;
rv_dc_lum.table[(0x7F << (DC_VLC_BITS - 7)) + i][1] = 18;
}
rv_dc_chrom.table = &table[1472];
rv_dc_chrom.table_allocated = 992;
avcodec/rv10: Reduce number of exceptions when reading VLC value RealVideo 1.0 uses an insane way to encode DC coefficients: There are several symbols that (for no good reason whatsoever) have multiple encodings, leading to longer codes than necessary. More specifically, the tree for the 256 luma symbols contains 255 codes belonging to 255 different symbols on the left; going further right, the tree consists of two blocks of 128 codes each of length 14 encoding consecutive numbers (including two encodings for the symbol missing among the 255 codes on the left); this is followed by two blocks of codes of length 16 each containing 256 elements with consecutive symbols (i.e. each of the blocks allows to encode all symbols). The rest of the tree consists of 2^11 codes that all encode the same symbol. The tree for the 256 chroma symbols is similar, but is missing the blocks of length 256 and there are only 2^9 consecutive codes that encode the same symbol; furthermore, the chroma tree is incomplete: The right-most node has no right child. All of this caused problems when parsing these codes; the reason is that the code for this predates commit b613bacca9c256f1483c46847f713e47a0e9a5f6 which added support for explicit symbol tables and thereby removed the requirement that different codes have different symbols. In order to address this, the trees used for parsing were incomplete: They contained the 255 codes on the left and one code for the remaining symbol. Whenever a code not in these trees was encountered, it was dealt with in special cases (one for each of the blocks mentioned above). This commit reduces the number of special cases: Using a symbols table allows to treat the blocks of consecutive symbols like ordinary codes; only the blocks encoding a single symbol are still treated specially (in order not to waste memory on tables for them). In order to not increment the size of the tables used to initialize the VLCs both the symbols as well as the lengths are now run-length encoded. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
2020-10-28 00:26:17 +02:00
rv10_build_vlc(&rv_dc_chrom, rv_chrom_len_count,
rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len) - 2);
for (int i = 0; i < 1 << (DC_VLC_BITS - 9 /* Length of skip prefix */); i++) {
/* Same as above. */
rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][0] = 255;
rv_dc_chrom.table[(0x1FE << (DC_VLC_BITS - 9)) + i][1] = 18;
}
ff_h263_decode_init_vlc();
}
static av_cold int rv10_decode_init(AVCodecContext *avctx)
{
static AVOnce init_static_once = AV_ONCE_INIT;
RVDecContext *rv = avctx->priv_data;
MpegEncContext *s = &rv->m;
int major_ver, minor_ver, micro_ver, ret;
if (avctx->extradata_size < 8) {
av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n");
return AVERROR_INVALIDDATA;
}
if ((ret = av_image_check_size(avctx->coded_width,
avctx->coded_height, 0, avctx)) < 0)
return ret;
ff_mpv_decode_init(s, avctx);
s->out_format = FMT_H263;
rv->orig_width =
s->width = avctx->coded_width;
rv->orig_height =
s->height = avctx->coded_height;
s->h263_long_vectors = ((uint8_t *) avctx->extradata)[3] & 1;
rv->sub_id = AV_RB32((uint8_t *) avctx->extradata + 4);
major_ver = RV_GET_MAJOR_VER(rv->sub_id);
minor_ver = RV_GET_MINOR_VER(rv->sub_id);
micro_ver = RV_GET_MICRO_VER(rv->sub_id);
s->low_delay = 1;
switch (major_ver) {
case 1:
s->rv10_version = micro_ver ? 3 : 1;
2013-04-09 21:06:44 +03:00
s->obmc = micro_ver == 2;
break;
case 2:
if (minor_ver >= 2) {
2013-04-09 21:06:44 +03:00
s->low_delay = 0;
s->avctx->has_b_frames = 1;
}
break;
default:
av_log(s->avctx, AV_LOG_ERROR, "unknown header %X\n", rv->sub_id);
avpriv_request_sample(avctx, "RV1/2 version");
return AVERROR_PATCHWELCOME;
}
2013-04-09 21:06:44 +03:00
if (avctx->debug & FF_DEBUG_PICT_INFO) {
av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%"PRIX32"\n", rv->sub_id,
((uint32_t *) avctx->extradata)[0]);
}
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
ff_mpv_idct_init(s);
if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
ff_h263dsp_init(&s->h263dsp);
/* init static VLCs */
ff_thread_once(&init_static_once, rv10_init_static);
return 0;
}
static av_cold int rv10_decode_end(AVCodecContext *avctx)
{
MpegEncContext *s = avctx->priv_data;
ff_mpv_common_end(s);
return 0;
}
static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf,
int buf_size, int buf_size2, int whole_size)
{
RVDecContext *rv = avctx->priv_data;
MpegEncContext *s = &rv->m;
int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret;
active_bits_size = buf_size * 8;
init_get_bits(&s->gb, buf, FFMAX(buf_size, buf_size2) * 8);
2013-04-09 21:06:44 +03:00
if (s->codec_id == AV_CODEC_ID_RV10)
mb_count = rv10_decode_picture_header(s);
else
mb_count = rv20_decode_picture_header(rv, whole_size);
if (mb_count < 0) {
if (mb_count != ERROR_SKIP_FRAME)
av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");
return AVERROR_INVALIDDATA;
}
if (s->mb_x >= s->mb_width ||
s->mb_y >= s->mb_height) {
av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y);
return AVERROR_INVALIDDATA;
}
mb_pos = s->mb_y * s->mb_width + s->mb_x;
left = s->mb_width * s->mb_height - mb_pos;
if (mb_count > left) {
av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n");
return AVERROR_INVALIDDATA;
}
if (whole_size < s->mb_width * s->mb_height / 8)
return AVERROR_INVALIDDATA;
if ((s->mb_x == 0 && s->mb_y == 0) || !s->current_picture_ptr) {
// FIXME write parser so we always have complete frames?
if (s->current_picture_ptr) {
ff_er_frame_end(&s->er);
ff_mpv_frame_end(s);
2013-04-09 21:06:44 +03:00
s->mb_x = s->mb_y = s->resync_mb_x = s->resync_mb_y = 0;
}
if ((ret = ff_mpv_frame_start(s, avctx)) < 0)
return ret;
ff_mpeg_er_frame_start(s);
} else {
if (s->current_picture_ptr->f->pict_type != s->pict_type) {
av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
return AVERROR_INVALIDDATA;
}
}
ff_dlog(avctx, "qscale=%d\n", s->qscale);
/* default quantization values */
2013-04-09 21:06:44 +03:00
if (s->codec_id == AV_CODEC_ID_RV10) {
if (s->mb_y == 0)
s->first_slice_line = 1;
} else {
s->first_slice_line = 1;
s->resync_mb_x = s->mb_x;
}
2013-04-09 21:06:44 +03:00
start_mb_x = s->mb_x;
s->resync_mb_y = s->mb_y;
if (s->h263_aic) {
s->y_dc_scale_table =
s->c_dc_scale_table = ff_aic_dc_scale_table;
2013-04-09 21:06:44 +03:00
} else {
s->y_dc_scale_table =
s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
}
2013-04-09 21:06:44 +03:00
if (s->modified_quant)
s->chroma_qscale_table = ff_h263_chroma_qscale_table;
ff_set_qscale(s, s->qscale);
s->rv10_first_dc_coded[0] = 0;
s->rv10_first_dc_coded[1] = 0;
s->rv10_first_dc_coded[2] = 0;
2013-04-09 21:06:44 +03:00
s->block_wrap[0] =
s->block_wrap[1] =
s->block_wrap[2] =
s->block_wrap[3] = s->b8_stride;
s->block_wrap[4] =
s->block_wrap[5] = s->mb_stride;
ff_init_block_index(s);
2013-04-09 21:06:44 +03:00
/* decode each macroblock */
for (s->mb_num_left = mb_count; s->mb_num_left > 0; s->mb_num_left--) {
int ret;
ff_update_block_index(s);
ff_tlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y);
2013-04-09 21:06:44 +03:00
s->mv_dir = MV_DIR_FORWARD;
s->mv_type = MV_TYPE_16X16;
2013-04-09 21:06:44 +03:00
ret = ff_h263_decode_mb(s, s->block);
// Repeat the slice end check from ff_h263_decode_mb with our active
// bitstream size
if (ret != SLICE_ERROR && active_bits_size >= get_bits_count(&s->gb)) {
int v = show_bits(&s->gb, 16);
if (get_bits_count(&s->gb) + 16 > active_bits_size)
v >>= get_bits_count(&s->gb) + 16 - active_bits_size;
if (!v)
ret = SLICE_END;
}
if (ret != SLICE_ERROR && active_bits_size < get_bits_count(&s->gb) &&
8 * buf_size2 >= get_bits_count(&s->gb)) {
active_bits_size = buf_size2 * 8;
av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n",
8 * buf_size, active_bits_size);
2013-04-09 21:06:44 +03:00
ret = SLICE_OK;
}
if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) {
av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x,
s->mb_y);
return AVERROR_INVALIDDATA;
}
2013-04-09 21:06:44 +03:00
if (s->pict_type != AV_PICTURE_TYPE_B)
ff_h263_update_motion_val(s);
ff_mpv_reconstruct_mb(s, s->block);
2013-04-09 21:06:44 +03:00
if (s->loop_filter)
ff_h263_loop_filter(s);
if (++s->mb_x == s->mb_width) {
s->mb_x = 0;
s->mb_y++;
ff_init_block_index(s);
}
2013-04-09 21:06:44 +03:00
if (s->mb_x == s->resync_mb_x)
s->first_slice_line = 0;
if (ret == SLICE_END)
break;
}
ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x - 1, s->mb_y,
2013-04-09 21:06:44 +03:00
ER_MB_END);
return active_bits_size;
}
static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
{
2013-04-09 21:06:44 +03:00
if (avctx->slice_count)
return avctx->slice_offset[n];
else
return AV_RL32(buf + n * 8);
}
static int rv10_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
2013-04-09 21:06:44 +03:00
int buf_size = avpkt->size;
MpegEncContext *s = avctx->priv_data;
AVFrame *pict = data;
int i, ret;
int slice_count;
const uint8_t *slices_hdr = NULL;
ff_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
/* no supplementary picture */
if (buf_size == 0) {
return 0;
}
2013-04-09 21:06:44 +03:00
if (!avctx->slice_count) {
slice_count = (*buf++) + 1;
buf_size--;
if (!slice_count || buf_size <= 8 * slice_count) {
av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n",
slice_count);
return AVERROR_INVALIDDATA;
}
slices_hdr = buf + 4;
2013-04-09 21:06:44 +03:00
buf += 8 * slice_count;
buf_size -= 8 * slice_count;
} else
slice_count = avctx->slice_count;
2013-04-09 21:06:44 +03:00
for (i = 0; i < slice_count; i++) {
unsigned offset = get_slice_offset(avctx, slices_hdr, i);
int size, size2;
if (offset >= buf_size)
return AVERROR_INVALIDDATA;
2013-04-09 21:06:44 +03:00
if (i + 1 == slice_count)
size = buf_size - offset;
else
2013-04-09 21:06:44 +03:00
size = get_slice_offset(avctx, slices_hdr, i + 1) - offset;
2013-04-09 21:06:44 +03:00
if (i + 2 >= slice_count)
size2 = buf_size - offset;
else
2013-04-09 21:06:44 +03:00
size2 = get_slice_offset(avctx, slices_hdr, i + 2) - offset;
if (size <= 0 || size2 <= 0 ||
offset + FFMAX(size, size2) > buf_size)
return AVERROR_INVALIDDATA;
if ((ret = rv10_decode_packet(avctx, buf + offset, size, size2, buf_size)) < 0)
return ret;
if (ret > 8 * size)
i++;
}
if (s->current_picture_ptr && s->mb_y >= s->mb_height) {
ff_er_frame_end(&s->er);
ff_mpv_frame_end(s);
if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
return ret;
ff_print_debug_info(s, s->current_picture_ptr, pict);
ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG1);
} else if (s->last_picture_ptr) {
if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)
return ret;
ff_print_debug_info(s, s->last_picture_ptr, pict);
ff_mpv_export_qp_table(s, pict,s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
}
2013-04-09 21:06:44 +03:00
if (s->last_picture_ptr || s->low_delay) {
*got_frame = 1;
}
2013-04-09 21:06:44 +03:00
// so we can detect if frame_end was not called (find some nicer solution...)
s->current_picture_ptr = NULL;
}
return avpkt->size;
}
const AVCodec ff_rv10_decoder = {
.name = "rv10",
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_RV10,
.priv_data_size = sizeof(RVDecContext),
.init = rv10_decode_init,
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
.max_lowres = 3,
2014-03-17 20:03:47 +03:00
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
},
};
const AVCodec ff_rv20_decoder = {
.name = "rv20",
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_RV20,
.priv_data_size = sizeof(RVDecContext),
.init = rv10_decode_init,
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.flush = ff_mpeg_flush,
.max_lowres = 3,
2014-03-17 20:03:47 +03:00
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_NONE
},
};