• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
va_swap32(unsigned int val)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 
bitstream_start(bitstream * bs)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 
bitstream_end(bitstream * bs)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 
bitstream_put_ui(bitstream * bs,unsigned int val,int size_in_bits)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 
bitstream_put_ue(bitstream * bs,unsigned int val)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 
bitstream_put_se(bitstream * bs,int val)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 
bitstream_byte_aligning(bitstream * bs,int bit)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 
rbsp_trailing_bits(bitstream * bs)133 static void rbsp_trailing_bits(bitstream *bs)
134 {
135     bitstream_put_ui(bs, 1, 1);
136     bitstream_byte_aligning(bs, 0);
137 }
138 
nal_start_code_prefix(bitstream * bs)139 static void nal_start_code_prefix(bitstream *bs)
140 {
141     bitstream_put_ui(bs, 0x00000001, 32);
142 }
143 
nal_header(bitstream * bs,int nal_ref_idc,int nal_unit_type)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 
sps_rbsp(bitstream * bs,VAProfile profile,int frame_bit_rate,VAEncSequenceParameterBufferH264 * seq_param)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 
pps_rbsp(bitstream * bs,VAEncPictureParameterBufferH264 * pic_param)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 
build_packed_seq_buffer(unsigned char ** header_buffer,VAProfile profile,VAEncSequenceParameterBufferH264 * seq_param)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 
build_packed_pic_buffer(unsigned char ** header_buffer,VAEncPictureParameterBufferH264 * pic_param)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 
build_packed_sei_buffer_timing(unsigned int init_cpb_removal_delay,unsigned int init_cpb_removal_delay_offset,unsigned int cpb_removal_length,unsigned int cpb_removal_delay,unsigned int dpb_output_length,unsigned int dpb_output_delay,unsigned char ** sei_buffer)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