Originally committed as revision 2833 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -291,6 +291,8 @@ extern int motion_estimation_method; | |||||
used */ | used */ | ||||
#define CODEC_CAP_PARSE_ONLY 0x0004 | #define CODEC_CAP_PARSE_ONLY 0x0004 | ||||
#define CODEC_CAP_TRUNCATED 0x0008 | #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 | //the following defines might change, so dont expect compatibility if u use them | ||||
#define MB_TYPE_INTRA4x4 0x0001 | #define MB_TYPE_INTRA4x4 0x0001 | ||||
@@ -1010,7 +1010,7 @@ static inline int get_qscale(MpegEncContext *s) | |||||
#define MT_DMV 3 | #define MT_DMV 3 | ||||
static int mpeg_decode_mb(MpegEncContext *s, | 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; | int i, j, k, cbp, val, mb_type, motion_type; | ||||
@@ -1026,7 +1026,7 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||||
/* skip mb */ | /* skip mb */ | ||||
s->mb_intra = 0; | s->mb_intra = 0; | ||||
for(i=0;i<6;i++) | |||||
for(i=0;i<12;i++) | |||||
s->block_last_index[i] = -1; | s->block_last_index[i] = -1; | ||||
if(s->picture_structure == PICT_FRAME) | if(s->picture_structure == PICT_FRAME) | ||||
s->mv_type = MV_TYPE_16X16; | s->mv_type = MV_TYPE_16X16; | ||||
@@ -1126,7 +1126,7 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||||
#endif | #endif | ||||
if (s->codec_id == CODEC_ID_MPEG2VIDEO) { | 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) | if (mpeg2_decode_block_intra(s, s->pblocks[i], i) < 0) | ||||
return -1; | return -1; | ||||
} | } | ||||
@@ -1311,6 +1311,12 @@ static int mpeg_decode_mb(MpegEncContext *s, | |||||
return -1; | return -1; | ||||
} | } | ||||
cbp++; | 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 | #ifdef HAVE_XVMC | ||||
//on 1 we memcpy blocks in xvmcvideo | //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) { | if (s->codec_id == CODEC_ID_MPEG2VIDEO) { | ||||
for(i=0;i<6;i++) { | 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) | if (mpeg2_decode_block_non_intra(s, s->pblocks[i], i) < 0) | ||||
return -1; | return -1; | ||||
} else { | } else { | ||||
s->block_last_index[i] = -1; | 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 { | } else { | ||||
for(i=0;i<6;i++) { | for(i=0;i<6;i++) { | ||||
@@ -1654,7 +1680,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, | |||||
component = 0; | component = 0; | ||||
}else{ | }else{ | ||||
quant_matrix = s->chroma_intra_matrix; | quant_matrix = s->chroma_intra_matrix; | ||||
component = n - 3; | |||||
component = (n&1) + 1; | |||||
} | } | ||||
diff = decode_dc(&s->gb, component); | diff = decode_dc(&s->gb, component); | ||||
if (diff >= 0xffff) | if (diff >= 0xffff) | ||||
@@ -1817,13 +1843,13 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s) | |||||
profile= get_bits(&s->gb, 3); | profile= get_bits(&s->gb, 3); | ||||
level= get_bits(&s->gb, 4); | level= get_bits(&s->gb, 4); | ||||
s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */ | 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); | horiz_size_ext = get_bits(&s->gb, 2); | ||||
vert_size_ext = get_bits(&s->gb, 2); | vert_size_ext = get_bits(&s->gb, 2); | ||||
s->width |= (horiz_size_ext << 12); | s->width |= (horiz_size_ext << 12); | ||||
s->height |= (vert_size_ext << 12); | s->height |= (vert_size_ext << 12); | ||||
bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */ | 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 */ | skip_bits1(&s->gb); /* marker */ | ||||
s->avctx->rc_buffer_size += get_bits(&s->gb, 8)*1024*16<<10; | 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. | * finds the end of the current frame in the bitstream. | ||||
* @return the position of the first byte of the next frame, or -1 | * @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); | buf_ptr, input_size); | ||||
break; | break; | ||||
case GOP_START_CODE: | case GOP_START_CODE: | ||||
s2->first_field=0; | |||||
mpeg_decode_gop(avctx, buf_ptr, input_size); | |||||
break; | break; | ||||
default: | default: | ||||
if (start_code >= SLICE_MIN_START_CODE && | if (start_code >= SLICE_MIN_START_CODE && | ||||
@@ -2850,7 +2907,8 @@ AVCodec mpeg_xvmc_decoder = { | |||||
NULL, | NULL, | ||||
mpeg_decode_end, | mpeg_decode_end, | ||||
mpeg_decode_frame, | 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 | #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_h_scantable, ff_alternate_horizontal_scan); | ||||
ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); | ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan); | ||||
s->picture_structure= PICT_FRAME; | |||||
return 0; | 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->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]; | s->block= s->blocks[0]; | ||||
for(i=0;i<12;i++){ | for(i=0;i<12;i++){ | ||||
@@ -539,9 +537,18 @@ int MPV_common_init(MpegEncContext *s) | |||||
s->y_dc_scale_table= | s->y_dc_scale_table= | ||||
s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | s->c_dc_scale_table= ff_mpeg1_dc_scale_table; | ||||
s->chroma_qscale_table= ff_default_chroma_qscale_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; | s->coded_picture_number = 0; | ||||
y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); | 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_pict_type; | ||||
int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol | int last_non_b_pict_type; ///< used for mpeg4 gmc b-frames & ratecontrol | ||||
int frame_rate_index; | 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 */ | /* motion compensation */ | ||||
int unrestricted_mv; ///< mv can point outside of the coded picture | int unrestricted_mv; ///< mv can point outside of the coded picture | ||||
int h263_long_vectors; ///< use horrible h263v1 long vector mode | 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*/ | /** 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_intra_matrix16)[2][64]; | ||||
uint16_t (*q_inter_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 */ | /* scantables */ | ||||
ScanTable __align8 intra_scantable; | ScanTable __align8 intra_scantable; | ||||
ScanTable intra_h_scantable; | ScanTable intra_h_scantable; | ||||
@@ -653,6 +656,11 @@ typedef struct MpegEncContext { | |||||
int alternate_scan; | int alternate_scan; | ||||
int repeat_first_field; | int repeat_first_field; | ||||
int chroma_420_type; | int chroma_420_type; | ||||
int chroma_format; | |||||
#define CHROMA_420 1 | |||||
#define CHROMA_422 2 | |||||
#define CHROMA_444 3 | |||||
int progressive_frame; | int progressive_frame; | ||||
int full_pel[2]; | int full_pel[2]; | ||||
int interlaced_dct; | int interlaced_dct; | ||||
@@ -55,27 +55,66 @@ xvmc_render_state_t * render; | |||||
void XVMC_pack_pblocks(MpegEncContext *s, int cbp){ | void XVMC_pack_pblocks(MpegEncContext *s, int cbp){ | ||||
int i,j; | int i,j; | ||||
#define numblocks 6 | |||||
j=0; | 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++)]); | s->pblocks[i] = (short *)(&s->block[(j++)]); | ||||
}else{ | }else{ | ||||
s->pblocks[i] = NULL; | s->pblocks[i] = NULL; | ||||
} | } | ||||
// printf("s->pblocks[%d]=%p ,s->block=%p cbp=%d\n",i,s->pblocks[i],s->block,cbp); | // 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 */ | /* compute cbp */ | ||||
// for I420 bit_offset=5 | |||||
int i,cbp = 0; | int i,cbp = 0; | ||||
for(i=0; i<blocknum; i++) { | |||||
for(i=0; i<4; i++) { | |||||
if(s->block_last_index[i] >= 0) | if(s->block_last_index[i] >= 0) | ||||
cbp |= 1 << (5 - i); | 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; | return cbp; | ||||
} | } | ||||
@@ -121,7 +160,7 @@ xvmc_render_state_t * render,* last, * next; | |||||
assert(last->state & MP_XVMC_STATE_PREDICTION); | assert(last->state & MP_XVMC_STATE_PREDICTION); | ||||
render->p_past_surface = last->p_surface; | render->p_past_surface = last->p_surface; | ||||
return 0; | return 0; | ||||
} | |||||
} | |||||
return -1; | return -1; | ||||
} | } | ||||
@@ -256,17 +295,12 @@ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; | |||||
}//!intra | }//!intra | ||||
//time to handle data blocks; | //time to handle data blocks; | ||||
mv_block->index = render->next_free_data_block_num; | mv_block->index = render->next_free_data_block_num; | ||||
blocks_per_mb = 6; | 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->flags & CODEC_FLAG_GRAY){ | ||||
if(s->mb_intra){//intra frames are alwasy full chroma block | if(s->mb_intra){//intra frames are alwasy full chroma block | ||||
for(i=4; i<blocks_per_mb; i++){ | 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 | }else | ||||
blocks_per_mb = 4;//Luminance blocks only | blocks_per_mb = 4;//Luminance blocks only | ||||
} | } | ||||
cbp = calc_cbp(s,blocks_per_mb); | |||||
cbp = calc_cbp(s); | |||||
mv_block->coded_block_pattern = cbp; | mv_block->coded_block_pattern = cbp; | ||||
if(cbp == 0) | if(cbp == 0) | ||||
mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN; | mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN; | ||||