1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78
79 /*!
80 **************************************************************************************
81 * \file
82 * parset.c
83 * \brief
84 * Picture and Sequence Parameter set generation and handling
85 * \date 25 November 2002
86 * \author
87 * Main contributors (see contributors.h for copyright, address and affiliation details)
88 * - Stephan Wenger <stewe@cs.tu-berlin.de>
89 *
90 **************************************************************************************
91 */
92
93 #include <stdio.h>
94 #include <string.h>
95 #include "MFE_chip.h"
96 #include "mfe_type.h"
97 #include "mfe_common.h"
98 #include "ms_dprintf.h"
99
100 #include "parsetcommon.h"
101 #include "parset.h"
102 #include "nalu.h"
103 #include "vlc.h"
104
105 //seq_parameter_set_rbsp_t gSPS;
106 //pic_parameter_set_rbsp_t gPPS;
107 //seq_parameter_set_rbsp_t *active_sps;
108 //pic_parameter_set_rbsp_t *active_pps;
109
110 #define STATIC_SPS 0UL
111 #define STATIC_PPS 1UL
112
113 // Local helpers
114 static void _GenerateParameterSets(MFE_CONFIG* pConfig);
115 //static void _FreeParameterSets (MFE_CONFIG* pConfig);
116
117 static NALU_t* _GenerateSeq_parameter_set_NALU (MFE_CONFIG* pConfig);
118 static NALU_t* _GeneratePic_parameter_set_NALU(MFE_CONFIG *pConfig);
119
120 static MS_S32 _GenerateVUI_parameters_rbsp(seq_parameter_set_rbsp_t *sps, Bitstream *bitstream);
121 static MS_S32 _GenerateSeq_parameter_set_rbsp (seq_parameter_set_rbsp_t *sps, MS_U8 *rbsp);
122 static MS_S32 _GeneratePic_parameter_set_rbsp (MFE_CONFIG* pConfig, pic_parameter_set_rbsp_t *pps, MS_U8 *rbsp);
123 static void _GenerateVUIParameters(MFE_CONFIG *pConfig, seq_parameter_set_rbsp_t *sps);
124
125
MallocSPSPPSBuf(MFE_CONFIG * pConfig)126 void MallocSPSPPSBuf(MFE_CONFIG* pConfig)
127 {
128 pConfig->active_sps = MfeDrvMemMalloc(sizeof(seq_parameter_set_rbsp_t), (const MS_S8*)("active_sps"));
129 if (pConfig->active_sps)
130 {
131 memset(pConfig->active_sps, 0, sizeof(seq_parameter_set_rbsp_t));
132 }
133 else
134 {
135 ms_dprintk(DRV_L0, "Failed to allocate sps!\n");
136 }
137
138 pConfig->active_pps = MfeDrvMemMalloc(sizeof(pic_parameter_set_rbsp_t), (const MS_S8*)("active_pps"));
139 if (pConfig->active_pps)
140 {
141 memset(pConfig->active_pps, 0, sizeof(pic_parameter_set_rbsp_t));
142 }
143 else
144 {
145 ms_dprintk(DRV_L0, "Failed to allocate pps!\n");
146 }
147 }
148
FreeSPSPPSBuf(MFE_CONFIG * pConfig)149 void FreeSPSPPSBuf(MFE_CONFIG* pConfig)
150 {
151 MfeDrvMemFree((void**)&pConfig->active_sps, (const MS_S8*)("active_sps"));
152 MfeDrvMemFree((void**)&pConfig->active_pps, (const MS_S8*)("active_pps"));
153 }
154
155 /*!
156 *************************************************************************************
157 * \brief
158 * Prepare SPS and PPS NALU's for later usage.
159 *
160 * \return
161 * A NALU containing the Sequence ParameterSet
162 *
163 *************************************************************************************
164 */
GenerateSPSPPS(MFE_CONFIG * pConfig)165 void GenerateSPSPPS(MFE_CONFIG* pConfig)
166 {
167 _GenerateParameterSets(pConfig);
168 _GenerateSeq_parameter_set_NALU(pConfig);
169 _GeneratePic_parameter_set_NALU(pConfig);
170
171 }
172
173 /*!
174 *************************************************************************************
175 * \brief
176 * generates a sequence and picture parameter set and stores these in global
177 * active_sps and active_pps
178 *
179 * \return
180 * A NALU containing the Sequence ParameterSet
181 *
182 *************************************************************************************
183 */
_GenerateParameterSets(MFE_CONFIG * pConfig)184 static void _GenerateParameterSets(MFE_CONFIG* pConfig)
185 {
186 // active_sps = &gSPS;
187 // active_pps = &gPPS;
188 GenerateSequenceParameterSet(pConfig, pConfig->active_sps, 0);
189 GeneratePictureParameterSet (pConfig, pConfig->active_pps, pConfig->active_sps, 0);
190 }
191
192 /*!
193 *************************************************************************************
194 * \brief
195 * frees global parameter sets active_sps and active_pps
196 *
197 * \return
198 * A NALU containing the Sequence ParameterSet
199 *
200 *************************************************************************************
201 */
202 /*
203 static void _FreeParameterSets (MFE_CONFIG* pConfig)
204 {
205 active_pps = NULL;
206 active_pps = NULL;
207 }
208 */
209 /*!
210 *************************************************************************************
211 * \brief
212 * NALU_t* _GenerateSeq_parameter_set_NALU (void);
213 *
214 * \note
215 * Uses the global variables through GenerateSequenceParameterSet()
216 * and GeneratePictureParameterSet
217 *
218 * \return
219 * A NALU containing the Sequence ParameterSet
220 *
221 *************************************************************************************
222 */
223
_GenerateSeq_parameter_set_NALU(MFE_CONFIG * pConfig)224 static NALU_t* _GenerateSeq_parameter_set_NALU (MFE_CONFIG* pConfig)
225 {
226 NALU_t *n = &pConfig->NaluStruct[STATIC_SPS];
227 MS_S32 RBSPlen = 0;
228 // MS_S32 NALUlen;
229 MS_U8 rbsp[MAXRBSPSIZE];
230
231 n->buf = pConfig->NaluBuf[STATIC_SPS];
232
233 RBSPlen = _GenerateSeq_parameter_set_rbsp (pConfig->active_sps, rbsp);
234 // NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_SPS, NALU_PRIORITY_HIGHEST, 0, 1);
235 RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_SPS, NALU_PRIORITY_HIGHEST, 0, 1);
236 /* RefSW has this originally, ken marked
237 n->startcodeprefix_len = 4;
238 */
239 return n;
240 }
241
242
243 /*!
244 *************************************************************************************
245 * \brief
246 * NALU_t* _GeneratePic_parameter_set_NALU (MS_S32 PPS_id);
247 *
248 * \note
249 * Uses the global variables through GenerateSequenceParameterSet()
250 * and GeneratePictureParameterSet
251 *
252 * \return
253 * A NALU containing the Picture Parameter Set
254 *
255 *************************************************************************************
256 */
257
_GeneratePic_parameter_set_NALU(MFE_CONFIG * pConfig)258 static NALU_t* _GeneratePic_parameter_set_NALU(MFE_CONFIG *pConfig)
259 {
260 NALU_t *n = &pConfig->NaluStruct[STATIC_PPS];
261 MS_S32 RBSPlen = 0;
262 // MS_S32 NALUlen;
263 MS_U8 rbsp[MAXRBSPSIZE];
264
265 n->buf = pConfig->NaluBuf[STATIC_PPS];
266
267 RBSPlen = _GeneratePic_parameter_set_rbsp (pConfig, pConfig->active_pps, rbsp);
268 // NALUlen = RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1);
269 RBSPtoNALU (rbsp, n, RBSPlen, NALU_TYPE_PPS, NALU_PRIORITY_HIGHEST, 0, 1);
270 //RefSW set n->startcodeprefix_len = 4, ken marked
271 // n->startcodeprefix_len = 4;
272
273 return n;
274 }
275
276
277 /*!
278 ************************************************************************
279 * \brief
280 * GenerateSequenceParameterSet: extracts info from global variables and
281 * generates sequence parameter set structure
282 *
283 * \par
284 * Function reads all kinds of values from several global variables,
285 * including input-> and image-> and fills in the sps. Many
286 * values are current hard-coded to defaults.
287 *
288 ************************************************************************
289 */
290
GenerateSequenceParameterSet(MFE_CONFIG * pConfig,seq_parameter_set_rbsp_t * sps,MS_S32 SPS_id)291 void GenerateSequenceParameterSet( MFE_CONFIG *pConfig,
292 seq_parameter_set_rbsp_t *sps, //!< Sequence Parameter Set to be filled
293 MS_S32 SPS_id //!< SPS ID
294 )
295 {
296 H264INFO *pInfo = &pConfig->ctxH264Info;
297 int ntmpDispHeight;
298
299 ms_dprintk(DRV_L2,"In GenerateSequenceParameterSet\n");
300 // *************************************************************************
301 // Sequence Parameter Set
302 // *************************************************************************
303 MS_ASSERT (sps != NULL);
304 if (sps == NULL)
305 {
306 ms_dprintk(DRV_L4, "[GenerateSequenceParameterSetsps] sps is null\n");
307 return;
308 }
309
310 // Profile and Level should be calculated using the info from the config
311 // file. Calculation is hidden in IndetifyProfile() and IdentifyLevel()
312 sps->profile_idc = pInfo->ProfileIDC;
313 sps->level_idc = pInfo->LevelIDC;
314
315 // needs to be set according to profile
316 sps->constrained_set0_flag = FALSE;
317 sps->constrained_set1_flag = TRUE; // Constrained Baseline or Main
318 sps->constrained_set2_flag = FALSE;
319
320 if ( (sps->level_idc == 9) ) // Level 1.b
321 {
322 sps->constrained_set3_flag = TRUE;
323 sps->level_idc = 11;
324 }
325 else
326 {
327 sps->constrained_set3_flag = FALSE;
328 }
329
330 // Parameter Set ID hard coded to zero
331 sps->seq_parameter_set_id = 0;
332
333 // Fidelity Range Extensions stuff
334 sps->bit_depth_luma_minus8 = 0;
335 sps->bit_depth_chroma_minus8 = 0;
336
337 //! POC stuff:
338 //! The following values are hard-coded in init_poc(). Apparently,
339 //! the poc implementation covers only a subset of the poc functionality.
340 //! Here, the same subset is implemented. Changes in the POC stuff have
341 //! also to be reflected here
342 sps->log2_max_frame_num_minus4 = 1;//log2_max_frame_num_minus4;
343 sps->log2_max_pic_order_cnt_lsb_minus4 = 0; // Not used
344
345 sps->pic_order_cnt_type = 2; //This is for MFE
346 sps->num_ref_frames_in_pic_order_cnt_cycle = 1; // Not used
347 sps->delta_pic_order_always_zero_flag = FALSE; // Not used
348 sps->offset_for_non_ref_pic = 0; // Not used
349 sps->offset_for_top_to_bottom_field = 1;
350
351 /*
352 for (i=0; i<img->num_ref_frames_in_pic_order_cnt_cycle; i++)
353 {
354 sps->offset_for_ref_frame[i] = img->offset_for_ref_frame[i];
355 }
356 */
357 // End of POC stuff
358
359 // Number of Reference Frames
360 sps->num_ref_frames = pInfo->num_ref_frames;
361
362 //required_frame_num_update_behaviour_flag hardcoded to zero
363 sps->gaps_in_frame_num_value_allowed_flag = FALSE; // double check
364
365 sps->frame_mbs_only_flag = (MS_BOOL) (pConfig->bInterlace == PROGRESSIVE);
366
367 // Picture size, finally a simple one :-)
368 sps->pic_width_in_mbs_minus1 = (pConfig->nBufWidth/16) -1;
369 sps->pic_height_in_map_units_minus1 = ((pConfig->nBufHeight/16)/ (2 - sps->frame_mbs_only_flag)) - 1;
370
371 // a couple of flags, simple
372 sps->mb_adaptive_frame_field_flag = FALSE;
373 sps->direct_8x8_inference_flag = TRUE;
374
375 // Sequence VUI not implemented, signalled as not present
376 sps->vui_parameters_present_flag = TRUE;
377
378 sps->chroma_format_idc = 1;
379 sps->separate_colour_plane_flag = 0;
380 if ( sps->vui_parameters_present_flag )
381 _GenerateVUIParameters(pConfig, sps);
382
383 ntmpDispHeight = pConfig->nDispHeight;
384 if(sps->frame_mbs_only_flag == 0) //interlace
385 {
386 ntmpDispHeight = ntmpDispHeight*2;
387 }
388
389 if ((pConfig->nBufHeight != ntmpDispHeight) || (pConfig->nBufWidth != pConfig->nDispWidth)) {
390 sps->frame_cropping_flag = TRUE;
391 }
392 else {
393 sps->frame_cropping_flag = FALSE;
394 }
395
396 {
397 MS_U32 CropUnitX,CropUnitY;
398 if (sps->chroma_format_idc == 0) {
399 CropUnitX = 1;
400 CropUnitY = 2 - sps->frame_mbs_only_flag;
401 }
402 else { //only support 420.
403 CropUnitX = 2;
404 CropUnitY = 2 * (2 - sps->frame_mbs_only_flag);
405
406 }
407 if (pConfig->MfeCropInfo.crop_en == TRUE) {
408 sps->frame_cropping_flag = TRUE;
409 sps->frame_cropping_rect_left_offset = pConfig->MfeCropInfo.crop_left / CropUnitX;
410 sps->frame_cropping_rect_right_offset = pConfig->MfeCropInfo.crop_right / CropUnitX;
411 sps->frame_cropping_rect_top_offset = pConfig->MfeCropInfo.crop_top / CropUnitY;
412 sps->frame_cropping_rect_bottom_offset = pConfig->MfeCropInfo.crop_bottom / CropUnitY;
413 } else if (sps->frame_cropping_flag == TRUE) {
414 sps->frame_cropping_rect_left_offset = 0;
415 sps->frame_cropping_rect_top_offset = 0;
416 if (pConfig->nBufWidth != pConfig->nDispWidth)
417 sps->frame_cropping_rect_right_offset = (16 - pConfig->nDispWidth % 16) / CropUnitX;
418 else
419 sps->frame_cropping_rect_right_offset = 0;
420 if (pConfig->nBufHeight != ntmpDispHeight)
421 sps->frame_cropping_rect_bottom_offset = (16 - pConfig->nDispHeight % 16) / CropUnitY;
422 else
423 sps->frame_cropping_rect_bottom_offset = 0;
424 }
425 else {
426 sps->frame_cropping_rect_left_offset = 0;
427 sps->frame_cropping_rect_top_offset = 0;
428 sps->frame_cropping_rect_right_offset = 0;
429 sps->frame_cropping_rect_bottom_offset = 0;
430 }
431 }
432 }
433
434 /*!
435 ************************************************************************
436 * \brief
437 * GeneratePictureParameterSet:
438 * Generates a Picture Parameter Set structure
439 *
440 * \par
441 * Regarding the QP
442 * The previous software versions coded the absolute QP only in the
443 * slice header. This is kept, and the offset in the PPS is coded
444 * even if we could save bits by intelligently using this field.
445 *
446 ************************************************************************
447 */
448
GeneratePictureParameterSet(MFE_CONFIG * pConfig,pic_parameter_set_rbsp_t * pps,seq_parameter_set_rbsp_t * sps,MS_S32 PPS_id)449 void GeneratePictureParameterSet( MFE_CONFIG* pConfig,
450 pic_parameter_set_rbsp_t *pps, //!< Picture Parameter Set to be filled
451 seq_parameter_set_rbsp_t *sps, //!< used Sequence Parameter Set
452 MS_S32 PPS_id //!< PPS ID
453 )
454 {
455 H264INFO *pInfo = &pConfig->ctxH264Info;
456
457 // *************************************************************************
458 // Picture Parameter Set
459 // *************************************************************************
460
461 pps->seq_parameter_set_id = sps->seq_parameter_set_id;
462 pps->pic_parameter_set_id = PPS_id;
463
464 pps->entropy_coding_mode_flag = (pConfig->UseCABAC==1);
465
466 // JVT-Fxxx (by Stephan Wenger, make this flag unconditional
467 pps->pic_order_present_flag = pInfo->pic_order_present_flag;
468
469 pps->num_slice_groups_minus1 = 0;
470
471 pps->num_ref_idx_l0_active_minus1 = pInfo->num_ref_idx_l0_active_minus1;//sps->frame_mbs_only_flag ? (sps->num_ref_frames-1) : (2 * sps->num_ref_frames - 1) ; // set defaults
472 pps->num_ref_idx_l1_active_minus1 = pInfo->num_ref_idx_l0_active_minus1;//sps->frame_mbs_only_flag ? (sps->num_ref_frames-1) : (2 * sps->num_ref_frames - 1) ; // set defaults
473
474 pps->weighted_pred_flag = FALSE;
475 pps->weighted_bipred_idc = FALSE;
476
477 pps->pic_init_qp_minus26 = 0; // hard coded to zero, QP lives in the slice header
478 pps->pic_init_qs_minus26 = 0;
479
480 pps->chroma_qp_index_offset = 0;
481
482 pps->deblocking_filter_control_present_flag = (MS_BOOL) pInfo->bDeblockCtrlPresent;
483 pps->constrained_intra_pred_flag = (MS_BOOL) pInfo->ieap_constraint_intra;
484
485 // if redundant slice is in use.
486 pps->redundant_pic_cnt_present_flag = 0;
487 }
488
489
490 /*!
491 *************************************************************************************
492 * \brief
493 * MS_S32 _GenerateSeq_parameter_set_rbsp (seq_parameter_set_rbsp_t *sps, MS_U8 *rbsp);
494 *
495 * \param sps
496 * sequence parameter structure
497 * \param rbsp
498 * buffer to be filled with the rbsp, size should be at least MAXIMUMPARSETRBSPSIZE
499 *
500 * \return
501 * size of the RBSP in bytes
502 *
503 * \note
504 * Sequence Parameter VUI function is called, but the function implements
505 * an exit (-1)
506 *************************************************************************************
507 */
_GenerateSeq_parameter_set_rbsp(seq_parameter_set_rbsp_t * sps,MS_U8 * rbsp)508 static MS_S32 _GenerateSeq_parameter_set_rbsp (seq_parameter_set_rbsp_t *sps, MS_U8 *rbsp)
509 {
510 Bitstream stream, *bitstream = &stream;
511 MS_S32 len = 0, LenInBytes;
512 MS_U32 i;
513
514 MS_ASSERT (rbsp != NULL);
515
516 // .. and use the rbsp provided (or allocated above) for the data
517 bitstream->streamBuffer = rbsp;
518 bitstream->byte_pos = 0;
519 bitstream->byte_buf = 0;
520 bitstream->bits_to_go = 8;
521 bitstream->zerocount = 0;
522
523 len+=u_v (8, (MS_S8*)("SPS: profile_idc"), sps->profile_idc, bitstream);
524
525 len+=u_1 ((MS_S8*)("SPS: constrained_set0_flag"), sps->constrained_set0_flag, bitstream);
526 len+=u_1 ((MS_S8*)("SPS: constrained_set1_flag"), sps->constrained_set1_flag, bitstream);
527 len+=u_1 ((MS_S8*)("SPS: constrained_set2_flag"), sps->constrained_set2_flag, bitstream);
528 len+=u_1 ((MS_S8*)("SPS: constrained_set3_flag"), sps->constrained_set3_flag, bitstream);
529 len+=u_v (4, (MS_S8*)("SPS: reserved_zero_4bits"), 0, bitstream);
530
531 len+=u_v (8, (MS_S8*)("SPS: level_idc"), sps->level_idc, bitstream);
532
533 len+=ue_v ((MS_S8*)("SPS: seq_parameter_set_id"), sps->seq_parameter_set_id, bitstream);
534
535 len+=ue_v ((MS_S8*)("SPS: log2_max_frame_num_minus4"), sps->log2_max_frame_num_minus4, bitstream);
536 len+=ue_v ((MS_S8*)("SPS: pic_order_cnt_type"), sps->pic_order_cnt_type, bitstream);
537
538 if (sps->pic_order_cnt_type == 0)
539 len+=ue_v ((MS_S8*)("SPS: log2_max_pic_order_cnt_lsb_minus4"), sps->log2_max_pic_order_cnt_lsb_minus4, bitstream);
540 else if (sps->pic_order_cnt_type == 1)
541 {
542 len+=u_1 ((MS_S8*)("SPS: delta_pic_order_always_zero_flag"), sps->delta_pic_order_always_zero_flag, bitstream);
543 len+=se_v ((MS_S8*)("SPS: offset_for_non_ref_pic"), sps->offset_for_non_ref_pic, bitstream);
544 len+=se_v ((MS_S8*)("SPS: offset_for_top_to_bottom_field"), sps->offset_for_top_to_bottom_field, bitstream);
545 len+=ue_v ((MS_S8*)("SPS: num_ref_frames_in_pic_order_cnt_cycle"), sps->num_ref_frames_in_pic_order_cnt_cycle, bitstream);
546 for (i=0; i<sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
547 len+=se_v ((MS_S8*)("SPS: offset_for_ref_frame"), sps->offset_for_ref_frame[i], bitstream);
548 }
549 len+=ue_v ((MS_S8*)("SPS: num_ref_frames"), sps->num_ref_frames, bitstream);
550 len+=u_1 ((MS_S8*)("SPS: gaps_in_frame_num_value_allowed_flag"), sps->gaps_in_frame_num_value_allowed_flag, bitstream);
551 len+=ue_v ((MS_S8*)("SPS: pic_width_in_mbs_minus1"), sps->pic_width_in_mbs_minus1, bitstream);
552 len+=ue_v ((MS_S8*)("SPS: pic_height_in_map_units_minus1"), sps->pic_height_in_map_units_minus1, bitstream);
553 len+=u_1 ((MS_S8*)("SPS: frame_mbs_only_flag"), sps->frame_mbs_only_flag, bitstream);
554 if (!sps->frame_mbs_only_flag)
555 {
556 len+=u_1 ((MS_S8*)("SPS: mb_adaptive_frame_field_flag"), sps->mb_adaptive_frame_field_flag, bitstream);
557 }
558 len+=u_1 ((MS_S8*)("SPS: direct_8x8_inference_flag"), sps->direct_8x8_inference_flag, bitstream);
559
560 len+=u_1 ((MS_S8*)("SPS: frame_cropping_flag"), sps->frame_cropping_flag, bitstream);
561
562 if (sps->frame_cropping_flag)
563 {
564 len+=ue_v ((MS_S8*)("SPS: frame_cropping_rect_left_offset"), sps->frame_cropping_rect_left_offset, bitstream);
565 len+=ue_v ((MS_S8*)("SPS: frame_cropping_rect_right_offset"), sps->frame_cropping_rect_right_offset, bitstream);
566 len+=ue_v ((MS_S8*)("SPS: frame_cropping_rect_top_offset"), sps->frame_cropping_rect_top_offset, bitstream);
567 len+=ue_v ((MS_S8*)("SPS: frame_cropping_rect_bottom_offset"), sps->frame_cropping_rect_bottom_offset, bitstream);
568 }
569
570 len+=u_1 ((MS_S8*)("SPS: vui_parameters_present_flag"), sps->vui_parameters_present_flag, bitstream);
571
572 if (sps->vui_parameters_present_flag)
573 len+=_GenerateVUI_parameters_rbsp(sps, bitstream); // currently a dummy, asserting
574
575 SODBtoRBSP(bitstream); // copies the last couple of bits into the byte buffer
576
577 LenInBytes=bitstream->byte_pos;
578
579 //free (bitstream);
580
581 return LenInBytes;
582 }
583
584
585 /*!
586 ***********************************************************************************************
587 * \brief
588 * MS_S32 _GeneratePic_parameter_set_rbsp (pic_parameter_set_rbsp_t *sps, MS_U8 *rbsp);
589 *
590 * \param pps
591 * picture parameter structure
592 * \param rbsp
593 * buffer to be filled with the rbsp, size should be at least MAXIMUMPARSETRBSPSIZE
594 *
595 * \return
596 * size of the RBSP in bytes, negative in case of an error
597 *
598 * \note
599 * Picture Parameter VUI function is called, but the function implements
600 * an exit (-1)
601 ************************************************************************************************
602 */
603
_GeneratePic_parameter_set_rbsp(MFE_CONFIG * pConfig,pic_parameter_set_rbsp_t * pps,MS_U8 * rbsp)604 static MS_S32 _GeneratePic_parameter_set_rbsp (MFE_CONFIG* pConfig, pic_parameter_set_rbsp_t *pps, MS_U8 *rbsp)
605 {
606 Bitstream stream, *bitstream = &stream;
607 MS_S32 len = 0, LenInBytes;
608 // MS_S32 profile_idc;
609
610 MS_ASSERT (rbsp != NULL);
611
612 // .. and use the rbsp provided (or allocated above) for the data
613 bitstream->streamBuffer = rbsp;
614 bitstream->byte_pos = 0;
615 bitstream->byte_buf = 0;
616 bitstream->bits_to_go = 8;
617 bitstream->zerocount = 0;
618
619 pps->pic_order_present_flag = pConfig->ctxH264Info.pic_order_present_flag;
620
621 len+=ue_v ((MS_S8*)("PPS: pic_parameter_set_id"), pps->pic_parameter_set_id, bitstream);
622 len+=ue_v ((MS_S8*)("PPS: seq_parameter_set_id"), pps->seq_parameter_set_id, bitstream);
623 len+=u_1 ((MS_S8*)("PPS: entropy_coding_mode_flag"), pps->entropy_coding_mode_flag, bitstream);
624 len+=u_1 ((MS_S8*)("PPS: pic_order_present_flag"), pps->pic_order_present_flag, bitstream);
625 len+=ue_v ((MS_S8*)("PPS: num_slice_groups_minus1"), pps->num_slice_groups_minus1, bitstream);
626 MS_ASSERT(pps->num_slice_groups_minus1 == 0);
627
628 len+=ue_v ((MS_S8*)("PPS: num_ref_idx_l0_active_minus1"), pps->num_ref_idx_l0_active_minus1, bitstream);
629 len+=ue_v ((MS_S8*)("PPS: num_ref_idx_l1_active_minus1"), pps->num_ref_idx_l1_active_minus1, bitstream);
630 len+=u_1 ((MS_S8*)("PPS: weighted_pred_flag"), pps->weighted_pred_flag, bitstream);
631 len+=u_v (2, (MS_S8*)("PPS: weighted_bipred_idc"), pps->weighted_bipred_idc, bitstream);
632 len+=se_v ((MS_S8*)("PPS: pic_init_qp_minus26"), pps->pic_init_qp_minus26, bitstream);
633 len+=se_v ((MS_S8*)("PPS: pic_init_qs_minus26"), pps->pic_init_qs_minus26, bitstream);
634
635 // profile_idc = pConfig->ctxH264Info.ProfileIDC;//IdentifyProfile();
636 len+=se_v ((MS_S8*)("PPS: chroma_qp_index_offset"), pps->chroma_qp_index_offset, bitstream);
637
638 len+=u_1 ((MS_S8*)("PPS: deblocking_filter_control_present_flag"), pps->deblocking_filter_control_present_flag, bitstream);
639 len+=u_1 ((MS_S8*)("PPS: constrained_intra_pred_flag"), pps->constrained_intra_pred_flag, bitstream);
640 len+=u_1 ((MS_S8*)("PPS: redundant_pic_cnt_present_flag"), pps->redundant_pic_cnt_present_flag, bitstream);
641
642 SODBtoRBSP(bitstream); // copies the last couple of bits into the byte buffer
643
644 LenInBytes=bitstream->byte_pos;
645
646 // Get rid of the helper structures
647 //free (bitstream);
648
649 return LenInBytes;
650 }
651
652
653 /*!
654 *************************************************************************************
655 * \brief
656 * Function body for VUI Parameter generation (to be done)
657 *
658 * \return
659 * exits with error message
660 *************************************************************************************
661 */
_GenerateVUI_parameters_rbsp(seq_parameter_set_rbsp_t * sps,Bitstream * bitstream)662 static MS_S32 _GenerateVUI_parameters_rbsp(seq_parameter_set_rbsp_t *sps, Bitstream *bitstream)
663 {
664 MS_S32 len=0;
665 vui_seq_parameters_t *vui_seq_parameters = &(sps->vui_seq_parameters);
666
667 len+=u_1 ((MS_S8*)("VUI: aspect_ratio_info_present_flag"), vui_seq_parameters->aspect_ratio_info_present_flag, bitstream);
668 if (vui_seq_parameters->aspect_ratio_info_present_flag)
669 {
670 len+=u_v (8,(MS_S8*)("VUI: aspect_ratio_idc"), vui_seq_parameters->aspect_ratio_idc, bitstream);
671 if (vui_seq_parameters->aspect_ratio_idc == 255)
672 {
673 len+=u_v (16,(MS_S8*)("VUI: sar_width"), vui_seq_parameters->sar_width, bitstream);
674 len+=u_v (16,(MS_S8*)("VUI: sar_height"), vui_seq_parameters->sar_height, bitstream);
675 }
676 }
677
678 len+=u_1 ((MS_S8*)("VUI: overscan_info_present_flag"), vui_seq_parameters->overscan_info_present_flag, bitstream);
679 if (vui_seq_parameters->overscan_info_present_flag)
680 {
681 len+=u_1 ((MS_S8*)("VUI: overscan_appropriate_flag"), vui_seq_parameters->overscan_appropriate_flag, bitstream);
682 }
683
684 len+=u_1 ((MS_S8*)("VUI: video_signal_type_present_flag"), vui_seq_parameters->video_signal_type_present_flag, bitstream);
685 if (vui_seq_parameters->video_signal_type_present_flag)
686 {
687 len+=u_v (3,(MS_S8*)("VUI: video_format"), vui_seq_parameters->video_format, bitstream);
688 len+=u_1 ((MS_S8*)("VUI: video_full_range_flag"), vui_seq_parameters->video_full_range_flag, bitstream);
689 len+=u_1 ((MS_S8*)("VUI: colour_description_present_flag"), vui_seq_parameters->colour_description_present_flag, bitstream);
690 if (vui_seq_parameters->colour_description_present_flag)
691 {
692 len+=u_v (8,(MS_S8*)("VUI: colour_primaries"), vui_seq_parameters->colour_primaries, bitstream);
693 len+=u_v (8,(MS_S8*)("VUI: transfer_characteristics"), vui_seq_parameters->transfer_characteristics, bitstream);
694 len+=u_v (8,(MS_S8*)("VUI: matrix_coefficients"), vui_seq_parameters->matrix_coefficients, bitstream);
695 }
696 }
697
698 len+=u_1 ((MS_S8*)("VUI: chroma_loc_info_present_flag"), vui_seq_parameters->chroma_location_info_present_flag, bitstream);
699 if (vui_seq_parameters->chroma_location_info_present_flag)
700 {
701 len+=ue_v ((MS_S8*)("VUI: chroma_sample_loc_type_top_field"), vui_seq_parameters->chroma_sample_loc_type_top_field, bitstream);
702 len+=ue_v ((MS_S8*)("VUI: chroma_sample_loc_type_bottom_field"), vui_seq_parameters->chroma_sample_loc_type_bottom_field, bitstream);
703 }
704
705 len+=u_1 ((MS_S8*)("VUI: timing_info_present_flag"), vui_seq_parameters->timing_info_present_flag, bitstream);
706 // timing parameters
707 if (vui_seq_parameters->timing_info_present_flag)
708 {
709 len+=u_v (32,(MS_S8*)("VUI: num_units_in_tick"), vui_seq_parameters->num_units_in_tick, bitstream);
710 len+=u_v (32,(MS_S8*)("VUI: time_scale"), vui_seq_parameters->time_scale, bitstream);
711 len+=u_1 ((MS_S8*)("VUI: fixed_frame_rate_flag"), vui_seq_parameters->fixed_frame_rate_flag, bitstream);
712 }
713 // end of timing parameters
714 // nal_hrd_parameters_present_flag
715 len+=u_1 ((MS_S8*)("VUI: nal_hrd_parameters_present_flag"), vui_seq_parameters->nal_hrd_parameters_present_flag, bitstream);
716 MS_ASSERT(vui_seq_parameters->nal_hrd_parameters_present_flag==0);
717 // if ( vui_seq_parameters->nal_hrd_parameters_present_flag )
718 // {
719 // len += WriteHRDParameters(sps, bitstream);
720 // }
721 // vcl_hrd_parameters_present_flag
722 len+=u_1 ((MS_S8*)("VUI: vcl_hrd_parameters_present_flag"), vui_seq_parameters->vcl_hrd_parameters_present_flag, bitstream);
723 MS_ASSERT(vui_seq_parameters->vcl_hrd_parameters_present_flag==0);
724 // if ( vui_seq_parameters->vcl_hrd_parameters_present_flag )
725 // {
726 // len += WriteHRDParameters(sps, bitstream);
727 // }
728 if ( vui_seq_parameters->nal_hrd_parameters_present_flag || vui_seq_parameters->vcl_hrd_parameters_present_flag )
729 {
730 len+=u_1 ((MS_S8*)("VUI: low_delay_hrd_flag"), vui_seq_parameters->low_delay_hrd_flag, bitstream );
731 }
732 len+=u_1 ((MS_S8*)("VUI: pic_struct_present_flag"), vui_seq_parameters->pic_struct_present_flag, bitstream);
733
734 len+=u_1 ((MS_S8*)("VUI: bitstream_restriction_flag"), vui_seq_parameters->bitstream_restriction_flag, bitstream);
735 if (vui_seq_parameters->bitstream_restriction_flag)
736 {
737 len+=u_1 ((MS_S8*)("VUI: motion_vectors_over_pic_boundaries_flag"), vui_seq_parameters->motion_vectors_over_pic_boundaries_flag, bitstream);
738 len+=ue_v ((MS_S8*)("VUI: max_bytes_per_pic_denom"), vui_seq_parameters->max_bytes_per_pic_denom, bitstream);
739 len+=ue_v ((MS_S8*)("VUI: max_bits_per_mb_denom"), vui_seq_parameters->max_bits_per_mb_denom, bitstream);
740 len+=ue_v ((MS_S8*)("VUI: log2_max_mv_length_horizontal"), vui_seq_parameters->log2_max_mv_length_horizontal, bitstream);
741 len+=ue_v ((MS_S8*)("VUI: log2_max_mv_length_vertical"), vui_seq_parameters->log2_max_mv_length_vertical, bitstream);
742 len+=ue_v ((MS_S8*)("VUI: num_reorder_frames"), vui_seq_parameters->num_reorder_frames, bitstream);
743 len+=ue_v ((MS_S8*)("VUI: max_dec_frame_buffering"), vui_seq_parameters->max_dec_frame_buffering, bitstream);
744 }
745
746 return len;
747 }
748
749
750
751 /*!
752 *************************************************************************************
753 * \brief
754 * void _GenerateVUIParameters(seq_parameter_set_rbsp_t *sps)
755 *
756 *
757 * \return
758 * none
759 *
760 * \note
761 *************************************************************************************
762 */
_GenerateVUIParameters(MFE_CONFIG * pConfig,seq_parameter_set_rbsp_t * sps)763 static void _GenerateVUIParameters(MFE_CONFIG *pConfig, seq_parameter_set_rbsp_t *sps)
764 {
765 MS_U32 SchedSelIdx;
766 hrd_parameters_t *nal_hrd = &(sps->vui_seq_parameters.nal_hrd_parameters);
767 hrd_parameters_t *vcl_hrd = &(sps->vui_seq_parameters.vcl_hrd_parameters);
768 vui_seq_parameters_t *vui = &(sps->vui_seq_parameters);
769
770 vui->aspect_ratio_info_present_flag = (MS_BOOL) (pConfig->setVUI_aspect_ratio_info_present_flag == TRUE);
771 vui->aspect_ratio_idc = (MS_U32) 1;
772 vui->sar_width = (MS_U32) 0;
773 vui->sar_height = (MS_U32) 0;
774
775 if (pConfig->setVUI_aspect_ratio_info_present_flag == TRUE)
776 {
777 vui->aspect_ratio_idc = (MS_U32) pConfig->setVUI_aspect_ratio_idc;
778 vui->sar_width = (MS_U32) pConfig->setVUI_sar_width;
779 vui->sar_height = (MS_U32) pConfig->setVUI_sar_height;
780 }
781
782 vui->overscan_info_present_flag = (MS_BOOL) 0;
783 vui->overscan_appropriate_flag = (MS_BOOL) 0;
784 vui->video_signal_type_present_flag = (MS_BOOL) 0;
785 vui->video_format = (MS_U32) 5;
786 vui->video_full_range_flag = (MS_BOOL) 0;
787 vui->colour_description_present_flag = (MS_BOOL) 0;
788 vui->colour_primaries = (MS_U32) 2;
789 vui->transfer_characteristics = (MS_U32) 2;
790 vui->matrix_coefficients = (MS_U32) 2;
791 vui->chroma_location_info_present_flag = (MS_BOOL) 0;
792 vui->chroma_sample_loc_type_top_field = (MS_U32) 0;
793 vui->chroma_sample_loc_type_bottom_field = (MS_U32) 0;
794 vui->timing_info_present_flag = (MS_BOOL) TRUE;
795 switch (pConfig->FrameRatex100) {
796 case 3000:
797 vui->num_units_in_tick = (MS_U32) 1;
798 vui->time_scale = (MS_U32) 60;
799 break;
800 case 1500:
801 vui->num_units_in_tick = (MS_U32) 1;
802 vui->time_scale = (MS_U32) 30;
803 break;
804 case 2500:
805 vui->num_units_in_tick = (MS_U32) 1;
806 vui->time_scale = (MS_U32) 50;
807 break;
808 case 2997:
809 vui->num_units_in_tick = (MS_U32) 1001;
810 vui->time_scale = (MS_U32) 60000;
811 break;
812 default:
813 vui->num_units_in_tick = (MS_U32) 50;
814 vui->time_scale = (MS_U32) pConfig->FrameRatex100;
815 //MS_ASSERT(0);
816 }
817 vui->fixed_frame_rate_flag = (MS_BOOL) FALSE;
818
819 // NAL HRD parameters
820 vui->nal_hrd_parameters_present_flag = (MS_BOOL) 0;
821 nal_hrd->cpb_cnt_minus1 = (MS_U32) 0;
822 nal_hrd->bit_rate_scale = (MS_U32) 0;
823 nal_hrd->cpb_size_scale = (MS_U32) 0;
824 for ( SchedSelIdx = 0; SchedSelIdx <= nal_hrd->cpb_cnt_minus1; SchedSelIdx++ )
825 {
826 nal_hrd->bit_rate_value_minus1[SchedSelIdx] = (MS_U32) 0;
827 nal_hrd->cpb_size_value_minus1[SchedSelIdx] = (MS_U32) 0;
828 nal_hrd->cbr_flag[SchedSelIdx] = (MS_U32) 0;
829 }
830 nal_hrd->initial_cpb_removal_delay_length_minus1 = (MS_U32) 23;
831 nal_hrd->cpb_removal_delay_length_minus1 = (MS_U32) 23;
832 nal_hrd->dpb_output_delay_length_minus1 = (MS_U32) 23;
833 nal_hrd->time_offset_length = (MS_U32) 24;
834
835 // VCL HRD parameters
836 vui->vcl_hrd_parameters_present_flag = (MS_BOOL) 0;
837 vcl_hrd->cpb_cnt_minus1 = (MS_U32) 0;
838 vcl_hrd->bit_rate_scale = (MS_U32) 0;
839 vcl_hrd->cpb_size_scale = (MS_U32) 0;
840 for ( SchedSelIdx = 0; SchedSelIdx <= vcl_hrd->cpb_cnt_minus1; SchedSelIdx++ )
841 {
842 vcl_hrd->bit_rate_value_minus1[SchedSelIdx] = (MS_U32) 0;
843 vcl_hrd->cpb_size_value_minus1[SchedSelIdx] = (MS_U32) 0;
844 vcl_hrd->cbr_flag[SchedSelIdx] = (MS_U32) 0;
845 }
846 vcl_hrd->initial_cpb_removal_delay_length_minus1 = (MS_U32) 23;
847 vcl_hrd->cpb_removal_delay_length_minus1 = (MS_U32) 23;
848 vcl_hrd->dpb_output_delay_length_minus1 = (MS_U32) 23;
849 vcl_hrd->time_offset_length = (MS_U32) 24;
850
851 vui->low_delay_hrd_flag = (MS_BOOL) 0;
852 vui->pic_struct_present_flag = (MS_BOOL) 0;
853 vui->bitstream_restriction_flag = (MS_BOOL) 1;
854 vui->motion_vectors_over_pic_boundaries_flag = (MS_BOOL) 1;
855 vui->max_bytes_per_pic_denom = (MS_U32) 0;
856 vui->max_bits_per_mb_denom = (MS_U32) 0;
857 vui->log2_max_mv_length_horizontal = (MS_U32) 7;
858 vui->log2_max_mv_length_vertical = (MS_U32) 7;
859 vui->num_reorder_frames = (MS_U32) 0;
860 vui->max_dec_frame_buffering = (MS_U32) pConfig->ctxH264Info.num_ref_frames;
861 }
862
863
864 /*!
865 ********************************************************************************************
866 * \brief
867 * Writes a NALU to the Annex B Byte Stream
868 *
869 * \return
870 * number of bits written
871 *
872 ********************************************************************************************
873 */
WriteAnnexbNALU(OutStream * pStream,NALU_t * n)874 static MS_S32 WriteAnnexbNALU(OutStream* pStream, NALU_t *n)
875 {
876 MS_U32 i, leftbits;
877 MS_S32 BitsWritten = 0;
878 MS_ASSERT (n != NULL);
879 if (n == NULL)
880 {
881 ms_dprintk(DRV_L4, "[WriteAnnexbNALU] n is null\n");
882 return -1;
883 }
884
885 MS_ASSERT (n->forbidden_bit == 0);
886 MS_ASSERT (n->startcodeprefix_len == 3 || n->startcodeprefix_len == 4);
887
888 // printf ("WriteAnnexbNALU: writing %d bytes w/ startcode_len %d\n"), n->len+1, n->startcodeprefix_len);
889 if (n->startcodeprefix_len > 3)
890 {
891 osPutBits(pStream, 0, 8, (MS_S8*)("start-code 0"));
892 BitsWritten =+ 8;
893 }
894 osPutBits(pStream, 0, 8, (MS_S8*)("start-code 0"));
895 osPutBits(pStream, 0, 8, (MS_S8*)("start-code 0"));
896 osPutBits(pStream, 1, 8, (MS_S8*)("start-code 1"));
897 BitsWritten += 24;
898
899 n->buf[0] = (MS_U8) ((n->forbidden_bit << 7) | (n->nal_reference_idc << 5) | n->nal_unit_type);
900 // printf ("First Byte %x, nal_ref_idc %x, nal_unit_type %d\n"), n->buf[0], n->nal_reference_idc, n->nal_unit_type);
901
902 for (i=0; i<n->len/8; i++)
903 osPutBits(pStream, n->buf[i], 8, (MS_S8*)("nalu-body"));
904 leftbits = n->len - (i*8);
905 if (leftbits>0)
906 osPutBits(pStream, n->buf[i]&(0xFF>>(8-leftbits)), leftbits, (MS_S8*)("nalu-body (last-bits)"));
907 BitsWritten += n->len;
908
909 return BitsWritten;
910 }
911
912 /*!
913 ************************************************************************
914 * \brief
915 * Selects picture type and codes it to symbol
916 *
917 * \return
918 * symbol value for picture type
919 ************************************************************************
920 */
get_picture_type(MFE_CONFIG * pConfig)921 static MS_S32 get_picture_type(MFE_CONFIG* pConfig)
922 {
923 // set this value to zero for transmission without signaling
924 // that the whole picture has the same slice type
925 const MS_S32 same_slicetype_for_whole_frame = 0;//5;
926
927 switch (pConfig->vopPredType)
928 {
929 case I_VOP:
930 return 2 + same_slicetype_for_whole_frame;
931 break;
932 case P_VOP:
933 return 0 + same_slicetype_for_whole_frame;
934 break;
935 case B_VOP:
936 return 1 + same_slicetype_for_whole_frame;
937 break;
938 }
939
940 return 0;
941 }
942
943 /*!
944 ********************************************************************************************
945 * \brief
946 * writes the ref_pic_list_reordering syntax
947 * based on content of according fields in img structure
948 *
949 * \return
950 * number of bits used
951 ********************************************************************************************
952 */
ref_pic_list_reordering(MFE_CONFIG * pConfig,Bitstream * bitstream)953 static MS_S32 ref_pic_list_reordering(MFE_CONFIG* pConfig, Bitstream *bitstream)
954 {
955 MS_S32 len=0;
956
957 if (pConfig->vopPredType!=I_VOP)
958 {
959 len += u_1 ((MS_S8*)("SH: ref_pic_list_reordering_flag_l0"), /*currSlice->ref_pic_list_reordering_flag_l0*/0, bitstream);
960 }
961
962 return len;
963 }
964
965 /*!
966 ************************************************************************
967 * \brief
968 * write the memory management control operations
969 *
970 * \return
971 * number of bits used
972 ************************************************************************
973 */
dec_ref_pic_marking(MFE_CONFIG * pConfig,Bitstream * bitstream)974 static MS_S32 dec_ref_pic_marking(MFE_CONFIG* pConfig, Bitstream *bitstream)
975 {
976 H264INFO* pInfo = &pConfig->ctxH264Info;
977
978 MS_S32 len=0;
979
980 if (pInfo->idr_flag)
981 {
982 len += u_1((MS_S8*)("SH: no_output_of_prior_pics_flag"), /*img->no_output_of_prior_pics_flag*/0, bitstream);
983 len += u_1((MS_S8*)("SH: long_term_reference_flag"), /*img->long_term_reference_flag*/0, bitstream);
984 }
985 else
986 {
987 len += u_1((MS_S8*)("SH: adaptive_ref_pic_buffering_flag"), /*img->adaptive_ref_pic_buffering_flag*/0, bitstream);
988 }
989 return len;
990 }
991
992 /*!
993 ********************************************************************************************
994 * \brief
995 * Write a slice header
996 *
997 * \return
998 * number of bits used
999 ********************************************************************************************
1000 */
SliceHeader(MFE_CONFIG * pConfig,MS_U8 * rbsp)1001 static MS_S32 SliceHeader(MFE_CONFIG* pConfig, MS_U8 *rbsp)
1002 {
1003 Bitstream stream, *bitstream = &stream;
1004 H264INFO* pInfo = &pConfig->ctxH264Info;
1005 MS_S32 len = 0;
1006 MS_U32 field_pic_flag = 0, bottom_field_flag = 0;
1007
1008 bitstream->streamBuffer = rbsp;
1009 bitstream->byte_pos = 0;
1010 bitstream->byte_buf = 0;
1011 bitstream->bits_to_go = 8;
1012 bitstream->zerocount = 0;
1013
1014 len = ue_v((MS_S8*)("SH: first_mb_in_slice"), /*img->current_mb_nr*/0, bitstream);
1015 len += ue_v((MS_S8*)("SH: slice_type"), get_picture_type(pConfig), bitstream);
1016 len += ue_v((MS_S8*)("SH: pic_parameter_set_id"), pConfig->active_pps->pic_parameter_set_id ,bitstream);
1017 len += u_v (pInfo->log2_max_frame_num_minus4 + 4, (MS_S8*)("SH: frame_num"), pInfo->frame_num, bitstream);
1018
1019 if (!pConfig->active_sps->frame_mbs_only_flag)
1020 {
1021 // field_pic_flag u(1)
1022 field_pic_flag = (pInfo->structure ==TOP_FIELD || pInfo->structure ==BOTTOM_FIELD)?1:0;
1023 //MS_ASSERT( field_pic_flag == img->fld_flag );
1024 len += u_1((MS_S8*)("SH: field_pic_flag"), field_pic_flag, bitstream);
1025
1026 if (field_pic_flag)
1027 {
1028 //bottom_field_flag u(1)
1029 bottom_field_flag = (pInfo->structure == BOTTOM_FIELD)?1:0;
1030 len += u_1((MS_S8*)("SH: bottom_field_flag"), bottom_field_flag ,bitstream);
1031 }
1032 }
1033
1034 if (pInfo->idr_flag)
1035 {
1036 // idr_pic_id
1037 len += ue_v ((MS_S8*)("SH: idr_pic_id"), (pInfo->number % 2), bitstream);
1038 }
1039
1040 if (pInfo->pic_order_cnt_type == 0)
1041 {
1042 MS_ASSERT(0);
1043 /*
1044 if (active_sps->frame_mbs_only_flag)
1045 {
1046 img->pic_order_cnt_lsb = (img->toppoc & ~((((MS_U32)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
1047 }
1048 else
1049 {
1050 if (!field_pic_flag || img->structure == TOP_FIELD)
1051 img->pic_order_cnt_lsb = (img->toppoc & ~((((MS_U32)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
1052 else if ( img->structure == BOTTOM_FIELD )
1053 img->pic_order_cnt_lsb = (img->bottompoc & ~((((MS_U32)(-1)) << (log2_max_pic_order_cnt_lsb_minus4+4))) );
1054 }
1055
1056 len += u_v (log2_max_pic_order_cnt_lsb_minus4+4, "SH: pic_order_cnt_lsb"), img->pic_order_cnt_lsb, bitstream);
1057
1058 if (img->pic_order_present_flag && !field_pic_flag)
1059 {
1060 len += se_v ("SH: delta_pic_order_cnt_bottom"), img->delta_pic_order_cnt_bottom, bitstream);
1061 }
1062 */
1063 }
1064 if (pInfo->pic_order_cnt_type == 1 /*&& !img->delta_pic_order_always_zero_flag*/)
1065 {
1066 MS_ASSERT(0);
1067 /*
1068 len += se_v ("SH: delta_pic_order_cnt[0]"), img->delta_pic_order_cnt[0], bitstream);
1069
1070 if (img->pic_order_present_flag && !field_pic_flag)
1071 {
1072 len += se_v ("SH: delta_pic_order_cnt[1]"), img->delta_pic_order_cnt[1], bitstream);
1073 }
1074 */
1075 }
1076
1077 if (pConfig->vopPredType == P_VOP)
1078 {
1079 MS_S32 override_flag;
1080
1081 //this is for MFE fixed setting override_flag
1082 override_flag = (pInfo->num_ref_idx_l0_active != (pConfig->active_pps->num_ref_idx_l0_active_minus1 +1)) ? 1 : 0;
1083 ms_dprintk(DRV_L3,"override_flag = %d, num_ref_idx_l0_active = %d, num_ref_idx_l0_active_minus1 = %d\n",
1084 (int)override_flag, (int)pInfo->num_ref_idx_l0_active, (int)pConfig->active_pps->num_ref_idx_l0_active_minus1);
1085 len += u_1((MS_S8*)("SH: num_ref_idx_active_override_flag"), override_flag, bitstream);
1086 if (override_flag)
1087 {
1088 len += ue_v((MS_S8*)("SH: num_ref_idx_l0_active_minus1"), pInfo->num_ref_idx_l0_active-1, bitstream);
1089 }
1090 }
1091 len += ref_pic_list_reordering(pConfig, bitstream);
1092
1093 if (pInfo->nal_ref_idc)
1094 len += dec_ref_pic_marking(pConfig, bitstream);
1095
1096 if(pConfig->UseCABAC && pConfig->vopPredType != I_VOP)
1097 {
1098 len += ue_v((MS_S8*)("SH: cabac_init_idc"), 0, bitstream);
1099 }
1100
1101 len += se_v((MS_S8*)("SH: slice_qp_delta"), (pInfo->intQP - 26 - pConfig->active_pps->pic_init_qp_minus26), bitstream);
1102
1103 if (pConfig->active_pps->deblocking_filter_control_present_flag)
1104 {
1105 len += ue_v((MS_S8*)("SH: disable_deblocking_filter_idc"), pInfo->nDeblockIDC, bitstream); // Turn loop filter on/off on slice basis
1106 if (pInfo->nDeblockIDC!=1)
1107 {
1108 len += se_v ((MS_S8*)("SH: slice_alpha_c0_offset_div2"), pInfo->nDeblockAlpha / 2, bitstream);
1109 len += se_v ((MS_S8*)("SH: slice_beta_offset_div2"), pInfo->nDeblockBeta / 2, bitstream);
1110 }
1111 }
1112
1113 //The Slice header must be byte aligned iff enable CABAC.
1114 if(pConfig->UseCABAC && (bitstream->bits_to_go!=8)) {
1115 len+=bitstream->bits_to_go;
1116 writeVlcByteAlign(bitstream);
1117 }
1118 // Put final bits
1119 if (bitstream->bits_to_go!=8)
1120 bitstream->streamBuffer[bitstream->byte_pos] = bitstream->byte_buf;
1121
1122 return len;
1123 }
1124
1125 /*!
1126 ********************************************************************************************
1127 * \brief
1128 * Write dummy(P) slice header, and also dummy slice data
1129 *
1130 * \return
1131 * number of bits used
1132 ********************************************************************************************
1133 */
DummySliceHeaderAndData(MFE_CONFIG * pConfig,MS_U8 * rbsp)1134 static MS_S32 DummySliceHeaderAndData(MFE_CONFIG* pConfig, MS_U8 *rbsp)
1135 {
1136 Bitstream stream, *bitstream = &stream;
1137 H264INFO* pInfo = &pConfig->ctxH264Info;
1138 MS_S32 len = 0;
1139 MS_S32 nMbCount = ((pConfig->nDispWidth+15)>>4) * ((pConfig->nDispHeight+15)>>4);
1140
1141 bitstream->streamBuffer = rbsp;
1142 bitstream->byte_pos = 0;
1143 bitstream->byte_buf = 0;
1144 bitstream->bits_to_go = 8;
1145 bitstream->zerocount = 0;
1146
1147 len = ue_v((MS_S8*)("SH: first_mb_in_slice"), 0, bitstream);
1148 len += ue_v((MS_S8*)("SH: slice_type"), 0, bitstream); // Forced P-slice
1149 len += ue_v((MS_S8*)("SH: pic_parameter_set_id"), pConfig->active_pps->pic_parameter_set_id, bitstream);
1150 len += u_v (pInfo->log2_max_frame_num_minus4 + 4, (MS_S8*)("SH: frame_num"), pInfo->frame_num, bitstream);
1151
1152 len += u_1 ((MS_S8*)("SH: num_ref_idx_active_override_flag"), 0, bitstream); // Forced to 0
1153 len += u_1 ((MS_S8*)("SH: ref_pic_list_reordering_flag_l0"), 0, bitstream);
1154 len += se_v((MS_S8*)("SH: slice_qp_delta"), (/*pInfo->intStep*/26 - 26 - pConfig->active_pps->pic_init_qp_minus26), bitstream); // Forced to 26
1155
1156 if (pConfig->active_pps->deblocking_filter_control_present_flag)
1157 {
1158 len += ue_v((MS_S8*)("SH: disable_deblocking_filter_idc"), pInfo->nDeblockIDC, bitstream); // Turn loop filter on/off on slice basis
1159 if (pInfo->nDeblockIDC!=1)
1160 {
1161 len += se_v ((MS_S8*)("SH: slice_alpha_c0_offset_div2"), pInfo->nDeblockAlpha / 2, bitstream);
1162 len += se_v ((MS_S8*)("SH: slice_beta_offset_div2"), pInfo->nDeblockBeta / 2, bitstream);
1163 }
1164 }
1165
1166 // Above is slice_header()
1167 // Below is slice_data()
1168 len += ue_v((MS_S8*)("SD: mb_skip_run"), nMbCount, bitstream);
1169
1170 // rbsp_trailing_bits()
1171 len += u_1 ((MS_S8*)("SD: rbsp_stop_one_bit"), 1, bitstream);
1172 if (bitstream->bits_to_go!=8)
1173 len += u_v(bitstream->bits_to_go, (MS_S8*)("SD: rbsp_alignment_zero_bit"), 0, bitstream);
1174
1175 return len;
1176 }
1177
get_NALU_1stbyte(H264INFO * pInfo,MS_U8 vopPredType)1178 MS_U8 get_NALU_1stbyte(H264INFO *pInfo, MS_U8 vopPredType)
1179 {
1180 MS_S32 nal_unit_type, nal_reference_idc, forbidden_bit;
1181 if (pInfo->idr_flag)
1182 {
1183 nal_unit_type = NALU_TYPE_IDR;
1184 nal_reference_idc = NALU_PRIORITY_HIGHEST;
1185 }
1186 else if (vopPredType == B_VOP)
1187 {
1188 nal_unit_type = NALU_TYPE_SLICE;
1189 if (pInfo->nal_ref_idc !=0)
1190 {
1191 nal_reference_idc = NALU_PRIORITY_HIGH;
1192 }
1193 else
1194 {
1195 nal_reference_idc = NALU_PRIORITY_DISPOSABLE;
1196 }
1197 }
1198 else // non-b frame, non IDR slice
1199 {
1200 nal_unit_type = NALU_TYPE_SLICE;
1201 if (pInfo->nal_ref_idc !=0)
1202 {
1203 nal_reference_idc = NALU_PRIORITY_HIGH;
1204 }
1205 else
1206 {
1207 nal_reference_idc = NALU_PRIORITY_DISPOSABLE;
1208 }
1209 }
1210 forbidden_bit = 0;
1211 return (MS_U8) ((forbidden_bit << 7) | (nal_reference_idc << 5) | nal_unit_type);
1212 }
1213
codeSPSPPS(MFE_CONFIG * pConfig,OutStream * pStream)1214 void codeSPSPPS(MFE_CONFIG* pConfig,OutStream* pStream)
1215 {
1216 WriteAnnexbNALU(pStream, &pConfig->NaluStruct[STATIC_SPS]);
1217 WriteAnnexbNALU(pStream, &pConfig->NaluStruct[STATIC_PPS]);
1218 }
1219
codeH264ConfigHeaders(MFE_CONFIG * pConfig,MS_U32 * size_of_sps,MS_U32 * size_of_pps)1220 MS_S32 codeH264ConfigHeaders(MFE_CONFIG *pConfig,MS_U32* size_of_sps,MS_U32* size_of_pps)
1221 {
1222 OutStream* pStream = &pConfig->m_OutStream;
1223
1224 osReset(pStream);
1225
1226 // SPS, PPS
1227 //codeSPSPPS(pStream);
1228 *size_of_sps = WriteAnnexbNALU(pStream, &pConfig->NaluStruct[STATIC_SPS]) / 8;
1229 *size_of_pps = WriteAnnexbNALU(pStream, &pConfig->NaluStruct[STATIC_PPS]) / 8;
1230 // Finalize
1231 osFlushAll(pStream);
1232
1233 // The generated bytes start from pStream->m_pbFrameBuffer and with pStream->m_nByteCount bytes.
1234 return pStream->m_nByteCount;
1235 }
1236
codeSliceHeader(MFE_CONFIG * pConfig,OutStream * pStream)1237 void codeSliceHeader(MFE_CONFIG* pConfig, OutStream* pStream)
1238 {
1239 NALU_t naluBuf, *nalu = &naluBuf;
1240 H264INFO* pInfo = &pConfig->ctxH264Info;
1241 MS_U8 rbsp[MAXRBSPSIZE];
1242 MS_U8 Byte1;
1243
1244 nalu->buf = rbsp;
1245 nalu->len = 8 + SliceHeader(pConfig, &rbsp[1]); // rbsp[0] is reserved for nal_unit_idc and nal_unit_type
1246
1247 nalu->startcodeprefix_len = 4;
1248
1249 Byte1 = get_NALU_1stbyte(pInfo, pConfig->vopPredType);
1250 nalu->nal_unit_type = (NaluType)(Byte1&0x1f);
1251 nalu->nal_reference_idc = (NalRefIdc)((Byte1>>5)&0x3);
1252 nalu->forbidden_bit = 0;
1253
1254 WriteAnnexbNALU(pStream, nalu);
1255 }
1256
codeDummySliceHeader(MFE_CONFIG * pConfig,OutStream * pStream)1257 void codeDummySliceHeader(MFE_CONFIG* pConfig, OutStream* pStream)
1258 {
1259 NALU_t naluBuf, *nalu = &naluBuf;
1260 MS_U8 rbsp[MAXRBSPSIZE];
1261 MS_U8 Byte1;
1262
1263 nalu->buf = rbsp;
1264 nalu->len = 8 + DummySliceHeaderAndData(pConfig, &rbsp[1]); // rbsp[0] is reserved for nal_unit_idc and nal_unit_type
1265
1266 nalu->startcodeprefix_len = 4;
1267
1268 Byte1 = (MS_U8) ((/*forbidden_bit*/0 << 7) | (/*nal_reference_idc*/NALU_PRIORITY_DISPOSABLE << 5) | /*nal_unit_type*/NALU_TYPE_SLICE);
1269 nalu->nal_unit_type = Byte1&0x1f;
1270 nalu->nal_reference_idc = (Byte1>>5)&0x3;
1271 nalu->forbidden_bit = 0;
1272
1273 WriteAnnexbNALU(pStream, nalu);
1274 }