initial chroma_format changes,xvmc tweaks and codec_cap
authorIvan Kalvachev <ikalvachev@gmail.com>
Mon, 1 Mar 2004 14:55:21 +0000 (14:55 +0000)
committerIvan Kalvachev <ikalvachev@gmail.com>
Mon, 1 Mar 2004 14:55:21 +0000 (14:55 +0000)
Originally committed as revision 2833 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/avcodec.h
libavcodec/mpeg12.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/xvmcvideo.c

index e6e0338..b29653e 100644 (file)
@@ -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
index 98fca0a..ee99bd1 100644 (file)
@@ -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
index 828e74a..7a9889b 100644 (file)
@@ -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);
index 51cc5e1..3c3dcdb 100644 (file)
@@ -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;
index eed9860..cd64f4c 100644 (file)
@@ -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;