* RV10/RV20 decoder
*/
+#include <inttypes.h>
+
#include "libavutil/imgutils.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 "h263.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 DC_VLC_BITS 14 //FIXME find a better solution
+#define DC_VLC_BITS 14 // FIXME find a better solution
typedef struct RVDecContext {
MpegEncContext m;
int sub_id;
+ int orig_width, orig_height;
} RVDecContext;
static const uint16_t rv_lum_code[256] = {
code = get_vlc2(&s->gb, rv_dc_lum.table, DC_VLC_BITS, 2);
if (code < 0) {
/* XXX: I don't understand why they use LONGER codes than
- necessary. The following code would be completely useless
- if they had thought about it !!! */
+ * necessary. The following code would be completely useless
+ * if they had thought about it !!! */
code = get_bits(&s->gb, 7);
if (code == 0x7c) {
- code = (int8_t)(get_bits(&s->gb, 7) + 1);
+ code = (int8_t) (get_bits(&s->gb, 7) + 1);
} else if (code == 0x7d) {
code = -128 + get_bits(&s->gb, 7);
} else if (code == 0x7e) {
if (get_bits1(&s->gb) == 0)
- code = (int8_t)(get_bits(&s->gb, 8) + 1);
+ code = (int8_t) (get_bits(&s->gb, 8) + 1);
else
- code = (int8_t)(get_bits(&s->gb, 8));
+ code = (int8_t) (get_bits(&s->gb, 8));
} else if (code == 0x7f) {
skip_bits(&s->gb, 11);
code = 1;
if (code < 0) {
code = get_bits(&s->gb, 9);
if (code == 0x1fc) {
- code = (int8_t)(get_bits(&s->gb, 7) + 1);
+ code = (int8_t) (get_bits(&s->gb, 7) + 1);
} else if (code == 0x1fd) {
code = -128 + get_bits(&s->gb, 7);
} else if (code == 0x1fe) {
pb_frame = get_bits1(&s->gb);
- av_dlog(s->avctx, "pict_type=%d pb_frame=%d\n", s->pict_type, pb_frame);
+ 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");
+ avpriv_request_sample(s->avctx, "PB-frame");
return AVERROR_PATCHWELCOME;
}
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);
- av_dlog(s->avctx, "DC:%d %d %d\n", s->last_dc[0],
+ 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 */
+ * 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)) {
mb_count = s->mb_width * s->mb_height;
}
skip_bits(&s->gb, 3); /* ignored */
- s->f_code = 1;
+ s->f_code = 1;
s->unrestricted_mv = 1;
return mb_count;
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;
+ 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->last_picture_ptr == NULL && s->pict_type == AV_PICTURE_TYPE_B) {
+ 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;
}
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];
+ 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 = s->orig_width ;
- new_h = s->orig_height;
+ new_w = rv->orig_width;
+ new_h = rv->orig_height;
}
if (new_w != s->width || new_h != s->height) {
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);
- avcodec_set_dimensions(s->avctx, new_w, new_h);
+ ff_mpv_common_end(s);
+
+ 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)
+ if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
}
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");
+ "from seeking? skipping current B-frame\n");
return FRAME_SKIPPED;
}
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)
- skip_bits(&s->gb, 5); // binary decoder reads 3+2 bits here but they don't seem to be used
+ // 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->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_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);
}
assert(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
- return s->mb_width*s->mb_height - mb_pos;
+ return s->mb_width * s->mb_height - mb_pos;
}
static av_cold int rv10_decode_init(AVCodecContext *avctx)
{
- RVDecContext *rv = avctx->priv_data;
+ RVDecContext *rv = avctx->priv_data;
MpegEncContext *s = &rv->m;
static int done = 0;
int major_ver, minor_ver, micro_ver, ret;
avctx->coded_height, 0, avctx)) < 0)
return ret;
- ff_MPV_decode_defaults(s);
+ ff_mpv_decode_defaults(s);
- s->avctx = avctx;
- s->out_format = FMT_H263;
- s->codec_id = avctx->codec_id;
- avctx->flags |= CODEC_FLAG_EMU_EDGE;
+ s->avctx = avctx;
+ s->out_format = FMT_H263;
+ s->codec_id = avctx->codec_id;
- s->orig_width = s->width = avctx->coded_width;
- s->orig_height = s->height = avctx->coded_height;
+ 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);
+ 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);
if (avctx->debug & FF_DEBUG_PICT_INFO) {
av_log(avctx, AV_LOG_DEBUG, "ver:%X ver0:%X\n", rv->sub_id,
- avctx->extradata_size >= 4 ? ((uint32_t*)avctx->extradata)[0] : -1);
+ avctx->extradata_size >= 4 ? ((int *) avctx->extradata)[0] : -1);
}
avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- if ((ret = ff_MPV_common_init(s)) < 0)
+ ff_mpv_idct_init(s);
+ if ((ret = ff_mpv_common_init(s)) < 0)
return ret;
+ ff_h263dsp_init(&s->h263dsp);
ff_h263_decode_init_vlc();
/* init rv vlc */
{
MpegEncContext *s = avctx->priv_data;
- ff_MPV_common_end(s);
+ ff_mpv_common_end(s);
return 0;
}
-static int rv10_decode_packet(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size, int buf_size2)
+static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf,
+ int buf_size, int buf_size2)
{
- RVDecContext *rv = avctx->priv_data;
+ RVDecContext *rv = avctx->priv_data;
MpegEncContext *s = &rv->m;
int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret;
return AVERROR_INVALIDDATA;
}
mb_pos = s->mb_y * s->mb_width + s->mb_x;
- left = s->mb_width * s->mb_height - mb_pos;
+ 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 ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr == NULL) {
- if (s->current_picture_ptr) { // FIXME write parser so we always have complete frames?
+ 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);
+ 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)
+ 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) {
+ 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;
}
}
- av_dlog(avctx, "qscale=%d\n", s->qscale);
+ ff_dlog(avctx, "qscale=%d\n", s->qscale);
/* default quantization values */
if (s->codec_id == AV_CODEC_ID_RV10) {
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;
+ 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;
+ s->y_dc_scale_table =
+ s->c_dc_scale_table = ff_mpeg1_dc_scale_table;
}
if (s->modified_quant)
for (s->mb_num_left = mb_count; s->mb_num_left > 0; s->mb_num_left--) {
int ret;
ff_update_block_index(s);
- av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y);
+ ff_dlog(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;
}
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);
+ 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_decode_mb(s, s->block);
+ ff_mpv_decode_mb(s, s->block);
if (s->loop_filter)
ff_h263_loop_filter(s);
break;
}
- ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y,
+ 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;
return AV_RL32(buf + n * 8);
}
-static int rv10_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
+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;
+ MpegEncContext *s = avctx->priv_data;
+ AVFrame *pict = data;
int i, ret;
int slice_count;
const uint8_t *slices_hdr = NULL;
- av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
+ ff_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
/* no supplementary picture */
if (buf_size == 0) {
buf_size--;
if (!slice_count || buf_size <= 8 * slice_count) {
- av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n", slice_count);
+ av_log(avctx, AV_LOG_ERROR, "Invalid slice count: %d.\n",
+ slice_count);
return AVERROR_INVALIDDATA;
}
offset + FFMAX(size, size2) > buf_size)
return AVERROR_INVALIDDATA;
- if (rv10_decode_packet(avctx, buf + offset, size, size2) > 8 * size)
+ if ((ret = rv10_decode_packet(avctx, buf + offset, size, size2)) < 0)
+ return ret;
+
+ if (ret > 8 * size)
i++;
}
- if (s->current_picture_ptr != NULL && s->mb_y >= s->mb_height) {
+ if (s->current_picture_ptr && s->mb_y >= s->mb_height) {
ff_er_frame_end(&s->er);
- ff_MPV_frame_end(s);
+ 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)
+ if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
return ret;
ff_print_debug_info(s, s->current_picture_ptr);
- } else if (s->last_picture_ptr != NULL) {
- if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+ } 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);
}
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 = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
- .pix_fmts = ff_pixfmt_list_420,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .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 = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
.flush = ff_mpeg_flush,
- .long_name = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
- .pix_fmts = ff_pixfmt_list_420,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
};