msmpeg4v2 decoding (no encoding yet)
Originally committed as revision 376 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
fcb609f432
commit
84afee348f
@ -14,7 +14,9 @@ enum CodecID {
|
|||||||
CODEC_ID_MJPEG,
|
CODEC_ID_MJPEG,
|
||||||
CODEC_ID_MPEG4,
|
CODEC_ID_MPEG4,
|
||||||
CODEC_ID_RAWVIDEO,
|
CODEC_ID_RAWVIDEO,
|
||||||
CODEC_ID_MSMPEG4,
|
CODEC_ID_MSMPEG4V1,
|
||||||
|
CODEC_ID_MSMPEG4V2,
|
||||||
|
CODEC_ID_MSMPEG4V3,
|
||||||
CODEC_ID_H263P,
|
CODEC_ID_H263P,
|
||||||
CODEC_ID_H263I,
|
CODEC_ID_H263I,
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ enum CodecID {
|
|||||||
CODEC_ID_PCM_MULAW,
|
CODEC_ID_PCM_MULAW,
|
||||||
CODEC_ID_PCM_ALAW,
|
CODEC_ID_PCM_ALAW,
|
||||||
};
|
};
|
||||||
|
#define CODEC_ID_MSMPEG4 CODEC_ID_MSMPEG4V3
|
||||||
|
|
||||||
enum CodecType {
|
enum CodecType {
|
||||||
CODEC_TYPE_VIDEO,
|
CODEC_TYPE_VIDEO,
|
||||||
@ -200,11 +203,15 @@ extern AVCodec h263p_encoder;
|
|||||||
extern AVCodec rv10_encoder;
|
extern AVCodec rv10_encoder;
|
||||||
extern AVCodec mjpeg_encoder;
|
extern AVCodec mjpeg_encoder;
|
||||||
extern AVCodec mpeg4_encoder;
|
extern AVCodec mpeg4_encoder;
|
||||||
extern AVCodec msmpeg4_encoder;
|
extern AVCodec msmpeg4v1_encoder;
|
||||||
|
extern AVCodec msmpeg4v2_encoder;
|
||||||
|
extern AVCodec msmpeg4v3_encoder;
|
||||||
|
|
||||||
extern AVCodec h263_decoder;
|
extern AVCodec h263_decoder;
|
||||||
extern AVCodec mpeg4_decoder;
|
extern AVCodec mpeg4_decoder;
|
||||||
extern AVCodec msmpeg4_decoder;
|
extern AVCodec msmpeg4v1_decoder;
|
||||||
|
extern AVCodec msmpeg4v2_decoder;
|
||||||
|
extern AVCodec msmpeg4v3_decoder;
|
||||||
extern AVCodec mpeg_decoder;
|
extern AVCodec mpeg_decoder;
|
||||||
extern AVCodec h263i_decoder;
|
extern AVCodec h263i_decoder;
|
||||||
extern AVCodec rv10_decoder;
|
extern AVCodec rv10_decoder;
|
||||||
|
@ -40,13 +40,13 @@ static const UINT8 inter_MCBPC_bits[20] = {
|
|||||||
3, 7, 7, 8,
|
3, 7, 7, 8,
|
||||||
};*/
|
};*/
|
||||||
|
|
||||||
static const UINT8 cbpy_tab[16][2] =
|
const UINT8 cbpy_tab[16][2] =
|
||||||
{
|
{
|
||||||
{3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4},
|
{3,4}, {5,5}, {4,5}, {9,4}, {3,5}, {7,4}, {2,6}, {11,4},
|
||||||
{2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2}
|
{2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const UINT8 mvtab[33][2] =
|
const UINT8 mvtab[33][2] =
|
||||||
{
|
{
|
||||||
{1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
|
{1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
|
||||||
{11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10},
|
{11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10},
|
||||||
|
@ -47,9 +47,20 @@ static int h263_decode_init(AVCodecContext *avctx)
|
|||||||
s->h263_pred = 1;
|
s->h263_pred = 1;
|
||||||
s->has_b_frames = 1;
|
s->has_b_frames = 1;
|
||||||
break;
|
break;
|
||||||
case CODEC_ID_MSMPEG4:
|
case CODEC_ID_MSMPEG4V1:
|
||||||
s->h263_msmpeg4 = 1;
|
s->h263_msmpeg4 = 1;
|
||||||
s->h263_pred = 1;
|
s->h263_pred = 1;
|
||||||
|
s->msmpeg4_version=1;
|
||||||
|
break;
|
||||||
|
case CODEC_ID_MSMPEG4V2:
|
||||||
|
s->h263_msmpeg4 = 1;
|
||||||
|
s->h263_pred = 1;
|
||||||
|
s->msmpeg4_version=2;
|
||||||
|
break;
|
||||||
|
case CODEC_ID_MSMPEG4V3:
|
||||||
|
s->h263_msmpeg4 = 1;
|
||||||
|
s->h263_pred = 1;
|
||||||
|
s->msmpeg4_version=3;
|
||||||
break;
|
break;
|
||||||
case CODEC_ID_H263I:
|
case CODEC_ID_H263I:
|
||||||
s->h263_intel = 1;
|
s->h263_intel = 1;
|
||||||
@ -269,10 +280,34 @@ AVCodec h263_decoder = {
|
|||||||
CODEC_CAP_DRAW_HORIZ_BAND,
|
CODEC_CAP_DRAW_HORIZ_BAND,
|
||||||
};
|
};
|
||||||
|
|
||||||
AVCodec msmpeg4_decoder = {
|
AVCodec msmpeg4v1_decoder = {
|
||||||
|
"msmpeg4v1",
|
||||||
|
CODEC_TYPE_VIDEO,
|
||||||
|
CODEC_ID_MSMPEG4V1,
|
||||||
|
sizeof(MpegEncContext),
|
||||||
|
h263_decode_init,
|
||||||
|
NULL,
|
||||||
|
h263_decode_end,
|
||||||
|
h263_decode_frame,
|
||||||
|
CODEC_CAP_DRAW_HORIZ_BAND,
|
||||||
|
};
|
||||||
|
|
||||||
|
AVCodec msmpeg4v2_decoder = {
|
||||||
|
"msmpeg4v2",
|
||||||
|
CODEC_TYPE_VIDEO,
|
||||||
|
CODEC_ID_MSMPEG4V2,
|
||||||
|
sizeof(MpegEncContext),
|
||||||
|
h263_decode_init,
|
||||||
|
NULL,
|
||||||
|
h263_decode_end,
|
||||||
|
h263_decode_frame,
|
||||||
|
CODEC_CAP_DRAW_HORIZ_BAND,
|
||||||
|
};
|
||||||
|
|
||||||
|
AVCodec msmpeg4v3_decoder = {
|
||||||
"msmpeg4",
|
"msmpeg4",
|
||||||
CODEC_TYPE_VIDEO,
|
CODEC_TYPE_VIDEO,
|
||||||
CODEC_ID_MSMPEG4,
|
CODEC_ID_MSMPEG4V3,
|
||||||
sizeof(MpegEncContext),
|
sizeof(MpegEncContext),
|
||||||
h263_decode_init,
|
h263_decode_init,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
#define GMC_SPRITE 2
|
#define GMC_SPRITE 2
|
||||||
|
|
||||||
/* dc encoding for mpeg4 */
|
/* dc encoding for mpeg4 */
|
||||||
static const UINT8 DCtab_lum[13][2] =
|
const UINT8 DCtab_lum[13][2] =
|
||||||
{
|
{
|
||||||
{3,3}, {3,2}, {2,2}, {2,3}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7},
|
{3,3}, {3,2}, {2,2}, {2,3}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7},
|
||||||
{1,8}, {1,9}, {1,10}, {1,11},
|
{1,8}, {1,9}, {1,10}, {1,11},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const UINT8 DCtab_chrom[13][2] =
|
const UINT8 DCtab_chrom[13][2] =
|
||||||
{
|
{
|
||||||
{3,2}, {2,2}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8},
|
{3,2}, {2,2}, {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {1,7}, {1,8},
|
||||||
{1,9}, {1,10}, {1,11}, {1,12},
|
{1,9}, {1,10}, {1,11}, {1,12},
|
||||||
@ -103,3 +103,22 @@ static const UINT16 sprite_trajectory_tab[15][2] = {
|
|||||||
static const UINT8 mb_type_b_tab[4][2] = {
|
static const UINT8 mb_type_b_tab[4][2] = {
|
||||||
{1, 1}, {1, 2}, {1, 3}, {1, 4},
|
{1, 1}, {1, 2}, {1, 3}, {1, 4},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const UINT16 pixel_aspect[16][2]={
|
||||||
|
{0, 0},
|
||||||
|
{1, 1},
|
||||||
|
{12, 11},
|
||||||
|
{10, 11},
|
||||||
|
{16, 11},
|
||||||
|
{40, 33},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
};
|
||||||
|
@ -355,11 +355,26 @@ int MPV_encode_init(AVCodecContext *avctx)
|
|||||||
s->h263_pred = 1;
|
s->h263_pred = 1;
|
||||||
s->unrestricted_mv = 1;
|
s->unrestricted_mv = 1;
|
||||||
break;
|
break;
|
||||||
case CODEC_ID_MSMPEG4:
|
case CODEC_ID_MSMPEG4V1:
|
||||||
s->out_format = FMT_H263;
|
s->out_format = FMT_H263;
|
||||||
s->h263_msmpeg4 = 1;
|
s->h263_msmpeg4 = 1;
|
||||||
s->h263_pred = 1;
|
s->h263_pred = 1;
|
||||||
s->unrestricted_mv = 1;
|
s->unrestricted_mv = 1;
|
||||||
|
s->msmpeg4_version= 1;
|
||||||
|
break;
|
||||||
|
case CODEC_ID_MSMPEG4V2:
|
||||||
|
s->out_format = FMT_H263;
|
||||||
|
s->h263_msmpeg4 = 1;
|
||||||
|
s->h263_pred = 1;
|
||||||
|
s->unrestricted_mv = 1;
|
||||||
|
s->msmpeg4_version= 2;
|
||||||
|
break;
|
||||||
|
case CODEC_ID_MSMPEG4V3:
|
||||||
|
s->out_format = FMT_H263;
|
||||||
|
s->h263_msmpeg4 = 1;
|
||||||
|
s->h263_pred = 1;
|
||||||
|
s->unrestricted_mv = 1;
|
||||||
|
s->msmpeg4_version= 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
@ -2117,10 +2132,30 @@ AVCodec mpeg4_encoder = {
|
|||||||
MPV_encode_end,
|
MPV_encode_end,
|
||||||
};
|
};
|
||||||
|
|
||||||
AVCodec msmpeg4_encoder = {
|
AVCodec msmpeg4v1_encoder = {
|
||||||
"msmpeg4",
|
"msmpeg4v1",
|
||||||
CODEC_TYPE_VIDEO,
|
CODEC_TYPE_VIDEO,
|
||||||
CODEC_ID_MSMPEG4,
|
CODEC_ID_MSMPEG4V1,
|
||||||
|
sizeof(MpegEncContext),
|
||||||
|
MPV_encode_init,
|
||||||
|
MPV_encode_picture,
|
||||||
|
MPV_encode_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
AVCodec msmpeg4v2_encoder = {
|
||||||
|
"msmpeg4v2",
|
||||||
|
CODEC_TYPE_VIDEO,
|
||||||
|
CODEC_ID_MSMPEG4V2,
|
||||||
|
sizeof(MpegEncContext),
|
||||||
|
MPV_encode_init,
|
||||||
|
MPV_encode_picture,
|
||||||
|
MPV_encode_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
AVCodec msmpeg4v3_encoder = {
|
||||||
|
"msmpeg4",
|
||||||
|
CODEC_TYPE_VIDEO,
|
||||||
|
CODEC_ID_MSMPEG4V3,
|
||||||
sizeof(MpegEncContext),
|
sizeof(MpegEncContext),
|
||||||
MPV_encode_init,
|
MPV_encode_init,
|
||||||
MPV_encode_picture,
|
MPV_encode_picture,
|
||||||
|
@ -267,6 +267,7 @@ typedef struct MpegEncContext {
|
|||||||
int first_slice_line; /* used in mpeg4 too to handle resync markers */
|
int first_slice_line; /* used in mpeg4 too to handle resync markers */
|
||||||
int flipflop_rounding;
|
int flipflop_rounding;
|
||||||
int bitrate;
|
int bitrate;
|
||||||
|
int msmpeg4_version; /* 1=mp41, 2=mp42, 3=mp43/divx3 */
|
||||||
/* decompression specific */
|
/* decompression specific */
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* TODO:
|
* TODO:
|
||||||
* - (encoding) select best mv table (two choices)
|
* - (encoding) select best mv table (two choices)
|
||||||
* - (encoding) select best vlc/dc table
|
* - (encoding) select best vlc/dc table
|
||||||
* - (decoding) handle slice indication
|
|
||||||
*/
|
*/
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
|
|
||||||
@ -44,6 +43,9 @@ typedef struct MVTable {
|
|||||||
VLC vlc; /* decoding: vlc */
|
VLC vlc; /* decoding: vlc */
|
||||||
} MVTable;
|
} MVTable;
|
||||||
|
|
||||||
|
static UINT32 v2_dc_lum_table[512][2];
|
||||||
|
static UINT32 v2_dc_chroma_table[512][2];
|
||||||
|
|
||||||
static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
|
static void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);
|
||||||
static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
|
static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
|
||||||
int n, int coded);
|
int n, int coded);
|
||||||
@ -620,6 +622,72 @@ static VLC mb_non_intra_vlc;
|
|||||||
static VLC mb_intra_vlc;
|
static VLC mb_intra_vlc;
|
||||||
static VLC dc_lum_vlc[2];
|
static VLC dc_lum_vlc[2];
|
||||||
static VLC dc_chroma_vlc[2];
|
static VLC dc_chroma_vlc[2];
|
||||||
|
static VLC v2_dc_lum_vlc;
|
||||||
|
static VLC v2_dc_chroma_vlc;
|
||||||
|
static VLC cbpy_vlc;
|
||||||
|
static VLC v2_intra_cbpc_vlc;
|
||||||
|
static VLC v2_mb_type_vlc;
|
||||||
|
static VLC v2_mv_vlc;
|
||||||
|
|
||||||
|
/* this table is practically identical to the one from h263 except that its inverted */
|
||||||
|
static void init_h263_dc_for_msmpeg4()
|
||||||
|
{
|
||||||
|
static int inited=0;
|
||||||
|
|
||||||
|
if(!inited){
|
||||||
|
int level, uni_code, uni_len;
|
||||||
|
inited=1;
|
||||||
|
|
||||||
|
for(level=-255; level<256; level++){
|
||||||
|
int size, v, l;
|
||||||
|
/* find number of bits */
|
||||||
|
size = 0;
|
||||||
|
v = abs(level);
|
||||||
|
while (v) {
|
||||||
|
v >>= 1;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level < 0)
|
||||||
|
l= (-level) ^ ((1 << size) - 1);
|
||||||
|
else
|
||||||
|
l= level;
|
||||||
|
|
||||||
|
/* luminance h263 */
|
||||||
|
uni_code= DCtab_lum[size][0];
|
||||||
|
uni_len = DCtab_lum[size][1];
|
||||||
|
uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
uni_code<<=size; uni_code|=l;
|
||||||
|
uni_len+=size;
|
||||||
|
if (size > 8){
|
||||||
|
uni_code<<=1; uni_code|=1;
|
||||||
|
uni_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v2_dc_lum_table[level+256][0]= uni_code;
|
||||||
|
v2_dc_lum_table[level+256][1]= uni_len;
|
||||||
|
|
||||||
|
/* chrominance h263 */
|
||||||
|
uni_code= DCtab_chrom[size][0];
|
||||||
|
uni_len = DCtab_chrom[size][1];
|
||||||
|
uni_code ^= (1<<uni_len)-1; //M$ doesnt like compatibility
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
uni_code<<=size; uni_code|=l;
|
||||||
|
uni_len+=size;
|
||||||
|
if (size > 8){
|
||||||
|
uni_code<<=1; uni_code|=1;
|
||||||
|
uni_len++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v2_dc_chroma_table[level+256][0]= uni_code;
|
||||||
|
v2_dc_chroma_table[level+256][1]= uni_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* init all vlc decoding tables */
|
/* init all vlc decoding tables */
|
||||||
int msmpeg4_decode_init_vlc(MpegEncContext *s)
|
int msmpeg4_decode_init_vlc(MpegEncContext *s)
|
||||||
@ -650,6 +718,27 @@ int msmpeg4_decode_init_vlc(MpegEncContext *s)
|
|||||||
init_vlc(&dc_chroma_vlc[1], 9, 120,
|
init_vlc(&dc_chroma_vlc[1], 9, 120,
|
||||||
&table1_dc_chroma[0][1], 8, 4,
|
&table1_dc_chroma[0][1], 8, 4,
|
||||||
&table1_dc_chroma[0][0], 8, 4);
|
&table1_dc_chroma[0][0], 8, 4);
|
||||||
|
|
||||||
|
init_h263_dc_for_msmpeg4();
|
||||||
|
init_vlc(&v2_dc_lum_vlc, 9, 512,
|
||||||
|
&v2_dc_lum_table[0][1], 8, 4,
|
||||||
|
&v2_dc_lum_table[0][0], 8, 4);
|
||||||
|
init_vlc(&v2_dc_chroma_vlc, 9, 512,
|
||||||
|
&v2_dc_chroma_table[0][1], 8, 4,
|
||||||
|
&v2_dc_chroma_table[0][0], 8, 4);
|
||||||
|
|
||||||
|
init_vlc(&cbpy_vlc, 6, 16,
|
||||||
|
&cbpy_tab[0][1], 2, 1,
|
||||||
|
&cbpy_tab[0][0], 2, 1);
|
||||||
|
init_vlc(&v2_intra_cbpc_vlc, 3, 4,
|
||||||
|
&v2_intra_cbpc[0][1], 2, 1,
|
||||||
|
&v2_intra_cbpc[0][0], 2, 1);
|
||||||
|
init_vlc(&v2_mb_type_vlc, 5, 8,
|
||||||
|
&v2_mb_type[0][1], 2, 1,
|
||||||
|
&v2_mb_type[0][0], 2, 1);
|
||||||
|
init_vlc(&v2_mv_vlc, 9, 33,
|
||||||
|
&mvtab[0][1], 2, 1,
|
||||||
|
&mvtab[0][0], 2, 1);
|
||||||
|
|
||||||
init_vlc(&mb_non_intra_vlc, 9, 128,
|
init_vlc(&mb_non_intra_vlc, 9, 128,
|
||||||
&table_mb_non_intra[0][1], 8, 4,
|
&table_mb_non_intra[0][1], 8, 4,
|
||||||
@ -670,66 +759,10 @@ static int decode012(GetBitContext *gb)
|
|||||||
return get_bits1(gb) + 1;
|
return get_bits1(gb) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int msmpeg4v2_decode_picture_header(MpegEncContext * s)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
s->pict_type = get_bits(&s->gb, 2) + 1;
|
|
||||||
if (s->pict_type != I_TYPE &&
|
|
||||||
s->pict_type != P_TYPE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
s->qscale = get_bits(&s->gb, 5);
|
|
||||||
|
|
||||||
if (s->pict_type == I_TYPE) {
|
|
||||||
code = get_bits(&s->gb, 5);
|
|
||||||
/* 0x17: one slice, 0x18: three slices */
|
|
||||||
/* XXX: implement it */
|
|
||||||
//printf("%d %d %d\n", code, s->slice_height, s->first_slice_line);
|
|
||||||
if (code < 0x17)
|
|
||||||
return -1;
|
|
||||||
s->slice_height = s->mb_height / (code - 0x16);
|
|
||||||
/* s->rl_chroma_table_index = decode012(&s->gb);
|
|
||||||
s->rl_table_index = decode012(&s->gb);
|
|
||||||
|
|
||||||
s->dc_table_index = get_bits1(&s->gb);*/
|
|
||||||
s->no_rounding = 1;
|
|
||||||
} else {
|
|
||||||
s->use_skip_mb_code = get_bits1(&s->gb);
|
|
||||||
|
|
||||||
/* s->rl_table_index = decode012(&s->gb);
|
|
||||||
s->rl_chroma_table_index = s->rl_table_index;
|
|
||||||
|
|
||||||
s->dc_table_index = get_bits1(&s->gb);
|
|
||||||
|
|
||||||
s->mv_table_index = get_bits1(&s->gb);*/
|
|
||||||
if(s->flipflop_rounding){
|
|
||||||
s->no_rounding ^= 1;
|
|
||||||
}else{
|
|
||||||
s->no_rounding = 0;
|
|
||||||
}
|
|
||||||
// printf("%d", s->no_rounding);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s q:%d s:%X ", s->pict_type == I_TYPE ? "I" : "P" , s->qscale,
|
|
||||||
s->pict_type == I_TYPE ? code : s->use_skip_mb_code);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int msmpeg4_decode_picture_header(MpegEncContext * s)
|
int msmpeg4_decode_picture_header(MpegEncContext * s)
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
msmpeg4v2_decode_picture_header(s);
|
|
||||||
for(i=0; i<s->gb.size*8; i++)
|
|
||||||
printf("%d", get_bits1(&s->gb));
|
|
||||||
printf("END\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
s->pict_type = get_bits(&s->gb, 2) + 1;
|
s->pict_type = get_bits(&s->gb, 2) + 1;
|
||||||
if (s->pict_type != I_TYPE &&
|
if (s->pict_type != I_TYPE &&
|
||||||
s->pict_type != P_TYPE)
|
s->pict_type != P_TYPE)
|
||||||
@ -739,16 +772,21 @@ return -1;
|
|||||||
|
|
||||||
if (s->pict_type == I_TYPE) {
|
if (s->pict_type == I_TYPE) {
|
||||||
code = get_bits(&s->gb, 5);
|
code = get_bits(&s->gb, 5);
|
||||||
/* 0x17: one slice, 0x18: three slices */
|
/* 0x17: one slice, 0x18: two slices */
|
||||||
/* XXX: implement it */
|
|
||||||
//printf("%d %d %d\n", code, s->slice_height, s->first_slice_line);
|
|
||||||
if (code < 0x17)
|
if (code < 0x17)
|
||||||
return -1;
|
return -1;
|
||||||
s->slice_height = s->mb_height / (code - 0x16);
|
s->slice_height = s->mb_height / (code - 0x16);
|
||||||
s->rl_chroma_table_index = decode012(&s->gb);
|
if(s->msmpeg4_version==2){
|
||||||
s->rl_table_index = decode012(&s->gb);
|
s->rl_chroma_table_index = 2;
|
||||||
|
s->rl_table_index = 2;
|
||||||
|
|
||||||
s->dc_table_index = get_bits1(&s->gb);
|
s->dc_table_index = 0; //not used
|
||||||
|
}else{
|
||||||
|
s->rl_chroma_table_index = decode012(&s->gb);
|
||||||
|
s->rl_table_index = decode012(&s->gb);
|
||||||
|
|
||||||
|
s->dc_table_index = get_bits1(&s->gb);
|
||||||
|
}
|
||||||
s->no_rounding = 1;
|
s->no_rounding = 1;
|
||||||
/* printf(" %d %d %d %d \n",
|
/* printf(" %d %d %d %d \n",
|
||||||
s->qscale,
|
s->qscale,
|
||||||
@ -758,12 +796,21 @@ return -1;
|
|||||||
} else {
|
} else {
|
||||||
s->use_skip_mb_code = get_bits1(&s->gb);
|
s->use_skip_mb_code = get_bits1(&s->gb);
|
||||||
|
|
||||||
s->rl_table_index = decode012(&s->gb);
|
if(s->msmpeg4_version==2){
|
||||||
s->rl_chroma_table_index = s->rl_table_index;
|
s->rl_table_index = 2;
|
||||||
|
s->rl_chroma_table_index = s->rl_table_index;
|
||||||
|
|
||||||
s->dc_table_index = get_bits1(&s->gb);
|
s->dc_table_index = 0; //not used
|
||||||
|
|
||||||
s->mv_table_index = get_bits1(&s->gb);
|
s->mv_table_index = 0;
|
||||||
|
}else{
|
||||||
|
s->rl_table_index = decode012(&s->gb);
|
||||||
|
s->rl_chroma_table_index = s->rl_table_index;
|
||||||
|
|
||||||
|
s->dc_table_index = get_bits1(&s->gb);
|
||||||
|
|
||||||
|
s->mv_table_index = get_bits1(&s->gb);
|
||||||
|
}
|
||||||
/* printf(" %d %d %d %d %d \n",
|
/* printf(" %d %d %d %d %d \n",
|
||||||
s->use_skip_mb_code,
|
s->use_skip_mb_code,
|
||||||
s->rl_table_index,
|
s->rl_table_index,
|
||||||
@ -778,7 +825,20 @@ return -1;
|
|||||||
// printf("%d", s->no_rounding);
|
// printf("%d", s->no_rounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if(s->msmpeg4_version==2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("%s q:%d s:%X ", s->pict_type == I_TYPE ? "I" : "P" , s->qscale,
|
||||||
|
s->pict_type == I_TYPE ? code : s->use_skip_mb_code);
|
||||||
|
for(i=0; i<s->gb.size*8; i++)
|
||||||
|
// printf("%d", get_bits1(&s->gb));
|
||||||
|
get_bits1(&s->gb);
|
||||||
|
printf("END\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("*****frame %d:\n", frame_count++);
|
printf("*****frame %d:\n", frame_count++);
|
||||||
#endif
|
#endif
|
||||||
@ -814,6 +874,103 @@ static inline void memsetw(short *tab, int val, int n)
|
|||||||
tab[i] = val;
|
tab[i] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this is identical to h263 except that its range is multiplied by 2 */
|
||||||
|
static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
|
||||||
|
{
|
||||||
|
int code, val, sign, shift;
|
||||||
|
|
||||||
|
code = get_vlc(&s->gb, &v2_mv_vlc);
|
||||||
|
if (code < 0)
|
||||||
|
return 0xffff;
|
||||||
|
|
||||||
|
if (code == 0)
|
||||||
|
return pred;
|
||||||
|
sign = get_bits1(&s->gb);
|
||||||
|
shift = f_code - 1;
|
||||||
|
val = (code - 1) << shift;
|
||||||
|
if (shift > 0)
|
||||||
|
val |= get_bits(&s->gb, shift);
|
||||||
|
val++;
|
||||||
|
if (sign)
|
||||||
|
val = -val;
|
||||||
|
val += pred;
|
||||||
|
|
||||||
|
if (val <= -64)
|
||||||
|
val += 64;
|
||||||
|
else if (val >= 64)
|
||||||
|
val -= 64;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int msmpeg4v2_decode_mb(MpegEncContext *s,
|
||||||
|
DCTELEM block[6][64])
|
||||||
|
{
|
||||||
|
int cbp, code, i;
|
||||||
|
//printf("M");
|
||||||
|
//fflush(stderr); fflush(stdout);
|
||||||
|
if (s->pict_type == P_TYPE) {
|
||||||
|
if (s->use_skip_mb_code) {
|
||||||
|
if (get_bits1(&s->gb)) {
|
||||||
|
/* skip mb */
|
||||||
|
s->mb_intra = 0;
|
||||||
|
for(i=0;i<6;i++)
|
||||||
|
s->block_last_index[i] = -1;
|
||||||
|
s->mv_dir = MV_DIR_FORWARD;
|
||||||
|
s->mv_type = MV_TYPE_16X16;
|
||||||
|
s->mv[0][0][0] = 0;
|
||||||
|
s->mv[0][0][1] = 0;
|
||||||
|
s->mb_skiped = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
code = get_vlc(&s->gb, &v2_mb_type_vlc);
|
||||||
|
s->mb_intra = code >>2;
|
||||||
|
|
||||||
|
cbp = code & 0x3;
|
||||||
|
} else {
|
||||||
|
s->mb_intra = 1;
|
||||||
|
//printf("%X ", show_bits(&s->gb, 24));
|
||||||
|
cbp= get_vlc(&s->gb, &v2_intra_cbpc_vlc);
|
||||||
|
//printf("%X ", show_bits(&s->gb, 24));
|
||||||
|
//printf("CBP: %X ",cbp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s->mb_intra) {
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
|
cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
|
||||||
|
if((cbp&3) != 3) cbp^= 0x3C;
|
||||||
|
|
||||||
|
h263_pred_motion(s, 0, &mx, &my);
|
||||||
|
mx= msmpeg4v2_decode_motion(s, mx, 1);
|
||||||
|
my= msmpeg4v2_decode_motion(s, my, 1);
|
||||||
|
|
||||||
|
s->mv_dir = MV_DIR_FORWARD;
|
||||||
|
s->mv_type = MV_TYPE_16X16;
|
||||||
|
s->mv[0][0][0] = mx;
|
||||||
|
s->mv[0][0][1] = my;
|
||||||
|
} else {
|
||||||
|
//if(s->pict_type == P_TYPE) printf("intra cbp: %X", cbp);
|
||||||
|
s->ac_pred = get_bits1(&s->gb);
|
||||||
|
//printf("AC: %d ",s->ac_pred);
|
||||||
|
cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2;
|
||||||
|
//printf("cbp: %X ",cbp);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)
|
||||||
|
{
|
||||||
|
//fflush(stderr); fflush(stdout);
|
||||||
|
fprintf(stderr,"\nIgnoring error while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int msmpeg4_decode_mb(MpegEncContext *s,
|
int msmpeg4_decode_mb(MpegEncContext *s,
|
||||||
DCTELEM block[6][64])
|
DCTELEM block[6][64])
|
||||||
{
|
{
|
||||||
@ -850,6 +1007,8 @@ int msmpeg4_decode_mb(MpegEncContext *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(s->msmpeg4_version==2) return msmpeg4v2_decode_mb(s, block); //FIXME merge if possible
|
||||||
|
|
||||||
if (s->pict_type == P_TYPE) {
|
if (s->pict_type == P_TYPE) {
|
||||||
set_stat(ST_INTER_MB);
|
set_stat(ST_INTER_MB);
|
||||||
if (s->use_skip_mb_code) {
|
if (s->use_skip_mb_code) {
|
||||||
@ -962,7 +1121,12 @@ static int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
|
|||||||
qadd = (s->qscale - 1) | 1;
|
qadd = (s->qscale - 1) | 1;
|
||||||
i = 0;
|
i = 0;
|
||||||
rl = &rl_table[3 + s->rl_table_index];
|
rl = &rl_table[3 + s->rl_table_index];
|
||||||
run_diff = 1;
|
|
||||||
|
if(s->msmpeg4_version==2)
|
||||||
|
run_diff = 0;
|
||||||
|
else
|
||||||
|
run_diff = 1;
|
||||||
|
|
||||||
if (!coded) {
|
if (!coded) {
|
||||||
s->block_last_index[n] = i - 1;
|
s->block_last_index[n] = i - 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1046,21 +1210,33 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
|
|||||||
int level, pred;
|
int level, pred;
|
||||||
INT16 *dc_val;
|
INT16 *dc_val;
|
||||||
|
|
||||||
if (n < 4) {
|
if(s->msmpeg4_version==2){
|
||||||
level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
|
if (n < 4) {
|
||||||
} else {
|
level = get_vlc(&s->gb, &v2_dc_lum_vlc);
|
||||||
level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
|
} else {
|
||||||
}
|
level = get_vlc(&s->gb, &v2_dc_chroma_vlc);
|
||||||
if (level < 0)
|
}
|
||||||
return -1;
|
if (level < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (level == DC_MAX) {
|
level-=256;
|
||||||
level = get_bits(&s->gb, 8);
|
}else{ //FIXME optimize use unified tables & index
|
||||||
if (get_bits1(&s->gb))
|
if (n < 4) {
|
||||||
level = -level;
|
level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]);
|
||||||
} else if (level != 0) {
|
} else {
|
||||||
if (get_bits1(&s->gb))
|
level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]);
|
||||||
level = -level;
|
}
|
||||||
|
if (level < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (level == DC_MAX) {
|
||||||
|
level = get_bits(&s->gb, 8);
|
||||||
|
if (get_bits1(&s->gb))
|
||||||
|
level = -level;
|
||||||
|
} else if (level != 0) {
|
||||||
|
if (get_bits1(&s->gb))
|
||||||
|
level = -level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
|
pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
|
||||||
|
@ -569,6 +569,13 @@ extern const UINT16 intra_vlc[103][2];
|
|||||||
extern const INT8 intra_level[102];
|
extern const INT8 intra_level[102];
|
||||||
extern const INT8 intra_run[102];
|
extern const INT8 intra_run[102];
|
||||||
|
|
||||||
|
extern const UINT8 DCtab_lum[13][2];
|
||||||
|
extern const UINT8 DCtab_chrom[13][2];
|
||||||
|
|
||||||
|
extern const UINT8 cbpy_tab[16][2];
|
||||||
|
extern const UINT8 mvtab[33][2];
|
||||||
|
|
||||||
|
|
||||||
#define NB_RL_TABLES 6
|
#define NB_RL_TABLES 6
|
||||||
|
|
||||||
static RLTable rl_table[NB_RL_TABLES] = {
|
static RLTable rl_table[NB_RL_TABLES] = {
|
||||||
@ -1765,3 +1772,12 @@ static MVTable mv_tables[2] = {
|
|||||||
table1_mvy,
|
table1_mvy,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const UINT8 v2_mb_type[8][2] = {
|
||||||
|
{1, 1}, {0 , 2}, {3 , 3}, {9 , 5},
|
||||||
|
{5, 4}, {0x21, 7}, {0x20, 7}, {0x11, 6},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const UINT8 v2_intra_cbpc[4][2] = {
|
||||||
|
{1, 1}, {0, 3}, {1, 3}, {1, 2},
|
||||||
|
};
|
||||||
|
@ -416,7 +416,9 @@ void avcodec_register_all(void)
|
|||||||
register_avcodec(&rv10_encoder);
|
register_avcodec(&rv10_encoder);
|
||||||
register_avcodec(&mjpeg_encoder);
|
register_avcodec(&mjpeg_encoder);
|
||||||
register_avcodec(&mpeg4_encoder);
|
register_avcodec(&mpeg4_encoder);
|
||||||
register_avcodec(&msmpeg4_encoder);
|
register_avcodec(&msmpeg4v1_encoder);
|
||||||
|
register_avcodec(&msmpeg4v2_encoder);
|
||||||
|
register_avcodec(&msmpeg4v3_encoder);
|
||||||
#endif /* CONFIG_ENCODERS */
|
#endif /* CONFIG_ENCODERS */
|
||||||
register_avcodec(&rawvideo_codec);
|
register_avcodec(&rawvideo_codec);
|
||||||
|
|
||||||
@ -424,7 +426,9 @@ void avcodec_register_all(void)
|
|||||||
#ifdef CONFIG_DECODERS
|
#ifdef CONFIG_DECODERS
|
||||||
register_avcodec(&h263_decoder);
|
register_avcodec(&h263_decoder);
|
||||||
register_avcodec(&mpeg4_decoder);
|
register_avcodec(&mpeg4_decoder);
|
||||||
register_avcodec(&msmpeg4_decoder);
|
register_avcodec(&msmpeg4v1_decoder);
|
||||||
|
register_avcodec(&msmpeg4v2_decoder);
|
||||||
|
register_avcodec(&msmpeg4v3_decoder);
|
||||||
register_avcodec(&mpeg_decoder);
|
register_avcodec(&mpeg_decoder);
|
||||||
register_avcodec(&h263i_decoder);
|
register_avcodec(&h263i_decoder);
|
||||||
register_avcodec(&rv10_decoder);
|
register_avcodec(&rv10_decoder);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user