1 /*
2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3  * Copyright (c) Imagination Technologies Limited, UK
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *    Elaine Wang <elaine.wang@intel.com>
27  *    Zeng Li <zeng.li@intel.com>
28  *
29  */
30 
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include "img_types.h"
35 #include "psb_def.h"
36 #include "psb_drv_debug.h"
37 #include "pnw_hostheader.h"
38 
39 
40 /* Global stores the latest QP information for the DoHeader()
41  * routine, should be filled in by the rate control algorithm.
42  */
43 #define HEADERS_VERBOSE_OUTPUT 0
44 
45 /* #define USESTATICWHEREPOSSIBLE 1 */
46 
47 #define MAXNUMBERELEMENTS 16
48 #define HEADER_SIZE (128*2)
49 
50 /* SOME USEFUL TEST FUNCTIONS */
51 #if 0
52 
53 static void Show_Bits(
54     IMG_UINT8 *ucBitStream,
55     IMG_UINT32 ByteStartBit,
56     IMG_UINT32 Bits)
57 {
58     char Txt[1024];
59     IMG_UINT32 uiByteSize;
60     IMG_UINT32 uiLp, uiBt, Bcnt;
61     Bcnt = 0;
62     uiByteSize = (Bits + ByteStartBit + 7) >> 3;
63     for (uiLp = 0; uiLp < uiByteSize; uiLp++) {
64         snprintf(Txt, strlen(" "), " ");
65         for (uiBt = 128; uiBt >= 1; uiBt = uiBt >> 1) {
66             Bcnt++;
67             if (Bcnt > Bits + ByteStartBit || Bcnt <= ByteStartBit)
68                 snprintf(Txt, sizeof(Txt), "%sX", Txt);
69             else
70                 snprintf(Txt, sizeof(Txt), "%s%i", Txt, (ucBitStream[uiLp] & uiBt) > 0);
71         }
72 
73         snprintf(Txt, sizeof(Txt), "%s ", Txt);
74         printf("%s", Txt);
75         if ((uiLp + 1) % 8 == 0) printf("\n");
76     }
77 
78     printf("\n\n");
79 }
80 #endif
81 
82 #if 0
83 
84 static void Show_Elements(
85     MTX_HEADER_PARAMS *mtx_hdr,
86     MTX_HEADER_ELEMENT **elt_p)
87 {
88     IMG_UINT8 f;
89     IMG_UINT32 TotalByteSize;
90     IMG_UINT32 RTotalByteSize;
91 
92     RTotalByteSize = TotalByteSize = 0;
93     for (f = 0; f < mtx_hdr->Elements; f++) {
94 #if HEADERS_VERBOSE_OUTPUT
95         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Encoding Element [%i] - Type:%i\n", f, elt_p[f]->Element_Type);
96 #endif
97         if (elt_p[f]->Element_Type == ELEMENT_STARTCODE_RAWDATA ||
98             elt_p[f]->Element_Type == ELEMENT_RAWDATA) {
99             TotalByteSize = elt_p[f]->Size;
100 #if HEADERS_VERBOSE_OUTPUT
101             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Writing %i RAW bits to element.\n", elt_p[f]->Size);
102             Show_Bits((IMG_UINT8 *)(&elt_p[f]->Size) + 1, 0, TotalByteSize);
103 #endif
104             TotalByteSize += 8;
105 
106             RTotalByteSize += (((IMG_UINT32)((TotalByteSize + 7) / 8)) * 8);
107             RTotalByteSize += 32;
108         } else {
109             TotalByteSize = 0;
110             switch (elt_p[f]->Element_Type) {
111             case ELEMENT_QP:
112 #if HEADERS_VERBOSE_OUTPUT
113                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_QP (H264)- for MTX to generate and insert this value\n");
114 #endif
115                 break;
116             case ELEMENT_SQP:
117 #if HEADERS_VERBOSE_OUTPUT
118                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SQP (H264)- for MTX to generate and insert this value\n");
119 #endif
120                 break;
121             case ELEMENT_FRAMEQSCALE:
122 #if HEADERS_VERBOSE_OUTPUT
123                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_FRAMEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
124 #endif
125                 break;
126             case ELEMENT_SLICEQSCALE:
127 #if HEADERS_VERBOSE_OUTPUT
128                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SLICEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
129 #endif
130                 break;
131             case ELEMENT_INSERTBYTEALIGN_H264:
132 #if HEADERS_VERBOSE_OUTPUT
133                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_H264 -  MTX to generate 'rbsp_trailing_bits()' field\n");
134 #endif
135                 break;
136             case ELEMENT_INSERTBYTEALIGN_MPG4:
137 #if HEADERS_VERBOSE_OUTPUT
138                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_MPG4 -  MTX to generate MPEG4 'byte_aligned_bits' field\n");
139 #endif
140                 break;
141             default:
142                 break;
143             }
144 
145             RTotalByteSize += 32;
146 #if HEADERS_VERBOSE_OUTPUT
147             drv_debug_msg(VIDEO_DEBUG_GENERAL, "No RAW bits\n\n");
148 #endif
149         }
150     }
151 
152     /* TotalByteSize=TotalByteSize+32+(&elt_p[f-1]->Element_Type-&elt_p[0]->Element_Type)*8; */
153 
154 #if HEADERS_VERBOSE_OUTPUT
155     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nCombined ELEMENTS Stream:\n");
156     Show_Bits((IMG_UINT8 *) mtx_hdr->asElementStream, 0, RTotalByteSize);
157 #endif
158 }
159 #endif
160 
161 
162 /**
163  * Header Writing Functions
164  * Low level bit writing and ue, se functions
165  * HOST CODE
166  */
pnw__write_upto8bits_elements(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 wrt_bits,IMG_UINT16 bit_cnt)167 static void pnw__write_upto8bits_elements(
168     MTX_HEADER_PARAMS *mtx_hdr,
169     MTX_HEADER_ELEMENT **elt_p,
170     IMG_UINT8 wrt_bits,
171     IMG_UINT16 bit_cnt)
172 {
173     /* This is the core function to write bits/bytes
174      * to a header stream, it writes them directly to ELEMENT structures.
175      */
176     IMG_UINT8 *wrt_bytes_p;
177     IMG_UINT8 *size_bits_p;
178     union {
179         IMG_UINT32 UI16Input;
180         IMG_UINT8 UI8Input[2];
181     } InputVal = {0, };
182     IMG_UINT8 OutByteIndex;
183     IMG_INT16 Shift;
184 
185     if (bit_cnt == 0) return;
186 
187     /* WA for klockwork */
188     if (mtx_hdr->Elements >= MAXNUMBERELEMENTS) {
189         drv_debug_msg(VIDEO_DEBUG_ERROR, "mtx_hdr->Elments overflow\n");
190         return;
191     }
192 
193     /* First ensure that unused bits in wrt_bits are zeroed */
194     wrt_bits &= (0x00ff >> (8 - bit_cnt));
195 
196     InputVal.UI16Input = 0;
197 
198     /* Pointer to the bit count field */
199     size_bits_p = &(elt_p[mtx_hdr->Elements]->Size);
200 
201     /* Pointer to the space where header bits are to be written */
202     wrt_bytes_p = &(elt_p[mtx_hdr->Elements]->Bits);
203 
204     OutByteIndex = (size_bits_p[0] / 8);
205 
206     if (!(size_bits_p[0] & 7)) {
207         if (size_bits_p[0] >= 120 && ((mtx_hdr->Elements + 1) < MAXNUMBERELEMENTS)) {
208             /* Element maximum bits send to element, time to start a new one */
209             mtx_hdr->Elements++; /* Increment element index */
210             /* Element pointer set to position of next element (120/8 = 15 bytes) */
211             elt_p[mtx_hdr->Elements] = (MTX_HEADER_ELEMENT *) & wrt_bytes_p[15];
212 
213             /* Write ELEMENT_TYPE */
214             elt_p[mtx_hdr->Elements]->Element_Type = ELEMENT_RAWDATA;
215 
216             /* Set new element size (bits) to zero */
217             elt_p[mtx_hdr->Elements]->Size = 0;
218 
219             /* Begin writing to the new element */
220             pnw__write_upto8bits_elements(mtx_hdr, elt_p, wrt_bits, bit_cnt);
221             return;
222         }
223 
224         wrt_bytes_p[OutByteIndex] = 0; /* Beginning a new byte, clear byte */
225     }
226 
227     Shift = (IMG_INT16)((8 - bit_cnt) - (size_bits_p[0] & 7));
228 
229     if (Shift >= 0) {
230         wrt_bits <<= Shift;
231         wrt_bytes_p[OutByteIndex] |= wrt_bits;
232         size_bits_p[0] = size_bits_p[0] + bit_cnt;
233     } else {
234         InputVal.UI8Input[1] = (IMG_UINT8) wrt_bits + 256;
235         InputVal.UI16Input >>= -Shift;
236 
237         wrt_bytes_p[OutByteIndex] |= InputVal.UI8Input[1];
238 
239         size_bits_p[0] = size_bits_p[0] + bit_cnt;
240         size_bits_p[0] = size_bits_p[0] - ((IMG_UINT8) - Shift);
241         InputVal.UI8Input[0] = InputVal.UI8Input[0] >> (8 + Shift);
242 
243         pnw__write_upto8bits_elements(mtx_hdr, elt_p, InputVal.UI8Input[0], (IMG_UINT16) - Shift);
244     }
245 }
246 
pnw__write_upto32bits_elements(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 wrt_bits,IMG_UINT32 bit_cnt)247 static void pnw__write_upto32bits_elements(
248     MTX_HEADER_PARAMS *mtx_hdr,
249     MTX_HEADER_ELEMENT **elt_p,
250     IMG_UINT32 wrt_bits,
251     IMG_UINT32 bit_cnt)
252 {
253     IMG_UINT32 BitLp;
254     IMG_UINT32 EndByte;
255     IMG_UINT8 Bytes[4];
256 
257     for (BitLp = 0; BitLp < 4; BitLp++) {
258         Bytes[BitLp] = (IMG_UINT8)(wrt_bits & 255);
259         wrt_bits = wrt_bits >> 8;
260     }
261 
262     EndByte = ((bit_cnt + 7) / 8);
263 
264     if ((bit_cnt) % 8)
265         pnw__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[EndByte-1], (IMG_UINT8)((bit_cnt) % 8));
266     else
267         pnw__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[EndByte-1], 8);
268 
269     if (EndByte > 1)
270         for (BitLp = EndByte - 1; BitLp > 0; BitLp--) {
271             pnw__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[BitLp-1], 8);
272         }
273 }
274 
pnw__generate_ue(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 uiVal)275 static void pnw__generate_ue(
276     MTX_HEADER_PARAMS *mtx_hdr,
277     MTX_HEADER_ELEMENT **elt_p,
278     IMG_UINT32 uiVal)
279 {
280     IMG_UINT32 uiLp;
281     IMG_UINT8 ucZeros;
282     IMG_UINT32 uiChunk;
283 
284     for (uiLp = 1, ucZeros = 0; (uiLp - 1) < uiVal ; uiLp = uiLp + uiLp, ucZeros++)
285         uiVal = uiVal - uiLp;
286 
287     /* ucZeros = number of preceding zeros required
288      * uiVal = value to append after zeros and 1 bit
289      */
290 
291     /* Write preceding zeros */
292     for (uiLp = (IMG_UINT32) ucZeros; uiLp + 1 > 8; uiLp -= 8)
293         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
294 
295     /* Write zeros and 1 bit set */
296     pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) 1, (IMG_UINT8)(uiLp + 1));
297 
298     /* Write Numeric part */
299     while (ucZeros > 8) {
300         ucZeros -= 8;
301         uiChunk = (uiVal >> ucZeros);
302         pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiChunk, 8);
303         uiVal = uiVal - (uiChunk << ucZeros);
304     }
305 
306     pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiVal, ucZeros);
307 }
308 
309 
pnw__generate_se(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,int iVal)310 static void pnw__generate_se(
311     MTX_HEADER_PARAMS *mtx_hdr,
312     MTX_HEADER_ELEMENT **elt_p,
313     int iVal)
314 {
315     IMG_UINT32 uiCodeNum;
316 
317     if (iVal > 0)
318         uiCodeNum = (IMG_UINT32)(iVal + iVal - 1);
319     else
320         uiCodeNum = (IMG_UINT32)(-iVal - iVal);
321 
322     pnw__generate_ue(mtx_hdr, elt_p, uiCodeNum);
323 }
324 
325 
pnw__insert_element_token(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,HEADER_ELEMENT_TYPE Token)326 static void pnw__insert_element_token(
327     MTX_HEADER_PARAMS *mtx_hdr,
328     MTX_HEADER_ELEMENT **elt_p,
329     HEADER_ELEMENT_TYPE Token)
330 {
331     IMG_UINT8 Offset;
332     IMG_UINT8 *P;
333 
334     if (mtx_hdr->Elements != ELEMENTS_EMPTY &&
335 	    mtx_hdr->Elements > (MAXNUMBERELEMENTS - 1))
336 	return;
337 
338     if (mtx_hdr->Elements != ELEMENTS_EMPTY) {
339         if (elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_STARTCODE_RAWDATA
340             || elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_RAWDATA) {
341             /*Add a new element aligned to word boundary
342              *Find RAWBit size in bytes (rounded to word boundary))
343              */
344 
345             /* NumberofRawbits (excluding size of bit count field)+ size of the bitcount field  */
346             Offset = elt_p[mtx_hdr->Elements]->Size + 8 + 31;
347             Offset /= 32;/* Now contains rawbits size in words */
348             Offset += 1;/* Now contains rawbits+element_type size in words */
349             Offset *= 4;/* Convert to number of bytes (total size of structure in bytes, aligned to word boundary) */
350         } else {
351             Offset = 4;
352         }
353 
354         mtx_hdr->Elements++;
355 
356 	if (mtx_hdr->Elements > (MAXNUMBERELEMENTS - 1))
357 	    return;
358         P = (IMG_UINT8 *) elt_p[mtx_hdr->Elements-1];
359         P += Offset;
360         elt_p[mtx_hdr->Elements] = (MTX_HEADER_ELEMENT *) P;
361     } else
362         mtx_hdr->Elements = 0;
363 
364     elt_p[mtx_hdr->Elements]->Element_Type = Token;
365     elt_p[mtx_hdr->Elements]->Size = 0;
366 }
367 
368 /*
369  * Intermediary functions to build H264 headers
370  */
pnw__H264_writebits_startcode_prefix_element(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 ByteSize)371 static void pnw__H264_writebits_startcode_prefix_element(
372     MTX_HEADER_PARAMS *mtx_hdr,
373     MTX_HEADER_ELEMENT **elt_p,
374     IMG_UINT32 ByteSize)
375 {
376     /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */
377     IMG_UINT32 Lp;
378 
379     /*
380      * Byte aligned (bit 0)
381      * (3 bytes in slice header when slice is first in a picture
382      * without sequence/picture_header before picture
383      */
384 
385     for (Lp = 0; Lp < ByteSize - 1; Lp++)
386         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
387 
388     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
389 
390     /* Byte aligned (bit 32 or 24) */
391     return;
392 }
393 
394 
pnw__H264_writebits_VUI_params(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_VUI_PARAMS * VUIParams)395 static void pnw__H264_writebits_VUI_params(
396     MTX_HEADER_PARAMS *mtx_hdr,
397     MTX_HEADER_ELEMENT **elt_p,
398     H264_VUI_PARAMS *VUIParams)
399 {
400     /* Builds VUI Params for the Sequence Header (only present in the 1st sequence of stream) */
401     if (VUIParams->aspect_ratio_info_present_flag && (VUIParams->aspect_ratio_idc == 0xff)) {
402         /* aspect_ratio_info_present_flag u(1) */
403         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
404         /* aspect_ratio_idc u(8) Extended_SAR */
405         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0xff, 8);
406         /* sar_width u(16) */
407         pnw__write_upto32bits_elements(mtx_hdr, elt_p, VUIParams->sar_width, 16);
408         /* sar_height u(16) */
409         pnw__write_upto32bits_elements(mtx_hdr, elt_p, VUIParams->sar_height, 16);
410     } else {
411         /* aspect_ratio_info_present_flag u(1) */
412         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
413     }
414 
415     pnw__write_upto8bits_elements(
416                 mtx_hdr, elt_p,
417                 (0 << 3) | /* overscan_info_present_flag (1 bit) = 0 in Topaz */
418                 (0 << 2) | /* video_signal_type_present_flag (1 bit) = 0 in Topaz */
419                 (0 << 1) | /* chroma_loc_info_present_flag (1 bit) = 0 in Topaz */
420                 (1),/* timing_info_present_flag (1 bit) = 1 in Topaz */
421                 4);
422 
423     /* num_units_in_tick (32 bits) = 1 in Topaz */
424     pnw__write_upto32bits_elements(mtx_hdr, elt_p, VUIParams->num_units_in_tick, 32);
425 
426     /* time_scale (32 bits) = frame rate */
427     pnw__write_upto32bits_elements(mtx_hdr, elt_p, VUIParams->Time_Scale, 32);
428 
429     /* fixed_frame_rate_flag (1 bit) = 1 in Topaz */
430     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
431     /* nal_hrd_parameters_present_flag (1 bit) = 1 in Topaz */
432     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
433 
434     /** Definitions for nal_hrd_parameters() contained in VUI structure for Topaz
435      *  cpb_cnt_minus1 ue(v) = 0 in Topaz = 1b
436      */
437     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
438     /* bit_rate_scale (4 bits) = 0 in Topaz, cpb_size_scale (4 bits) = 0 in Topaz */
439     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4);
440     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 2, 4);
441 
442     /* bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2] */
443     pnw__generate_ue(mtx_hdr, elt_p, VUIParams->bit_rate_value_minus1);
444     /* cpb_size_value_minus1[0] ue(v) = (CPB_Bits_Size/16)-1
445      * where CPB_Bits_Size = 1.5 * Bitrate  [RANGE:0 to (2^32)-2]
446      */
447     pnw__generate_ue(mtx_hdr, elt_p, VUIParams->cbp_size_value_minus1);
448 
449     /* cbr_flag[0] (1 bit) = 0 for VBR, 1 for CBR */
450     pnw__write_upto8bits_elements(mtx_hdr, elt_p, VUIParams->CBR, 1);
451 
452     pnw__write_upto8bits_elements(
453         mtx_hdr, elt_p,
454         VUIParams->initial_cpb_removal_delay_length_minus1,
455         5); /* initial_cpb_removal_delay_length_minus1 (5 bits) = ??? */
456 
457     pnw__write_upto8bits_elements(
458         mtx_hdr,
459         elt_p,
460         VUIParams->cpb_removal_delay_length_minus1,
461         5); /* cpb_removal_delay_length_minus1 (5 bits) = ??? */
462 
463     pnw__write_upto8bits_elements(
464         mtx_hdr, elt_p,
465         VUIParams->dpb_output_delay_length_minus1,
466         5); /* dpb_output_delay_length_minus1 (5 bits) = ??? */
467 
468     pnw__write_upto8bits_elements(
469         mtx_hdr,
470         elt_p,
471         VUIParams->time_offset_length,
472         5); /* time_offst_length (5 bits) = ??? */
473 
474     /* End of nal_hrd_parameters()  */
475 
476     pnw__write_upto8bits_elements(
477         mtx_hdr,
478         elt_p,
479         0, 1);/* vcl_hrd_parameters_present_flag (1 bit) = 0 in Topaz */
480 
481     /* if( nal_hrd_parameters_present_flag  ||  vcl_hrd_parameters_present_flag )
482      * FIX for BRN23039
483      * low_delay_hrd_flag
484      */
485     pnw__write_upto8bits_elements(
486         mtx_hdr, elt_p,
487         0, 1);/* low_delay_hrd_flag */
488 
489 
490     pnw__write_upto8bits_elements(
491         mtx_hdr, elt_p,
492         0, 1);/* pic_struct_present_flag (1 bit) = 0 in Topaz */
493 
494     pnw__write_upto8bits_elements(
495         mtx_hdr, elt_p,
496         0, 1);/* bitstream_restriction_flag (1 bit) = 0 in Topaz */
497 }
498 
499 
pnw__H264_writebits_picture_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_BOOL bCabacEnabled,IMG_BOOL b_8x8transform,IMG_BOOL bIntraConstrained,IMG_INT8 i8CbQPOffset,IMG_INT8 i8CrQPOffset)500 static void pnw__H264_writebits_picture_header(
501     MTX_HEADER_PARAMS *pMTX_Header,
502     MTX_HEADER_ELEMENT **aui32ElementPointers,
503     IMG_BOOL bCabacEnabled,
504     IMG_BOOL b_8x8transform,
505     IMG_BOOL bIntraConstrained,
506     IMG_INT8 i8CbQPOffset,
507     IMG_INT8 i8CrQPOffset)
508 {
509     //**-- Begin building the picture header element
510     IMG_UINT8 ui8ECMF = (bCabacEnabled ? 1 : 0);
511 
512     pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
513 
514     pnw__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
515 
516     ///* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE *///
517     ///**** ELEMENT BITCOUNT: 18
518 
519     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
520     // Byte aligned (bit 32)
521     pnw__write_upto8bits_elements(pMTX_Header,
522                                   aui32ElementPointers,
523                                   (0 << 7) |    // forbidden_zero_bit
524                                   (1 << 5) |    // nal_ref_idc (2 bits) = 1
525                                   (8),  // nal_unit_tpye (5 bits) = 8
526                                   8);
527     // Byte aligned (bit 40)
528     pnw__write_upto8bits_elements(pMTX_Header,
529                                   aui32ElementPointers,
530                                   (1 << 7) |            // pic_parameter_set_id ue(v) = 0 in Topaz
531                                   (1 << 6) |            // seq_parameter_set_id ue(v) = 0 in Topaz
532                                   (ui8ECMF << 5) |      // entropy_coding_mode_flag (1 bit) 0 for CAVLC
533                                   (0 << 4) |            // pic_order_present_flag (1 bit) = 0
534                                   (1 << 3) |            // num_slice_group_minus1 ue(v) = 0 in Topaz
535                                   (1 << 2) |            // num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz
536                                   (1 << 1) |            // num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz
537                                   (0),          // weighted_pred_flag (1 bit) = 0 in Topaz
538                                   8);
539     // Byte aligned (bit 48)
540     // weighted_bipred_flag (2 bits) = 0 in Topaz
541     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2);
542 
543     //MTX fills this value in
544     pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_QP);
545     pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
546 
547     ///**** GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE ****///
548     ///**** ELEMENT BITCOUNT: 5
549     //The following field will be generated as a special case by MTX - so not here
550     // pnw__generate_se(pMTX_Header, pPHParams->pic_init_qp_minus26);
551     // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz
552     // pic_int_qs_minus26 se(v) = 0 in Topaz
553     //chroma_qp_index_offset se(v) = 0 in Topaz
554     pnw__generate_se(pMTX_Header, aui32ElementPointers, 0);
555     pnw__generate_se(pMTX_Header, aui32ElementPointers, i8CbQPOffset);
556     pnw__write_upto8bits_elements(pMTX_Header,
557                                   aui32ElementPointers,
558                                   // deblocking_filter_control_present_flag (1 bit) = 1 in Topaz
559                                   (1 << 2) |
560                                   // constrained_intra_pred_Flag (1 bit) = 0 in Topaz
561                                   ((bIntraConstrained ? 1 : 0) << 1) |
562                                   (0),// redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz
563                                   3);
564     // Byte align is done using an element command (MTX elements in this structure, we don't know it's size)
565 
566     if (b_8x8transform || (i8CbQPOffset != i8CrQPOffset)) {
567         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
568                                       (b_8x8transform << 1) |   // 8x8 transform flag
569                                       (0),      // pic_scaling_matrix_present_flag
570                                       2);
571         pnw__generate_se(pMTX_Header, aui32ElementPointers, i8CrQPOffset);
572         // second_chroma_qp_index_offset se(v) = 0 in Topaz
573     }
574     // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
575     pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
576 
577     return;
578 }
579 
580 
pnw__H264_writebits_slice_header0(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams)581 static void pnw__H264_writebits_slice_header0(
582     MTX_HEADER_PARAMS *mtx_hdr,
583     MTX_HEADER_ELEMENT **elt_p,
584     H264_SLICE_HEADER_PARAMS *pSlHParams)
585 {
586     /* GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
587      * ELEMENT BITCOUNT: 8
588      *
589      * StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
590      * (3 bytes when slice is first in a picture without sequence/picture_header before picture
591      * Byte aligned (bit 32 or 24)
592      * NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
593      */
594     pnw__write_upto8bits_elements(
595         mtx_hdr, elt_p,
596         (0 << 7) |/* forbidden_zero_bit */
597         ((pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE ? 0 : 1) << 5) | /* nal_ref_idc (2 bits) = 0 for B-frame and 1 for I or P-frame */
598         ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),/* nal_unit_tpye (5 bits) = I-frame IDR, and 1 for  rest */
599         8);
600 }
601 
602 
pnw__H264_writebits_slice_header1(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT16 uiIdrPicId)603 static void pnw__H264_writebits_slice_header1(
604     MTX_HEADER_PARAMS *mtx_hdr,
605     MTX_HEADER_ELEMENT **elt_p,
606     H264_SLICE_HEADER_PARAMS *pSlHParams,
607     IMG_UINT16 uiIdrPicId)
608 {
609     /* GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
610      * The following is slice parameter set in BP/MP
611      */
612 
613     /* first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619) */
614     pnw__generate_ue(mtx_hdr, elt_p, (IMG_UINT32) pSlHParams->First_MB_Address);
615 
616     pnw__generate_ue(
617         mtx_hdr, elt_p,
618         (IMG_UINT32)((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) ? SLHP_I_SLICEFRAME_TYPE : pSlHParams->SliceFrame_Type));  /* slice_type ue(v): 0 for P-slice, 1 for B-slice, 2 for I-slice */
619 
620     /* kab: not clean change from IDR to intra, IDR should have separate flag */
621 
622     pnw__write_upto8bits_elements(
623         mtx_hdr, elt_p,
624         (1 << 5) | /* pic_parameter_set_id, ue(v) = 0  (=1b) in Topaz */
625         pSlHParams->Frame_Num_DO,/* frame_num (5 bits) = frame nuo. in decoding order */
626         6);
627 
628     /* frame_mb_only_flag is always 1, so no need for field_pic_flag or bottom_field_flag */
629     if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
630         pnw__generate_ue(mtx_hdr, elt_p, uiIdrPicId);/* idr_pic_id ue(v) = 0 (1b) in Topaz */
631 
632     /* kab: Idr_pic_id only for IDR, not nessesarely for all I pictures */
633 
634     /* customer request POC type should be 2*/
635     /* if (pic_order_cnt_type == 0) Note: (pic_order_cnt_type always 0 in Topaz)
636     pnw__write_upto8bits_elements(
637         mtx_hdr, elt_p,
638         pSlHParams->Picture_Num_DO,
639         6);  pic_order_cnt_lsb (6 bits) - picture no in display order */
640 
641 #if 0
642     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
643         pnw__write_upto8bits_elements(
644             mtx_hdr,
645             elt_p,
646             0,
647             1);/* direct_spatial_mv_pred_flag (1 bit) = 0, spatial direct mode not supported in Topaz */
648 #endif
649 
650     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE || pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
651         pnw__write_upto8bits_elements(
652             mtx_hdr,
653             elt_p,
654             0,
655             1);/* num_ref_idx_active_override_flag (1 bit) = 0 in Topaz */
656 
657     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE &&
658         pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
659         /*
660         if (pSlHParams->UsesLongTermRef) {
661             // ref_pic_list_ordering_flag_I0 (1 bit) = 1, L0 reference picture ordering
662             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
663             // modification_of_pic_nums_idc = 2
664             pnw__generate_ue(mtx_hdr, elt_p, 2);
665             // long_term_pic_num = 0
666             pnw__generate_ue(mtx_hdr, elt_p, 0);
667             // modification_of_pic_nums_idc = 3
668             pnw__generate_ue(mtx_hdr, elt_p, 3);
669         } else
670         */
671             pnw__write_upto8bits_elements(
672                 mtx_hdr,
673                 elt_p,
674                 0,
675                 1);/* ref_pic_list_ordering_flag_I0 (1 bit) = 0 */
676     }
677 
678 #if 0
679     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
680         pnw__write_upto8bits_elements(
681             mtx_hdr,
682             elt_p,
683             0,
684             1); /* ref_pic_list_ordering_flag_I1 (1 bit) = 0, no reference picture ordering in Topaz */
685 #endif
686 
687     if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
688         /* no_output_of_prior_pics_flag (1 bit) = 0 */
689         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
690         /* long_term_reference_flag (1 bit)*/
691         pnw__write_upto8bits_elements(mtx_hdr, elt_p,
692                                       pSlHParams->IsLongTermRef ? 1 : 0, 1);
693     }
694 #if 0
695     else if (pSlHParams->UsesLongTermRef) {
696         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* long_term_reference_flag (1 bit) = 0 */
697         // Allow a single long-term reference
698         pnw__generate_ue(mtx_hdr, elt_p, 4);
699         // memory_management_control_operation
700         pnw__generate_ue(mtx_hdr, elt_p, 1);
701 
702         // Set current picture as the long-term reference
703         // memory_management_control_operation
704         pnw__generate_ue(mtx_hdr, elt_p, 6);
705         // long_term_frame_idx
706         pnw__generate_ue(mtx_hdr, elt_p, 0);
707 
708         // End
709         pnw__generate_ue(mtx_hdr, elt_p, 0);
710     }
711 #endif
712     else {
713         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);/* adaptive_ref_pic_marking_mode_flag (1 bit) = 0 */
714     }
715 }
716 
717 
pnw__H264_writebits_slice_header2(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams)718 static void pnw__H264_writebits_slice_header2(
719     MTX_HEADER_PARAMS *mtx_hdr,
720     MTX_HEADER_ELEMENT **elt_p,
721     H264_SLICE_HEADER_PARAMS *pSlHParams)
722 {
723     /* GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
724      * ELEMENT BITCOUNT: 11
725      */
726 
727 #if 0
728     /* Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here */
729 
730     /* slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26) */
731     /* pucHS=pnw__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta);  */
732 #endif
733 
734     pnw__generate_ue(
735         mtx_hdr,
736         elt_p,
737         pSlHParams->Disable_Deblocking_Filter_Idc); /* disable_deblocking_filter_idc ue(v) = 2?  */
738 
739     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
740         pnw__generate_se(mtx_hdr, elt_p, 0); /* slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz */
741         pnw__generate_se(mtx_hdr, elt_p, 0); /* slice_beta_offset_div2 se(v) = 0 (1b) in Topaz */
742     }
743 
744     /* num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
745      * no byte alignment at end of slice headers
746      */
747 }
748 
pnw__H264_writebits_sequence_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCrop)749 static void pnw__H264_writebits_sequence_header(
750     MTX_HEADER_PARAMS *pMTX_Header,
751     MTX_HEADER_ELEMENT **aui32ElementPointers,
752     H264_SEQUENCE_HEADER_PARAMS *pSHParams, H264_CROP_PARAMS *psCrop)
753 {
754     IMG_UINT8 ui8SBP = 0;
755 
756     pnw__insert_element_token(pMTX_Header,
757                               aui32ElementPointers,
758                               ELEMENT_STARTCODE_RAWDATA);
759 
760     pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
761             aui32ElementPointers,
762             4);
763 
764     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
765 
766     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
767     // Byte aligned (bit 32)
768     pnw__write_upto8bits_elements(pMTX_Header,
769                                   aui32ElementPointers, (0 << 7) |      // forbidden_zero_bit=0
770                                   (0x3 << 5) |                  // nal_ref_idc=01 (may be 11)
771                                   (7),          // nal_unit_type=00111
772                                   8);
773 
774     if (pSHParams->ucProfile != SH_PROFILE_HP) {
775         // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
776         pnw__write_upto8bits_elements(pMTX_Header,
777                                       aui32ElementPointers,
778                                       (pSHParams->ucProfile == SH_PROFILE_BP ? 66 : 77), 8);
779 
780         // Byte aligned (bit 48)
781         pnw__write_upto8bits_elements(pMTX_Header,
782                                       // constrain_set0_flag = 1 for BP constraints
783                                       aui32ElementPointers, (0 << 7) |
784                                       // constrain_set1_flag  = 1 for MP constraints and Constrained Baseline profile.
785                                       ((pSHParams->ucProfile == SH_PROFILE_BP ? 1 : 0) << 6) |
786                                       (0 << 5) |        // constrain_set2_flag = 1 for HP
787                                       // constrain_set3_flag = 1 for level 1b, 0 for others
788                                       ((pSHParams->ucLevel == SH_LEVEL_1B ?     1 : 0) <<       4),
789                                       // reserved_zero_4bits = 0
790                                       8);
791         // Byte aligned (bit 56)
792         pnw__write_upto8bits_elements(pMTX_Header,
793                                       aui32ElementPointers,
794                                       // level_idc (8 bits) = 11 for 1b, 10xlevel for others
795                                       (IMG_UINT8) pSHParams->ucLevel, 8);
796 #if 0
797         // Byte aligned (bit 64)
798         pnw__write_upto8bits_elements(pMTX_Header,
799                                       // seq_parameter_Set_id = 0 in Topaz ->  ue(0)= 1b
800                                       aui32ElementPointers, (1 << 7) |
801                                       (2 << 4) |// log2_max_frame_num_minus4 = 1 in Topaz ->  ue(1)= 010b
802                                       (1 << 3) |        // pic_order_cnt_type = 0 in Topaz ->  ue(0)= 1b
803                                       (3),      // log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz ->  ue(2)= 011b
804                                       8);
805         // Bytes aligned (bit 72)
806 #else
807         /*Customer request POC type should be 2*/
808         pnw__write_upto8bits_elements(pMTX_Header,
809                                       // seq_parameter_Set_id = 0 in Topaz ->  ue(0)= 1b
810                                       aui32ElementPointers, (1 << 6) |
811                                       (2 << 3) |// log2_max_frame_num_minus4 = 1 in Topaz ->  ue(1)= 010b
812                                       (3),// log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz ->  ue(2)= 011b$
813                                       7);
814 #endif
815     } else {
816 #if PSB_MFLD_DUMMY_CODE
817         // Byte aligned (bit 40)
818         // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
819         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 100, 8);
820 
821         // Byte aligned (bit 48)
822         pnw__write_upto8bits_elements(pMTX_Header,
823                                       aui32ElementPointers, (1 << 7) |
824                                       // constrain_set0_flag = 1 for MP + BP constraints
825                                       (1 << 6) |        // constrain_set1_flag  = 1 for MP + BP constraints
826                                       (0 << 5) |        // constrain_set2_flag = always 0 in BP/MP
827                                       (0 << 4), // constrain_set3_flag = 1 for level 1b, 0 for others
828                                       // reserved_zero_4bits = 0
829                                       8);
830 
831         // Byte aligned (bit 56)
832         pnw__write_upto8bits_elements(pMTX_Header,
833                                       aui32ElementPointers, (IMG_UINT8) pSHParams->ucLevel, 8);
834         // level_idc (8 bits) = 11 for 1b, 10xlevel for others
835 
836         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
837         // seq_parameter_Set_id = 0
838         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 1);
839         // chroma_format_idc = 1
840         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
841         // bit_depth_luma_minus8 = 0
842         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
843         // bit_depth_chroma_minus8 = 0
844         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
845         // qpprime_y_zero_transform_bypass_flag = 0
846 
847         //if (pSHParams->bUseDefaultScalingList)
848         //{
849         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
850         // seq_scaling_matrix_present_flag
851         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
852         // seq_scaling_matrix_present_flag[i] = 0; 0 < i < 8
853         //}
854         //else
855         //{
856         //      pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // seq_scaling_matrix_present_flag
857         //}
858 
859         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 1);
860         // log2_max_frame_num_minus4 = 1
861         // Customer request POC type should be 2.
862         //pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
863         // pic_order_cnt_type = 0
864         pnw__generate_ue(pMTX_Header, aui32ElementPointers, 2);
865         // log2_max_pic_order_cnt_Isb_minus4 = 2
866 
867         // Bytes aligned (bit 72)
868 #endif
869     }
870     // max_num_ref_frames. long term reference isn't used.
871     //pnw__generate_u(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames);
872     pnw__generate_ue(pMTX_Header, aui32ElementPointers, 1);
873     // gaps_in_frame_num_value_allowed_Flag - (1 bit)
874     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->gaps_in_frame_num_value, 1);
875 
876 
877     ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
878     ///**** ELEMENT BITCOUNT: xx
879     pnw__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1);
880     //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
881     pnw__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1);
882     //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column)
883 
884     // We don't know the alignment at this point, so will have to use bit writing functions
885     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->ucFrame_mbs_only_flag, 1);
886     // frame_mb_only_flag 1=frame encoding, 0=field encoding
887 
888 #if 0
889     if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
890         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
891     // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
892 #endif
893 
894     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
895     // direct_8x8_inference_flag=1 in Topaz
896 
897     if (psCrop->bClip) {
898         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
899         pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->LeftCropOffset);
900         pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->RightCropOffset);
901         pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->TopCropOffset);
902         pnw__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->BottomCropOffset);
903 
904     } else {
905         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
906     }
907 
908     ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
909     ///**** ELEMENT BITCOUNT: xx
910     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
911                                   (pSHParams->VUI_Params_Present),
912                                   // vui_parameters_present_flag (VUI only in 1st sequence of stream)
913                                   1);
914     if (pSHParams->VUI_Params_Present > 0)
915         pnw__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
916 
917     // Finally we need to align to the next byte
918     // We know the size of the data in the sequence header (no MTX variables)  and start is byte aligned, so it's possible to add this field here rather than MTX ELEMENT_INSERTBYTEALIGN_H264 command.
919     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
920     if (pMTX_Header->Elements < MAXNUMBERELEMENTS) {
921         ui8SBP = (aui32ElementPointers[pMTX_Header->Elements]->Size) & 7;
922     } else {
923         ui8SBP = 0;
924     }
925     if (ui8SBP > 0)
926         pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8 - (ui8SBP));
927     return;
928 }
929 
930 
pnw__H264_writebits_slice_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL __maybe_unused bCabacEnabled,IMG_UINT16 uiIdrPicId)931 static void pnw__H264_writebits_slice_header(
932     MTX_HEADER_PARAMS *mtx_hdr,
933     MTX_HEADER_ELEMENT **elt_p,
934     H264_SLICE_HEADER_PARAMS *pSlHParams,
935     IMG_BOOL __maybe_unused bCabacEnabled,
936     IMG_UINT16 uiIdrPicId)
937 {
938 #ifdef USESTATICWHEREPOSSIBLE
939     IMG_UINT32 *p;
940     p = (IMG_UINT32 *) mtx_hdr;
941 
942     p[0] = p[1] = 0;
943     p[2] = 40;
944     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) p[3] = 257;
945     else if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) p[3] = 9473;
946     else p[3] = 8449;
947 #else
948     /* -- Begin building the picture header element */
949     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
950 
951     pnw__H264_writebits_startcode_prefix_element(
952         mtx_hdr,
953         elt_p,
954         pSlHParams->Start_Code_Prefix_Size_Bytes); /* Can be 3 or 4 bytes - always 4 bytes in our implementations */
955     pnw__H264_writebits_slice_header0(mtx_hdr, elt_p, pSlHParams);
956 #endif
957 
958     pnw__H264_writebits_slice_header1(mtx_hdr, elt_p, pSlHParams, uiIdrPicId);
959 
960 #if 0
961     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
962                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
963         pnw__generate_ue(mtx_hdr, elt_p, 0);    /* hard code cabac_init_idc value of 0 */
964     }
965 #endif
966 
967     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_SQP); /* MTX fills this value in */
968 
969     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
970     pnw__H264_writebits_slice_header2(mtx_hdr, elt_p, pSlHParams);
971 
972     /* no byte alignment at end of slice headers */
973 }
974 
975 
pnw__H264_getelements_skip_P_slice(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT32 MB_No_In_Slice,IMG_BOOL bCabacEnabled)976 static void pnw__H264_getelements_skip_P_slice(
977     MTX_HEADER_PARAMS *mtx_hdr,
978     H264_SLICE_HEADER_PARAMS *pSlHParams,
979     IMG_UINT32 MB_No_In_Slice,
980     IMG_BOOL bCabacEnabled)
981 {
982     /* Skipped P-Slice
983      * Ensure pSlHParams is filled with appropriate parameters for a B-slice
984      * Essential we initialise our header structures before building
985      */
986     MTX_HEADER_ELEMENT *This_Element;
987     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
988     mtx_hdr->Elements = ELEMENTS_EMPTY;
989     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
990     elt_p[0] = This_Element;
991 
992     /* pnw__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */
993     /* Not sure if this will be required in the final spec */
994     pnw__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, bCabacEnabled, 0);
995     pnw__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */
996 
997     /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
998     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
999     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1000 }
1001 
1002 
1003 
pnw__H264_getelements_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCropParams)1004 static void pnw__H264_getelements_sequence_header(
1005     MTX_HEADER_PARAMS *mtx_hdr,
1006     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
1007     H264_CROP_PARAMS *psCropParams)
1008 {
1009     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1010      * Essential we initialise our header structures before building
1011      */
1012     MTX_HEADER_ELEMENT *This_Element;
1013     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1014     mtx_hdr->Elements = ELEMENTS_EMPTY;
1015     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1016     elt_p[0] = This_Element;
1017 
1018     pnw__H264_writebits_sequence_header(mtx_hdr, elt_p, pSHParams, psCropParams);
1019     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1020 }
1021 
1022 
1023 
pnw__H264_getelements_slice_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled,IMG_UINT16 uiIdrPicId)1024 static void pnw__H264_getelements_slice_header(
1025     MTX_HEADER_PARAMS *mtx_hdr,
1026     H264_SLICE_HEADER_PARAMS *pSlHParams,
1027     IMG_BOOL bCabacEnabled,
1028     IMG_UINT16 uiIdrPicId)
1029 {
1030     /* Builds a single slice header from the given parameters (mid frame)
1031      * Essential we initialise our header structures before building
1032      */
1033     MTX_HEADER_ELEMENT *This_Element;
1034     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1035     mtx_hdr->Elements = ELEMENTS_EMPTY;
1036     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1037     elt_p[0] = This_Element;
1038 
1039     /* Not sure if this will be required in the final spec */
1040     /* pnw__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/
1041     pnw__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, bCabacEnabled, uiIdrPicId);
1042 
1043     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1044 }
1045 
1046 
Bits2Code(IMG_UINT32 CodeVal)1047 static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1048 {
1049     IMG_UINT8 Bits = 32;
1050     if (CodeVal == 0)
1051         return 1;
1052     while (!(CodeVal & 0x80000000)) {
1053         CodeVal <<= 1;
1054         Bits--;
1055     }
1056     return Bits;
1057 }
1058 
1059 /*
1060  * Intermediary functions to build MPEG4 headers
1061  */
1062 #define MATCH_TO_ENC
1063 
1064 
pnw__MPEG4_writebits_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_BOOL __maybe_unused bBFrame,MPEG4_PROFILE_TYPE bProfile,IMG_UINT8 Profile_and_level_indication,FIXED_VOP_TIME_TYPE __maybe_unused sFixed_vop_time_increment,IMG_UINT32 Picture_Width_Pixels,IMG_UINT32 Picture_Height_Pixels,VBVPARAMS __maybe_unused * sVBVParams,IMG_UINT32 VopTimeResolution)1065 static void pnw__MPEG4_writebits_sequence_header(
1066     MTX_HEADER_PARAMS *mtx_hdr,
1067     MTX_HEADER_ELEMENT **elt_p,
1068     IMG_BOOL __maybe_unused bBFrame,
1069     MPEG4_PROFILE_TYPE bProfile,
1070     IMG_UINT8 Profile_and_level_indication,
1071     FIXED_VOP_TIME_TYPE __maybe_unused sFixed_vop_time_increment,
1072     IMG_UINT32 Picture_Width_Pixels,
1073     IMG_UINT32 Picture_Height_Pixels,
1074     VBVPARAMS __maybe_unused * sVBVParams,
1075     IMG_UINT32 VopTimeResolution) /* Send NULL pointer if there are no VBVParams */
1076 {
1077     /* Essential we insert the element before we try to fill it! */
1078     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1079 
1080     /* visual_object_sequence_start_code        = 32 Bits       = 0x1B0 */
1081     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1082 
1083     /* profile_and_level_indication = 8 Bits = SP L0-L3 and SP L4-L5 are supported */
1084     pnw__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1085 
1086     /* visual_object_start_code = 32 Bits       = 0x1B5 */
1087     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1088     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1089     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1090     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 181, 8);
1091 
1092     /* is_visual_object_identifier = 1 Bit      = 0 */
1093     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1094 
1095     /* visual_object_type = 4 Bits      = Video ID = 1 */
1096     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1097 
1098     /* video_signal_type = 1 Bit                = 1 */
1099     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1100 
1101     /* byte_aligned_bits = 2 Bits       = 01b (byte_aligned_bits is 2-bit stuffing bit field 01) */
1102     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1103 
1104     /* video_object_start_code = 32 Bits        = 0x100 One VO only in a Topaz video stream */
1105     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1106     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1107     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1108     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1109 
1110     /* video_object_layer_start_code = 32 Bits  = 0x120 One VOL only in a Topaz stream */
1111     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1112     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1113     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1114     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 32, 8);
1115 
1116     /* random_accessible_vol = 1 Bit            = 0 (P-Frame in GOP) */
1117     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1118 
1119     if (bProfile == SP) {
1120         /* video_object_type_indication = 8 Bits        = 0x01 for SP */
1121         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1122 #ifndef MATCH_TO_ENC
1123         /* is_object_layer_identifier   = 1 Bit         = 0 for SP */
1124         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1125 #else
1126         /* to match the encoder */
1127 
1128         /* is_object_layer_identifier   = 1 Bit          */
1129         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1130 
1131         /* video_object_layer_verid     = 4 Bits         */
1132         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1133 
1134         /* video_object_layer_priority  = 3 Bits         */
1135         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3);  // 0 is reserved...
1136 #endif
1137     } else {
1138         /* video_object_type_indication = 8 Bits        = 0x11 for ASP */
1139         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 3, 8);
1140 
1141         /* is_object_layer_identifier   = 1 Bit         = 1 for ASP */
1142         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1143 
1144         /* video_object_layer_verid     = 4 Bits        = 5 is for ASP */
1145         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4);
1146 
1147         /* video_object_layer_priority  = 3 Bits        = 1 (Highest priority) */
1148         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3);
1149     }
1150 
1151     /* aspect_ratio_info                = 4 Bits        =0x1 (Square pixel) */
1152     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1153 #ifndef MATCH_TO_ENC
1154     /* vol_control_parameters           = 1 Bit         = 1 (Always send VOL control parameters) */
1155     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1156 #else
1157     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1158 
1159 #endif
1160 
1161 #ifndef MATCH_TO_ENC
1162     /* chroma_format                    = 2 Bits        = 01b (4:2:0) */
1163     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1164 
1165     /* low_delay = 1 Bit = 0 with B-frame and 1 without B-frame */
1166     if (bBFrame)
1167         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1168     else
1169         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1170 
1171     /* vbv_parameters                   = 1 Bit                 =0/1  */
1172     if (sVBVParams) {
1173         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1174 
1175         /* For recording, only send vbv parameters in 1st sequence header.
1176          * For video phone, it should be sent more often, such as once per sequence
1177          */
1178         pnw__write_upto32bits_elements(
1179             mtx_hdr,
1180             elt_p,
1181             sVBVParams->First_half_bit_rate,
1182             15); /* first_half_bit_rate */
1183 
1184         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1185         pnw__write_upto32bits_elements(
1186             mtx_hdr,
1187             elt_p,
1188             sVBVParams->Latter_half_bit_rate,
1189             15); /* latter_half_bit_rate */
1190 
1191         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1192         pnw__write_upto32bits_elements(
1193             mtx_hdr,
1194             elt_p,
1195             sVBVParams->First_half_vbv_buffer_size,
1196             15);/* first_half_vbv_buffer_size */
1197 
1198         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1199         pnw__write_upto32bits_elements(
1200             mtx_hdr, elt_p,
1201             sVBVParams->Latter_half_vbv_buffer_size,
1202             15); /* latter_half_vbv_buffer_size */
1203         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1204         pnw__write_upto32bits_elements(
1205             mtx_hdr,
1206             elt_p,
1207             sVBVParams->First_half_vbv_occupancy,
1208             15);  /* first_half_vbv_occupancy */
1209         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1210         pnw__write_upto32bits_elements(
1211             mtx_hdr,
1212             elt_p,
1213             sVBVParams->Latter_half_vbv_occupancy,
1214             15); /* latter_half_vbv_occupancy */
1215         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1216     } else
1217         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); /* No vbv parameters present */
1218 #endif
1219     /* video_object_layer_shape = 2 Bits =      00b     Rectangular shape */
1220     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1221     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1222 
1223     /* vop_time_increment_solution = 16 Bits */
1224     pnw__write_upto32bits_elements(mtx_hdr, elt_p, VopTimeResolution, 16);
1225     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1226 
1227 #ifndef MATCH_TO_ENC
1228     /* fixed_vop_rate = 1 Bits  = 1 Always fixed frame rate */
1229     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1230 
1231     /* fixed_vop_time_increment         = Variable number of bits based on the time increment resolution. */
1232     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, Bits2Code(VopTimeResolution - 1));
1233     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1234 #else
1235     /* fixed_vop_rate   = 1 Bits =      0 */
1236     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1237     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1238 
1239 #endif
1240     /* video_object_layer_width = 13 Bits  Picture width in pixel units */
1241     pnw__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Width_Pixels, 13);
1242     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1243 
1244     /* video_object_layer_height = 13 Bits Picture height in pixel units */
1245     pnw__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Height_Pixels, 13);
1246     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1247 
1248     /* interlaced = 1 Bit = 0 Topaz only encodes progressive frames */
1249     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1250 
1251     /* obmc_disable = 1 Bit = 1 No overlapped MC in Topaz */
1252     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1253 
1254     /* sprite_enable = 1 Bit = 0 Not use sprite in Topaz */
1255     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1256 
1257     /* not_8_bit = 1    Bit = 0 8-bit video in Topaz */
1258     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1259 
1260     /* quant_type = 1 Bit = 0 2nd quantization method in Topaz */
1261     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1262 
1263     if (bProfile == ASP) {
1264         /* quarter_sample = 1 Bit = 0 No �-pel MC in Topaz */
1265         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1266     }
1267 
1268     /* complexity_estimation_disable    = 1 Bit = 1 No complexity estimation in Topaz */
1269     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1270 #ifndef MATCH_TO_ENC
1271 
1272     /* resync_marker_disable = 1 Bit = 0 Always enable resync marker in Topaz */
1273     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1274 #else
1275     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1276 #endif
1277     /* data_partitioned = 1 Bit = 0 No data partitioning in Topaz */
1278     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1279 
1280     if (bProfile == ASP) {
1281         /* newpred_enable = 1 Bit = 0 No newpred mode in SP/ASP */
1282         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1283         /* reduced_vop_resolution_enable=1 Bit = 0      No reduced resolution frame in SP/ASP */
1284         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1285     }
1286 
1287     /* scalability = 1 Bit = 0  No scalability in SP/ASP */
1288     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1289 
1290     /* byte_aligned_bits */
1291 
1292     /* Tell MTX to insert the byte align field
1293      * (we don't know final stream size for alignment at this point)
1294      */
1295     pnw__insert_element_token(
1296         mtx_hdr,
1297         elt_p,
1298         ELEMENT_INSERTBYTEALIGN_MPG4);
1299 
1300     return;
1301 }
1302 
1303 
1304 /* Utility function */
1305 /*
1306   IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1307   {
1308   IMG_UINT8 Bits=32;
1309   if(CodeVal==0)
1310   return 1;
1311   while(!(CodeVal & 0x80000000))
1312   {
1313   CodeVal<<=1;
1314   Bits--;
1315   }
1316   return Bits;
1317   }
1318 */
1319 
1320 /* MPEG 4 VOP (Picture) Header */
pnw__MPEG4_writebits_VOP_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_BOOL bIsVOP_coded,IMG_UINT8 VOP_time_increment,SEARCH_RANGE_TYPE sSearch_range,VOP_CODING_TYPE sVopCodingType,IMG_UINT32 VopTimeResolution)1321 static void pnw__MPEG4_writebits_VOP_header(
1322     MTX_HEADER_PARAMS *mtx_hdr,
1323     MTX_HEADER_ELEMENT **elt_p,
1324     IMG_BOOL    bIsVOP_coded,
1325     IMG_UINT8   VOP_time_increment,
1326     SEARCH_RANGE_TYPE sSearch_range,
1327     VOP_CODING_TYPE sVopCodingType,
1328     IMG_UINT32 VopTimeResolution)
1329 {
1330     IMG_BOOL bIsSyncPoint;
1331     /* Essential we insert the element before we try to fill it! */
1332     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1333 
1334     /* visual_object_sequence_start_code        = 32 Bits       = 0x1B6 */
1335     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 438, 32);
1336 
1337     /* vop_coding_type  = 2 Bits = 0 for I-frame and 1 for P-frame */
1338     pnw__write_upto8bits_elements(mtx_hdr, elt_p, sVopCodingType, 2);
1339     bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0);
1340 
1341 #ifndef MATCH_TO_ENC
1342     /* modulo_time_base = 1 Bit = 0 As at least  1 synchronization point (I-frame) per second in Topaz */
1343     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1344 #else
1345 
1346     pnw__write_upto8bits_elements(mtx_hdr, elt_p, bIsSyncPoint  ? 2 : 0 , bIsSyncPoint ? 2 : 1);
1347 
1348 #endif
1349 
1350     /* marker_bit = 1   Bits    = 1      */
1351     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1352 
1353 #ifndef MATCH_TO_ENC
1354     /* vop_time_increment = Variable bits based on resolution
1355      *  = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame
1356      */
1357     pnw__write_upto8bits_elements(mtx_hdr, elt_p, VOP_time_increment, 5);
1358 #else
1359     /* will chrash here... */
1360     pnw__write_upto8bits_elements(
1361         mtx_hdr, elt_p,
1362         (VOP_time_increment) % VopTimeResolution,
1363         Bits2Code(VopTimeResolution - 1));
1364 
1365 #endif
1366     /* marker_bit = 1 Bit               = 1      */
1367     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1368 
1369     if (!bIsVOP_coded) {
1370         /* vop_coded    = 1 Bit         = 0 for skipped frame */
1371         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1372 
1373         /* byte_aligned_bits (skipped pictures are byte aligned) */
1374         /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1375          * End of VOP - skipped picture
1376          */
1377         pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_MPG4);
1378     } else {
1379         /* vop_coded = 1 Bit            = 1 for normal coded frame */
1380         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1381 
1382         if (sVopCodingType == P_FRAME) {
1383             /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */
1384             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1385         }
1386 
1387         /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */
1388         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3);
1389 
1390         /* vop_quant = 5 Bits   = x     5-bit frame Q_scale from rate control - GENERATED BY MTX */
1391         /* pnw__write_upto8bits_elements(mtx_hdr, elt_p, Frame_Q_scale, 5); */
1392         pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE);
1393 
1394         if (sVopCodingType == P_FRAME) {
1395             /* vop_fcode_forward = 3 bits       = 2 for +/-32 and 3 for +/-64 search range  */
1396             pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1397             pnw__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3);
1398         }
1399 
1400         /*
1401         **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE
1402         pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1403         video_packet_data ( )                   = 1st  VP that doesn�t have the VP header
1404 
1405         while (nextbits_bytealigned ( ) == resync_marker)
1406         {
1407         video_packet _header( )
1408         video_packet _data( )                   All MB in the slice
1409         }
1410         */
1411     }
1412 }
1413 
1414 #if PSB_MFLD_DUMMY_CODE
1415 /*
1416  * Intermediary functions to build H263 headers
1417  */
H263_writebits_VideoSequenceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 Profile_and_level_indication)1418 static void H263_writebits_VideoSequenceHeader(
1419     MTX_HEADER_PARAMS *mtx_hdr,
1420     MTX_HEADER_ELEMENT **elt_p,
1421     IMG_UINT8 Profile_and_level_indication)
1422 {
1423     /* Essential we insert the element before we try to fill it! */
1424     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1425 
1426     /* visual_object_sequence_start_code        = 32 Bits       = 0x1B0 */
1427     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1428 
1429     /* profile_and_level_indication = 8 Bits =  x SP L0-L3 and SP L4-L5 are supported */
1430     pnw__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1431 
1432     /* visual_object_start_code = 32 Bits       = 0x1B5 */
1433 
1434     /* 437 too large for the   pnw__write_upto32bits_elements function */
1435     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 437, 32);
1436 
1437     /* is_visual_object_identifier = 1 Bit              = 0 */
1438     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1439 
1440     /* is_visual_object_type    = 4 Bits        = 1 Video ID */
1441     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1442 
1443     /* video_signal_type = 1 Bit                = 0      */
1444     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1445 
1446     /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */
1447     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1448 
1449     /* video_object_start_code  =32 Bits        = 0x100 One VO only in a Topaz video stream */
1450     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 256, 32);
1451 
1452     return;
1453 }
1454 #endif
1455 
1456 
H263_writebits_VideoPictureHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 FrameRate,IMG_UINT32 PictureWidth,IMG_UINT32 PictureHeight)1457 static void H263_writebits_VideoPictureHeader(
1458     MTX_HEADER_PARAMS *mtx_hdr,
1459     MTX_HEADER_ELEMENT **elt_p,
1460     IMG_UINT8 Temporal_Ref,
1461     H263_PICTURE_CODING_TYPE PictureCodingType,
1462     //IMG_UINT8 Q_Scale,
1463     H263_SOURCE_FORMAT_TYPE SourceFormatType,
1464     IMG_UINT8 FrameRate,
1465     IMG_UINT32 PictureWidth,
1466     IMG_UINT32 PictureHeight)
1467 {
1468     IMG_UINT8 UFEP;
1469     IMG_UINT8 OCPCF = 0;
1470 
1471     /* Essential we insert the element before we try to fill it! */
1472     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1473 
1474     /* short_video_start_marker = 22 Bits       = 0x20 Picture start code */
1475     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 32, 22);
1476 
1477     /* temporal_reference = 8 Bits      = 0-255 Each picture increased by 1 */
1478     pnw__write_upto8bits_elements(mtx_hdr, elt_p, Temporal_Ref, 8);
1479 
1480     /* marker_bit = 1 Bit = 1    */
1481     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1482 
1483     /* zero_bit = 1 Bits        = 0      */
1484     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1485 
1486     /* split_screen_indicator   = 1     Bits    = 0     No direct effect on encoding of picture */
1487     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1488 
1489     /* document_camera_indicator= 1     Bits    = 0     No direct effect on encoding of picture */
1490     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1491 
1492     /* full_picture_freeze_release=1 Bits       = 0     No direct effect on encoding of picture */
1493     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1494 
1495     /* source_format                            = 3     Bits    = 1-4   See note */
1496     pnw__write_upto8bits_elements(mtx_hdr, elt_p, SourceFormatType, 3);
1497 
1498     /*Write optional Custom Picture Clock Frequency(OCPCF)*/
1499     if (FrameRate == 30 || FrameRate == 0/* unspecified */) {
1500         OCPCF = 0; // 0 for CIF PCF
1501     } else {
1502         OCPCF = 1; //1 for Custom PCF
1503     }
1504 
1505     if (SourceFormatType != 7) {
1506         // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1507         pnw__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 1);
1508         // four_reserved_zero_bits      = 4 Bits        = 0
1509         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4);
1510     } else {
1511         static unsigned char  RTYPE = 0;
1512 
1513         // if I- Frame set Update Full Extended PTYPE to true
1514         if ((PictureCodingType == I_FRAME) || (SourceFormatType == 7) || OCPCF) {
1515             UFEP = 1;
1516         } else {
1517             UFEP = 0;
1518         }
1519         pnw__write_upto8bits_elements(mtx_hdr, elt_p, UFEP, 3);
1520         if (UFEP == 1) {
1521             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 6, 3);
1522             pnw__write_upto8bits_elements(mtx_hdr, elt_p, OCPCF , 1);
1523 
1524             /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1525              *  - Optional Unrestricted Motion Vector (UMV)
1526              *  - Optional Syntax-based Arithmetic Coding (SAC)
1527              *  - Optional Advanced Prediction (AP) mode
1528              *  - Optional Advanced INTRA Coding (AIC) mode
1529              *  - Optional Deblocking Filter (DF) mode
1530              *  - Optional Slice Structured (SS) mode
1531              *  - Optional Reference Picture Selection(RPS) mode.
1532              *  - Optional Independent Segment Decoding (ISD) mode
1533              *  - Optional Alternative INTER VLC (AIV) mode
1534              *  - Optional Modified Quantization (MQ) mode */
1535 
1536             pnw__write_upto32bits_elements(mtx_hdr, elt_p, 0, 10);
1537             // 10 reserve bits
1538             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 8, 4);
1539             // 4 reserve bits
1540         }
1541         // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1542         pnw__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 3);
1543 
1544         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1545         // two_reserve_bits,      rounding_type,       two_reserve_bits       marker_bit       CPM
1546         // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1547         pnw__write_upto8bits_elements(mtx_hdr, elt_p, RTYPE, 1);
1548         //2 reserve bits
1549         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1550         //   - 1 (ON) to prevent start code emulation.
1551         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1 , 1);
1552         // CPM immediately follows the PPTYPE part of the header.
1553         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0 , 1);
1554 
1555 
1556         if (UFEP == 1) {
1557             IMG_UINT16 ui16PWI, ui16PHI;
1558             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1559             // aspect ratio
1560             //PictureWidth--;
1561             //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth >> 8), 1);
1562             //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth & 0xFF), 8);
1563             //Width = (PWI-1)*4, Height = PHI*4, see H263 spec 5.1.5
1564             ui16PWI = (PictureWidth >> 2) - 1;
1565             pnw__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PWI, 9);
1566 
1567             pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1568             // marker_bit                               = 1 Bit         = 1
1569             //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeight >> 8), 1);
1570             //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeight & 0xFF), 8);
1571 
1572             ui16PHI = PictureHeight >> 2;
1573             pnw__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PHI, 9);
1574             // good up to that point
1575             //  pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1576             // marker_bit                               = 1 Bit         = 1
1577             // just checking
1578             if (OCPCF == 1) {
1579                 //IMG_UINT8 CPCFC;
1580                 //CPCFC = (IMG_UINT8)(1800/(IMG_UINT16)FrameRate);
1581                 /* you can use the table for division */
1582                 //CPCFC <<= 1; /* for Clock Conversion Code */
1583                 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1584                 // Clock Divisor : 7 bits The natural binary representation of the value of the clock divisor.
1585                 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1800000 / (FrameRate * 1000), 7);
1586             }
1587         }
1588         if (OCPCF == 1) {
1589             IMG_UINT8 ui8ETR; // extended Temporal reference
1590             // Two MSBs of 10 bit temporal_reference : value 0
1591             ui8ETR = Temporal_Ref >> 8;
1592 
1593             pnw__write_upto8bits_elements(mtx_hdr, elt_p, ui8ETR, 2);
1594             /* Two MSBs of temporal_reference */
1595         }
1596     }
1597     // vop_quant                                = 5 Bits        = x     5-bit frame Q_scale from rate control - GENERATED BY MTX
1598     //pnw__write_upto8bits_elements(mtx_hdr, elt_p, ui8Q_Scale, 5);
1599     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE); // Insert token to tell MTX to insert rate-control value (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, FrameQScale))
1600     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1601     // zero_bit                                 = 1 Bit         = 0
1602     // pei                                              = 1 Bit         = 0     No direct effect on encoding of picture
1603     if (SourceFormatType != 7) {
1604         pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1605     }
1606 
1607     pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1608     // FOLLOWING SECTION CAN'T BE GENERATED HERE
1609     //gob_data( )
1610     //for(i=1; i<num_gob_in_picture; i++) {
1611     //      gob_header( )
1612     //      gob_data( )
1613     // }
1614     return;
1615 }
1616 
H263_writebits_GOBSliceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)1617 static void H263_writebits_GOBSliceHeader(
1618     MTX_HEADER_PARAMS *mtx_hdr,
1619     MTX_HEADER_ELEMENT **elt_p,
1620     IMG_UINT8 GOBNumber,
1621     IMG_UINT8 GOBFrameId)
1622 {
1623     /* Essential we insert the element before we try to fill it! */
1624     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1625 
1626     /* gob_resync_marker                = 17            = 0x1 */
1627     pnw__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17);
1628 
1629     /* gob_number = 5   = 0-17  It is gob number in a picture */
1630     pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOBNumber, 5);
1631 
1632     /* gob_frame_id     = 2 = 0-3       See note */
1633     pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOBFrameId, 2);
1634 
1635     /* quant_scale      = 5     = 1-32  gob (Slice) Q_scale  */
1636     /* pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOB_Q_Scale, 5); */
1637 
1638     /* Insert token to tell MTX to insert rate-control value
1639      *  (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale))
1640      */
1641     pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_SLICEQSCALE);
1642     return;
1643 }
1644 
1645 /*
1646  * High level functions to call when a H263 header is required - HOST ROUTINES
1647  */
1648 
1649 // SEI_INSERTION
1650 #if PSB_MFLD_DUMMY_CODE
pnw__H264_writebits_AUD_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers)1651 static void pnw__H264_writebits_AUD_header(
1652     MTX_HEADER_PARAMS *pMTX_Header,
1653     MTX_HEADER_ELEMENT **aui32ElementPointers)
1654 {
1655     // Essential we insert the element before we try to fill it!
1656     pnw__insert_element_token(pMTX_Header,
1657                               aui32ElementPointers,
1658                               ELEMENT_STARTCODE_RAWDATA);
1659 
1660     pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1661             aui32ElementPointers, 4); // 00 00 00 01 start code prefix
1662 
1663     pnw__write_upto8bits_elements(pMTX_Header,
1664                                   aui32ElementPointers,
1665                                   9,
1666                                   8); // AUD nal_unit_type = 09
1667 
1668     // primary_pic_type  u(3) 0=I slice, 1=P or I slice, 2=P,B or I slice
1669     pnw__write_upto8bits_elements(pMTX_Header,
1670                                   aui32ElementPointers,
1671                                   2,
1672                                   3);
1673 
1674     pnw__write_upto8bits_elements(pMTX_Header,
1675                                   aui32ElementPointers,
1676                                   1 << 4, 5); // rbsp_trailing_bits
1677 
1678     // Write terminator
1679     pnw__write_upto8bits_elements(pMTX_Header,
1680                                   aui32ElementPointers, 0x80, 8);
1681     return;
1682 }
1683 #endif
1684 #define SEI_NOT_USE_TOKEN_ALIGN
1685 
pnw__H264_writebits_SEI_buffering_period_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 ui8NalHrdBpPresentFlag,IMG_UINT8 ui8nal_cpb_cnt_minus1,IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,IMG_UINT32 ui32nal_initial_cpb_removal_delay,IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,IMG_UINT8 ui8VclHrdBpPresentFlag,IMG_UINT8 ui8vcl_cpb_cnt_minus1,IMG_UINT32 ui32vcl_initial_cpb_removal_delay,IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)1686 static void pnw__H264_writebits_SEI_buffering_period_header(
1687     MTX_HEADER_PARAMS *pMTX_Header,
1688     MTX_HEADER_ELEMENT **aui32ElementPointers,
1689     IMG_UINT8 ui8NalHrdBpPresentFlag,
1690     IMG_UINT8 ui8nal_cpb_cnt_minus1,
1691     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
1692     IMG_UINT32 ui32nal_initial_cpb_removal_delay,
1693     IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
1694     IMG_UINT8 ui8VclHrdBpPresentFlag,
1695     IMG_UINT8 ui8vcl_cpb_cnt_minus1,
1696     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
1697     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
1698 {
1699     IMG_UINT8 ui8SchedSelIdx;
1700     IMG_UINT8 ui8PayloadSizeBits;
1701 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1702     IMG_UINT8 ui8Pad;
1703 #endif
1704     // Essential we insert the element before we try to fill it!
1705     pnw__insert_element_token(pMTX_Header,
1706                               aui32ElementPointers,
1707                               ELEMENT_STARTCODE_RAWDATA);
1708 
1709     pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1710             aui32ElementPointers,
1711             4); // 00 00 01 start code prefix
1712 
1713     pnw__write_upto8bits_elements(pMTX_Header,
1714                                   aui32ElementPointers,
1715                                   6, 8); // nal_unit_type = 06 (SEI Message)
1716 
1717     pnw__write_upto8bits_elements(pMTX_Header,
1718                                   aui32ElementPointers,
1719                                   0, 8); // SEI payload type (buffering period)
1720 
1721     ui8PayloadSizeBits = 1; // seq_parameter_set_id bitsize = 1
1722     if (ui8NalHrdBpPresentFlag)
1723         ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1)
1724                                * ui8nal_initial_cpb_removal_delay_length * 2);
1725     if (ui8VclHrdBpPresentFlag)
1726         ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1)
1727                                * ui8nal_initial_cpb_removal_delay_length * 2);
1728 
1729     pnw__write_upto8bits_elements(pMTX_Header,
1730                                   aui32ElementPointers,
1731                                   ((ui8PayloadSizeBits + 7) / 8),
1732                                   8);
1733     // SEI payload size = No of bytes required for SEI payload
1734     // (including seq_parameter_set_id)
1735 
1736     //seq_parameter_set_id      ue(v) = 0 default? = 1 (binary)
1737     //= sequence parameter set containing HRD attributes
1738     pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
1739 
1740     if (ui8NalHrdBpPresentFlag) {
1741         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++) {
1742             // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access
1743             // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit.
1744             // Delay is based on the time taken for a 90 kHz clock.
1745             // Range >0 and < 90000 * (CPBsize / BitRate)
1746             // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation.
1747             // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
1748 
1749             pnw__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,
1750 		    ui32nal_initial_cpb_removal_delay,
1751 		    ui8nal_initial_cpb_removal_delay_length);
1752 
1753 /*
1754             pnw__insert_element_token(pMTX_Header,
1755                                       aui32ElementPointers,
1756                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY);*/
1757 
1758             // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to
1759             // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset
1760             // Delay is based on the time taken for a 90 kHz clock.
1761             // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C
1762 
1763             pnw__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,
1764 		    ui32nal_initial_cpb_removal_delay_offset,
1765 		    ui8nal_initial_cpb_removal_delay_length);
1766 
1767             /*pnw__insert_element_token(pMTX_Header,
1768                                       aui32ElementPointers,
1769                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET);*/
1770 
1771         }
1772     }
1773     if (ui8VclHrdBpPresentFlag) {
1774         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++) {
1775             pnw__insert_element_token(pMTX_Header,
1776                                       aui32ElementPointers,
1777                                       ELEMENT_STARTCODE_RAWDATA);
1778             // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
1779             pnw__write_upto32bits_elements(pMTX_Header,
1780                                            aui32ElementPointers,
1781                                            ui32vcl_initial_cpb_removal_delay,
1782                                            ui8nal_initial_cpb_removal_delay_length);
1783             // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required
1784             pnw__write_upto32bits_elements(pMTX_Header,
1785                                            aui32ElementPointers,
1786                                            ui32vcl_initial_cpb_removal_delay_offset,
1787                                            ui8nal_initial_cpb_removal_delay_length);
1788         }
1789     }
1790 
1791     // Pad to end of byte
1792 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1793     if (!ui8VclHrdBpPresentFlag)
1794         pnw__insert_element_token(pMTX_Header,
1795                                   aui32ElementPointers,
1796                                   ELEMENT_STARTCODE_RAWDATA);
1797     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
1798     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
1799     if (ui8Pad > 0)
1800         pnw__write_upto8bits_elements(pMTX_Header,
1801                                       aui32ElementPointers,
1802                                       1 << (ui8Pad - 1),
1803                                       ui8Pad); // SEI payload type (buffering period)
1804 #else
1805     pnw__write_upto8bits_elements(pMTX_Header,
1806                                   aui32ElementPointers,
1807                                   1, 1); // rbsp_trailing_bits
1808 
1809     pnw__insert_element_token(pMTX_Header,
1810                               aui32ElementPointers,
1811                               ELEMENT_INSERTBYTEALIGN_H264);
1812     // Tell MTX to insert the byte align field
1813     pnw__insert_element_token(pMTX_Header,
1814                               aui32ElementPointers,
1815                               ELEMENT_STARTCODE_RAWDATA);
1816 #endif
1817 
1818     // Write terminator
1819     pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8);
1820 
1821     return;
1822 }
1823 
1824 #define SEI_HOSTCALC_CPB_DPB
1825 
pnw__H264_writebits_SEI_picture_timing_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 ui8CpbDpbDelaysPresentFlag,IMG_UINT32 ui32cpb_removal_delay_length_minus1,IMG_UINT32 ui32dpb_output_delay_length_minus1,IMG_UINT32 ui32cpb_removal_delay,IMG_UINT32 ui32dpb_output_delay,IMG_UINT8 ui8pic_struct_present_flag,IMG_UINT8 __maybe_unused ui8pic_struct,IMG_UINT8 __maybe_unused ui8NumClockTS,IMG_UINT8 __maybe_unused * aui8clock_timestamp_flag,IMG_UINT8 __maybe_unused ui8full_timestamp_flag,IMG_UINT8 __maybe_unused ui8seconds_flag,IMG_UINT8 __maybe_unused ui8minutes_flag,IMG_UINT8 __maybe_unused ui8hours_flag,IMG_UINT8 __maybe_unused ui8seconds_value,IMG_UINT8 __maybe_unused ui8minutes_value,IMG_UINT8 __maybe_unused ui8hours_value,IMG_UINT8 __maybe_unused ui8ct_type,IMG_UINT8 __maybe_unused ui8nuit_field_based_flag,IMG_UINT8 __maybe_unused ui8counting_type,IMG_UINT8 __maybe_unused ui8discontinuity_flag,IMG_UINT8 __maybe_unused ui8cnt_dropped_flag,IMG_UINT8 __maybe_unused ui8n_frames,IMG_UINT8 __maybe_unused ui8time_offset_length,IMG_UINT32 __maybe_unused i32time_offset)1826 static void pnw__H264_writebits_SEI_picture_timing_header(
1827     MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1828     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
1829     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
1830     IMG_UINT32 ui32dpb_output_delay_length_minus1,
1831     IMG_UINT32 ui32cpb_removal_delay,
1832     IMG_UINT32 ui32dpb_output_delay,
1833     IMG_UINT8 ui8pic_struct_present_flag,
1834     IMG_UINT8 __maybe_unused ui8pic_struct,
1835     IMG_UINT8 __maybe_unused ui8NumClockTS,
1836     IMG_UINT8 __maybe_unused * aui8clock_timestamp_flag,
1837     IMG_UINT8 __maybe_unused ui8full_timestamp_flag,
1838     IMG_UINT8 __maybe_unused ui8seconds_flag,
1839     IMG_UINT8 __maybe_unused ui8minutes_flag,
1840     IMG_UINT8 __maybe_unused ui8hours_flag,
1841     IMG_UINT8 __maybe_unused ui8seconds_value,
1842     IMG_UINT8 __maybe_unused ui8minutes_value,
1843     IMG_UINT8 __maybe_unused ui8hours_value,
1844     IMG_UINT8 __maybe_unused ui8ct_type,
1845     IMG_UINT8 __maybe_unused ui8nuit_field_based_flag,
1846     IMG_UINT8 __maybe_unused ui8counting_type,
1847     IMG_UINT8 __maybe_unused ui8discontinuity_flag,
1848     IMG_UINT8 __maybe_unused ui8cnt_dropped_flag,
1849     IMG_UINT8 __maybe_unused ui8n_frames,
1850     IMG_UINT8 __maybe_unused ui8time_offset_length,
1851     IMG_UINT32 __maybe_unused i32time_offset)
1852 {
1853     IMG_UINT8 ui8PayloadSizeBits, ui8Tmp;
1854 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1855     IMG_UINT8 ui8Pad;
1856 #endif
1857 
1858     // Essential we insert the element before we try to fill it!
1859     pnw__insert_element_token(pMTX_Header,
1860                               aui32ElementPointers,
1861                               ELEMENT_STARTCODE_RAWDATA);
1862 
1863     pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1864             aui32ElementPointers,
1865             4); // 00 00 01 start code prefix
1866 
1867     pnw__write_upto8bits_elements(pMTX_Header,
1868                                   aui32ElementPointers,
1869                                   6, 8); // nal_unit_type = 06 (SEI Message)
1870 
1871     pnw__write_upto8bits_elements(pMTX_Header,
1872                                   aui32ElementPointers,
1873                                   1, 8); // SEI payload type (picture timing)
1874 
1875 
1876     // Precalculate the payload bit size
1877     ui8PayloadSizeBits = 0;
1878     if (ui8CpbDpbDelaysPresentFlag)
1879         ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1
1880                               + 1 + ui32dpb_output_delay_length_minus1 + 1;
1881 
1882 #if 0
1883     if (ui8pic_struct_present_flag) {
1884         ui8PayloadSizeBits += 4;
1885         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
1886             ui8PayloadSizeBits += 1;
1887 
1888             if (aui8clock_timestamp_flag[ui8Tmp]) {
1889                 ui8PayloadSizeBits += 2 + 1 + 5 + 1 + 1 + 1 + 8;
1890                 if (ui8full_timestamp_flag)
1891                     ui8PayloadSizeBits += 6 + 6 + 5;
1892                 else {
1893                     ui8PayloadSizeBits += 1;
1894                     if (ui8seconds_flag) {
1895                         ui8PayloadSizeBits += 6 + 1;
1896                         if (ui8minutes_flag) {
1897                             ui8PayloadSizeBits += 6 + 1;
1898                             if (ui8hours_flag)
1899                                 ui8PayloadSizeBits += 5;
1900                         }
1901                     }
1902                 }
1903 
1904                 if (ui8time_offset_length > 0)
1905                     ui8PayloadSizeBits += ui8time_offset_length;
1906             }
1907         }
1908     }
1909 #endif
1910 
1911     pnw__write_upto8bits_elements(pMTX_Header,
1912                                   aui32ElementPointers,
1913                                   ((ui8PayloadSizeBits + 7) / 8), 8);
1914     // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id)
1915 
1916 
1917     if (ui8CpbDpbDelaysPresentFlag) {
1918         //SEI_INSERTION
1919 #ifdef SEI_HOSTCALC_CPB_DPB
1920         pnw__write_upto32bits_elements(pMTX_Header,
1921                                        aui32ElementPointers,
1922                                        ui32cpb_removal_delay,
1923                                        ui32cpb_removal_delay_length_minus1 + 1); // cpb_removal_delay
1924         pnw__write_upto32bits_elements(pMTX_Header,
1925                                        aui32ElementPointers,
1926                                        ui32dpb_output_delay,
1927                                        ui32dpb_output_delay_length_minus1 + 1); // dpb_output_delay
1928 #else
1929         pnw__insert_element_token(pMTX_Header,
1930                                   aui32ElementPointers,
1931                                   PTH_SEI_NAL_CPB_REMOVAL_DELAY);
1932         pnw__insert_element_token(pMTX_Header,
1933                                   aui32ElementPointers,
1934                                   PTH_SEI_NAL_DPB_OUTPUT_DELAY);
1935 #endif
1936     }
1937 
1938 #if 0
1939     if (ui8pic_struct_present_flag) {
1940         pnw__insert_element_token(pMTX_Header,
1941                                   aui32ElementPointers,
1942                                   ELEMENT_STARTCODE_RAWDATA);
1943         pnw__write_upto8bits_elements(pMTX_Header,
1944                                       aui32ElementPointers,
1945                                       ui8pic_struct, 4); // See TRM able D 1 � Interpretation of pic_struct
1946 
1947         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
1948             pnw__write_upto8bits_elements(pMTX_Header,
1949                                           aui32ElementPointers,
1950                                           aui8clock_timestamp_flag[ui8Tmp], 1);
1951 
1952             if (aui8clock_timestamp_flag[ui8Tmp]) {
1953                 pnw__write_upto8bits_elements(pMTX_Header,
1954                                               aui32ElementPointers,
1955                                               ui8ct_type, 2);
1956                 // (2=Unknown) See TRM Table D 2 � Mapping of ct_type to source picture scan
1957                 pnw__write_upto8bits_elements(pMTX_Header,
1958                                               aui32ElementPointers,
1959                                               ui8nuit_field_based_flag, 1);
1960                 pnw__write_upto8bits_elements(pMTX_Header,
1961                                               aui32ElementPointers,
1962                                               ui8counting_type, 5);
1963                 // See TRM Table D 3 � Definition of counting_type values
1964                 pnw__write_upto8bits_elements(pMTX_Header,
1965                                               aui32ElementPointers,
1966                                               ui8full_timestamp_flag, 1);
1967                 pnw__write_upto8bits_elements(pMTX_Header,
1968                                               aui32ElementPointers,
1969                                               ui8discontinuity_flag, 1);
1970                 pnw__write_upto8bits_elements(pMTX_Header,
1971                                               aui32ElementPointers,
1972                                               ui8cnt_dropped_flag, 1);
1973                 pnw__write_upto8bits_elements(pMTX_Header,
1974                                               aui32ElementPointers,
1975                                               ui8n_frames, 8);
1976 
1977                 if (ui8full_timestamp_flag) {
1978                     pnw__write_upto8bits_elements(pMTX_Header,
1979                                                   aui32ElementPointers,
1980                                                   ui8seconds_value, 6); // 0 - 59
1981                     pnw__write_upto8bits_elements(pMTX_Header,
1982                                                   aui32ElementPointers,
1983                                                   ui8minutes_value, 6); // 0 - 59
1984                     pnw__write_upto8bits_elements(pMTX_Header,
1985                                                   aui32ElementPointers,
1986                                                   ui8hours_value, 5); // 0 - 23
1987                 } else {
1988                     pnw__write_upto8bits_elements(pMTX_Header,
1989                                                   aui32ElementPointers,
1990                                                   ui8seconds_flag, 1);
1991 
1992                     if (ui8seconds_flag) {
1993                         pnw__write_upto8bits_elements(pMTX_Header,
1994                                                       aui32ElementPointers,
1995                                                       ui8seconds_value, 6); // 0 - 59
1996                         pnw__write_upto8bits_elements(pMTX_Header,
1997                                                       aui32ElementPointers,
1998                                                       ui8minutes_flag, 1);
1999 
2000                         if (ui8minutes_flag) {
2001                             pnw__write_upto8bits_elements(pMTX_Header,
2002                                                           aui32ElementPointers,
2003                                                           ui8minutes_value, 6); // 0 - 59
2004                             pnw__write_upto8bits_elements(pMTX_Header,
2005                                                           aui32ElementPointers,
2006                                                           ui8hours_flag, 1);
2007 
2008                             if (ui8hours_flag)
2009                                 pnw__write_upto8bits_elements(pMTX_Header,
2010                                                               aui32ElementPointers,
2011                                                               ui8hours_value, 5); // 0 - 23
2012                         }
2013                     }
2014                 }
2015 
2016                 if (ui8time_offset_length > 0) {
2017                     // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset)
2018                     if ((int)i32time_offset < 0)
2019                         pnw__write_upto32bits_elements(pMTX_Header,
2020                                                        aui32ElementPointers,
2021                                                        (IMG_UINT32)((2 ^ ui8time_offset_length) + i32time_offset),
2022                                                        ui8time_offset_length);
2023                     else
2024                         pnw__write_upto32bits_elements(pMTX_Header,
2025                                                        aui32ElementPointers,
2026                                                        (IMG_UINT32) i32time_offset,
2027                                                        ui8time_offset_length);
2028                 }
2029             }
2030         }
2031     }
2032 #endif
2033 
2034 #ifdef SEI_NOT_USE_TOKEN_ALIGN
2035     // Pad to end of byte
2036     if (!ui8pic_struct_present_flag)
2037         pnw__insert_element_token(pMTX_Header,
2038                                   aui32ElementPointers,
2039                                   ELEMENT_STARTCODE_RAWDATA);
2040     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2041     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2042     if (ui8Pad > 0)
2043         pnw__write_upto8bits_elements(pMTX_Header,
2044                                       aui32ElementPointers,
2045                                       1 << (ui8Pad - 1),
2046                                       ui8Pad); // SEI payload type (buffering period)
2047 #else
2048     pnw__insert_element_token(pMTX_Header,
2049                               aui32ElementPointers,
2050                               ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field
2051     pnw__insert_element_token(pMTX_Header,
2052                               aui32ElementPointers,
2053                               ELEMENT_STARTCODE_RAWDATA);
2054 #endif
2055 
2056     // Write terminator
2057     pnw__write_upto8bits_elements(pMTX_Header,
2058                                   aui32ElementPointers,
2059                                   0x80, 8);
2060     return;
2061 }
2062 
pnw__H264_writebits_SEI_FPA_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,char * sei_data_buf,IMG_UINT32 data_size)2063 static void pnw__H264_writebits_SEI_FPA_header(
2064         MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
2065         char* sei_data_buf, IMG_UINT32 data_size)
2066 {
2067     IMG_UINT8 i;
2068 
2069     // Essential we insert the element before we try to fill it!
2070     pnw__insert_element_token(pMTX_Header,
2071             aui32ElementPointers,
2072             ELEMENT_STARTCODE_RAWDATA);
2073 
2074     pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
2075             aui32ElementPointers,
2076             4); // 00 00 01 start code prefix
2077 
2078     for (i = 0; i < data_size; i++)
2079         pnw__write_upto8bits_elements(pMTX_Header,
2080                 aui32ElementPointers,
2081                 sei_data_buf[i], 8); //sei_data_buf (SEI Message)
2082     // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
2083     //pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
2084 
2085     return;
2086 }
2087 
2088 
2089 #if PSB_MFLD_DUMMY_CODE
pnw__H264_prepare_AUD_header(MTX_HEADER_PARAMS * pMTX_Header)2090 void pnw__H264_prepare_AUD_header(MTX_HEADER_PARAMS * pMTX_Header)
2091 {
2092     // Essential we initialise our header structures before building
2093     MTX_HEADER_ELEMENT *This_Element;
2094     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2095     pMTX_Header->Elements = ELEMENTS_EMPTY;
2096     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2097     aui32ElementPointers[0] = This_Element;
2098 
2099     pnw__H264_writebits_AUD_header(pMTX_Header, aui32ElementPointers);
2100 
2101     pMTX_Header->Elements++; //Has been used as an index, so need to add 1 for a valid element count
2102 }
2103 #endif
2104 
pnw__H264_prepare_SEI_buffering_period_header(MTX_HEADER_PARAMS * pMTX_Header,IMG_UINT8 ui8NalHrdBpPresentFlag,IMG_UINT8 ui8nal_cpb_cnt_minus1,IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,IMG_UINT32 ui32nal_initial_cpb_removal_delay,IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,IMG_UINT8 ui8VclHrdBpPresentFlag,IMG_UINT8 ui8vcl_cpb_cnt_minus1,IMG_UINT32 ui32vcl_initial_cpb_removal_delay,IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)2105 void pnw__H264_prepare_SEI_buffering_period_header(
2106     MTX_HEADER_PARAMS * pMTX_Header,
2107     IMG_UINT8 ui8NalHrdBpPresentFlag,
2108     IMG_UINT8 ui8nal_cpb_cnt_minus1,
2109     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
2110     IMG_UINT32 ui32nal_initial_cpb_removal_delay,
2111     IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
2112     IMG_UINT8 ui8VclHrdBpPresentFlag,
2113     IMG_UINT8 ui8vcl_cpb_cnt_minus1,
2114     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
2115     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
2116 {
2117     // Essential we initialise our header structures before building
2118     MTX_HEADER_ELEMENT *This_Element;
2119     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2120     pMTX_Header->Elements = ELEMENTS_EMPTY;
2121     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2122     aui32ElementPointers[0] = This_Element;
2123 
2124     pnw__H264_writebits_SEI_buffering_period_header(
2125         pMTX_Header, aui32ElementPointers,
2126         ui8NalHrdBpPresentFlag,
2127         ui8nal_cpb_cnt_minus1,
2128         ui8nal_initial_cpb_removal_delay_length,
2129         ui32nal_initial_cpb_removal_delay,
2130         ui32nal_initial_cpb_removal_delay_offset,
2131         ui8VclHrdBpPresentFlag,
2132         ui8vcl_cpb_cnt_minus1,
2133         ui32vcl_initial_cpb_removal_delay,
2134         ui32vcl_initial_cpb_removal_delay_offset);
2135 
2136     pMTX_Header->Elements++;
2137     //Has been used as an index, so need to add 1 for a valid element count
2138     return;
2139 }
2140 
pnw__H264_prepare_SEI_picture_timing_header(MTX_HEADER_PARAMS * pMTX_Header,IMG_UINT8 ui8CpbDpbDelaysPresentFlag,IMG_UINT32 ui32cpb_removal_delay_length_minus1,IMG_UINT32 ui32dpb_output_delay_length_minus1,IMG_UINT32 ui32cpb_removal_delay,IMG_UINT32 ui32dpb_output_delay,IMG_UINT8 ui8pic_struct_present_flag,IMG_UINT8 ui8pic_struct,IMG_UINT8 ui8NumClockTS,IMG_UINT8 * aui8clock_timestamp_flag,IMG_UINT8 ui8full_timestamp_flag,IMG_UINT8 ui8seconds_flag,IMG_UINT8 ui8minutes_flag,IMG_UINT8 ui8hours_flag,IMG_UINT8 ui8seconds_value,IMG_UINT8 ui8minutes_value,IMG_UINT8 ui8hours_value,IMG_UINT8 ui8ct_type,IMG_UINT8 ui8nuit_field_based_flag,IMG_UINT8 ui8counting_type,IMG_UINT8 ui8discontinuity_flag,IMG_UINT8 ui8cnt_dropped_flag,IMG_UINT8 ui8n_frames,IMG_UINT8 ui8time_offset_length,IMG_INT32 i32time_offset)2141 void pnw__H264_prepare_SEI_picture_timing_header(
2142     MTX_HEADER_PARAMS * pMTX_Header,
2143     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2144     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2145     IMG_UINT32 ui32dpb_output_delay_length_minus1,
2146     IMG_UINT32 ui32cpb_removal_delay,
2147     IMG_UINT32 ui32dpb_output_delay,
2148     IMG_UINT8 ui8pic_struct_present_flag,
2149     IMG_UINT8 ui8pic_struct,
2150     IMG_UINT8 ui8NumClockTS,
2151     IMG_UINT8 *aui8clock_timestamp_flag,
2152     IMG_UINT8 ui8full_timestamp_flag,
2153     IMG_UINT8 ui8seconds_flag,
2154     IMG_UINT8 ui8minutes_flag,
2155     IMG_UINT8 ui8hours_flag,
2156     IMG_UINT8 ui8seconds_value,
2157     IMG_UINT8 ui8minutes_value,
2158     IMG_UINT8 ui8hours_value,
2159     IMG_UINT8 ui8ct_type,
2160     IMG_UINT8 ui8nuit_field_based_flag,
2161     IMG_UINT8 ui8counting_type,
2162     IMG_UINT8 ui8discontinuity_flag,
2163     IMG_UINT8 ui8cnt_dropped_flag,
2164     IMG_UINT8 ui8n_frames,
2165     IMG_UINT8 ui8time_offset_length,
2166     IMG_INT32 i32time_offset)
2167 {
2168     // Essential we initialise our header structures before building
2169     MTX_HEADER_ELEMENT *This_Element;
2170     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2171     pMTX_Header->Elements = ELEMENTS_EMPTY;
2172     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2173     aui32ElementPointers[0] = This_Element;
2174 
2175     pnw__H264_writebits_SEI_picture_timing_header(
2176         pMTX_Header, aui32ElementPointers,
2177         ui8CpbDpbDelaysPresentFlag,
2178         ui32cpb_removal_delay_length_minus1,
2179         ui32dpb_output_delay_length_minus1,
2180         ui32cpb_removal_delay,
2181         ui32dpb_output_delay,
2182         ui8pic_struct_present_flag,
2183         ui8pic_struct,
2184         ui8NumClockTS,
2185         aui8clock_timestamp_flag,
2186         ui8full_timestamp_flag,
2187         ui8seconds_flag,
2188         ui8minutes_flag,
2189         ui8hours_flag,
2190         ui8seconds_value,
2191         ui8minutes_value,
2192         ui8hours_value,
2193         ui8ct_type,
2194         ui8nuit_field_based_flag,
2195         ui8counting_type,
2196         ui8discontinuity_flag,
2197         ui8cnt_dropped_flag,
2198         ui8n_frames,
2199         ui8time_offset_length,
2200         i32time_offset);
2201 
2202     pMTX_Header->Elements++;
2203     //Has been used as an index, so need to add 1 for a valid element count
2204     return;
2205 }
2206 
2207 #if PSB_MFLD_DUMMY_CODE
pnw__H264_prepare_SEI_FPA_header(MTX_HEADER_PARAMS * pMTX_Header,char * sei_data_buf,IMG_UINT32 data_size)2208 void pnw__H264_prepare_SEI_FPA_header(
2209         MTX_HEADER_PARAMS * pMTX_Header,
2210         char* sei_data_buf,
2211         IMG_UINT32 data_size)
2212 {
2213     // Essential we initialise our header structures before building
2214     MTX_HEADER_ELEMENT *This_Element;
2215     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2216     pMTX_Header->Elements = ELEMENTS_EMPTY;
2217     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2218     aui32ElementPointers[0] = This_Element;
2219 
2220     pnw__H264_writebits_SEI_FPA_header(
2221             pMTX_Header, aui32ElementPointers,
2222             sei_data_buf, data_size);
2223 
2224     pMTX_Header->Elements++;
2225     //Has been used as an index, so need to add 1 for a valid element count
2226     return;
2227 }
2228 #endif
2229 
2230 
pnw__H264_prepare_sequence_header(unsigned char * pHeaderMemory,IMG_UINT32 uiPicWidthInMbs,IMG_UINT32 uiPicHeightInMbs,IMG_BOOL VUI_present,H264_VUI_PARAMS * VUI_params,H264_CROP_PARAMS * psCropParams,IMG_UINT8 uiLevel,IMG_UINT8 uiProfile)2231 void pnw__H264_prepare_sequence_header(
2232         unsigned char *pHeaderMemory,
2233         IMG_UINT32 uiPicWidthInMbs,
2234         IMG_UINT32 uiPicHeightInMbs,
2235         IMG_BOOL VUI_present, H264_VUI_PARAMS *VUI_params,
2236         H264_CROP_PARAMS *psCropParams,
2237         IMG_UINT8 uiLevel,
2238         IMG_UINT8 uiProfile)
2239 {
2240     H264_SEQUENCE_HEADER_PARAMS SHParams;
2241     MTX_HEADER_PARAMS   *mtx_hdr;
2242 
2243     /* Route output elements to memory provided */
2244     memset(&SHParams, 0, sizeof(SHParams));
2245     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2246 
2247     /* Setup Sequence Header information  */
2248 
2249 
2250     switch (uiProfile) {
2251     case 5:
2252         SHParams.ucProfile  = SH_PROFILE_BP;
2253         break;
2254     case 6:
2255         SHParams.ucProfile  = SH_PROFILE_MP;
2256         break;
2257     default:
2258         SHParams.ucProfile  = SH_PROFILE_MP;
2259         break;
2260     }
2261 
2262     switch (uiLevel) {
2263     case 10:
2264         SHParams.ucLevel =  SH_LEVEL_1;
2265         break;
2266     case 111:
2267         SHParams.ucLevel =  SH_LEVEL_1B;
2268         break;
2269     case 11:
2270         SHParams.ucLevel =  SH_LEVEL_11;
2271         break;
2272     case 12:
2273         SHParams.ucLevel =  SH_LEVEL_12;
2274         break;
2275     case 20:
2276         SHParams.ucLevel =  SH_LEVEL_2;
2277         break;
2278     case 30:
2279         SHParams.ucLevel =  SH_LEVEL_3;
2280         break;
2281     case 31:
2282         SHParams.ucLevel =  SH_LEVEL_31;
2283         break;
2284     case 32:
2285         SHParams.ucLevel =  SH_LEVEL_32;
2286         break;
2287     case 40:
2288         SHParams.ucLevel =  SH_LEVEL_4;
2289         break;
2290     case 41:
2291         SHParams.ucLevel =  SH_LEVEL_41;
2292         break;
2293     case 42:
2294         SHParams.ucLevel =  SH_LEVEL_42;
2295         break;
2296     default:
2297         SHParams.ucLevel =  SH_LEVEL_3;
2298         break;
2299     }
2300 
2301     SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)(uiPicWidthInMbs - 1);
2302     SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)(uiPicHeightInMbs - 1);
2303     SHParams.VUI_Params_Present = VUI_present;
2304     if (VUI_present)
2305         SHParams.VUI_Params = *VUI_params;
2306     SHParams.gaps_in_frame_num_value = IMG_FALSE;
2307     SHParams.ucFrame_mbs_only_flag = IMG_TRUE;
2308 
2309     /* All picture header information is static
2310      * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway)
2311      */
2312 
2313     /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug
2314      * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0;
2315      */
2316 
2317 #if HEADERS_VERBOSE_OUTPUT
2318     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2319     drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2320     drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2321 #endif
2322 
2323     /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */
2324     pnw__H264_getelements_sequence_header(mtx_hdr, &SHParams, psCropParams);
2325 }
2326 
pnw__H264_prepare_picture_header(unsigned char * pHeaderMemory,IMG_BOOL bCabacEnabled,IMG_INT8 CQPOffset)2327 void pnw__H264_prepare_picture_header(unsigned char *pHeaderMemory, IMG_BOOL bCabacEnabled, IMG_INT8 CQPOffset)
2328 {
2329     MTX_HEADER_PARAMS *mtx_hdr;
2330 
2331     /* Route output elements to memory provided */
2332     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2333 
2334 
2335     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2336      * Essential we initialise our header structures before building
2337      */
2338     MTX_HEADER_ELEMENT *This_Element;
2339     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2340     mtx_hdr->Elements = ELEMENTS_EMPTY;
2341     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2342     elt_p[0] = This_Element;
2343 
2344     pnw__H264_writebits_picture_header(mtx_hdr, elt_p, bCabacEnabled,
2345                                        0, 0,
2346                                        CQPOffset, CQPOffset);
2347     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2348 }
2349 
pnw__H264_prepare_slice_header(unsigned char * pHeaderMemory,IMG_BOOL bIntraSlice,IMG_UINT32 uiDisableDeblockingFilterIDC,IMG_UINT32 uiFrameNumber,IMG_UINT32 uiFirst_MB_Address,IMG_UINT32 uiMBSkipRun,IMG_BOOL bCabacEnabled,IMG_BOOL bForceIDR,IMG_BOOL bUsesLongTermRef,IMG_BOOL bIsLongTermRef,IMG_UINT16 uiIdrPicId)2350 void pnw__H264_prepare_slice_header(
2351     unsigned char *pHeaderMemory,
2352     IMG_BOOL    bIntraSlice,
2353     IMG_UINT32 uiDisableDeblockingFilterIDC,
2354     IMG_UINT32 uiFrameNumber,
2355     IMG_UINT32 uiFirst_MB_Address,
2356     IMG_UINT32 uiMBSkipRun,
2357     IMG_BOOL bCabacEnabled,
2358     IMG_BOOL bForceIDR,
2359     IMG_BOOL bUsesLongTermRef,
2360     IMG_BOOL bIsLongTermRef,
2361     IMG_UINT16 uiIdrPicId)
2362 {
2363     H264_SLICE_HEADER_PARAMS SlHParams;
2364     MTX_HEADER_PARAMS *mtx_hdr;
2365 
2366     memset(&SlHParams, 0, sizeof(SlHParams));
2367 
2368     /* Route output elements to memory provided */
2369     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2370 
2371     SlHParams.Start_Code_Prefix_Size_Bytes = 4;
2372     SlHParams.UsesLongTermRef = bUsesLongTermRef;
2373     SlHParams.IsLongTermRef = bIsLongTermRef;
2374 
2375     if (bForceIDR || (uiFrameNumber == 0)) {
2376         drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ: Generate a IDR slice\n");
2377         SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
2378     } else
2379         SlHParams.SliceFrame_Type = bIntraSlice ? SLHP_I_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE;
2380 
2381     /*SlHParams.SliceFrame_Type =       bIntraSlice ? (((uiFrameNumber%(1<<5))==0) ? SLHP_IDR_SLICEFRAME_TYPE :SLHP_I_SLICEFRAME_TYPE ) : SLHP_P_SLICEFRAME_TYPE;*/
2382     SlHParams.Frame_Num_DO = (IMG_UINT8) uiFrameNumber % (1 << 5);
2383     SlHParams.Picture_Num_DO = (IMG_UINT8)(SlHParams.Frame_Num_DO * 2);
2384 
2385 
2386     SlHParams.First_MB_Address  =  uiFirst_MB_Address;
2387     SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) uiDisableDeblockingFilterIDC;
2388 
2389     {
2390         IMG_UINT32      *pMTX_Header_Mem = (IMG_UINT32 *)mtx_hdr;
2391         // rhk: first insert normal header.
2392         pnw__H264_getelements_slice_header(mtx_hdr, &SlHParams, bCabacEnabled, uiIdrPicId);
2393 
2394         // put a marker to indicate that this is a complex header
2395         // note that first "int" in the buffer is used for number of elements
2396         // which is not going to be more than 255
2397         *pMTX_Header_Mem |= 0x100;
2398 
2399         // rhk: insert skipped frame header at an offset of 128 bytes
2400         pMTX_Header_Mem += (HEADER_SIZE >> 3);  // get a pointer to the second half of memory
2401         mtx_hdr = (MTX_HEADER_PARAMS *)pMTX_Header_Mem;
2402         pnw__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun, bCabacEnabled);
2403     }
2404 
2405 }
2406 
2407 
pnw__MPEG4_prepare_sequence_header(unsigned char * pHeaderMemory,IMG_BOOL bBFrame,MPEG4_PROFILE_TYPE sProfile,IMG_UINT8 Profile_and_level_indication,FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,IMG_UINT32 Picture_Width_Pixels,IMG_UINT32 Picture_Height_Pixels,VBVPARAMS * psVBVParams,IMG_UINT32 VopTimeResolution)2408 void pnw__MPEG4_prepare_sequence_header(
2409     unsigned char *pHeaderMemory,
2410     IMG_BOOL bBFrame,
2411     MPEG4_PROFILE_TYPE sProfile,
2412     IMG_UINT8 Profile_and_level_indication,
2413     FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
2414     IMG_UINT32 Picture_Width_Pixels,
2415     IMG_UINT32 Picture_Height_Pixels,
2416     VBVPARAMS * psVBVParams,
2417     IMG_UINT32 VopTimeResolution)
2418 {
2419     MTX_HEADER_PARAMS *mtx_hdr;
2420 
2421     /* Route output elements to memory provided */
2422     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2423     /* Builds a single MPEG4 video sequence header from the given parameters */
2424 
2425     /* Essential we initialise our header structures before building */
2426     MTX_HEADER_ELEMENT *This_Element;
2427     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2428     mtx_hdr->Elements = ELEMENTS_EMPTY;
2429     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2430     elt_p[0] = This_Element;
2431 
2432     pnw__MPEG4_writebits_sequence_header(
2433         mtx_hdr,
2434         elt_p,
2435         bBFrame, sProfile,
2436         Profile_and_level_indication,
2437         sFixed_vop_time_increment,
2438         Picture_Width_Pixels,
2439         Picture_Height_Pixels,
2440         psVBVParams, VopTimeResolution);
2441 
2442     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2443 
2444 }
2445 
pnw__MPEG4_prepare_vop_header(unsigned char * pHeaderMem,IMG_BOOL bIsVOP_coded,IMG_UINT32 VOP_time_increment,IMG_UINT8 sSearch_range,IMG_UINT8 eVop_Coding_Type,IMG_UINT32 VopTimeResolution)2446 void pnw__MPEG4_prepare_vop_header(
2447     unsigned char *pHeaderMem,
2448     IMG_BOOL bIsVOP_coded,
2449     IMG_UINT32 VOP_time_increment,
2450     IMG_UINT8 sSearch_range,
2451     IMG_UINT8 eVop_Coding_Type,
2452     IMG_UINT32 VopTimeResolution)
2453 {
2454     MTX_HEADER_PARAMS *mtx_hdr;
2455 
2456     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2457 
2458     /* Builds a single MPEG4 VOP (picture) header from the given parameters */
2459     /* Essential we initialise our header structures before building */
2460     MTX_HEADER_ELEMENT *This_Element;
2461     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2462     mtx_hdr->Elements = ELEMENTS_EMPTY;
2463     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2464     elt_p[0] = This_Element;
2465 
2466     /* Frame QScale no longer written here as it is inserted by MTX later
2467      * (add as parameter to MTX_Send_Elements_To_VLC)
2468      */
2469     pnw__MPEG4_writebits_VOP_header(
2470         mtx_hdr, elt_p, bIsVOP_coded,
2471         VOP_time_increment,
2472         sSearch_range,
2473         eVop_Coding_Type,
2474         VopTimeResolution);
2475 
2476     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2477 
2478 }
2479 
2480 
2481 #if PSB_MFLD_DUMMY_CODE
pnw__H263_prepare_sequence_header(unsigned char * pHeaderMem,IMG_UINT8 Profile_and_level_indication)2482 void pnw__H263_prepare_sequence_header(
2483     unsigned char *pHeaderMem,
2484     IMG_UINT8 Profile_and_level_indication)
2485 {
2486     MTX_HEADER_PARAMS *mtx_hdr;
2487 
2488     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2489 
2490     /* Builds a single H263 video sequence header from the given parameters */
2491 
2492     /* Essential we initialise our header structures before building */
2493     MTX_HEADER_ELEMENT *This_Element;
2494     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2495     mtx_hdr->Elements = ELEMENTS_EMPTY;
2496     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2497     elt_p[0] = This_Element;
2498 
2499     H263_writebits_VideoSequenceHeader(mtx_hdr, elt_p, Profile_and_level_indication);
2500 
2501     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2502 
2503 }
2504 #endif
2505 
pnw__H263_prepare_picture_header(unsigned char * pHeaderMem,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 FrameRate,IMG_UINT16 PictureWidth,IMG_UINT16 PictureHeigth)2506 void pnw__H263_prepare_picture_header(
2507     unsigned char *pHeaderMem,
2508     IMG_UINT8 Temporal_Ref,
2509     H263_PICTURE_CODING_TYPE PictureCodingType,
2510     H263_SOURCE_FORMAT_TYPE SourceFormatType,
2511     IMG_UINT8 FrameRate,
2512     IMG_UINT16 PictureWidth,
2513     IMG_UINT16 PictureHeigth)
2514 {
2515     MTX_HEADER_PARAMS *mtx_hdr;
2516 
2517     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2518 
2519     /* Essential we initialise our header structures before building */
2520     MTX_HEADER_ELEMENT *This_Element;
2521     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2522     mtx_hdr->Elements = ELEMENTS_EMPTY;
2523     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2524     elt_p[0] = This_Element;
2525 
2526     H263_writebits_VideoPictureHeader(
2527         mtx_hdr, elt_p,
2528         Temporal_Ref,
2529         PictureCodingType,
2530         SourceFormatType,
2531         FrameRate,
2532         PictureWidth,
2533         PictureHeigth);
2534 
2535     mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2536 }
2537 
pnw__H263_prepare_GOBslice_header(unsigned char * pHeaderMem,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)2538 void pnw__H263_prepare_GOBslice_header(
2539     unsigned char *pHeaderMem,
2540     IMG_UINT8 GOBNumber,
2541     IMG_UINT8 GOBFrameId)
2542 {
2543     MTX_HEADER_PARAMS *mtx_hdr;
2544 
2545     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2546 
2547     /* Essential we initialise our header structures before building */
2548     MTX_HEADER_ELEMENT *This_Element;
2549     MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2550     mtx_hdr->Elements = ELEMENTS_EMPTY;
2551     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2552     elt_p[0] = This_Element;
2553 
2554     H263_writebits_GOBSliceHeader(mtx_hdr, elt_p, GOBNumber, GOBFrameId);
2555 
2556     mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
2557 
2558     /*
2559     (void)pnw__H264_writebits_SEI_rbspheader;
2560     (void)pnw__H264_getelements_skip_B_slice;
2561     (void)pnw__H264_getelements_backward_zero_B_slice;
2562     (void)pnw__H264_getelements_rbsp_ATE_only;
2563     (void)pnw_MPEG4_getelements_video_packet_header;
2564     */
2565 }
2566 
2567