#define RV_GET_MICRO_VER(x) (((x) >> 12) & 0xFF)
#define MAX_VLC_ENTRIES 1023 // Note: Does not include the skip entries.
-#define DC_VLC_BITS 14 // FIXME find a better solution
+#define DC_VLC_BITS 9
typedef struct RVDecContext {
MpegEncContext m;
if (n < 4) {
code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2);
- if (code < 0) {
- /* Skip entry - no error. */
- skip_bits(&s->gb, 18);
- code = 255;
- }
} else {
code = get_vlc2(&s->gb, rv_dc_chrom.table, DC_VLC_BITS, 2);
if (code < 0) {
- if (show_bits(&s->gb, 9) == 0x1FE) {
- /* Skip entry - no error. */
- skip_bits(&s->gb, 18);
- code = 255;
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
- return -1;
- }
+ av_log(s->avctx, AV_LOG_ERROR, "chroma dc error\n");
+ return -1;
}
}
return code;
return mb_count;
}
-static int rv20_decode_picture_header(RVDecContext *rv)
+static int rv20_decode_picture_header(RVDecContext *rv, int whole_size)
{
MpegEncContext *s = &rv->m;
int seq, mb_pos, i, ret;
new_w = rv->orig_width;
new_h = rv->orig_height;
}
- if (new_w != s->width || new_h != s->height) {
+ if (new_w != s->width || new_h != s->height || !s->context_initialized) {
AVRational old_aspect = s->avctx->sample_aspect_ratio;
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
static av_cold void rv10_init_static(void)
{
- static VLC_TYPE table[16896 + 16640][2];
+ static VLC_TYPE table[1472 + 992][2];
rv_dc_lum.table = table;
- rv_dc_lum.table_allocated = 16896;
+ rv_dc_lum.table_allocated = 1472;
rv10_build_vlc(&rv_dc_lum, rv_lum_len_count,
rv_sym_run_len, FF_ARRAY_ELEMS(rv_sym_run_len));
- rv_dc_chrom.table = &table[16896];
- rv_dc_chrom.table_allocated = 16640;
+ 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;
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();
}
avctx->coded_height, 0, avctx)) < 0)
return ret;
- ff_mpv_decode_defaults(s);
ff_mpv_decode_init(s, avctx);
s->out_format = FMT_H263;
if (s->codec_id == AV_CODEC_ID_RV10)
mb_count = rv10_decode_picture_header(s);
else
- mb_count = rv20_decode_picture_header(rv);
+ 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 avpkt->size;
}
-AVCodec ff_rv10_decoder = {
+const AVCodec ff_rv10_decoder = {
.name = "rv10",
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
.type = AVMEDIA_TYPE_VIDEO,
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {
AV_PIX_FMT_YUV420P,
},
};
-AVCodec ff_rv20_decoder = {
+const AVCodec ff_rv20_decoder = {
.name = "rv20",
.long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
.type = AVMEDIA_TYPE_VIDEO,
.close = rv10_decode_end,
.decode = rv10_decode_frame,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
- .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
.flush = ff_mpeg_flush,
.max_lowres = 3,
.pix_fmts = (const enum AVPixelFormat[]) {