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; | |||