mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-12 19:18:44 +02:00
d4b9e117ce
This mostly reverts commit4b2863ff01
. Said commit removed the freeing code from ff_mpv_common_init(), ff_mpv_common_frame_size_change() and ff_mpeg_framesize_alloc() and instead added the FF_CODEC_CAP_INIT_CLEANUP to several codecs that use ff_mpv_common_init(). This introduced several bugs: a) Several decoders using ff_mpv_common_init() in their init function were forgotten: This affected FLV, Intel H.263, RealVideo 3.0 and V4.0 as well as VC-1/WMV3. b) ff_mpv_common_init() is not only called from the init function of codecs, it is also called from AVCodec.decode functions. If an error happens after an allocation has succeeded, it can lead to memleaks; furthermore, it is now possible for the MpegEncContext to be marked as initialized even when ff_mpv_common_init() returns an error and this can lead to segfaults because decoders that call ff_mpv_common_init() when decoding a frame can mistakenly think that the MpegEncContext has been properly initialized. This can e.g. happen with H.261 or MPEG-4. c) Removing code for freeing from ff_mpeg_framesize_alloc() (which can't be called from any init function) can lead to segfaults because the check for whether it needs to allocate consists of checking whether the first of the buffers allocated there has been allocated. This part has already been fixed in76cea1d2ce
. d) ff_mpv_common_frame_size_change() can also not be reached from any AVCodec.init function; yet the changes can e.g. lead to segfaults with decoders using ff_h263_decode_frame() upon allocation failure, because the MpegEncContext will upon return be flagged as both initialized and not in need of reinitialization (granted, the fact that ff_h263_decode_frame() clears context_reinit before the context has been reinited is a bug in itself). With the earlier version, the context would be cleaned upon failure and it would be attempted to initialize the context again in the next call to ff_h263_decode_frame(). While a) could be fixed by adding the missing FF_CODEC_CAP_INIT_CLEANUP, keeping the current approach would entail adding cleanup code to several other places because of b). Therefore ff_mpv_common_init() is again made to clean up after itself; the changes to the wmv2 decoder and the SVQ1 encoder have not been reverted: The former fixed a memleak, the latter allowed to remove cleanup code. Fixes: double free Fixes: ff_free_picture_tables.mp4 Fixes: ff_mpeg_update_thread_context.mp4 Fixes: decode_colskip.mp4 Fixes: memset.mp4 Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
714 lines
22 KiB
C
714 lines
22 KiB
C
/*
|
|
* 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 "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)
|
|
|
|
#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;
|
|
|
|
/* (run, length) encoded value for the symbols table. The actual symbols
|
|
* are run..run - length (mod 256).
|
|
* 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 },
|
|
};
|
|
|
|
/* 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,
|
|
};
|
|
|
|
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)
|
|
{
|
|
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;
|
|
|
|
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);
|
|
|
|
if (pb_frame) {
|
|
avpriv_request_sample(s->avctx, "PB-frame");
|
|
return AVERROR_PATCHWELCOME;
|
|
}
|
|
|
|
s->qscale = get_bits(&s->gb, 5);
|
|
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 */
|
|
|
|
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 {
|
|
s->mb_x = 0;
|
|
s->mb_y = 0;
|
|
mb_count = s->mb_width * s->mb_height;
|
|
}
|
|
skip_bits(&s->gb, 3); /* ignored */
|
|
s->f_code = 1;
|
|
s->unrestricted_mv = 1;
|
|
|
|
return mb_count;
|
|
}
|
|
|
|
static int rv20_decode_picture_header(RVDecContext *rv)
|
|
{
|
|
MpegEncContext *s = &rv->m;
|
|
int seq, mb_pos, i, ret;
|
|
int rpr_max;
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
if (s->qscale == 0) {
|
|
av_log(s->avctx, AV_LOG_ERROR, "Invalid qscale value: 0\n");
|
|
return AVERROR_INVALIDDATA;
|
|
}
|
|
|
|
if (RV_GET_MINOR_VER(rv->sub_id) >= 2)
|
|
s->loop_filter = get_bits1(&s->gb) && !s->avctx->lowres;
|
|
|
|
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);
|
|
|
|
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];
|
|
} else {
|
|
new_w = rv->orig_width;
|
|
new_h = rv->orig_height;
|
|
}
|
|
if (new_w != s->width || new_h != s->height) {
|
|
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;
|
|
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;
|
|
}
|
|
|
|
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);
|
|
|
|
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);
|
|
}
|
|
|
|
s->no_rounding = get_bits1(&s->gb);
|
|
|
|
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);
|
|
|
|
s->f_code = 1;
|
|
s->unrestricted_mv = 1;
|
|
s->h263_aic = s->pict_type == AV_PICTURE_TYPE_I;
|
|
s->modified_quant = 1;
|
|
if (!s->avctx->lowres)
|
|
s->loop_filter = 1;
|
|
|
|
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;
|
|
}
|
|
|
|
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--;
|
|
}
|
|
|
|
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];
|
|
|
|
rv_dc_lum.table = table;
|
|
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));
|
|
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();
|
|
}
|
|
|
|
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;
|
|
s->obmc = micro_ver == 2;
|
|
break;
|
|
case 2:
|
|
if (minor_ver >= 2) {
|
|
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;
|
|
}
|
|
|
|
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);
|
|
if (s->codec_id == AV_CODEC_ID_RV10)
|
|
mb_count = rv10_decode_picture_header(s);
|
|
else
|
|
mb_count = rv20_decode_picture_header(rv);
|
|
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);
|
|
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 */
|
|
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;
|
|
}
|
|
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;
|
|
} else {
|
|
s->y_dc_scale_table =
|
|
s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
|
|
}
|
|
|
|
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;
|
|
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);
|
|
|
|
/* 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);
|
|
|
|
s->mv_dir = MV_DIR_FORWARD;
|
|
s->mv_type = MV_TYPE_16X16;
|
|
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);
|
|
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;
|
|
}
|
|
if (s->pict_type != AV_PICTURE_TYPE_B)
|
|
ff_h263_update_motion_val(s);
|
|
ff_mpv_reconstruct_mb(s, s->block);
|
|
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);
|
|
}
|
|
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,
|
|
ER_MB_END);
|
|
|
|
return active_bits_size;
|
|
}
|
|
|
|
static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
|
|
{
|
|
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;
|
|
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;
|
|
}
|
|
|
|
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;
|
|
buf += 8 * slice_count;
|
|
buf_size -= 8 * slice_count;
|
|
} else
|
|
slice_count = avctx->slice_count;
|
|
|
|
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;
|
|
|
|
if (i + 1 == slice_count)
|
|
size = buf_size - offset;
|
|
else
|
|
size = get_slice_offset(avctx, slices_hdr, i + 1) - offset;
|
|
|
|
if (i + 2 >= slice_count)
|
|
size2 = buf_size - offset;
|
|
else
|
|
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);
|
|
}
|
|
|
|
if (s->last_picture_ptr || s->low_delay) {
|
|
*got_frame = 1;
|
|
}
|
|
|
|
// so we can detect if frame_end was not called (find some nicer solution...)
|
|
s->current_picture_ptr = NULL;
|
|
}
|
|
|
|
return avpkt->size;
|
|
}
|
|
|
|
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,
|
|
.pix_fmts = (const enum AVPixelFormat[]) {
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NONE
|
|
},
|
|
};
|
|
|
|
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,
|
|
.pix_fmts = (const enum AVPixelFormat[]) {
|
|
AV_PIX_FMT_YUV420P,
|
|
AV_PIX_FMT_NONE
|
|
},
|
|
};
|