Commit 5e5c247a authored by Ivan Kalvachev's avatar Ivan Kalvachev

initial chroma_format changes,xvmc tweaks and codec_cap

Originally committed as revision 2833 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 3f1d4e96
...@@ -291,6 +291,8 @@ extern int motion_estimation_method; ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 = { ...@@ -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) ...@@ -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){ ...@@ -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) ...@@ -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->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) if (!s->encoding)
s->progressive_sequence= 1; s->progressive_sequence= 1;
s->progressive_frame= 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 { ...@@ -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 { ...@@ -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 { ...@@ -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; ...@@ -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++){ for(i=0;i<6;i++){
if(cbp & (1<<(numblocks-1-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;
} }
...@@ -256,17 +295,12 @@ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; ...@@ -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;
/* if( s->chroma_format >= 2){
switch( s->chroma_format){ block_per_mb = 4 + (1 << (s->chroma_format));
case CHROMA_422:
blocks_per_mb = 8;
break;
case CHROMA_444:
blocks_per_mb = 12;
break;
} }
*/
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; ...@@ -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;
......
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