Home | History | Annotate | Download | only in videoencoder
      1 /*
      2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 #ifndef __BITSTREAM_H__
     18 #define __BITSTREAM_H__
     19 
     20 #include <VideoEncoderBase.h>
     21 #include <assert.h>
     22 
     23 struct bitstream {
     24     unsigned int *buffer;
     25     int bit_offset;
     26     int max_size_in_dword;
     27 };
     28 
     29 #define BITSTREAM_ALLOCATE_STEPPING     4096
     30 
     31 static unsigned int va_swap32(unsigned int val)
     32 {
     33     unsigned char *pval = (unsigned char *)&val;
     34 
     35     return ((pval[0] << 24)     |
     36             (pval[1] << 16)     |
     37             (pval[2] << 8)      |
     38             (pval[3] << 0));
     39 }
     40 
     41 static void bitstream_start(bitstream *bs)
     42 {
     43     bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING;
     44     bs->buffer = (unsigned int*)calloc(bs->max_size_in_dword * sizeof(int), 1);
     45     bs->bit_offset = 0;
     46 }
     47 
     48 static void bitstream_end(bitstream *bs)
     49 {
     50     int pos = (bs->bit_offset >> 5);
     51     int bit_offset = (bs->bit_offset & 0x1f);
     52     int bit_left = 32 - bit_offset;
     53 
     54     if (bit_offset) {
     55         bs->buffer[pos] = va_swap32((bs->buffer[pos] << bit_left));
     56     }
     57 }
     58 
     59 static void bitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits)
     60 {
     61     int pos = (bs->bit_offset >> 5);
     62     int bit_offset = (bs->bit_offset & 0x1f);
     63     int bit_left = 32 - bit_offset;
     64 
     65     if (!size_in_bits)
     66         return;
     67 
     68     bs->bit_offset += size_in_bits;
     69 
     70     if (bit_left > size_in_bits) {
     71         bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
     72     } else {
     73         size_in_bits -= bit_left;
     74         bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
     75         bs->buffer[pos] = va_swap32(bs->buffer[pos]);
     76 
     77         if (pos + 1 == bs->max_size_in_dword) {
     78             bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
     79             bs->buffer = (unsigned int*)realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
     80             if (bs->buffer == NULL)
     81                 abort();
     82         }
     83 
     84         bs->buffer[pos + 1] = val;
     85     }
     86 }
     87 
     88 static void bitstream_put_ue(bitstream *bs, unsigned int val)
     89 {
     90     int size_in_bits = 0;
     91     int tmp_val = ++val;
     92 
     93     while (tmp_val) {
     94         tmp_val >>= 1;
     95         size_in_bits++;
     96     }
     97 
     98     bitstream_put_ui(bs, 0, size_in_bits - 1); // leading zero
     99     bitstream_put_ui(bs, val, size_in_bits);
    100 }
    101 
    102 static void bitstream_put_se(bitstream *bs, int val)
    103 {
    104     unsigned int new_val;
    105 
    106     if (val <= 0)
    107         new_val = -2 * val;
    108     else
    109         new_val = 2 * val - 1;
    110 
    111     bitstream_put_ue(bs, new_val);
    112 }
    113 
    114 static void bitstream_byte_aligning(bitstream *bs, int bit)
    115 {
    116     int bit_offset = (bs->bit_offset & 0x7);
    117     int bit_left = 8 - bit_offset;
    118     int new_val;
    119 
    120     if (!bit_offset)
    121         return;
    122 
    123     assert(bit == 0 || bit == 1);
    124 
    125     if (bit)
    126         new_val = (1 << bit_left) - 1;
    127     else
    128         new_val = 0;
    129 
    130     bitstream_put_ui(bs, new_val, bit_left);
    131 }
    132 
    133 static void rbsp_trailing_bits(bitstream *bs)
    134 {
    135     bitstream_put_ui(bs, 1, 1);
    136     bitstream_byte_aligning(bs, 0);
    137 }
    138 
    139 static void nal_start_code_prefix(bitstream *bs)
    140 {
    141     bitstream_put_ui(bs, 0x00000001, 32);
    142 }
    143 
    144 static void nal_header(bitstream *bs, int nal_ref_idc, int nal_unit_type)
    145 {
    146     bitstream_put_ui(bs, 0, 1);                /* forbidden_zero_bit: 0 */
    147     bitstream_put_ui(bs, nal_ref_idc, 2);
    148     bitstream_put_ui(bs, nal_unit_type, 5);
    149 }
    150 
    151 #define NAL_REF_IDC_NONE        0
    152 #define NAL_REF_IDC_LOW         1
    153 #define NAL_REF_IDC_MEDIUM      2
    154 #define NAL_REF_IDC_HIGH        3
    155 
    156 #define NAL_NON_IDR             1
    157 #define NAL_IDR                 5
    158 #define NAL_SPS                 7
    159 #define NAL_PPS                 8
    160 #define NAL_SEI			6
    161 
    162 #define SLICE_TYPE_P            0
    163 #define SLICE_TYPE_B            1
    164 #define SLICE_TYPE_I            2
    165 
    166 #define ENTROPY_MODE_CAVLC      0
    167 #define ENTROPY_MODE_CABAC      1
    168 
    169 #define PROFILE_IDC_BASELINE    66
    170 #define PROFILE_IDC_MAIN        77
    171 #define PROFILE_IDC_HIGH        100
    172 
    173 static void sps_rbsp(bitstream *bs, VAProfile profile, int frame_bit_rate, VAEncSequenceParameterBufferH264 *seq_param)
    174 {
    175     int profile_idc = 0;
    176     int constraint_set_flag = 0;
    177 
    178     if (profile == VAProfileH264High) {
    179         profile_idc = PROFILE_IDC_HIGH;
    180         constraint_set_flag |= (1 << 3); /* Annex A.2.4 */
    181     }
    182     else if (profile == VAProfileH264Main) {
    183         profile_idc = PROFILE_IDC_MAIN;
    184         constraint_set_flag |= (1 << 1); /* Annex A.2.2 */
    185     } else {
    186         profile_idc = PROFILE_IDC_BASELINE;
    187         constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
    188     }
    189 
    190     bitstream_put_ui(bs, profile_idc, 8);               /* profile_idc */
    191     bitstream_put_ui(bs, !!(constraint_set_flag & 1), 1);                         /* constraint_set0_flag */
    192     bitstream_put_ui(bs, !!(constraint_set_flag & 2), 1);                         /* constraint_set1_flag */
    193     bitstream_put_ui(bs, !!(constraint_set_flag & 4), 1);                         /* constraint_set2_flag */
    194     bitstream_put_ui(bs, !!(constraint_set_flag & 8), 1);                         /* constraint_set3_flag */
    195     bitstream_put_ui(bs, 0, 4);                         /* reserved_zero_4bits */
    196     bitstream_put_ui(bs, seq_param->level_idc, 8);      /* level_idc */
    197     bitstream_put_ue(bs, seq_param->seq_parameter_set_id);      /* seq_parameter_set_id */
    198 
    199     if ( profile_idc == PROFILE_IDC_HIGH) {
    200         bitstream_put_ue(bs, 1);        /* chroma_format_idc = 1, 4:2:0 */
    201         bitstream_put_ue(bs, 0);        /* bit_depth_luma_minus8 */
    202         bitstream_put_ue(bs, 0);        /* bit_depth_chroma_minus8 */
    203         bitstream_put_ui(bs, 0, 1);     /* qpprime_y_zero_transform_bypass_flag */
    204         bitstream_put_ui(bs, 0, 1);     /* seq_scaling_matrix_present_flag */
    205     }
    206 
    207     bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
    208     bitstream_put_ue(bs, seq_param->seq_fields.bits.pic_order_cnt_type);        /* pic_order_cnt_type */
    209 
    210     if (seq_param->seq_fields.bits.pic_order_cnt_type == 0)
    211         bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);     /* log2_max_pic_order_cnt_lsb_minus4 */
    212     else {
    213         assert(0);
    214     }
    215 
    216     bitstream_put_ue(bs, seq_param->max_num_ref_frames);        /* num_ref_frames */
    217     bitstream_put_ui(bs, 0, 1);                                 /* gaps_in_frame_num_value_allowed_flag */
    218 
    219     bitstream_put_ue(bs, seq_param->picture_width_in_mbs - 1);  /* pic_width_in_mbs_minus1 */
    220     bitstream_put_ue(bs, seq_param->picture_height_in_mbs - 1); /* pic_height_in_map_units_minus1 */
    221     bitstream_put_ui(bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);    /* frame_mbs_only_flag */
    222 
    223     if (!seq_param->seq_fields.bits.frame_mbs_only_flag) {
    224         assert(0);
    225     }
    226 
    227     bitstream_put_ui(bs, seq_param->seq_fields.bits.direct_8x8_inference_flag, 1);      /* direct_8x8_inference_flag */
    228     bitstream_put_ui(bs, seq_param->frame_cropping_flag, 1);            /* frame_cropping_flag */
    229 
    230     if (seq_param->frame_cropping_flag) {
    231         bitstream_put_ue(bs, seq_param->frame_crop_left_offset);        /* frame_crop_left_offset */
    232         bitstream_put_ue(bs, seq_param->frame_crop_right_offset);       /* frame_crop_right_offset */
    233         bitstream_put_ue(bs, seq_param->frame_crop_top_offset);         /* frame_crop_top_offset */
    234         bitstream_put_ue(bs, seq_param->frame_crop_bottom_offset);      /* frame_crop_bottom_offset */
    235     }
    236 
    237     if ( frame_bit_rate < 0 ) {
    238         bitstream_put_ui(bs, 0, 1); /* vui_parameters_present_flag */
    239     } else {
    240         bitstream_put_ui(bs, 1, 1); /* vui_parameters_present_flag */
    241         bitstream_put_ui(bs, 0, 1); /* aspect_ratio_info_present_flag */
    242         bitstream_put_ui(bs, 0, 1); /* overscan_info_present_flag */
    243         bitstream_put_ui(bs, 0, 1); /* video_signal_type_present_flag */
    244         bitstream_put_ui(bs, 0, 1); /* chroma_loc_info_present_flag */
    245         bitstream_put_ui(bs, 1, 1); /* timing_info_present_flag */
    246         {
    247             bitstream_put_ui(bs, 15, 32);
    248             bitstream_put_ui(bs, 900, 32);
    249             bitstream_put_ui(bs, 1, 1);
    250         }
    251         bitstream_put_ui(bs, 1, 1); /* nal_hrd_parameters_present_flag */
    252         {
    253             // hrd_parameters
    254             bitstream_put_ue(bs, 0);    /* cpb_cnt_minus1 */
    255             bitstream_put_ui(bs, 4, 4); /* bit_rate_scale */
    256             bitstream_put_ui(bs, 6, 4); /* cpb_size_scale */
    257 
    258             bitstream_put_ue(bs, frame_bit_rate - 1); /* bit_rate_value_minus1[0] */
    259             bitstream_put_ue(bs, frame_bit_rate*8 - 1); /* cpb_size_value_minus1[0] */
    260             bitstream_put_ui(bs, 1, 1);  /* cbr_flag[0] */
    261 
    262             bitstream_put_ui(bs, 23, 5);   /* initial_cpb_removal_delay_length_minus1 */
    263             bitstream_put_ui(bs, 23, 5);   /* cpb_removal_delay_length_minus1 */
    264             bitstream_put_ui(bs, 23, 5);   /* dpb_output_delay_length_minus1 */
    265             bitstream_put_ui(bs, 23, 5);   /* time_offset_length  */
    266         }
    267         bitstream_put_ui(bs, 0, 1);   /* vcl_hrd_parameters_present_flag */
    268         bitstream_put_ui(bs, 0, 1);   /* low_delay_hrd_flag */
    269 
    270         bitstream_put_ui(bs, 0, 1); /* pic_struct_present_flag */
    271         bitstream_put_ui(bs, 0, 1); /* bitstream_restriction_flag */
    272     }
    273 
    274     rbsp_trailing_bits(bs);     /* rbsp_trailing_bits */
    275 }
    276 
    277 static void pps_rbsp(bitstream *bs, VAEncPictureParameterBufferH264 *pic_param)
    278 {
    279 
    280     bitstream_put_ue(bs, pic_param->pic_parameter_set_id);      /* pic_parameter_set_id */
    281     bitstream_put_ue(bs, pic_param->seq_parameter_set_id);      /* seq_parameter_set_id */
    282 
    283     bitstream_put_ui(bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1);  /* entropy_coding_mode_flag */
    284 
    285     bitstream_put_ui(bs, 0, 1);                         /* pic_order_present_flag: 0 */
    286 
    287     bitstream_put_ue(bs, 0);                            /* num_slice_groups_minus1 */
    288 
    289     bitstream_put_ue(bs, pic_param->num_ref_idx_l0_active_minus1);      /* num_ref_idx_l0_active_minus1 */
    290     bitstream_put_ue(bs, pic_param->num_ref_idx_l1_active_minus1);      /* num_ref_idx_l1_active_minus1 1 */
    291 
    292     bitstream_put_ui(bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);     /* weighted_pred_flag: 0 */
    293     bitstream_put_ui(bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2);	/* weighted_bipred_idc: 0 */
    294 
    295     bitstream_put_se(bs, pic_param->pic_init_qp - 26);  /* pic_init_qp_minus26 */
    296     bitstream_put_se(bs, 0);                            /* pic_init_qs_minus26 */
    297     bitstream_put_se(bs, 0);                            /* chroma_qp_index_offset */
    298 
    299     bitstream_put_ui(bs, pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); /* deblocking_filter_control_present_flag */
    300     bitstream_put_ui(bs, 0, 1);                         /* constrained_intra_pred_flag */
    301     bitstream_put_ui(bs, 0, 1);                         /* redundant_pic_cnt_present_flag */
    302 
    303     /* more_rbsp_data */
    304     bitstream_put_ui(bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1);    /*transform_8x8_mode_flag */
    305     bitstream_put_ui(bs, 0, 1);                         /* pic_scaling_matrix_present_flag */
    306     bitstream_put_se(bs, pic_param->second_chroma_qp_index_offset );    /*second_chroma_qp_index_offset */
    307 
    308     rbsp_trailing_bits(bs);
    309 }
    310 
    311 int build_packed_seq_buffer(unsigned char **header_buffer, VAProfile profile, VAEncSequenceParameterBufferH264 *seq_param)
    312 {
    313     bitstream bs;
    314 
    315     bitstream_start(&bs);
    316     nal_start_code_prefix(&bs);
    317     nal_header(&bs, NAL_REF_IDC_HIGH, NAL_SPS);
    318     sps_rbsp(&bs, profile, seq_param->bits_per_second, seq_param);
    319     bitstream_end(&bs);
    320 
    321     *header_buffer = (unsigned char *)bs.buffer;
    322     return bs.bit_offset;
    323 }
    324 
    325 int build_packed_pic_buffer(unsigned char **header_buffer, VAEncPictureParameterBufferH264 *pic_param)
    326 {
    327     bitstream bs;
    328 
    329     bitstream_start(&bs);
    330     nal_start_code_prefix(&bs);
    331     nal_header(&bs, NAL_REF_IDC_HIGH, NAL_PPS);
    332     pps_rbsp(&bs, pic_param);
    333     bitstream_end(&bs);
    334 
    335     *header_buffer = (unsigned char *)bs.buffer;
    336     return bs.bit_offset;
    337 }
    338 
    339 int build_packed_sei_buffer_timing(unsigned int init_cpb_removal_delay,
    340 				unsigned int init_cpb_removal_delay_offset,
    341 				unsigned int cpb_removal_length,
    342 				unsigned int cpb_removal_delay,
    343 				unsigned int dpb_output_length,
    344 				unsigned int dpb_output_delay,
    345 				unsigned char **sei_buffer)
    346 {
    347     unsigned char *byte_buf;
    348     int bp_byte_size, i, pic_byte_size;
    349 
    350     bitstream nal_bs;
    351     bitstream sei_bp_bs, sei_pic_bs;
    352 
    353     bitstream_start(&sei_bp_bs);
    354     bitstream_put_ue(&sei_bp_bs, 0);       /*seq_parameter_set_id*/
    355     bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length);
    356     bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length);
    357     if ( sei_bp_bs.bit_offset & 0x7) {
    358         bitstream_put_ui(&sei_bp_bs, 1, 1);
    359     }
    360     bitstream_end(&sei_bp_bs);
    361     bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8;
    362 
    363     bitstream_start(&sei_pic_bs);
    364     bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length);
    365     bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length);
    366     if ( sei_pic_bs.bit_offset & 0x7) {
    367         bitstream_put_ui(&sei_pic_bs, 1, 1);
    368     }
    369     bitstream_end(&sei_pic_bs);
    370     pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8;
    371 
    372     bitstream_start(&nal_bs);
    373     nal_start_code_prefix(&nal_bs);
    374     nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI);
    375 
    376     /* Write the SEI buffer period data */
    377     bitstream_put_ui(&nal_bs, 0, 8);
    378     bitstream_put_ui(&nal_bs, bp_byte_size, 8);
    379 
    380     byte_buf = (unsigned char *)sei_bp_bs.buffer;
    381     for(i = 0; i < bp_byte_size; i++) {
    382         bitstream_put_ui(&nal_bs, byte_buf[i], 8);
    383     }
    384     free(byte_buf);
    385 	/* write the SEI timing data */
    386     bitstream_put_ui(&nal_bs, 0x01, 8);
    387     bitstream_put_ui(&nal_bs, pic_byte_size, 8);
    388 
    389     byte_buf = (unsigned char *)sei_pic_bs.buffer;
    390     for(i = 0; i < pic_byte_size; i++) {
    391         bitstream_put_ui(&nal_bs, byte_buf[i], 8);
    392     }
    393     free(byte_buf);
    394 
    395     rbsp_trailing_bits(&nal_bs);
    396     bitstream_end(&nal_bs);
    397 
    398     *sei_buffer = (unsigned char *)nal_bs.buffer;
    399 
    400     return nal_bs.bit_offset;
    401 }
    402 
    403 #endif
    404