Originally committed as revision 2833 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -291,6 +291,8 @@ extern int motion_estimation_method; | |||
used */ | |||
#define CODEC_CAP_PARSE_ONLY 0x0004 | |||
#define CODEC_CAP_TRUNCATED 0x0008 | |||
/* codec can export data for HW decoding (XvMC) */ | |||
#define CODEC_CAP_HWACCEL 0x0010 | |||
//the following defines might change, so dont expect compatibility if u use them | |||
#define MB_TYPE_INTRA4x4 0x0001 | |||
@@ -1010,7 +1010,7 @@ static inline int get_qscale(MpegEncContext *s) | |||
#define MT_DMV 3 | |||
static int mpeg_decode_mb(MpegEncContext *s, | |||
DCTELEM block[6][64]) | |||
DCTELEM block[12][64]) | |||
{ | |||
int i, j, k, cbp, val, mb_type, motion_type; | |||
@@ -1026,7 +1026,7 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||
/* skip mb */ | |||
s->mb_intra = 0; | |||
for(i=0;i<6;i++) | |||
for(i=0;i<12;i++) | |||
s->block_last_index[i] = -1; | |||
if(s->picture_structure == PICT_FRAME) | |||
s->mv_type = MV_TYPE_16X16; | |||
@@ -1126,7 +1126,7 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||
#endif | |||
if (s->codec_id == CODEC_ID_MPEG2VIDEO) { | |||
for(i=0;i<6;i++) { | |||
for(i=0;i<4+(1<<s->chroma_format);i++) { | |||
if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0) | |||
return -1; | |||
} | |||
@@ -1311,6 +1311,12 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||
return -1; | |||
} | |||
cbp++; | |||
if(s->chroma_format == 2){//CHROMA422 | |||
cbp|= ( get_bits(&s->gb,2) ) << 6; | |||
}else | |||
if(s->chroma_format > 2){//CHROMA444 | |||
cbp|= ( get_bits(&s->gb,6) ) << 6; | |||
} | |||
#ifdef HAVE_XVMC | |||
//on 1 we memcpy blocks in xvmcvideo | |||
@@ -1324,13 +1330,33 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||
if (s->codec_id == CODEC_ID_MPEG2VIDEO) { | |||
for(i=0;i<6;i++) { | |||
if (cbp & 32) { | |||
if (cbp & (1<<(5-i)) ) { | |||
if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) | |||
return -1; | |||
} else { | |||
s->block_last_index[i] = -1; | |||
} | |||
cbp+=cbp; | |||
} | |||
if (s->chroma_format >= 2) { | |||
if (s->chroma_format == 2) {//CHROMA_422) | |||
for(i=6;i<8;i++) { | |||
if (cbp & (1<<(6+7-i)) ) { | |||
if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) | |||
return -1; | |||
} else { | |||
s->block_last_index[i] = -1; | |||
} | |||
} | |||
}else{ /*CHROMA_444*/ | |||
for(i=6;i<12;i++) { | |||
if (cbp & (1<<(6+11-i)) ) { | |||
if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) | |||
return -1; | |||
} else { | |||
s->block_last_index[i] = -1; | |||
} | |||
} | |||
} | |||
} | |||
} else { | |||
for(i=0;i<6;i++) { | |||
@@ -1654,7 +1680,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, | |||
component = 0; | |||
}else{ | |||
quant_matrix = s->chroma_intra_matrix; | |||
component = n - 3; | |||
component = (n&1) + 1; | |||
} | |||
diff = decode_dc(&s->gb, component); | |||
if (diff >= 0xffff) | |||
@@ -1817,13 +1843,13 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s) | |||
profile= get_bits(&s->gb, 3); | |||
level= get_bits(&s->gb, 4); | |||
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ | |||
skip_bits(&s->gb, 2); /* chroma_format */ | |||
s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */ | |||
horiz_size_ext = get_bits(&s->gb, 2); | |||
vert_size_ext = get_bits(&s->gb, 2); | |||
s->width |= (horiz_size_ext << 12); | |||
s->height |= (vert_size_ext << 12); | |||
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ | |||
s->bit_rate = ((s->bit_rate / 400) | (bit_rate_ext << 12)) * 400; | |||
s->bit_rate += (bit_rate_ext << 12) * 400; | |||
skip_bits1(&s->gb); /* marker */ | |||
s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10; | |||
@@ -2556,6 +2582,37 @@ static void mpeg_decode_user_data(AVCodecContext *avctx, | |||
} | |||
} | |||
static void mpeg_decode_gop(AVCodecContext *avctx, | |||
uint8_t *buf, int buf_size){ | |||
Mpeg1Context *s1 = avctx->priv_data; | |||
MpegEncContext *s = &s1->mpeg_enc_ctx; | |||
int drop_frame_flag; | |||
int time_code_hours, time_code_minutes; | |||
int time_code_seconds, time_code_pictures; | |||
int broken_link; | |||
s->first_field = 0; | |||
init_get_bits(&s->gb, buf, buf_size*8); | |||
drop_frame_flag = get_bits1(&s->gb); | |||
time_code_hours=get_bits(&s->gb,5); | |||
time_code_minutes = get_bits(&s->gb,6); | |||
skip_bits1(&s->gb);//marker bit | |||
time_code_seconds = get_bits(&s->gb,6); | |||
time_code_pictures = get_bits(&s->gb,6); | |||
/*broken_link indicate that after editing the | |||
reference frames of the first B-Frames after GOP I-Frame | |||
are missing (open gop)*/ | |||
broken_link = get_bits1(&s->gb); | |||
if(broken_link == 1){ | |||
// avcodec_flush_buffers(avctx); | |||
ff_mpeg_flush(avctx); | |||
} | |||
} | |||
/** | |||
* finds the end of the current frame in the bitstream. | |||
* @return the position of the first byte of the next frame, or -1 | |||
@@ -2692,7 +2749,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, | |||
buf_ptr, input_size); | |||
break; | |||
case GOP_START_CODE: | |||
s2->first_field=0; | |||
mpeg_decode_gop(avctx, buf_ptr, input_size); | |||
break; | |||
default: | |||
if (start_code >= SLICE_MIN_START_CODE && | |||
@@ -2850,7 +2907,8 @@ AVCodec mpeg_xvmc_decoder = { | |||
NULL, | |||
mpeg_decode_end, | |||
mpeg_decode_frame, | |||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, | |||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL, | |||
.flush= ff_mpeg_flush, | |||
}; | |||
#endif | |||
@@ -267,8 +267,6 @@ int DCT_common_init(MpegEncContext *s) | |||
ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan); | |||
ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); | |||
s->picture_structure= PICT_FRAME; | |||
return 0; | |||
} | |||
@@ -424,7 +422,7 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ | |||
CHECKED_ALLOCZ(s->dct_error_sum, 2 * 64 * sizeof(int)) | |||
} | |||
} | |||
CHECKED_ALLOCZ(s->blocks, 64*6*2 * sizeof(DCTELEM)) | |||
CHECKED_ALLOCZ(s->blocks, 64*12*2 * sizeof(DCTELEM)) | |||
s->block= s->blocks[0]; | |||
for(i=0;i<12;i++){ | |||
@@ -539,9 +537,18 @@ int MPV_common_init(MpegEncContext *s) | |||
s->y_dc_scale_table= | |||
s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | |||
s->chroma_qscale_table= ff_default_chroma_qscale_table; | |||
if (!s->encoding) | |||
s->progressive_sequence= 1; | |||
s->progressive_frame= 1; | |||
if( s->codec_id != CODEC_ID_MPEG1VIDEO && | |||
s->codec_id != CODEC_ID_MPEG2VIDEO) | |||
{ | |||
/* default structure is frame */ | |||
s->progressive_frame= 1; | |||
s->picture_structure= PICT_FRAME; | |||
s->y_dc_scale_table= | |||
s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | |||
if (!s->encoding) | |||
s->progressive_sequence= 1; | |||
} | |||
s->coded_picture_number = 0; | |||
y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); | |||
@@ -355,6 +355,9 @@ typedef struct MpegEncContext { | |||
int last_pict_type; | |||
int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol | |||
int frame_rate_index; | |||
int frame_rate_ext_n; ///< MPEG-2 specific framerate modificators (numerator) | |||
int frame_rate_ext_d; ///< MPEG-2 specific framerate modificators (denominator) | |||
/* motion compensation */ | |||
int unrestricted_mv; ///< mv can point outside of the coded picture | |||
int h263_long_vectors; ///< use horrible h263v1 long vector mode | |||
@@ -465,7 +468,7 @@ typedef struct MpegEncContext { | |||
/** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/ | |||
uint16_t (*q_intra_matrix16)[2][64]; | |||
uint16_t (*q_inter_matrix16)[2][64]; | |||
int block_last_index[6]; ///< last non zero coefficient in block | |||
int block_last_index[12]; ///< last non zero coefficient in block | |||
/* scantables */ | |||
ScanTable __align8 intra_scantable; | |||
ScanTable intra_h_scantable; | |||
@@ -653,6 +656,11 @@ typedef struct MpegEncContext { | |||
int alternate_scan; | |||
int repeat_first_field; | |||
int chroma_420_type; | |||
int chroma_format; | |||
#define CHROMA_420 1 | |||
#define CHROMA_422 2 | |||
#define CHROMA_444 3 | |||
int progressive_frame; | |||
int full_pel[2]; | |||
int interlaced_dct; | |||
@@ -55,27 +55,66 @@ xvmc_render_state_t * render; | |||
void XVMC_pack_pblocks(MpegEncContext *s, int cbp){ | |||
int i,j; | |||
#define numblocks 6 | |||
j=0; | |||
for(i=0;i<numblocks;i++){ | |||
if(cbp & (1<<(numblocks-1-i)) ){ | |||
for(i=0;i<6;i++){ | |||
if(cbp & (1<<(5-i)) ){ | |||
s->pblocks[i] = (short *)(&s->block[(j++)]); | |||
}else{ | |||
s->pblocks[i] = NULL; | |||
} | |||
// printf("s->pblocks[%d]=%p ,s->block=%p cbp=%d\n",i,s->pblocks[i],s->block,cbp); | |||
} | |||
if (s->chroma_format >= 2){ | |||
if (s->chroma_format == 2){//CHROMA_422 | |||
for(i=6;i<8;i++){ | |||
if(cbp & (1<<(6+7-i)) ){ | |||
s->pblocks[i] = (short *)(&s->block[(j++)]); | |||
}else{ | |||
s->pblocks[i] = NULL; | |||
} | |||
} | |||
}else{//CHROMA_444 | |||
for(i=6; i<12; i++){ | |||
if(cbp & (1<<(6+11-i)) ){ | |||
s->pblocks[i] = (short *)(&s->block[(j++)]); | |||
}else{ | |||
s->pblocks[i] = NULL; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
static int calc_cbp(MpegEncContext *s, int blocknum){ | |||
static int calc_cbp(MpegEncContext *s){ | |||
/* compute cbp */ | |||
// for I420 bit_offset=5 | |||
int i,cbp = 0; | |||
for(i=0; i<blocknum; i++) { | |||
for(i=0; i<4; i++) { | |||
if(s->block_last_index[i] >= 0) | |||
cbp |= 1 << (5 - i); | |||
} | |||
if(s->flags & CODEC_FLAG_GRAY) | |||
return cbp; //4 block for grayscale one done | |||
for(i=4; i<6; i++) { | |||
if(s->block_last_index[i] >= 0) | |||
cbp |= 1 << (5 - i); | |||
} | |||
if(s->chroma_format < 2) return cbp; | |||
if(s->chroma_format == 2){/*CHROMA_422*/ | |||
for(i=6; i<8; i++) { | |||
if(s->block_last_index[i] >= 0) | |||
cbp |= 1 << (6+7 - i); | |||
} | |||
}else{/*CHROMA_444*/ | |||
for(i=6; i<12; i++) { | |||
if(s->block_last_index[i] >= 0) | |||
cbp |= 1 << (6+11 - i); | |||
} | |||
} | |||
return cbp; | |||
} | |||
@@ -121,7 +160,7 @@ xvmc_render_state_t * render,* last, * next; | |||
assert(last->state & MP_XVMC_STATE_PREDICTION); | |||
render->p_past_surface = last->p_surface; | |||
return 0; | |||
} | |||
} | |||
return -1; | |||
} | |||
@@ -256,17 +295,12 @@ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; | |||
}//!intra | |||
//time to handle data blocks; | |||
mv_block->index = render->next_free_data_block_num; | |||
blocks_per_mb = 6; | |||
/* | |||
switch( s->chroma_format){ | |||
case CHROMA_422: | |||
blocks_per_mb = 8; | |||
break; | |||
case CHROMA_444: | |||
blocks_per_mb = 12; | |||
break; | |||
if( s->chroma_format >= 2){ | |||
block_per_mb = 4 + (1 << (s->chroma_format)); | |||
} | |||
*/ | |||
if(s->flags & CODEC_FLAG_GRAY){ | |||
if(s->mb_intra){//intra frames are alwasy full chroma block | |||
for(i=4; i<blocks_per_mb; i++){ | |||
@@ -277,7 +311,7 @@ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; | |||
}else | |||
blocks_per_mb = 4;//Luminance blocks only | |||
} | |||
cbp = calc_cbp(s,blocks_per_mb); | |||
cbp = calc_cbp(s); | |||
mv_block->coded_block_pattern = cbp; | |||
if(cbp == 0) | |||
mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN; | |||