Commit b40cd4e0 authored by Michael Niedermayer's avatar Michael Niedermayer

rv20 (h263) b frame decoding support

Originally committed as revision 2561 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 6952f123
This diff is collapsed.
......@@ -29,6 +29,49 @@ const uint8_t inter_MCBPC_bits[28] = {
11, 13, 13, 13,/* inter4Q*/
};
static const uint8_t h263_mbtype_b_tab[15][2] = {
{1, 1},
{3, 3},
{1, 5},
{4, 4},
{5, 4},
{6, 6},
{2, 4},
{3, 4},
{7, 6},
{4, 6},
{5, 6},
{1, 6},
{1,10},
{1, 7},
{1, 8},
};
static const int h263_mb_type_b_map[15]= {
MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT,
MB_TYPE_L1,
MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
MB_TYPE_L0L1,
MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
0, //stuffing
MB_TYPE_INTRA | MB_TYPE_CBP,
MB_TYPE_INTRA | MB_TYPE_CBP | MB_TYPE_QUANT,
};
const uint8_t cbpc_b_tab[4][2] = {
{0, 1},
{2, 2},
{7, 3},
{6, 3},
};
const uint8_t cbpy_tab[16][2] =
{
{3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4},
......
......@@ -1109,7 +1109,7 @@ static int mpeg_decode_mb(MpegEncContext *s,
}
} else {
if (mb_type & MB_TYPE_ZERO_MV){
assert(mb_type & MB_TYPE_PAT);
assert(mb_type & MB_TYPE_CBP);
/* compute dct type */
if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var?
......@@ -1140,7 +1140,7 @@ static int mpeg_decode_mb(MpegEncContext *s,
/* compute dct type */
if (s->picture_structure == PICT_FRAME && //FIXME add a interlaced_dct coded var?
!s->frame_pred_frame_dct && IS_PAT(mb_type)) {
!s->frame_pred_frame_dct && HAS_CBP(mb_type)) {
s->interlaced_dct = get_bits1(&s->gb);
}
......@@ -1266,7 +1266,7 @@ static int mpeg_decode_mb(MpegEncContext *s,
s->mb_intra = 0;
if (IS_PAT(mb_type)) {
if (HAS_CBP(mb_type)) {
cbp = get_vlc2(&s->gb, mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
if (cbp < 0){
av_log(s->avctx, AV_LOG_ERROR, "invalid cbp at %d %d\n", s->mb_x, s->mb_y);
......
......@@ -283,10 +283,8 @@ static const uint8_t mbPatTable[63][2] = {
{0xc, 6}
};
#define MB_TYPE_PAT 0x40000000
#define MB_TYPE_ZERO_MV 0x20000000
#define IS_ZERO_MV(a) ((a)&MB_TYPE_ZERO_MV)
#define IS_PAT(a) ((a)&MB_TYPE_PAT)
static const uint8_t table_mb_ptype[7][2] = {
{ 3, 5 }, // 0x01 MB_INTRA
......@@ -300,12 +298,12 @@ static const uint8_t table_mb_ptype[7][2] = {
static const uint32_t ptype2mb_type[7] = {
MB_TYPE_INTRA,
MB_TYPE_L0 | MB_TYPE_PAT | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_PAT,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_PAT | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_PAT,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
};
static const uint8_t table_mb_btype[11][2] = {
......@@ -325,15 +323,15 @@ static const uint8_t table_mb_btype[11][2] = {
static const uint32_t btype2mb_type[11] = {
MB_TYPE_INTRA,
MB_TYPE_L1,
MB_TYPE_L1 | MB_TYPE_PAT,
MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_L0,
MB_TYPE_L0 | MB_TYPE_PAT,
MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_L0L1,
MB_TYPE_L0L1 | MB_TYPE_PAT,
MB_TYPE_L0L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_INTRA,
MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_PAT,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_PAT,
MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_PAT,
MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
};
static const uint8_t mbMotionVectorTable[17][2] = {
......
......@@ -265,6 +265,8 @@ static void copy_picture(Picture *dst, Picture *src){
static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) doesnt sig11
const int mb_array_size= s->mb_stride*s->mb_height;
const int b8_array_size= s->b8_stride*s->mb_height*2;
const int b4_array_size= s->b4_stride*s->mb_height*4;
int i;
if(shared){
......@@ -310,8 +312,14 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
pic->mb_type= pic->mb_type_base + s->mb_stride+1;
if(s->out_format == FMT_H264){
for(i=0; i<2; i++){
CHECKED_ALLOCZ(pic->motion_val[i], 2 * 16 * s->mb_num * sizeof(uint16_t))
CHECKED_ALLOCZ(pic->ref_index[i] , 4 * s->mb_num * sizeof(uint8_t))
CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b4_array_size+1) * sizeof(uint16_t))
pic->motion_val[i]= pic->motion_val_base[i]+1;
CHECKED_ALLOCZ(pic->ref_index[i] , b8_array_size * sizeof(uint8_t))
}
}else if(s->out_format == FMT_H263){
for(i=0; i<2; i++){
CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+1) * sizeof(uint16_t))
pic->motion_val[i]= pic->motion_val_base[i]+1;
}
}
pic->qstride= s->mb_stride;
......@@ -348,7 +356,7 @@ static void free_picture(MpegEncContext *s, Picture *pic){
av_freep(&pic->pan_scan);
pic->mb_type= NULL;
for(i=0; i<2; i++){
av_freep(&pic->motion_val[i]);
av_freep(&pic->motion_val_base[i]);
av_freep(&pic->ref_index[i]);
}
......@@ -374,6 +382,8 @@ int MPV_common_init(MpegEncContext *s)
s->mb_width = (s->width + 15) / 16;
s->mb_height = (s->height + 15) / 16;
s->mb_stride = s->mb_width + 1;
s->b8_stride = s->mb_width*2 + 1;
s->b4_stride = s->mb_width*4 + 1;
mb_array_size= s->mb_height * s->mb_stride;
/* set default edge pos, will be overriden in decode_header if needed */
......@@ -2364,7 +2374,7 @@ static inline void MPV_motion(MpegEncContext *s,
mb_x = s->mb_x;
mb_y = s->mb_y;
if(s->obmc){
if(s->obmc && s->pict_type != B_TYPE){
int16_t mv_cache[4][4][2];
const int xy= s->mb_x + s->mb_y*s->mb_stride;
const int mot_stride= s->mb_width*2 + 2;
......
......@@ -135,7 +135,8 @@ typedef struct Picture{
*/
uint8_t *interpolated[3];
int16_t (*motion_val[2])[2];
int16_t (*motion_val_base[2])[2];
int16_t (*motion_val[2])[2]; ///< motion_val_base+1, so motion_val[][-1] doesnt segfault
int8_t *ref_index[2];
uint32_t *mb_type_base;
uint32_t *mb_type; ///< mb_type_base + mb_width + 2, note: only used for decoding currently
......@@ -149,7 +150,7 @@ typedef struct Picture{
#define MB_TYPE_INTERLACED 0x0080
#define MB_TYPE_DIRECT2 0x0100 //FIXME
#define MB_TYPE_ACPRED 0x0200
#define MB_TYPE_GMC 0x0400 //FIXME mpeg4 specific
#define MB_TYPE_GMC 0x0400
#define MB_TYPE_SKIP 0x0800
#define MB_TYPE_P0L0 0x1000
#define MB_TYPE_P1L0 0x2000
......@@ -159,7 +160,8 @@ typedef struct Picture{
#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
#define MB_TYPE_QUANT 0x00010000
//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 pat, ...)
#define MB_TYPE_CBP 0x00020000
//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
#define IS_INTRA4x4(a) ((a)&MB_TYPE_INTRA4x4)
#define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
......@@ -183,6 +185,7 @@ typedef struct Picture{
#define IS_QUANT(a) ((a)&MB_TYPE_QUANT)
#define IS_DIR(a, part, list) ((a) & (MB_TYPE_P0L0<<((part)+2*(list))))
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list)))) ///< does this mb use listX, note doesnt work if subMBs
#define HAS_CBP(a) ((a)&MB_TYPE_CBP)
int field_poc[2]; ///< h264 top/bottom POC
......@@ -296,6 +299,8 @@ typedef struct MpegEncContext {
int b_frames_since_non_b; ///< used for encoding, relative to not yet reordered input
int mb_width, mb_height; ///< number of MBs horizontally & vertically
int mb_stride; ///< mb_width+1 used for some arrays to allow simple addressng of left & top MBs withoutt sig11
int b8_stride; ///< 2*mb_width+1 used for some 8x8 block arrays to allow simple addressng
int b4_stride; ///< 4*mb_width+1 used for some 4x4 block arrays to allow simple addressng
int h_edge_pos, v_edge_pos;///< horizontal / vertical position of the right/bottom edge (pixel replicateion)
int mb_num; ///< number of MBs of a picture
int linesize; ///< line size, in bytes, may be different from width
......
......@@ -340,6 +340,13 @@ static int rv10_decode_picture_header(MpegEncContext *s)
static int rv20_decode_picture_header(MpegEncContext *s)
{
int seq, mb_pos, i;
if(s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){
if (get_bits(&s->gb, 3)){
av_log(s->avctx, AV_LOG_ERROR, "unknown triplet set\n");
return -1;
}
}
i= get_bits(&s->gb, 2);
switch(i){
......@@ -362,12 +369,41 @@ static int rv20_decode_picture_header(MpegEncContext *s)
av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");
return -1;
}
if(s->avctx->sub_id == 0x20200002)
seq= get_bits(&s->gb, 16);
else
seq= get_bits(&s->gb, 8);
if(s->avctx->sub_id == 0x30203002){
if (get_bits(&s->gb, 1)){
av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n");
return -1;
}
}
if(s->avctx->sub_id == 0x20200002 || s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){
if (get_bits(&s->gb, 1)){
av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n");
return -1;
}
seq= get_bits(&s->gb, 15);
}else
seq= get_bits(&s->gb, 8)*128;
//printf("%d\n", seq);
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!=B_TYPE){
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->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){
printf("messed up order, seeking?, skiping current b frame\n");
return FRAME_SKIPED;
}
}
}
// printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time);
for(i=0; i<6; i++){
if(s->mb_width*s->mb_height < ff_mba_max[i]) break;
}
......@@ -390,10 +426,7 @@ static int rv20_decode_picture_header(MpegEncContext *s)
seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding);
}
if (s->pict_type == B_TYPE){
av_log(s->avctx, AV_LOG_ERROR, "b frame not supported\n");
return -1;
}
assert(s->pict_type != B_TYPE || !s->low_delay);
return s->mb_width*s->mb_height - mb_pos;
}
......@@ -414,14 +447,17 @@ static int rv10_decode_init(AVCodecContext *avctx)
case 0x10000000:
s->rv10_version= 0;
s->h263_long_vectors=0;
s->low_delay=1;
break;
case 0x10003000:
s->rv10_version= 3;
s->h263_long_vectors=1;
s->low_delay=1;
break;
case 0x10003001:
s->rv10_version= 3;
s->h263_long_vectors=0;
s->low_delay=1;
break;
case 0x20001000:
case 0x20100001: //ok
......@@ -613,9 +649,15 @@ static int rv10_decode_frame(AVCodecContext *avctx,
if(s->mb_y>=s->mb_height){
MPV_frame_end(s);
*pict= *(AVFrame*)&s->current_picture;
if(s->pict_type==B_TYPE || s->low_delay){
*pict= *(AVFrame*)&s->current_picture;
ff_print_debug_info(s, s->current_picture_ptr);
} else {
*pict= *(AVFrame*)&s->last_picture;
ff_print_debug_info(s, s->last_picture_ptr);
}
*data_size = sizeof(AVFrame);
}else{
*data_size = 0;
......@@ -647,3 +689,4 @@ AVCodec rv20_decoder = {
rv10_decode_frame,
CODEC_CAP_DR1
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment