]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h264.c
initial commit for Id RoQ and Interplay MVE multimedia subsystems
[ffmpeg] / libavcodec / h264.c
index 62550f9f3786b164000974e3dec6a4fc5312efa5..ef17407fd76430f9062f912adc21b29bde9149c0 100644 (file)
@@ -59,9 +59,6 @@ typedef struct SPS{
     
     int profile_idc;
     int level_idc;
-    int multiple_slice_groups;         ///< more_than_one_slice_group_allowed_flag
-    int arbitrary_slice_order;         ///< arbitrary_slice_order_allowed_flag
-    int redundant_slices;              ///< redundant_slices_allowed_flag
     int log2_max_frame_num;            ///< log2_max_frame_num_minus4 + 4
     int poc_type;                      ///< pic_order_cnt_type
     int log2_max_poc_lsb;              ///< log2_max_pic_order_cnt_lsb_minus4
@@ -70,12 +67,17 @@ typedef struct SPS{
     int offset_for_top_to_bottom_field;
     int poc_cycle_length;              ///< num_ref_frames_in_pic_order_cnt_cycle
     int ref_frame_count;               ///< num_ref_frames
-    int required_frame_num_update_behaviour_flag;
+    int gaps_in_frame_num_allowed_flag;
     int mb_width;                      ///< frame_width_in_mbs_minus1 + 1
     int mb_height;                     ///< frame_height_in_mbs_minus1 + 1
     int frame_mbs_only_flag;
     int mb_aff;                        ///<mb_adaptive_frame_field_flag
     int direct_8x8_inference_flag;
+    int crop;                   ///< frame_cropping_flag
+    int crop_left;              ///< frame_cropping_rect_left_offset
+    int crop_right;             ///< frame_cropping_rect_right_offset
+    int crop_top;               ///< frame_cropping_rect_top_offset
+    int crop_bottom;            ///< frame_cropping_rect_bottom_offset
     int vui_parameters_present_flag;
     int sar_width;
     int sar_height;
@@ -100,11 +102,6 @@ typedef struct PPS{
     int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag
     int constrained_intra_pred; ///< constrained_intra_pred_flag
     int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
-    int crop;                   ///< frame_cropping_flag
-    int crop_left;              ///< frame_cropping_rect_left_offset
-    int crop_right;             ///< frame_cropping_rect_right_offset
-    int crop_top;               ///< frame_cropping_rect_top_offset
-    int crop_bottom;            ///< frame_cropping_rect_bottom_offset
 }PPS;
 
 /**
@@ -198,6 +195,9 @@ typedef struct H264Context{
     int halfpel_flag;
     int thirdpel_flag;
 
+    int unknown_svq3_flag;
+    int next_slice_index;
+
     SPS sps_buffer[MAX_SPS_COUNT];
     SPS sps; ///< current sps
     
@@ -297,6 +297,14 @@ static VLC run7_vlc;
 static void svq3_luma_dc_dequant_idct_c(DCTELEM *block, int qp);
 static void svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, int dc);
 
+static inline uint32_t pack16to32(int a, int b){
+#ifdef WORDS_BIGENDIAN
+   return (b&0xFFFF) + (a<<16);
+#else
+   return (a&0xFFFF) + (b<<16);
+#endif
+}
+
 /**
  * fill a rectangle.
  * @param h height of the recatangle, should be a constant
@@ -778,7 +786,6 @@ static inline void pred_motion(H264Context * const h, int n, int part_width, int
 
     diagonal_ref= fetch_diagonal_mv(h, &C, index8, list, part_width);
     match_count= (diagonal_ref==ref) + (top_ref==ref) + (left_ref==ref);
-    
     if(match_count > 1){ //most common
         *mx= mid_pred(A[0], B[0], C[0]);
         *my= mid_pred(A[1], B[1], C[1]);
@@ -1476,7 +1483,7 @@ static void pred4x4_down_right_c(uint8_t *src, uint8_t *topright, int stride){
     src[2+0*stride]=
     src[3+1*stride]=(t0 + 2*t1 + t2 + 2)>>2;
     src[3+0*stride]=(t1 + 2*t2 + t3 + 2)>>2;
-};
+}
 
 static void pred4x4_down_left_c(uint8_t *src, uint8_t *topright, int stride){
     LOAD_TOP_EDGE    
@@ -1499,7 +1506,7 @@ static void pred4x4_down_left_c(uint8_t *src, uint8_t *topright, int stride){
     src[3+2*stride]=
     src[2+3*stride]=(t5 + t7 + 2*t6 + 2)>>2;
     src[3+3*stride]=(t6 + 3*t7 + 2)>>2;
-};
+}
 
 static void pred4x4_vertical_right_c(uint8_t *src, uint8_t *topright, int stride){
     const int lt= src[-1-1*stride];
@@ -1523,7 +1530,7 @@ static void pred4x4_vertical_right_c(uint8_t *src, uint8_t *topright, int stride
     src[3+1*stride]=(t1 + 2*t2 + t3 + 2)>>2;
     src[0+2*stride]=(lt + 2*l0 + l1 + 2)>>2;
     src[0+3*stride]=(l0 + 2*l1 + l2 + 2)>>2;
-};
+}
 
 static void pred4x4_vertical_left_c(uint8_t *src, uint8_t *topright, int stride){
     LOAD_TOP_EDGE    
@@ -1546,7 +1553,7 @@ static void pred4x4_vertical_left_c(uint8_t *src, uint8_t *topright, int stride)
     src[3+1*stride]=
     src[2+3*stride]=(t3 + 2*t4 + t5 + 2)>>2;
     src[3+3*stride]=(t4 + 2*t5 + t6 + 2)>>2;
-};
+}
 
 static void pred4x4_horizontal_up_c(uint8_t *src, uint8_t *topright, int stride){
     LOAD_LEFT_EDGE    
@@ -1567,7 +1574,7 @@ static void pred4x4_horizontal_up_c(uint8_t *src, uint8_t *topright, int stride)
     src[2+2*stride]=
     src[2+3*stride]=
     src[3+3*stride]=l3;
-};
+}
     
 static void pred4x4_horizontal_down_c(uint8_t *src, uint8_t *topright, int stride){
     const int lt= src[-1-1*stride];
@@ -1591,7 +1598,7 @@ static void pred4x4_horizontal_down_c(uint8_t *src, uint8_t *topright, int strid
     src[3+3*stride]=(l0 + 2*l1 + l2 + 2)>>2;
     src[0+3*stride]=(l2 + l3 + 1)>>1;
     src[1+3*stride]=(l1 + 2*l2 + l3 + 2)>>2;
-};
+}
 
 static void pred16x16_vertical_c(uint8_t *src, int stride){
     int i;
@@ -1701,6 +1708,9 @@ static inline void pred16x16_plane_compat_c(uint8_t *src, int stride, const int
   if(svq3){
     H = ( 5*(H/4) ) / 16;
     V = ( 5*(V/4) ) / 16;
+
+    /* required for 100% accuracy */
+    i = H; H = V; V = i;
   }else{
     H = ( 5*H+32 ) >> 6;
     V = ( 5*V+32 ) >> 6;
@@ -1887,7 +1897,7 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
        || full_my < 0-extra_height 
        || full_mx + 16/*FIXME*/ > s->width + extra_width 
        || full_my + 16/*FIXME*/ > s->height + extra_height){
-        ff_emulated_edge_mc(s, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, s->width, s->height);
+        ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, s->width, s->height);
             src_y= s->edge_emu_buffer + 2 + 2*s->linesize;
         emu=1;
     }
@@ -1900,13 +1910,13 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
     if(s->flags&CODEC_FLAG_GRAY) return;
     
     if(emu){
-        ff_emulated_edge_mc(s, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
+        ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
             src_cb= s->edge_emu_buffer;
     }
     chroma_op(dest_cb, src_cb, s->uvlinesize, chroma_height, mx&7, my&7);
 
     if(emu){
-        ff_emulated_edge_mc(s, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
+        ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
             src_cr= s->edge_emu_buffer;
     }
     chroma_op(dest_cr, src_cr, s->uvlinesize, chroma_height, mx&7, my&7);
@@ -2092,16 +2102,6 @@ static void init_pred_ptrs(H264Context *h){
     h->pred16x16[DC_128_PRED8x8 ]= pred16x16_128_dc_c;
 }
 
-//FIXME factorize
-#define CHECKED_ALLOCZ(p, size)\
-{\
-    p= av_mallocz(size);\
-    if(p==NULL){\
-        perror("malloc");\
-        goto fail;\
-    }\
-}
-
 static void free_tables(H264Context *h){
     av_freep(&h->intra4x4_pred_mode);
     av_freep(&h->non_zero_count);
@@ -2872,16 +2872,12 @@ static int decode_slice_header(H264Context *h){
     s->mb_x = first_mb_in_slice % s->mb_width;
     s->mb_y = first_mb_in_slice / s->mb_width; //FIXME AFFW
     
-    s->width = 16*s->mb_width - 2*(h->pps.crop_left + h->pps.crop_right );
+    s->width = 16*s->mb_width - 2*(h->sps.crop_left + h->sps.crop_right );
     if(h->sps.frame_mbs_only_flag)
-        s->height= 16*s->mb_height - 2*(h->pps.crop_top  + h->pps.crop_bottom);
+        s->height= 16*s->mb_height - 2*(h->sps.crop_top  + h->sps.crop_bottom);
     else
-        s->height= 16*s->mb_height - 4*(h->pps.crop_top  + h->pps.crop_bottom); //FIXME recheck
+        s->height= 16*s->mb_height - 4*(h->sps.crop_top  + h->sps.crop_bottom); //FIXME recheck
     
-    if(h->pps.crop_left || h->pps.crop_top){
-        fprintf(stderr, "insane croping not completly supported, this could look slightly wrong ...\n");
-    }
-
     if(s->aspected_height) //FIXME emms at end of slice ?
         new_aspect= h->sps.sar_width*s->width / (float)(s->height*h->sps.sar_height);
     else
@@ -3226,7 +3222,7 @@ static int decode_mb(H264Context *h){
             fill_caches(h, mb_type); //FIXME check what is needed and what not ...
             pred_pskip_motion(h, &mx, &my);
             fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
-            fill_rectangle(  h->mv_cache[0][scan8[0]], 4, 4, 8, (mx&0xFFFF)+(my<<16), 4);
+            fill_rectangle(  h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx,my), 4);
             write_back_motion(h, mb_type);
 
             s->current_picture.mb_type[mb_xy]= mb_type; //FIXME SKIP type
@@ -3456,7 +3452,7 @@ decode_intra_mb:
                     my += get_se_golomb(&s->gb);
                     tprintf("final mv:%d %d\n", mx, my);
 
-                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, (mx&0xFFFF) + (my<<16), 4);
+                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
                 }
             }
         }
@@ -3479,7 +3475,7 @@ decode_intra_mb:
                         my += get_se_golomb(&s->gb);
                         tprintf("final mv:%d %d\n", mx, my);
 
-                        fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (mx&0xFFFF) + (my<<16), 4);
+                        fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
                     }
                 }
             }
@@ -3503,7 +3499,7 @@ decode_intra_mb:
                         my += get_se_golomb(&s->gb);
                         tprintf("final mv:%d %d\n", mx, my);
 
-                        fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (mx&0xFFFF) + (my<<16), 4);
+                        fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
                     }
                 }
             }
@@ -3803,28 +3799,23 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
 
 static inline int decode_seq_parameter_set(H264Context *h){
     MpegEncContext * const s = &h->s;
-    int profile_idc, level_idc, multiple_slice_groups, arbitrary_slice_order, redundant_slices;
+    int profile_idc, level_idc;
     int sps_id, i;
     SPS *sps;
     
     profile_idc= get_bits(&s->gb, 8);
+    get_bits1(&s->gb);   //constraint_set0_flag
+    get_bits1(&s->gb);   //constraint_set1_flag
+    get_bits1(&s->gb);   //constraint_set2_flag
+    get_bits(&s->gb, 5); // reserved
     level_idc= get_bits(&s->gb, 8);
-    multiple_slice_groups= get_bits1(&s->gb);
-    arbitrary_slice_order= get_bits1(&s->gb);
-    redundant_slices= get_bits1(&s->gb);
-    
     sps_id= get_ue_golomb(&s->gb);
     
     sps= &h->sps_buffer[ sps_id ];
-    
     sps->profile_idc= profile_idc;
     sps->level_idc= level_idc;
-    sps->multiple_slice_groups= multiple_slice_groups;
-    sps->arbitrary_slice_order= arbitrary_slice_order;
-    sps->redundant_slices= redundant_slices;
     
     sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4;
-
     sps->poc_type= get_ue_golomb(&s->gb);
     
     if(sps->poc_type == 0){ //FIXME #define
@@ -3844,7 +3835,7 @@ static inline int decode_seq_parameter_set(H264Context *h){
     }
 
     sps->ref_frame_count= get_ue_golomb(&s->gb);
-    sps->required_frame_num_update_behaviour_flag= get_bits1(&s->gb);
+    sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
     sps->mb_width= get_ue_golomb(&s->gb) + 1;
     sps->mb_height= get_ue_golomb(&s->gb) + 1;
     sps->frame_mbs_only_flag= get_bits1(&s->gb);
@@ -3855,18 +3846,36 @@ static inline int decode_seq_parameter_set(H264Context *h){
 
     sps->direct_8x8_inference_flag= get_bits1(&s->gb);
 
+    sps->crop= get_bits1(&s->gb);
+    if(sps->crop){
+        sps->crop_left  = get_ue_golomb(&s->gb);
+        sps->crop_right = get_ue_golomb(&s->gb);
+        sps->crop_top   = get_ue_golomb(&s->gb);
+        sps->crop_bottom= get_ue_golomb(&s->gb);
+        if(sps->crop_left || sps->crop_top){
+            fprintf(stderr, "insane croping not completly supported, this could look slightly wrong ...\n");
+        }
+    }else{
+        sps->crop_left  = 
+        sps->crop_right = 
+        sps->crop_top   = 
+        sps->crop_bottom= 0;
+    }
+
     sps->vui_parameters_present_flag= get_bits1(&s->gb);
     if( sps->vui_parameters_present_flag )
         decode_vui_parameters(h, sps);
     
     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        printf("sps:%d profile:%d/%d poc:%d ref:%d %dx%d %s %s %s\n", 
+        printf("sps:%d profile:%d/%d poc:%d ref:%d %dx%d %s %s crop:%d/%d/%d/%d %s\n", 
                sps_id, sps->profile_idc, sps->level_idc,
                sps->poc_type,
                sps->ref_frame_count,
                sps->mb_width, sps->mb_height,
                sps->frame_mbs_only_flag ? "FRM" : (sps->mb_aff ? "MB-AFF" : "PIC-AFF"),
                sps->direct_8x8_inference_flag ? "8B8" : "",
+               sps->crop_left, sps->crop_right, 
+               sps->crop_top, sps->crop_bottom, 
                sps->vui_parameters_present_flag ? "VUI" : ""
                );
     }
@@ -3934,21 +3943,9 @@ fprintf(stderr, "FMO not supported\n");
     pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
     pps->constrained_intra_pred= get_bits1(&s->gb);
     pps->redundant_pic_cnt_present = get_bits1(&s->gb);
-    pps->crop= get_bits1(&s->gb);
-    if(pps->crop){
-        pps->crop_left  = get_ue_golomb(&s->gb);
-        pps->crop_right = get_ue_golomb(&s->gb);
-        pps->crop_top   = get_ue_golomb(&s->gb);
-        pps->crop_bottom= get_ue_golomb(&s->gb);
-    }else{
-        pps->crop_left  = 
-        pps->crop_right = 
-        pps->crop_top   = 
-        pps->crop_bottom= 0;
-    }
     
     if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-        printf("pps:%d sps:%d %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s crop:%d/%d/%d/%d\n", 
+        printf("pps:%d sps:%d %s slice_groups:%d ref:%d/%d %s qp:%d/%d/%d %s %s %s\n", 
                pps_id, pps->sps_id,
                pps->cabac ? "CABAC" : "CAVLC",
                pps->slice_group_count,
@@ -3957,9 +3954,7 @@ fprintf(stderr, "FMO not supported\n");
                pps->init_qp, pps->init_qs, pps->chroma_qp_index_offset,
                pps->deblocking_filter_parameters_present ? "LPAR" : "",
                pps->constrained_intra_pred ? "CONSTR" : "",
-               pps->redundant_pic_cnt_present ? "REDU" : "",
-               pps->crop_left, pps->crop_right, 
-               pps->crop_top, pps->crop_bottom
+               pps->redundant_pic_cnt_present ? "REDU" : ""
                );
     }
     
@@ -3998,8 +3993,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
     MpegEncContext * const s = &h->s;
     AVCodecContext * const avctx= s->avctx;
     int buf_index=0;
+#if 0
     int i;
-#if 0    
     for(i=0; i<32; i++){
         printf("%X ", buf[i]);
     }