xref: /utopia/UTPA2-700.0.x/modules/mfe/drv/mfe_ex/cModel/parset.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
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 }