|
|
|
@ -26,18 +26,19 @@ |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#include "libavutil/imgutils.h" |
|
|
|
|
|
|
|
|
|
#include "avcodec.h" |
|
|
|
|
#include "error_resilience.h" |
|
|
|
|
#include "h263.h" |
|
|
|
|
#include "internal.h" |
|
|
|
|
#include "mpegvideo.h" |
|
|
|
|
#include "mpeg4video.h" |
|
|
|
|
#include "h263.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; |
|
|
|
@ -194,18 +195,18 @@ int ff_rv_decode_dc(MpegEncContext *s, int n) |
|
|
|
|
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; |
|
|
|
@ -219,7 +220,7 @@ int ff_rv_decode_dc(MpegEncContext *s, int n) |
|
|
|
|
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) { |
|
|
|
@ -277,7 +278,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* 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)) { |
|
|
|
@ -290,7 +291,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) |
|
|
|
|
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; |
|
|
|
@ -304,10 +305,18 @@ static int rv20_decode_picture_header(RVDecContext *rv) |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
@ -350,10 +359,10 @@ static int rv20_decode_picture_header(RVDecContext *rv) |
|
|
|
|
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_w = s->orig_width; |
|
|
|
|
new_h = s->orig_height; |
|
|
|
|
} |
|
|
|
|
if (new_w != s->width || new_h != s->height) { |
|
|
|
@ -406,7 +415,8 @@ static int rv20_decode_picture_header(RVDecContext *rv) |
|
|
|
|
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; |
|
|
|
@ -415,18 +425,20 @@ static int rv20_decode_picture_header(RVDecContext *rv) |
|
|
|
|
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; |
|
|
|
@ -441,15 +453,17 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
|
|
ff_MPV_decode_defaults(s); |
|
|
|
|
|
|
|
|
|
s->avctx = avctx; |
|
|
|
|
s->out_format = FMT_H263; |
|
|
|
|
s->codec_id = avctx->codec_id; |
|
|
|
|
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; |
|
|
|
|
s->orig_width = |
|
|
|
|
s->width = avctx->coded_width; |
|
|
|
|
s->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); |
|
|
|
@ -475,7 +489,8 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) |
|
|
|
|
|
|
|
|
|
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 ? ((uint32_t *) avctx->extradata)[0] |
|
|
|
|
: -1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avctx->pix_fmt = AV_PIX_FMT_YUV420P; |
|
|
|
@ -508,10 +523,10 @@ static av_cold int rv10_decode_end(AVCodecContext *avctx) |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
@ -532,14 +547,15 @@ static int rv10_decode_packet(AVCodecContext *avctx, |
|
|
|
|
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?
|
|
|
|
|
// 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; |
|
|
|
@ -567,9 +583,11 @@ static int rv10_decode_packet(AVCodecContext *avctx, |
|
|
|
|
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) |
|
|
|
@ -618,7 +636,8 @@ static int rv10_decode_packet(AVCodecContext *avctx, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
@ -638,7 +657,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, |
|
|
|
|
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; |
|
|
|
@ -652,14 +671,13 @@ static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) |
|
|
|
|
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; |
|
|
|
@ -676,7 +694,8 @@ static int rv10_decode_frame(AVCodecContext *avctx, |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|