2009년 9월 1일 화요일

H.264 Encoder Driver / Test Code

* H.264/AVC Encoder Test Code

 

 

Code Overview                                                                                                           

 

main 

   1) h264_encoder_create()

 

      1-1) start_sequence()

 

           1-1-1) init_sps_nalu()

 

           1-1-2) init_pps_nalu()

 

           1-1-3) generate_sps_nalu() ========> SPS NAL Unit

 

           1-1-4) generate_pps_nalu() ========> PPS NAL Unit

 

   loop()

  {

   2) h264_encoder_encode()

      * Register Setting

      2-1) start_slice

      * Register Setting

      * Param Data Setting

 

      2-2) frame_code_I() (or frame_code_p())

      2-2) frame_code_p() (or frame_code_I()) 

      2-3) termiate_slice()

 

      ========> NAL Unit (I / P Slice )

   }

   3) h264_encoder_destroy()

 

 

* H.264 / AVC Encoder  Data Stream

 

 SPS

 PPS

 I

P

P

P

 ...

... 

 

                                                                                                                              

 

 

main

 

   1) h264_encoder_create()

      Encoder pattern description file을 읽어 Structure에 파싱하고

 

      * Register Setting

      설정할 Structure에 값으로, Register를 셋팅한다

 

      - PARM0 :

        각 encoded picture에서 Macroblocks의 갯수

        Macroblock 단위의 encoded picture의 Height

        Macroblock 단위의 encoded picture의 Width

 

      - PARM1 :

        Chroma QP Offset (chroma_qp_index_offset), -12 ~+12

        Alpha offset (slice_alpha_c0_offset_div2)

        Beta offset (slice_beta_offset_div2)

        LCT(Luma coefficients threshold), 0~7

        CCT(Chroma coefficients threshold), 0~7

        Coefficient threshold disable (0:Enable, 1:Disable)

        Intra I 4 * 4 number of modes (0 : 5 , 1 : 9)

 

      - PARM2 : Wathermark 

 

      - PARM4 :

        Disable deblocking operation (0 : Enable, 1 : Disable)

        QPy 의 initial value (Valid value : 0~51)

 

      - PARM6 :

        CbCr data of the current frame in the address mode

        ( 0 : Interleaved CbCr, 1 : Separated CbCr)

 

      - DMAA0 :

        System memory base address (word)

 

      - DMAC0 :

        Transfer length in unit of word

 

      - DMAA1 :

        System memory address increment

        System memory base address (word)

 

      - DMAC1 :

        The transfer length in units of word

        Transfer type (00 : Sequential address mode, 10 : Circular address mode)

        Transfer direction (0 : system -> internal memory, 1 : internal -> system memory)

 

      1-1) start_sequence()

 

           1-1-1) init_sps_nalu()

           SPS(Sequence Parameter Set) : 프로파일, 레벨 등 시퀀스 전체의 부호화에 걸쳐있는

           정보가 포함되어 있는 헤더정보이다. 단, SPC는 시퀀스의 선두에 바로 붙여 지는 것이

           아니고 시퀀스 선두위치에 이르기까지 가장 최근에 보내진 SPS를 헤더정보로 하여 사용함

          

           - profile_idc :

             비트열의 프로파일

 

           - constraint_set0_flag :

             비트열이 베이스라인 프로파일로 복호가능함을 표시하는 플래그

 

           - constraint_set1_flag :

             비트열이 메인 프로파일로 복호 가능함을 표시하는 플래그

 

           - constraint_set2_flag :

             비트열이 확장 프로파일로 복호 가능함을 표시하는 플래그

 

           - constraint_set3_flag :

             레벨로 비트열의 복호가 가능한지를 표시하는 플래그 (FRExt에서..)

 

           - level_idc :

             비트열의 레벨

 

           - seq_parameter_set_id :

             SPS의 ID. PPS는 이 ID를 지정하고 참조한다 0~31의 값을 가진다

 

           - log2_max_frame_num_minus4 :

             0~12의 값을 가지며, 프레임번호를 구할때 최대프레임 번호를 지정하는 파라미터

 

           - pic_order_cnt_type :

             POC(Picture Order Count)의 복호방법을 지정,0~2 의 값을 가짐

          

           - log2_max_pic_order_cnt_lsb_minus4 :

             POC 유형 1에서 MaxPicOrderCntLsb를 추출할 때 사용 0~12의 값을 가짐

 

           - num_ref_frame :

             참조프레임의 최대값을 지정. 0~16의 값을 갖는다

 

           - gqps_in_frame_num_value_allowed_flag :

             값이 1이면, frame_num에 차이가 존재하는 것이 허용된다

 

           - pic_width_in_mbs_minus1 :

             부호화되는 픽쳐의 수평방향 매크로블록 수

 

           - pic_height_in_map_units_minus1 :

             Pic_HeightInMapUnits와 PicSizeInMapUnits을 지정

             PicHeightInMapUnits = pic_height_in_map_units_minus1 + 1

             PicSizeInMapUnits = PicWidthIn * PicHeightInMapUnits

 

           - frame_mbs_only_flag :

             값이 1이면, 프레임 매크로블록 안에 포함된다

 

           - direct_8x8_inference_flag :

             B_Skip, B_Direct_16x16 및 B_Direct_8x8에서의 움직임벡터 추출에 사용된다

             frame_mbs_only_flag의 값이 0dlaus, direct_8x8_inference_flag는 1이다

 

           - frame_cropping_flag :

             값이 1이면, Frame Cropping 에 관한 파라미터가 전송된다

 

           - vui_parameters_present_flag :

             값이 1이면, VUI(Video Usability Information, 비디오표시정보) 파라미터를 전송한다

 

 

           1-1-2) init_pps_nalu()

           PPS(Picture Parameter Set)란 픽쳐 전체의 부호화 모드를 나타내는 헤더정보이다

           PPS는 모든 픽쳐에 반드시 붙여지는 것이 아니고 PPS가 없을 경우 픽쳐의 선두 위치에

           이르기까지 가장 최근에 보내진 PPS를 헤더정보로 하여 사용한다

 

           - pic_parameter_set_id :

             픽쳐 파라미터 세트의 ID. 슬라이스 벡터에서는 이 ID를 지정해서 참조한다

             0~255의 값을 갖는다

 

           - seq_parameter_set_id :

             이 픽쳐 파라미터 세트가 참조하는 SPS의 ID. 0~31의 값을 갖는다

 

           - entropy_coding_mode_flag :

             엔트로피 부호화의 모드를 가리키는 플래그.(0 :CAVLC, 1:CABAC)

 

           - pic_order_present_flag :

             값이 1이면 슬라이스 헤더에서 POC와 관련된 정보를 전송한다

 

           - num_slice_groups_minus1 :

             이 값에 1을 더한 것이 슬라이스 그룹의 수가된다. 값이 0이면 모든 슬라이스가

             동일한 슬라이스 그룹에 속하는 것이 된다

 

           - num_ref_idx_10_active_minus1 :

             num_ref_idx_active_override_flag의 값이 0이면, 참조 픽쳐 리스트 0 에서의 참조

             인덱스의 최대값을 규정한다. 이 값에 1을 더한것이 참조 인덱스의 최대값이 된다

             MbaffFrameFlag가 1인경우, num_ref_idx_10_active_minus1은 프레임 매크로블록에서

             참조 인덱스의 최대값이 되고 필드 매크로블록에서는 2*num_ref_idx_10_active_minus1

             +1 이 참조 인덱스의 최대값이 된다. (0~31의 값을 갖는다)

 

           - num_ref_idx_11_active_minus1 :

             참조 픽쳐 리스트 1에 대한 참조 인덱스의 최대값을 규정

             2*num_ref_idx_10_active_minus1 과 같다

 

           - weighted_pred_flag :

             값이 1이면 P 또는 SP 슬라이스에서 가중치 예측을 사용한다

 

           - weighted_bipred_idc:

             값이 1이면 명시적(Explicit)모드에서 가중치 예측이 B슬라이스에 적용된다

          

           - pic_init_qp_minus26 :

             이 값은 26을 더한 값이 각 슬라이스에서의 휘도에 대해서 양자화 스케일 SliceQSy의

             초기값이 된다

 

           - pic_init_qs_minus26 :

             이 값은 26을 더한 값이 각 SI 또는 SP슬라이스에서 휘도에 대한 양자화 스케일

             SliceQSy의초기값이 된다

 

           - chroma_qp_index_offset :

             색차의 양자화 스케일 QPC(Quantization Parameter - Chroma)를 결정할 때 표참조에

             사용되는 Offset값. -12 ~ +12 의 값을 갖는다

 

           - deblocking_filter_control_present_flag :

             값이 1이면, 디블록킹 필터의 특성을 변경하는 파라미터가 전송된다

 

           - constrained_intra_pred_flag:

             값이 1이면, 화면내 부호화 예측을 행할 때 화면 간 부호화 매크로블록을 참조하는

             것이 금지된다

 

           - redundant_pic_cnt_present_flag :

             값이 1이면, 중복된 픽쳐(Redundant Picture)에 대한 POC가 부호화되고 있는지의

             여부를 나타낸다. 이 경우 redundant_pic_cnt가 부호화 된다

 

           1-1-3) generate_sps_nalu()

           #define BITSTREAM_PUTBITS(value,size,exp_golomb,prevent_0x3) \
                      REG_WRITE(PARM7,(value)); \
                      REG_WRITE(CMD1 ,  REG_BITVAL(CMD1_PREVENT_0x3,prevent_0x3) \
                        | REG_BITVAL(CMD1_EXP_GOLOMB_CODE,exp_golomb) \
                        | REG_BITVAL(CMD1_EXT_PK_GO,1) \
                        | REG_BITVAL(CMD1_EXT_PK_LEN,(size)) )

           #define U(value,size)  BITSTREAM_PUTBITS((value),(size),0,0)
           #define U_RBSP(value,size)  BITSTREAM_PUTBITS((value),(size),0,1)
           #define UE_RBSP(value)  BITSTREAM_PUTBITS((value),0,1,1)  // for Exp-Golomb
           #define SE_RBSP(value)  BITSTREAM_PUTBITS(((value)>0)? (((value)<<1)-1): \

                                                                                ((-(value))<<1),0,1,1)           

           - U(0, 8); // 8  bits , additional zero byte 'leading_zero_8bits'

                         // if it is parameter sets and first slice in picture
           - U(1,24); // 24 bits , start code prefix

             // 위 두라인... Page 121 의 H.264/AVC의 바이트열 포멧을 참조하면

             // 각 NAL 단위의 맨 처음 위치에 시작부호를 부가한다 시작부호는 0x1(3byte)이며

             // 시작부호 앞의 패턴 "00"의 바이트를 임의의 수만큼 붙이는 것도 가능하다

 

           - U(((0<<7)|(NALU_PRIORITY_HIGHEST<<5)|NALU_TYPE_SPS),8);

             // NAL Header를 구성하고 있음... Page 113 참조

             // 8 bits , (forbidden_zero_bit | nal_ref_idc | nal_unit_type)

             // nal_unit_type 을 SPS Type(7)으로 설정함을 확인 할 수 있다(Page 114 테이블참조)

             // nal_unit_type >=6 이므로 비 VCL NAL 단위임을 알 수 있다

 

           - init_sps_nalu 에서 초기화한 SPS(Sequence Parameter Set) param data를 스트리밍

             Write, param에 따라 U_RBSP, UE_RBSP으로 Write함

 

           - SPS Data Write후 Trailing Bit Write

           #define RBSP_TRAILING_BITS() REG_BITWRITE (CMD1,CMD1_ADD_RBSP_TRAILING,1)

  

           1-1-4) generate_pps_nalu()

           - U(0, 8); // 8  bits , additional zero byte 'leading_zero_8bits'

                         // if it is parameter sets and first slice in picture
           - U(1,24); // 24 bits , start code prefix 

           - U(((0<<7)|(NALU_PRIORITY_HIGHEST<<5)|NALU_TYPE_PPS),8);

              // NAL Header를 구성하고 있음... Page 113 참조

              // 8 bits , (forbidden_zero_bit | nal_ref_idc | nal_unit_type)

              // nal_unit_type 을 PPS Type(8)으로 설정함을 확인 할 수 있다(Page 114 테이블참조)

              // nal_unit_type >=6 이므로 비 VCL NAL 단위임을 알 수 있다

 

           - init_pps_nalu 에서 초기화한 PPS(Picture Parameter Set) param data를 스트리밍

             Write, param에 따라 U_RBSP, UE_RBSP,SE_RBSP으로 Write함

 

           - PPS Data Write후 Trailing Bit Write

           #define RBSP_TRAILING_BITS() REG_BITWRITE (CMD1,CMD1_ADD_RBSP_TRAILING,1)

  

   2) h264_encoder_encode()

      * Register Setting

      - REG_BITWRITE(PARM4, PARM4_QP, pFrameStatus->quant);

         // QP : Specifies the initial value of QPy for all the macroblocks in the slice (0~51)

         // QP(Quantization Parameter) -> Page166 디블록킹필터 설명중..

         // pFrameStatus->quant 값은 config txt 에서 읽어온 데이터값

      -  watermark

      2-1) start_slice

         - slice_type 변수값 Setting : I_SLICE or P_SLICE (Page 117)

 

         NAL 헤더 구성

         - U(0, 8); // 8  bits , additional zero byte 'leading_zero_8bits'

                       // if it is parameter sets and first slice in picture
         - U(1,24); // 24 bits , start code prefix 

 

         - if(pEnc->very_first_flag)
              { U(((0<<7)|(NALU_PRIORITY_HIGHEST<<5)|NALU_TYPE_IDR),8); }

               // u(8) , (forbidden_zero_bit | nal_ref_idc | nal_unit_type)
            else  
              { U(((0<<7)|(NALU_PRIORITY_HIGH<<5)|NALU_TYPE_SLICE),8); }

               // u(8) , (forbidden_zero_bit | nal_ref_idc | nal_unit_type)

 

            // IDR (Instantaneous Decoding Refresh) :영상 시퀀스의 선두픽쳐

            // NALU_TYPE_IDR (5), NALU_TYPE_SLICE(1)

 

         Slice Header 구성

         // Page 334의 slice header  테이블 구조 참조

         // Slice header에 맞게 데이터 셋팅 및 업데이트

 

      Register Setting

      - REG_WRITE(DMAA1,REG_BITVAL(DMAA1_INCREMENT,1) | .....
      // System memory address increment

       

     - Config txt파일 및 변수설정값등으로 rec,x,y좌표,offset등 설정이후 DMA Control Cmd수행

      2-2) frame_code_I() (or frame_code_p())

      2-2) frame_code_p() (or frame_code_I()

     - CMD0 Cmd 수행

      // Slice Type , Watermark 관련

      // Cmd 수행하면... Encoding 시작(0Bit)...!!

 

      Encoding 끝날때까지 Delay (STS0 Register의 0Bit Read)

 

      Bitstream_length Return(STS0 Register Read)

 

      2-3) termiate_slice()

      - Encoding된 Data저장할 Buf의 포인터변경 <- Offset

 

   3) h264_encoder_destroy()

댓글 없음:

댓글 쓰기