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  *    Edward Lin <edward.lin@intel.com>
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 "tng_hostheader.h"
38 #ifdef _TOPAZHP_PDUMP_
39 #include "tng_trace.h"
40 #endif
41 /* Global stores the latest QP information for the DoHeader()
42  * routine, should be filled in by the rate control algorithm.
43  */
44 #define HEADERS_VERBOSE_OUTPUT 0
45 
46 /* #define USESTATICWHEREPOSSIBLE 1 */
47 
48 #define MAXNUMBERELEMENTS 16
49 
50 /* SOME USEFUL TEST FUNCTIONS */
51 #ifndef TOPAZ_MTX_HW
Show_Bits(IMG_UINT8 __maybe_unused * ucBitStream,IMG_UINT32 __maybe_unused ByteStartBit,IMG_UINT32 __maybe_unused Bits)52 static void Show_Bits(
53     IMG_UINT8 __maybe_unused * ucBitStream,
54     IMG_UINT32 __maybe_unused ByteStartBit,
55     IMG_UINT32 __maybe_unused Bits)
56 {
57     return ;
58 #if 0
59     char Txt[1024];
60     IMG_UINT32 uiByteSize;
61     IMG_UINT32 uiLp, uiBt, Bcnt;
62     Bcnt = 0;
63     uiByteSize = (Bits + ByteStartBit + 7) >> 3;
64     for (uiLp = 0; uiLp < uiByteSize; uiLp++) {
65         snprintf(Txt, strlen(" "), " ");
66         for (uiBt = 128; uiBt >= 1; uiBt = uiBt >> 1) {
67             Bcnt++;
68             if (Bcnt > Bits + ByteStartBit || Bcnt <= ByteStartBit)
69                 snprintf(Txt, sizeof(Txt), "%sX", Txt);
70             else
71                 snprintf(Txt, sizeof(Txt), "%s%i", Txt, (ucBitStream[uiLp] & uiBt) > 0);
72         }
73 
74         snprintf(Txt, sizeof(Txt), "%s ", Txt);
75         //printf(Txt);
76         if ((uiLp + 1) % 8 == 0) printf("\n");
77     }
78 
79     printf("\n\n");
80 #endif
81 }
82 #endif
83 
84 #ifndef TOPAZ_MTX_HW
85 
Show_Elements(MTX_HEADER_PARAMS __maybe_unused * mtx_hdr,MTX_HEADER_ELEMENT __maybe_unused ** aui32ElementPointers)86 static void Show_Elements(
87     MTX_HEADER_PARAMS __maybe_unused * mtx_hdr,
88     MTX_HEADER_ELEMENT __maybe_unused ** aui32ElementPointers)
89 {
90     return ;
91 #if 0
92     IMG_UINT8 f;
93     IMG_UINT32 TotalByteSize;
94     IMG_UINT32 RTotalByteSize;
95 
96     RTotalByteSize = TotalByteSize = 0;
97     for (f = 0; f < mtx_hdr->ui32Elements; f++) {
98 #if HEADERS_VERBOSE_OUTPUT
99         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Encoding Element [%i] - Type:%i\n", f, aui32ElementPointers[f]->Element_Type);
100 #endif
101         if (aui32ElementPointers[f]->Element_Type == ELEMENT_STARTCODE_RAWDATA ||
102             aui32ElementPointers[f]->Element_Type == ELEMENT_RAWDATA) {
103             TotalByteSize = aui32ElementPointers[f]->ui8Size;
104 #if HEADERS_VERBOSE_OUTPUT
105             drv_debug_msg(VIDEO_DEBUG_GENERAL, "Writing %i RAW bits to element.\n", aui32ElementPointers[f]->ui8Size);
106             Show_Bits((IMG_UINT8 *)(&aui32ElementPointers[f]->ui8Size) + 1, 0, TotalByteSize);
107 #endif
108             TotalByteSize += 8;
109 
110             RTotalByteSize += (((IMG_UINT32)((TotalByteSize + 7) / 8)) * 8);
111             RTotalByteSize += 32;
112         } else {
113             TotalByteSize = 0;
114             switch (aui32ElementPointers[f]->Element_Type) {
115             case ELEMENT_QP:
116 #if HEADERS_VERBOSE_OUTPUT
117                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_QP (H264)- for MTX to generate and insert this value\n");
118 #endif
119                 break;
120             case ELEMENT_SQP:
121 #if HEADERS_VERBOSE_OUTPUT
122                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SQP (H264)- for MTX to generate and insert this value\n");
123 #endif
124                 break;
125             case ELEMENT_FRAMEQSCALE:
126 #if HEADERS_VERBOSE_OUTPUT
127                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_FRAMEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
128 #endif
129                 break;
130             case ELEMENT_SLICEQSCALE:
131 #if HEADERS_VERBOSE_OUTPUT
132                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SLICEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
133 #endif
134                 break;
135             case ELEMENT_INSERTBYTEALIGN_H264:
136 #if HEADERS_VERBOSE_OUTPUT
137                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_H264 -  MTX to generate 'rbsp_trailing_bits()' field\n");
138 #endif
139                 break;
140             case ELEMENT_INSERTBYTEALIGN_MPG4:
141 #if HEADERS_VERBOSE_OUTPUT
142                 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_MPG4 -  MTX to generate MPEG4 'byte_aligned_bits' field\n");
143 #endif
144                 break;
145             default:
146                 break;
147             }
148 
149             RTotalByteSize += 32;
150 #if HEADERS_VERBOSE_OUTPUT
151             drv_debug_msg(VIDEO_DEBUG_GENERAL, "No RAW bits\n\n");
152 #endif
153         }
154     }
155 
156     /* TotalByteSize=TotalByteSize+32+(&aui32ElementPointers[f-1]->Element_Type-&aui32ElementPointers[0]->Element_Type)*8; */
157 
158 #if HEADERS_VERBOSE_OUTPUT
159     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nCombined ELEMENTS Stream:\n");
160     Show_Bits((IMG_UINT8 *) mtx_hdr->asElementStream, 0, RTotalByteSize);
161 #endif
162 #endif //0
163 }
164 #endif
165 
tng_print(unsigned char * ptmp,int num)166 static void tng_print(unsigned char *ptmp, int num)
167 {
168     int tmp;
169     do {
170       for(tmp=0;tmp < num;tmp++) {
171         if(tmp%8==0)
172             drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\t\t");
173        drv_debug_msg(VIDEO_DEBUG_GENERAL, "\t0x%02x", ptmp[tmp]);
174      }
175      drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\t\t}\n");
176     } while (0);
177 }
178 
179 /**
180  * Header Writing Functions
181  * Low level bit writing and ue, se functions
182  * HOST CODE
183  */
tng__write_upto8bits_elements(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 ui8WriteBits,IMG_UINT16 ui16BitCnt)184 static void tng__write_upto8bits_elements(
185     MTX_HEADER_PARAMS *pMTX_Header,
186     MTX_HEADER_ELEMENT **aui32ElementPointers,
187     IMG_UINT8 ui8WriteBits,
188     IMG_UINT16 ui16BitCnt)
189 {
190     // This is the core function to write bits/bytes to a header stream, it writes them directly to ELEMENT structures.
191     IMG_UINT8 *pui8WriteBytes;
192     IMG_UINT8 *pui8SizeBits;
193     union {
194         IMG_UINT32 UI16Input;
195         IMG_UINT8 UI8Input[2];
196     } InputVal;
197     IMG_UINT8 ui8OutByteIndex;
198     IMG_INT16 i16Shift;
199     if (ui16BitCnt==0)
200         return ;
201 
202 //    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: mtx_hdr->ui32Elments overflow (%d)\n", __FUNCTION__, pMTX_Header->ui32Elements);
203     /* WA for klockwork */
204 
205 //    if (pMTX_Header->ui32Elements >= MAXNUMBERELEMENTS) {
206 //        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: mtx_hdr->ui32Elments overflow (%d)\n", __FUNCTION__, pMTX_Header->ui32Elements);
207 //        return;
208 //    }
209     // First ensure that unused bits  in ui8WriteBits are zeroed
210     ui8WriteBits &= (0x00ff >> (8 - ui16BitCnt));
211     InputVal.UI16Input=0;
212     pui8SizeBits=&(aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size); //Pointer to the bit count field
213     pui8WriteBytes=&(aui32ElementPointers[pMTX_Header->ui32Elements]->aui8Bits); //Pointer to the space where header bits are to be written
214     ui8OutByteIndex=(pui8SizeBits[0] / 8);
215     if (!(pui8SizeBits[0]&7)) {
216         if (pui8SizeBits[0]>=120) {
217             //Element maximum bits send to element, time to start a new one
218             pMTX_Header->ui32Elements++; // Increment element index
219             aui32ElementPointers[pMTX_Header->ui32Elements]=(MTX_HEADER_ELEMENT *) &pui8WriteBytes[15]; //Element pointer set to position of next element (120/8 = 15 bytes)
220             aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type=ELEMENT_RAWDATA; //Write ELEMENT_TYPE
221             aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size=0; // Set new element size (bits) to zero
222             tng__write_upto8bits_elements(pMTX_Header,aui32ElementPointers, ui8WriteBits, ui16BitCnt); // Begin writing to the new element
223         return ;//(IMG_UINT32) ui16BitCnt;
224         }
225         pui8WriteBytes[ui8OutByteIndex]=0; // Beginning a new byte, clear byte
226     }
227     i16Shift=(IMG_INT16) ((8-ui16BitCnt)-(pui8SizeBits[0]&7));
228     if (i16Shift>=0) {
229         ui8WriteBits <<= i16Shift;
230         pui8WriteBytes[ui8OutByteIndex]|=ui8WriteBits;
231         pui8SizeBits[0]=pui8SizeBits[0]+ui16BitCnt;
232     } else {
233         InputVal.UI8Input[1]=(IMG_UINT8) ui8WriteBits+256;
234         InputVal.UI16Input >>= -i16Shift;
235         pui8WriteBytes[ui8OutByteIndex]|=InputVal.UI8Input[1];
236 
237         pui8SizeBits[0]=pui8SizeBits[0]+ui16BitCnt;
238         pui8SizeBits[0]=pui8SizeBits[0]-((IMG_UINT8) -i16Shift);
239         InputVal.UI8Input[0]=InputVal.UI8Input[0] >> (8+i16Shift);
240         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, InputVal.UI8Input[0],(IMG_UINT16) -i16Shift);
241     }
242     return ;//(IMG_UINT32) ui16BitCnt;
243 }
244 
tng__write_upto32bits_elements(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT32 ui32WriteBits,IMG_UINT32 ui32BitCnt)245 static void tng__write_upto32bits_elements(
246     MTX_HEADER_PARAMS *pMTX_Header,
247     MTX_HEADER_ELEMENT **aui32ElementPointers,
248     IMG_UINT32 ui32WriteBits,
249     IMG_UINT32 ui32BitCnt)
250 {
251     IMG_UINT32 ui32BitLp;
252     IMG_UINT32 ui32EndByte;
253     IMG_UINT8 ui8Bytes[4];
254     drv_debug_msg(VIDEO_DEBUG_GENERAL, "WBS(32) bits %x, cnt = %d\n", ui32WriteBits, ui32BitCnt);
255     for (ui32BitLp=0; ui32BitLp<4; ui32BitLp++) {
256         ui8Bytes[ui32BitLp]=(IMG_UINT8) (ui32WriteBits & 255);
257         ui32WriteBits = ui32WriteBits >> 8;
258     }
259 
260     ui32EndByte=((ui32BitCnt+7)/8);
261     if ((ui32BitCnt)%8)
262         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32EndByte-1], (IMG_UINT8) ((ui32BitCnt)%8));
263     else
264         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32EndByte-1], 8);
265     if (ui32EndByte>1)
266         for (ui32BitLp=ui32EndByte-1; ui32BitLp>0; ui32BitLp--) {
267             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32BitLp-1], 8);
268         }
269     return ;//ui32BitCnt;
270 }
271 
tng__generate_ue(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT32 uiVal)272 static void tng__generate_ue(
273     MTX_HEADER_PARAMS *pMTX_Header,
274     MTX_HEADER_ELEMENT **aui32ElementPointers,
275     IMG_UINT32 uiVal)
276 {
277     IMG_UINT32 uiLp;
278     IMG_UINT8 ucZeros;
279     IMG_UINT32 uiChunk;
280 
281     for (uiLp=1, ucZeros=0;  (uiLp-1) < uiVal ; uiLp=uiLp+uiLp, ucZeros++)
282         uiVal=uiVal-uiLp;
283     // ucZeros = number of preceding zeros required
284     // uiVal = value to append after zeros and 1 bit
285     //** Write preceding zeros
286     for (uiLp=(IMG_UINT32) ucZeros; uiLp+1>8; uiLp-=8)
287         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
288     //** Write zeros and 1 bit set
289     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) 1, (IMG_UINT8) (uiLp+1));
290     //** Write Numeric part
291     while (ucZeros>8) {
292         ucZeros-=8;
293         uiChunk=(uiVal >> ucZeros);
294         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) uiChunk, 8);
295         uiVal=uiVal-(uiChunk << ucZeros);
296     }
297     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) uiVal, ucZeros);
298 
299     return ;//ui32BitCnter;
300 }
301 
tng__generate_se(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,int iVal)302 static void tng__generate_se(
303     MTX_HEADER_PARAMS *pMTX_Header,
304     MTX_HEADER_ELEMENT **aui32ElementPointers,
305     int iVal)
306 {
307     IMG_UINT32 uiCodeNum;
308 
309     if (iVal > 0)
310         uiCodeNum=(IMG_UINT32) (iVal+iVal-1);
311     else
312         uiCodeNum=(IMG_UINT32) (-iVal-iVal);
313     tng__generate_ue(pMTX_Header, aui32ElementPointers, uiCodeNum);
314     return ;//ui32BitCnter;
315 }
316 
317 
tng__insert_element_token(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,HEADER_ELEMENT_TYPE ui32Token)318 static void tng__insert_element_token(
319     MTX_HEADER_PARAMS *pMTX_Header,
320     MTX_HEADER_ELEMENT **aui32ElementPointers,
321     HEADER_ELEMENT_TYPE ui32Token)
322 {
323     IMG_UINT8 ui8Offset = 0;
324     IMG_UINT8 *ui8P = NULL;
325 
326     /* WA for klockwork */
327     if ((pMTX_Header->ui32Elements != ELEMENTS_EMPTY) &&
328         (pMTX_Header->ui32Elements >= MAXNUMBERELEMENTS)) {
329         drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: mtx_hdr->ui32Elments overflow\n", __FUNCTION__);
330         return;
331     }
332 
333 
334     if (pMTX_Header->ui32Elements!=ELEMENTS_EMPTY) {
335         if (aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_STARTCODE_RAWDATA ||
336             aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_RAWDATA ||
337             aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_STARTCODE_MIDHDR) {
338             //Add a new element aligned to word boundary
339             //Find RAWBit size in bytes (rounded to word boundary))
340             ui8Offset=aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size+8+31; // NumberofRawbits (excluding size of bit count field)+ size of the bitcount field
341             ui8Offset/=32; //Now contains rawbits size in words
342             ui8Offset+=1; //Now contains rawbits+element_type size in words
343             ui8Offset*=4; //Convert to number of bytes (total size of structure in bytes, aligned to word boundary).
344         } else {
345             ui8Offset=4;
346         }
347         pMTX_Header->ui32Elements++;
348         ui8P=(IMG_UINT8 *) aui32ElementPointers[pMTX_Header->ui32Elements-1];
349         ui8P+=ui8Offset;
350         aui32ElementPointers[pMTX_Header->ui32Elements]=(MTX_HEADER_ELEMENT *) ui8P;
351     }
352     else
353         pMTX_Header->ui32Elements=0;
354 
355     aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type=ui32Token;
356     aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size=0;
357 }
358 
359 /*
360  * Intermediary functions to build H264 headers
361  */
tng__H264_writebits_startcode_prefix_element(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT32 ui32ByteSize)362 static void tng__H264_writebits_startcode_prefix_element(
363     MTX_HEADER_PARAMS *pMTX_Header,
364     MTX_HEADER_ELEMENT **aui32ElementPointers,
365     IMG_UINT32 ui32ByteSize)
366 {
367     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
368     IMG_UINT32 ui32Lp;
369     // Byte aligned (bit 0)
370     //(3 bytes in slice header when slice is first in a picture without sequence/picture_header before picture
371 
372     for (ui32Lp=0;ui32Lp<ui32ByteSize-1;ui32Lp++)
373         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
374     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
375     // Byte aligned (bit 32 or 24)
376     return;
377 }
378 
379 // helper function to start new raw data block
380 static IMG_BOOL bStartNextRawDataElement = IMG_FALSE;
CheckStartRawDataElement(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers)381 static void CheckStartRawDataElement(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers)
382 {
383     if(bStartNextRawDataElement)
384     {
385         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
386         bStartNextRawDataElement = IMG_FALSE;
387     }
388 }
389 
390 
tng__insert_prefix_nal_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL __maybe_unused bCabacEnabled)391 static void tng__insert_prefix_nal_header(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
392         H264_SLICE_HEADER_PARAMS *pSlHParams, IMG_BOOL __maybe_unused bCabacEnabled)
393 {
394     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
395 
396     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
397     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
398 
399     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,        0, 1);   // forbidden_zero_bit
400 
401     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
402     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
403 
404     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 14, 5);    // nal unit type
405 
406     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // SVC extension flag
407 
408     // nal_unit_header_mvc_extension()
409     {
410         if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
411             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
412         } else {
413             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // non_idr_flag flag
414         }
415 
416         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 6);   // priority_id flag
417         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,    0, 10);   // view_id flag
418 
419         //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 3);   // temporal_id flag
420         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_ID); // temporal_id flag
421 
422         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ANCHOR_PIC_FLAG); // anchor_pic_flag
423 
424         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
425 
426         if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
427             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // interview flag
428         } else {
429             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // interview flag
430         }
431 
432         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // reserved one bit
433     }
434 
435 }
436 
tng__H264_writebits_VUI_params(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_VUI_PARAMS * VUIParams)437 static void tng__H264_writebits_VUI_params(
438     MTX_HEADER_PARAMS *pMTX_Header,
439     MTX_HEADER_ELEMENT **aui32ElementPointers,
440     H264_VUI_PARAMS *VUIParams)
441 {
442 	// Builds VUI Params for the Sequence Header (only present in the 1st sequence of stream)
443 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
444 	(0 << 4) |	// aspect_ratio_info_present_flag = 0 in Topaz
445 	(0 << 3) |	// overscan_info_present_flag (1 bit) = 0 in Topaz
446 	(0 << 2) |	// video_signal_type_present_flag (1 bit) = 0 in Topaz
447 	(0 << 1) |	// chroma_loc_info_present_flag (1 bit) = 0 in Topaz
448 	(1),												// timing_info_present_flag (1 bit) = 1 in Topaz
449 	5);
450 	// num_units_in_tick (32 bits) = 1 in Topaz
451         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->num_units_in_tick, 32);
452 
453 	// time_scale (32 bits) = frame rate
454 	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->Time_Scale, 32);
455 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// fixed_frame_rate_flag (1 bit) = 1 in Topaz
456 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// nal_hrd_parameters_present_flag (1 bit) = 1 in Topaz
457 	//** Definitions for nal_hrd_parameters() contained in VUI structure for Topaz
458 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// cpb_cnt_minus1 ue(v) = 0 in Topaz = 1b
459 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 4);	// bit_rate_scale (4 bits) = 0 in Topaz
460 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 2, 4);	// cpb_size_scale (4 bits) = 2 in Topaz
461 
462 	tng__generate_ue(pMTX_Header, aui32ElementPointers, VUIParams->bit_rate_value_minus1); // bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2]
463 	tng__generate_ue(pMTX_Header, aui32ElementPointers, VUIParams->cbp_size_value_minus1); // cpb_size_value_minus1[0] ue(v) = (CPB_Bits_Size/16)-1   where CPB_Bits_Size = 1.5 * Bitrate  [RANGE:0 to (2^32)-2]
464 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->CBR,1);// cbr_flag[0] (1 bit) = 0 for VBR, 1 for CBR
465 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->initial_cpb_removal_delay_length_minus1, 5); // initial_cpb_removal_delay_length_minus1 (5 bits) = ???
466 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->cpb_removal_delay_length_minus1, 5); // cpb_removal_delay_length_minus1 (5 bits) = ???
467 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->dpb_output_delay_length_minus1, 5); // dpb_output_delay_length_minus1 (5 bits) = ???
468 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->time_offset_length, 5); // time_offst_length (5 bits) = ???
469 	///** End of nal_hrd_parameters()
470 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// vcl_hrd_parameters_present_flag (1 bit) = 0 in Topaz
471 	//if( nal_hrd_parameters_present_flag  ||  vcl_hrd_parameters_present_flag )
472 	//FIX for BRN23039
473 	//	low_delay_hrd_flag
474 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// low_delay_hrd_flag
475 
476 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// pic_struct_present_flag (1 bit) = 0 in Topaz
477 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// bitstream_restriction_flag (1 bit) = 0 in Topaz
478 }
479 
480 
tng__H264ES_writebits_picture_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_PICTURE_HEADER_PARAMS * pPHParams,H264_SCALING_MATRIX_PARAMS __maybe_unused * psScalingMatrix)481 static void tng__H264ES_writebits_picture_header(
482     MTX_HEADER_PARAMS *pMTX_Header,
483     MTX_HEADER_ELEMENT **aui32ElementPointers,
484     H264_PICTURE_HEADER_PARAMS *pPHParams,
485     H264_SCALING_MATRIX_PARAMS __maybe_unused * psScalingMatrix)
486 {
487 #ifdef _TOPAZHP_TRACE_
488     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pic_parameter_set_id = %d\n",__FUNCTION__, pPHParams->pic_parameter_set_id);
489     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: seq_parameter_set_id = %d\n",__FUNCTION__, pPHParams->seq_parameter_set_id);
490     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: entropy_coding_mode_flag = %d\n",__FUNCTION__, pPHParams->entropy_coding_mode_flag);
491     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: weighted_pred_flag = %d\n",__FUNCTION__, pPHParams->weighted_pred_flag);
492     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: weighted_bipred_idc = %d\n",__FUNCTION__, pPHParams->weighted_bipred_idc);
493     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: chroma_qp_index_offset = %d\n",__FUNCTION__, pPHParams->chroma_qp_index_offset);
494     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: constrained_intra_pred_flag = %d\n",__FUNCTION__, pPHParams->constrained_intra_pred_flag);
495     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: transform_8x8_mode_flag = %d\n",__FUNCTION__, pPHParams->transform_8x8_mode_flag);
496     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pic_scaling_matrix_present_flag = %d\n",__FUNCTION__, pPHParams->pic_scaling_matrix_present_flag);
497     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: bUseDefaultScalingList = %d\n",__FUNCTION__, pPHParams->bUseDefaultScalingList);
498     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: second_chroma_qp_index_offset = %d\n",__FUNCTION__, pPHParams->second_chroma_qp_index_offset);
499 #endif
500     //**-- Begin building the picture header element
501     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
502     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
503 
504     ///* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE *///
505     ///**** ELEMENT BITCOUNT: 18
506 
507     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
508     // Byte aligned (bit 32)
509     tng__write_upto8bits_elements(pMTX_Header,
510                                   aui32ElementPointers,
511                                   (0 << 7) |    // forbidden_zero_bit
512                                   (3 << 5) |    // nal_ref_idc (2 bits) = 0x3
513                                   (8),  // nal_unit_tpye (5 bits) = 8
514                                   8);
515    // Byte aligned (bit 40)
516     tng__generate_ue(pMTX_Header, aui32ElementPointers, pPHParams->pic_parameter_set_id);  // pic_parameter_set_id ue(v)
517     tng__generate_ue(pMTX_Header, aui32ElementPointers, pPHParams->seq_parameter_set_id);  // seq_parameter_set_id ue(v)
518     tng__write_upto8bits_elements(pMTX_Header,
519                                   aui32ElementPointers,
520                                   (pPHParams->entropy_coding_mode_flag << 4) |    // entropy_coding_mode_flag (1 bit) 0 for CAVLC
521                                   (0 << 3) |                                                                      // pic_order_present_flag (1 bit) = 0
522                                   (1 << 2) |                                                                      // num_slice_group_minus1 ue(v) = 0 in Topaz
523                                   (1 << 1) |                                                                      // num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz
524                                   (1),                                                                                    // num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz
525                                   5);
526     // WEIGHTED PREDICTION
527     tng__write_upto8bits_elements(pMTX_Header,
528         aui32ElementPointers,
529         (pPHParams->weighted_pred_flag << 2) |  // weighted_pred_flag (1 bit)
530         (pPHParams->weighted_bipred_idc),           // weighted_bipred_flag (2 bits)
531         3);
532 
533     //MTX fills this value in
534     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_QP);
535     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
536 
537     ///**** GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE ****///
538     ///**** ELEMENT BITCOUNT: 5
539     //The following field will be generated as a special case by MTX - so not here
540     // tng__generate_se(pMTX_Header, pPHParams->pic_init_qp_minus26); // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz
541     // pic_int_qs_minus26 se(v) = 0 in Topaz
542     tng__generate_se(pMTX_Header, aui32ElementPointers, 0);
543 
544     // chroma_qp_index_offset se(v) = 0 in Topaz
545     tng__generate_se(pMTX_Header, aui32ElementPointers, pPHParams->chroma_qp_index_offset);
546 
547     // deblocking_filter_control_present_flag (1 bit) = 1 in Topaz
548     // constrained_intra_pred_Flag (1 bit) = 0 in Topaz
549     // redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz
550     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (1 << 2) |
551                                   (pPHParams->constrained_intra_pred_flag << 1) |
552                                   (0),
553                                   3);
554 
555     if (pPHParams->transform_8x8_mode_flag ||
556         (pPHParams->second_chroma_qp_index_offset != pPHParams->chroma_qp_index_offset) ||
557         pPHParams->pic_scaling_matrix_present_flag) {
558         // 8x8 transform flag
559         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pPHParams->transform_8x8_mode_flag, 1);
560         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
561         // second_chroma_qp_index_offset se(v) = 0 in Topaz
562         tng__generate_se(pMTX_Header, aui32ElementPointers, pPHParams->second_chroma_qp_index_offset);
563     }
564 
565     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
566     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n",__FUNCTION__);
567 
568     return;
569 }
570 
tng__H264ES_writebits_scalinglists(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SCALING_MATRIX_PARAMS * psScalingMatrix,IMG_BOOL bWrite8x8)571 static void tng__H264ES_writebits_scalinglists(
572     MTX_HEADER_PARAMS *pMTX_Header,
573     MTX_HEADER_ELEMENT **aui32ElementPointers,
574     H264_SCALING_MATRIX_PARAMS * psScalingMatrix,
575     IMG_BOOL bWrite8x8)
576 {
577 	// Used by H264_WriteBits_SequenceHeader and H264_WriteBits_PictureHeader
578 	IMG_UINT32	ui32List, ui32Index;
579 	IMG_INT32	i32CurScale, i32DeltaScale;
580 
581 	if (!psScalingMatrix)
582 	{
583 		tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CUSTOM_QUANT);
584 		return;
585 	}
586 
587 	for (ui32List = 0; ui32List < 6; ui32List++)
588 	{
589 		if (psScalingMatrix->ui32ListMask & (1 << ui32List))
590 		{
591 			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_list_present_flag[ui32List] = 1
592 
593 			i32CurScale = 8;
594 			for (ui32Index = 0; ui32Index < 16; ui32Index++)
595 			{
596 				i32DeltaScale = ((IMG_INT32)psScalingMatrix->ui8ScalingLists4x4[ui32List][ui32Index]) - i32CurScale;
597 				i32CurScale += i32DeltaScale;
598 				tng__generate_se(pMTX_Header, aui32ElementPointers, i32DeltaScale); 	// delta_scale
599 			}
600 		}
601 		else
602 		{
603 			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); 	// seq_scaling_list_present_flag[ui32List] = 0
604 		}
605 	}
606 
607 	if (!bWrite8x8) return;
608 
609 	for (; ui32List < 8; ui32List++)
610 	{
611 		if (psScalingMatrix->ui32ListMask & (1 << ui32List))
612 		{
613 			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_list_present_flag[ui32List] = 1
614 
615 			i32CurScale = 8;
616 			for (ui32Index = 0; ui32Index < 64; ui32Index++)
617 			{
618 				i32DeltaScale = ((IMG_INT32)psScalingMatrix->ui8ScalingLists8x8[ui32List - 6][ui32Index]) - i32CurScale;
619 				i32CurScale += i32DeltaScale;
620 				tng__generate_se(pMTX_Header, aui32ElementPointers, i32DeltaScale);		// delta_scale
621 			}
622 		}
623 		else
624 		{
625 			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); 	// seq_scaling_list_present_flag[ui32List] = 0
626 		}
627 	}
628 
629 }
630 
tng__H264ES_writebits_sequence_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCrop,H264_SCALING_MATRIX_PARAMS * psScalingMatrix,IMG_BOOL8 __maybe_unused bASO)631 static void tng__H264ES_writebits_sequence_header(
632     MTX_HEADER_PARAMS *pMTX_Header,
633     MTX_HEADER_ELEMENT **aui32ElementPointers,
634     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
635     H264_CROP_PARAMS *psCrop,
636     H264_SCALING_MATRIX_PARAMS * psScalingMatrix,
637     IMG_BOOL8 __maybe_unused bASO)
638 {
639     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
640     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
641 
642 
643     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
644     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
645     // Byte aligned (bit 32)
646     tng__write_upto8bits_elements(pMTX_Header,
647         aui32ElementPointers,(0 << 7) | // forbidden_zero_bit=0
648 	(0x3 << 5) | // nal_ref_idc=0x3
649 	(7), // nal_unit_type=00111
650         8);
651     // Byte aligned (bit 40)
652     switch (pSHParams->ucProfile) {
653         case SH_PROFILE_BP:
654 	    // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP)
655             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 66, 8);
656 
657             // Byte	aligned	(bit 48)
658             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
659                 (1 << 7) |    // constraint_set0_flag = 1 for BP constraints
660                 (0 << 6) |    // constraint_set1_flag = 0 for MP constraints
661                 (0 << 5) |    // constraint_set2_flag = 0 for EP constraints
662                 ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4),  // constraint_set3_flag = 1 for level 1b, 0 for others
663                 // reserved_zero_4bits = 0
664                 8);
665             break;
666         case SH_PROFILE_MP:
667             // profile_idc = 8 bits = 77 for MP (PROFILE_IDC_MP)
668             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 77, 8);
669 
670             // Byte aligned (bit 48)
671             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
672                 (0 << 7) | // constraint_set0_flag = 0 for no BP constraints
673                 (1 << 6) | // constraint_set1_flag = 1 for MP constraints
674                 (0 << 5) | // constraint_set2_flag = 0 for EP constraints
675                 ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4),    // constraint_set3_flag = 1 for level 1b, 0 for others
676                 // reserved_zero_4bits = 0
677                 8);
678             break;
679         case SH_PROFILE_HP:
680             // profile_idc = 8 bits = 100 for HP (PROFILE_IDC_HP)
681             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 100, 8);
682             // Byte aligned (bit 48)
683             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
684                 (0 << 7) | // constraint_set0_flag = 0 for no BP constraints
685                 (0 << 6) | // constraint_set1_flag = 0 for no MP constraints
686                 (0 << 5) | // constraint_set2_flag = 0 for no EP constraints
687                 (0 << 4),  // constraint_set3_flag = 0
688                 // reserved_zero_4bits = 0
689                 8);
690             break;
691         case SH_PROFILE_H444P:
692             // profile_idc = 8 bits = 244 for H444P (PROFILE_IDC_H444P)
693             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 244, 8);
694 
695             // Byte aligned (bit 48)
696             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
697                 (0 << 7) |      // constraint_set0_flag = 0 for no BP constraints
698                 (0 << 6) |      // constraint_set1_flag = 0 for no MP constraints
699                 (0 << 5) |      // constraint_set2_flag = 0 for no EP constraints
700                 (0 << 4),	        // constraint_set3_flag = 0
701                 // reserved_zero_4bits = 0
702                 8);
703             break;
704 	}
705 
706 
707     // Byte aligned (bit 56)
708     // level_idc (8 bits) = 11 for 1b, 10xlevel for others
709     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);
710     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);		// seq_parameter_set_id = 0
711 
712     if ((pSHParams->ucProfile == SH_PROFILE_HP) || (pSHParams->ucProfile == SH_PROFILE_H444P)) {
713         tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);    // chroma_format_idc = 1
714         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);    // bit_depth_luma_minus8 = 0
715         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);    // bit_depth_chroma_minus8 = 0
716         // qpprime_y_zero_transform_bypass_flag = 1 if lossless
717         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->bIsLossless?1:0, 1);
718         if (pSHParams->bUseDefaultScalingList || pSHParams->seq_scaling_matrix_present_flag) {
719             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_matrix_present_flag
720             if (!pSHParams->bUseDefaultScalingList) {
721                 tng__H264ES_writebits_scalinglists(pMTX_Header, aui32ElementPointers, psScalingMatrix, IMG_TRUE);
722                 tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
723             } else {
724                 // seq_scaling_list_present_flag[i] = 0; 0 < i < 8
725                 tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
726             }
727         } else {
728             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);  // seq_scaling_matrix_present_flag
729         }
730     }
731 
732     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);  // log2_max_frame_num_minus4 = 1
733     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);  // pic_order_cnt_type = 0
734     // log2_max_pic_order_cnt_Isb_minus4 = 2
735     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->log2_max_pic_order_cnt - 4);
736     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames); //num_ref_frames ue(2), typically 2
737     // Bytes aligned (bit 72)
738     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
739         (pSHParams->gaps_in_frame_num_value), // gaps_in_frame_num_value_allowed_Flag	- (1 bit)
740         1);
741     ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
742     ///**** ELEMENT BITCOUNT: xx
743     //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
744     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1);
745     //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column)
746     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1);
747     // We don't know the alignment at this point, so will have to use bit writing functions
748     // frame_mb_only_flag 1=frame encoding, 0=field encoding
749     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,pSHParams->ucFrame_mbs_only_flag,1);
750     if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
751         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1); // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
752 
753     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1); // direct_8x8_inference_flag=1 in Topaz
754     if (psCrop->bClip) {
755         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1);
756         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16LeftCropOffset);
757 	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16RightCropOffset);
758 	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16TopCropOffset);
759 	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16BottomCropOffset);
760     } else {
761         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1);
762     }
763 
764     ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
765     ///**** ELEMENT BITCOUNT: xx
766     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
767         (pSHParams->VUI_Params_Present), // vui_parameters_present_flag (VUI only in 1st sequence of stream)
768         1);
769 
770     if (pSHParams->VUI_Params_Present > 0)
771         tng__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
772 
773 
774     // Finally we need to align to the next byte
775     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
776     // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
777 
778     //tng_print(pMTX_Header, 64);
779     return;
780 }
781 
782 
tng__H264ES_writebits_slice_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled)783 static void tng__H264ES_writebits_slice_header(
784     MTX_HEADER_PARAMS *pMTX_Header,
785     MTX_HEADER_ELEMENT **aui32ElementPointers,
786     H264_SLICE_HEADER_PARAMS *pSlHParams,
787     IMG_BOOL bCabacEnabled
788 )
789 {
790     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
791     //Can be 3 or 4 bytes - always 4 bytes in our implementations
792     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes);
793 
794     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
795     ///**** ELEMENT BITCOUNT: 8
796 
797     // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
798     //(3 bytes when slice is first in a picture without sequence/picture_header before picture
799     // Byte aligned (bit 32 or 24)
800     // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
801     tng__write_upto8bits_elements(pMTX_Header,
802                                   aui32ElementPointers, (0 << 7) |                // forbidden_zero_bit
803                                   ((pSlHParams->bReferencePicture) << 5) |        // nal_ref_idc (2 bits)
804                                   ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),    // nal_unit_tpye (5 bits) = I-frame IDR, and 1 for  rest
805                                   8);
806 
807     //MTX fills this value in
808     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR);
809     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
810 
811     ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
812     /* The following is slice parameter set in BP/MP */
813     //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
814     tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
815     // kab: //not clean change from IDR to intra, IDR should have separate flag
816     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
817                                   (1 << 5) |                                                                                                                                             //pic_parameter_set_id, ue(v) = 0  (=1b) in Topaz
818                                   pSlHParams->Frame_Num_DO,                                                                                                               //frame_num (5 bits) = frame nuo. in decoding order
819                                   6);
820 
821     // interlaced encoding
822     if (pSlHParams->bPiCInterlace) {
823         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
824         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->bFieldType, 1); // bottom_field_flag (0=top field, 1=bottom field)
825     }
826 
827     if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
828         tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Idr_Pic_Id);    // idr_pic_id ue(v)
829 
830     if (pSlHParams->bPiCInterlace)
831         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSlHParams->Picture_Num_DO + pSlHParams->bFieldType), pSlHParams->log2_max_pic_order_cnt);                    // pic_order_cnt_lsb (6 bits) - picture no in display order
832     else
833         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->Picture_Num_DO, pSlHParams->log2_max_pic_order_cnt);                       // pic_order_cnt_lsb (6 bits) - picture no in display order
834 
835 
836     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
837         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->direct_spatial_mv_pred_flag, 1);// direct_spatial_mv_pred_flag (1 bit)
838     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE || pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
839         if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE && pSlHParams->num_ref_idx_l0_active_minus1 > 0) { //Do we have more then one reference picture?
840             //Override amount of ref pics to be only 1 in L0 direction
841             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
842             tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->num_ref_idx_l0_active_minus1);
843         } else
844             // num_ref_idx_active_override_flag (1 bit) = 0 in Topaz
845             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
846     }
847     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
848         if ((pSlHParams->diff_ref_pic_num[0] || pSlHParams->bRefIsLongTermRef[0])
849             || ((pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) && (pSlHParams->num_ref_idx_l0_active_minus1 > 0))) {
850             //Specifiy first ref pic in L0
851             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //ref_pic_list_modification_flag_l0
852 
853             if (pSlHParams->bRefIsLongTermRef[0]) {
854                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
855                 tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[0]); // long_term_pic_num
856             } else if (pSlHParams->diff_ref_pic_num[0] == 0) {
857                 // Can't use 0, so use MaxPicNum which will wrap to 0
858                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add to)
859                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 31); // abs_diff_minus_1
860             } else if (pSlHParams->diff_ref_pic_num[0] < 0) {
861                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
862                 tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[0] - 1); // abs_diff_minus_1
863             } else {
864                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
865                 tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[0] - 1); // abs_diff_minus_1
866             }
867 
868             if ((pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) && pSlHParams->SliceFrame_Type != SLHP_B_SLICEFRAME_TYPE) { //potentially second reference picture on P
869                 if (pSlHParams->bRefIsLongTermRef[1]) {
870                     tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
871                     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[1]); // long_term_pic_num
872                 } else if (pSlHParams->diff_ref_pic_num[1] < 0) {
873                     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
874                     tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
875                 } else {
876                     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
877                     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
878                 }
879             }
880 
881             tng__generate_ue(pMTX_Header, aui32ElementPointers, 3); // mod_of_pic_num = 3 (no more changes)
882         } else
883             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // ref_pic_list_ordering_flag_I0 (1 bit) = 0, no reference picture ordering in Topaz
884     }
885     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
886         if (pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) {
887             //Specifiy first ref pic in L1
888             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //ref_pic_list_modification_flag_l1
889 
890             if (pSlHParams->bRefIsLongTermRef[1]) {
891                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
892                 tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[1]); // long_term_pic_num
893             } else if (pSlHParams->diff_ref_pic_num[1] < 0) {
894                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
895                 tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
896             } else {
897                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
898                 tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
899             }
900 
901             tng__generate_ue(pMTX_Header, aui32ElementPointers, 3); // mod_of_pic_num = 3 (no more changes)
902         } else
903             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // ref_pic_list_ordering_flag_I1 (1 bit) = 0, no reference picture ordering in Topaz
904     }
905     if (pSlHParams->weighted_pred_flag &&
906         ((pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) || (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE))
907         && (pSlHParams->weighted_bipred_idc == 1)) {
908         int i;
909         tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->luma_log2_weight_denom);
910         tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->chroma_log2_weight_denom); // Always do chroma
911         for (i = 0; i < (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE ? 2 : (pSlHParams->num_ref_idx_l0_active_minus1 + 1)); i++) { // Either 1 or 2
912             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->luma_weight_l0_flag[i], 1);
913             if (pSlHParams->luma_weight_l0_flag[i]) {
914                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->luma_weight_l0[i]);
915                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->luma_offset_l0[i]);
916             }
917             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->chroma_weight_l0_flag[i], 1);
918             if (pSlHParams->chroma_weight_l0_flag[i]) {
919                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaB_weight_l0[i]);
920                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaB_offset_l0[i]);
921                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaR_weight_l0[i]);
922                 tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaR_offset_l0[i]);
923             }
924         }
925     }
926 
927     if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
928         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // no_output_of_prior_pics_flag (1 bit) = 0
929         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->bIsLongTermRef ? 1 : 0, 1);  // long_term_reference_flag (1 bit) = 0
930     } else if (pSlHParams->bReferencePicture) {
931         if (pSlHParams->bIsLongTermRef) {
932             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
933 
934             // Allow a single long-term reference
935             tng__generate_ue(pMTX_Header, aui32ElementPointers, 4);                                 // memory_management_control_operation
936             tng__generate_ue(pMTX_Header, aui32ElementPointers, 2);                                 // max_long_term_frame_idx_plus1
937 
938             // Set current picture as the long-term reference
939             tng__generate_ue(pMTX_Header, aui32ElementPointers, 6);                                 // memory_management_control_operation
940             tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uLongTermRefNum);                                       // long_term_frame_idx
941 
942             // End
943             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // memory_management_control_operation
944         } else
945             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
946     }
947 
948     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
949                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
950         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
951     }
952     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
953     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
954 
955     ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
956     ///**** ELEMENT BITCOUNT: 11
957     // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
958     //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
959     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
960     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
961         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
962         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
963     }
964     //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
965     // no byte alignment at end of slice headers
966     return ;
967 }
968 
969 
tng__H264_getelements_skip_P_slice(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT32 MB_No_In_Slice,IMG_BOOL bCabacEnabled)970 static void tng__H264_getelements_skip_P_slice(
971     MTX_HEADER_PARAMS *mtx_hdr,
972     H264_SLICE_HEADER_PARAMS *pSlHParams,
973     IMG_UINT32 MB_No_In_Slice,
974     IMG_BOOL bCabacEnabled)
975 {
976     /* Skipped P-Slice
977      * Ensure pSlHParams is filled with appropriate parameters for a B-slice
978      * Essential we initialise our header structures before building
979      */
980     MTX_HEADER_ELEMENT *This_Element;
981     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
982     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
983     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
984     aui32ElementPointers[0] = This_Element;
985 
986     /* tng__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */
987     /* Not sure if this will be required in the final spec */
988     tng__H264ES_writebits_slice_header(mtx_hdr, aui32ElementPointers, pSlHParams, bCabacEnabled);
989     tng__generate_ue(mtx_hdr, aui32ElementPointers, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */
990 
991     /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
992     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
993     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
994 }
995 
996 
997 #if 0
998 static void tng__H264_getelements_sequence_header(
999     MTX_HEADER_PARAMS *mtx_hdr,
1000     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
1001     H264_CROP_PARAMS *psCropParams)
1002 {
1003     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1004      * Essential we initialise our header structures before building
1005      */
1006     MTX_HEADER_ELEMENT *This_Element;
1007     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1008     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
1009     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1010     aui32ElementPointers[0] = This_Element;
1011 
1012     tng__H264ES_writebits_sequence_header(mtx_hdr, aui32ElementPointers, pSHParams, psCropParams, NULL);
1013     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1014 }
1015 #endif
1016 
1017 //static void tng__H264_getelements_picture_header(MTX_HEADER_PARAMS *mtx_hdr)
1018 //{
1019 ///* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1020 //* Essential we initialise our header structures before building
1021 //*/
1022 //MTX_HEADER_ELEMENT *This_Element;
1023 //MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1024 //mtx_hdr->Elements=ELEMENTS_EMPTY;
1025 //This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1026 //aui32ElementPointers[0]=This_Element;
1027 //
1028 //tng__H264ES_writebits_picture_header(mtx_hdr, aui32ElementPointers);
1029 //mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
1030 //}
1031 
1032 
tng__H264_getelements_slice_header(MTX_HEADER_PARAMS * pMTX_Header,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled)1033 static void tng__H264_getelements_slice_header(
1034     MTX_HEADER_PARAMS *pMTX_Header,
1035     H264_SLICE_HEADER_PARAMS *pSlHParams,
1036     IMG_BOOL bCabacEnabled
1037 )
1038 {
1039     /* Builds a single slice header from the given parameters (mid frame)
1040      * Essential we initialise our header structures before building
1041      */
1042     MTX_HEADER_ELEMENT *This_Element;
1043     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1044     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
1045     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1046     aui32ElementPointers[0] = This_Element;
1047 
1048     /* Not sure if this will be required in the final spec */
1049     /* tng__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/
1050     tng__H264ES_writebits_slice_header(pMTX_Header, aui32ElementPointers, pSlHParams, bCabacEnabled);
1051 
1052     pMTX_Header->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1053 }
1054 
H263_NOTFORSIMS_WriteBits_VideoPictureHeader(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 __maybe_unused ui8FrameRate,IMG_UINT32 ui32PictureWidth,IMG_UINT32 ui32PictureHeight)1055 void H263_NOTFORSIMS_WriteBits_VideoPictureHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1056 					   H263_PICTURE_CODING_TYPE PictureCodingType,
1057 					   //IMG_UINT8 ui8Q_Scale,
1058 					   H263_SOURCE_FORMAT_TYPE SourceFormatType,
1059 					   IMG_UINT8 __maybe_unused ui8FrameRate,
1060 					   IMG_UINT32 ui32PictureWidth,
1061 					   IMG_UINT32 ui32PictureHeight
1062 					   )
1063 {
1064     IMG_UINT8 UFEP;
1065 
1066     // Essential we insert the element before we try to fill it!
1067     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1068 
1069     // short_video_start_marker	= 22 Bits	= 0x20 Picture start code
1070     tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 32, 22);
1071 
1072     // temporal_reference		= 8 Bits	= 0-255	Each picture increased by 1
1073     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_REFERENCE);
1074     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1075 
1076     // marker_bit				= 1 Bit		= 1
1077     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1078 
1079     // zero_bit					= 1 Bits	= 0
1080     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1081 
1082     // split_screen_indicator	= 1	Bits	= 0	No direct effect on encoding of picture
1083     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1084 
1085     // document_camera_indicator= 1	Bits	= 0	No direct effect on encoding of picture
1086     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1087 
1088     // full_picture_freeze_release=1 Bits	= 0	No direct effect on encoding of picture
1089     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1090 
1091     // source_format				= 3	Bits	= 1-4	See note
1092     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, SourceFormatType, 3);
1093 
1094     if (SourceFormatType != 7)
1095     {
1096 	// picture_coding_type		= 1 Bit		= 0/1	0 for I-frame and 1 for P-frame
1097 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, PictureCodingType, 1);
1098 	// four_reserved_zero_bits	= 4 Bits	= 0
1099 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 4);
1100     }
1101     // the else block is for PLUSPTYPE header insertion.
1102     else
1103     {
1104 	static IMG_UINT8 RTYPE = 0;
1105 
1106         // if I- Frame set Update Full Extended PTYPE to true
1107 	if (PictureCodingType == I_FRAME)
1108 	{
1109 	    UFEP = 1;
1110 	}
1111 	else
1112 	{
1113 	    UFEP = 0;
1114 	}
1115 
1116         // write UFEP of 3 bits.
1117 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, UFEP, 3);
1118 
1119         // if UFEP was present( if it was 1).
1120         // Optional part of PPTYPE.
1121 	if (UFEP == 1)
1122 	{
1123 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 6, 3);
1124 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1125 
1126             /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1127                - Optional Unrestricted Motion Vector (UMV)
1128                - Optional Syntax-based Arithmetic Coding (SAC)
1129                - Optional Advanced Prediction (AP) mode
1130                - Optional Advanced INTRA Coding (AIC) mode
1131                - Optional Deblocking Filter (DF) mode
1132                - Optional Slice Structured (SS) mode
1133                - Optional Reference Picture Selection(RPS) mode.
1134                - Optional Independent Segment Decoding (ISD) mode
1135                - Optional Alternative INTER VLC (AIV) mode
1136                - Optional Modified Quantization (MQ) mode
1137             */
1138 	    tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 0, 10); // 10 reserve bits
1139 
1140             /* 4 reserve bits
1141                - 1 (ON) to prevent start code emulation.
1142                - 0  Reserved(shall be 0).
1143                - 0  Reserved(shall be 0).
1144                - 0  Reserved(shall be 0).
1145             */
1146 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 8, 4);	// 4 reserve bits
1147 	}
1148         // Optional Part of PPTYPE ends.
1149 
1150         // Mandatory part of PPTYPE starts.(MPPTYPE)
1151         // picture_coding_type		= 1 Bit		= 0/1	0 for I-frame and 1 for P-frame
1152 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, PictureCodingType, 3 );
1153 
1154         /*
1155             - Optional Reference Picture Resampling (RPR) mode ( OFF) : 0
1156             - Optional Reference Picture Resampling (RPR) mode (OFF) : 0
1157          */
1158 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 , 2);
1159 
1160         // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1161         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, RTYPE, 1);
1162 
1163         /* 2 reserve bits
1164            - 0  Reserved(shall be 0).
1165            - 0  Reserved(shall be 0).
1166         */
1167         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2);
1168 
1169         //   - 1 (ON) to prevent start code emulation.
1170         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1 , 1);
1171 		// Mandatory part of PTYPE ends.
1172 
1173         // CPM immediately follows the PPTYPE part of the header.
1174         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 ,1);
1175 
1176         /* Custom Picture Format (CPFMT) */
1177         /* if UFEP was present and Source Format type was 7(custom format) */
1178 	if (UFEP == 1)
1179 	{
1180 	    IMG_UINT16 ui16PWI,ui16PHI;
1181 
1182             // aspect ratio 4 bits value = 0010 (12:11)
1183 			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x01, 4);
1184             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 2, 4);
1185 
1186             // Picture Width Indication 9 bits.
1187 			//ui16PictureWidth --;
1188 			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureWidth >> 8), 1);
1189 			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureWidth & 0xFF), 8);
1190             ui16PWI = (ui32PictureWidth >> 2) - 1;
1191             tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,ui16PWI, 9);
1192 
1193             // Marker bit 1bit = 1 to prevent start code emulation.
1194 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1195 
1196             // Picture Height Indication 9 bits.
1197 			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureHeigth >> 8), 1);
1198 			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureHeigth & 0xFF), 8);
1199             ui16PHI = ui32PictureHeight >> 2;
1200             tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,ui16PHI, 9);
1201             // good up to that point
1202 	}
1203     }
1204     // 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))
1205     // vop_quant				= 5 Bits	= x	5-bit frame Q_scale from rate control - GENERATED BY MTX
1206     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1207 
1208     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1209 
1210     // if it was not PLUSPTYPE i.e for standard format size insert CPM bit here.
1211     if (SourceFormatType != 7)
1212     {
1213         // cpm	= 1 Bit		= 0	No direct effect on encoding of picture
1214         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 ,1);
1215     }
1216     // pei						= 1 Bit		= 0	No direct effect on encoding of picture
1217     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1218 
1219     return;
1220 }
1221 
MPEG4_NOTFORSIMS_WriteBits_VOPHeader(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_BOOL bIsVOP_coded,SEARCH_RANGE_TYPE sSearch_range,VOP_CODING_TYPE sVopCodingType)1222 void MPEG4_NOTFORSIMS_WriteBits_VOPHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1223 							IMG_BOOL	bIsVOP_coded,
1224 							SEARCH_RANGE_TYPE sSearch_range,
1225 							VOP_CODING_TYPE sVopCodingType)
1226 {
1227     // Essential we insert the element before we try to fill it!
1228     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1229     // visual_object_sequence_start_code	= 32 Bits	= 0x1B6
1230     tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 438, 32);
1231     // vop_coding_type						= 2 Bits	= 0 for I-frame and 1 for P-frame
1232     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, sVopCodingType, 2);
1233 
1234     // modulo_time_base
1235     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_MODULO_TIME_BASE);
1236     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1237 
1238     // marker_bit							= 1	Bits	= 1
1239     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1240 
1241     // vop_time_increment
1242     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VOP_TIME_INCREMENT);
1243     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1244 
1245     // marker_bit							= 1 Bit		= 1
1246     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1247 
1248     if (!bIsVOP_coded)
1249     {
1250 	// vop_coded						= 1 Bit		= 0 for skipped frame
1251 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1252        	// byte_aligned_bits (skipped pictures are byte aligned)
1253 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1254 	// End of VOP - skipped picture
1255     } else {
1256 	// vop_coded						= 1 Bit		= 1 for normal coded frame
1257 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1258 	if (sVopCodingType == P_FRAME)
1259 	{
1260 	    // vop_rounding_type			= 1 Bit		= 0 vop_rounding_type is 0 in Topaz
1261 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1262 	}
1263 	// intra_dc_vlc_thr					= 3 Bits	= 0 Use intra DC VLC in Topaz
1264 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 3);
1265 	// vop_quant				= 5 Bits	= x	5-bit frame Q_scale from rate control - GENERATED BY MTX
1266 	//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, Frame_Q_scale, 5);
1267 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1268 	if (sVopCodingType == P_FRAME)
1269 	{
1270 	    // vop_fcode_forward			= 3 bits	= 2 for +/-32 and 3 for +/-64 search range
1271 	    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1272 	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, sSearch_range, 3);
1273 	}
1274     }
1275 }
1276 /**************************************************************************************************
1277  * * Function:         H263_GeneratePicHdrTemplate
1278  * * Description:      Generates the h.263 picture header template
1279  * *
1280  * ***************************************************************************************************/
tng__H263_notforsims_prepare_video_pictureheader(MTX_HEADER_PARAMS * pMTX_Header,H263_PICTURE_CODING_TYPE ePictureCodingType,H263_SOURCE_FORMAT_TYPE eSourceFormatType,IMG_UINT8 ui8FrameRate,IMG_UINT32 ui32PictureWidth,IMG_UINT32 ui32PictureHeigth)1281 void tng__H263_notforsims_prepare_video_pictureheader(
1282     MTX_HEADER_PARAMS* pMTX_Header,
1283     H263_PICTURE_CODING_TYPE ePictureCodingType,
1284     H263_SOURCE_FORMAT_TYPE eSourceFormatType,
1285     IMG_UINT8 ui8FrameRate,
1286     IMG_UINT32 ui32PictureWidth,
1287     IMG_UINT32 ui32PictureHeigth )
1288 {
1289     // Essential we initialise our header structures before building
1290     MTX_HEADER_ELEMENT *This_Element;
1291     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1292     pMTX_Header->ui32Elements=ELEMENTS_EMPTY;
1293     This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1294     aui32ElementPointers[0]=This_Element;
1295 
1296     H263_NOTFORSIMS_WriteBits_VideoPictureHeader(
1297                pMTX_Header,
1298                aui32ElementPointers,
1299                ePictureCodingType,
1300                eSourceFormatType,
1301                ui8FrameRate,
1302                ui32PictureWidth,
1303                ui32PictureHeigth );
1304 
1305     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
1306 }
1307 
1308 /**************************************************************************************************
1309  * * Function:         MPEG4_GeneratePicHdrTemplate
1310  * * Description:      Generates the MPEG4 picture header template
1311  * *
1312  * ***************************************************************************************************/
tng__MPEG4_notforsims_prepare_vop_header(MTX_HEADER_PARAMS * pMTX_Header,IMG_BOOL bIsVOP_coded,SEARCH_RANGE_TYPE eSearch_range,VOP_CODING_TYPE eVop_Coding_Type)1313 void tng__MPEG4_notforsims_prepare_vop_header(
1314     MTX_HEADER_PARAMS* pMTX_Header,
1315     IMG_BOOL bIsVOP_coded,
1316     SEARCH_RANGE_TYPE eSearch_range,
1317     VOP_CODING_TYPE eVop_Coding_Type)
1318 {
1319     //Builds a single MPEG4 VOP (picture) header from the given parameters
1320     //Essential we initialise our header structures before building
1321     MTX_HEADER_ELEMENT *This_Element;
1322     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1323     pMTX_Header->ui32Elements=ELEMENTS_EMPTY;
1324     This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1325     aui32ElementPointers[0]=This_Element;
1326 
1327     //Frame QScale no longer written here as it is inserted by MTX later (add as parameter to MTX_Send_Elements_To_VLC)
1328     MPEG4_NOTFORSIMS_WriteBits_VOPHeader(
1329 	pMTX_Header,
1330 	aui32ElementPointers,
1331 	bIsVOP_coded,
1332 	eSearch_range,
1333 	eVop_Coding_Type);
1334 
1335     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
1336 }
1337 
H263_NOTFORSIMS_WriteBits_GOBSliceHeader(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers)1338 void H263_NOTFORSIMS_WriteBits_GOBSliceHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers)
1339 {
1340        // Essential we insert the element before we try to fill it!
1341        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1342     // gob_resync_marker               = 17            = 0x1
1343        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 1, 17);
1344 
1345        // gob_number                           = 5                     = 0-17  It is gob number in a picture
1346        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICE_NUM); // Insert token to tell MTX to insert gob_number
1347 
1348     // gob_frame_id                            = 2                     = 0-3   See note
1349        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_GOB_FRAME_ID); // Insert token to tell MTX to insert gob_frame_id
1350 
1351        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1352 
1353        // quant_scale                          = 5                     = 1-32  gob (Slice) Q_scale
1354        // tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8GOB_Q_Scale, 5);
1355        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEQSCALE); // Insert token to tell MTX to insert rate-control value (QScale is sent as an argument
1356 }
1357 
1358 
1359 
Bits2Code(IMG_UINT32 CodeVal)1360 static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1361 {
1362     IMG_UINT8 Bits = 32;
1363     if (CodeVal == 0)
1364         return 1;
1365     while (!(CodeVal & 0x80000000)) {
1366         CodeVal <<= 1;
1367         Bits--;
1368     }
1369     return Bits;
1370 }
1371 
1372 /*
1373  * Intermediary functions to build MPEG4 headers
1374  */
1375 #define MATCH_TO_ENC
1376 
1377 
tng__MPEG4_writebits_sequence_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_BOOL bBFrame,MPEG4_PROFILE_TYPE bProfile,IMG_UINT8 ui8Profile_and_level_indication,FIXED_VOP_TIME_TYPE __maybe_unused sFixed_vop_time_increment,IMG_UINT32 Picture_Width_Pixels,IMG_UINT32 Picture_Height_Pixels,VBVPARAMS * sVBVParams,IMG_UINT32 ui32VopTimeResolution)1378 static void tng__MPEG4_writebits_sequence_header(
1379     MTX_HEADER_PARAMS *pMTX_Header,
1380     MTX_HEADER_ELEMENT **aui32ElementPointers,
1381     IMG_BOOL bBFrame,
1382     MPEG4_PROFILE_TYPE bProfile,
1383     IMG_UINT8 ui8Profile_and_level_indication,
1384     FIXED_VOP_TIME_TYPE __maybe_unused sFixed_vop_time_increment,
1385     IMG_UINT32 Picture_Width_Pixels,
1386     IMG_UINT32 Picture_Height_Pixels,
1387     VBVPARAMS *sVBVParams, IMG_UINT32 ui32VopTimeResolution) /* Send NULL pointer if there are no VBVParams */
1388 {
1389 	// Essential we insert the element before we try to fill it!
1390 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1391 	// visual_object_sequence_start_code	= 32 Bits	= 0x1B0
1392 	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 432, 32);
1393 	//profile_and_level_indication			= 8 Bits	= SP L0-L3 and SP L4-L5 are supported
1394 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Profile_and_level_indication, 8);
1395 
1396 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1397 	// visual_object_start_code				= 32 Bits	= 0x1B5
1398 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1399 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1400 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1401 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 181, 8);
1402 	// is_visual_object_identifier			= 1 Bit 	= 0
1403 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1404 	// visual_object_type					= 4 Bits	= Video ID = 1
1405 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1406 	// video_signal_type					= 1 Bit		= 1
1407 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1408 	// byte_aligned_bits					= 2 Bits	= 01b (byte_aligned_bits is 2-bit stuffing bit field 01)
1409 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 2);
1410 
1411 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1412 	//video_object_start_code				= 32 Bits	= 0x100 One VO only in a Topaz video stream
1413 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1414 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1415 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1416 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1417 
1418 	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1419 	// video_object_layer_start_code		= 32 Bits	= 0x120 One VOL only in a Topaz stream
1420 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1421 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1422 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1423 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 32, 8);
1424 	// random_accessible_vol				= 1 Bit		= 0 (P-Frame in GOP)
1425 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1426 	if (bProfile == SP)
1427 	{
1428 		// video_object_type_indication			= 8 Bits	= 0x01 for SP
1429 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1430 #ifndef MATCH_TO_ENC
1431 		// is_object_layer_identifier			= 1 Bit		= 0 for SP
1432 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1433 #else
1434 	// to match the encoder
1435 		// is_object_layer_identifier			= 1 Bit
1436 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1437 		// video_object_layer_verid				= 4 Bits
1438 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1439         // video_object_layer_priority			= 3 Bits
1440 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 3);  // 0 is reserved...
1441 #endif
1442 	}
1443 	else
1444 	{
1445 		// video_object_type_indication			= 8 Bits	= 0x11 for ASP
1446 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 3, 8);
1447 		// is_object_layer_identifier			= 1 Bit		= 1 for ASP
1448 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1449 		// video_object_layer_verid				= 4 Bits	= 5 is for ASP
1450 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 5, 4);
1451         // video_object_layer_priority			= 3 Bits	= 1 (Highest priority)
1452 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 3);
1453 	}
1454 	// aspect_ratio_info						= 4 Bits	=0x1 (Square pixel)
1455 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1456 #if !defined(MATCH_TO_ENC) || !defined (EXCLUDE_VOL_CONTROL_PARAMS)
1457 	// vol_control_parameters					= 1 Bit		= 1 (Always send VOL control parameters)
1458 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1459 
1460     // chroma_format							= 2 Bits	= 01b (4:2:0)
1461 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 2);
1462 	// low_delay							= 1 Bit			= 0 with B-frame and 1 without B-frame
1463 	if (bBFrame)
1464 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1465 	else
1466 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1467     // vbv_parameters						= 1 Bit			=0/1
1468 	if (sVBVParams)
1469 	{
1470 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1471 		 //For recording, only send vbv parameters in 1st sequence header. For video phone, it should be sent more often, such as once per sequence
1472 		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_bit_rate, 15);			// first_half_bit_rate
1473         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1474 		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_bit_rate, 15);			// latter_half_bit_rate
1475         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1476 		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_vbv_buffer_size, 15);	// first_half_vbv_buffer_size
1477         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1478         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_vbv_buffer_size, 3);	//  latter_half_vbv_buffer_size
1479         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_vbv_occupancy, 11);		//  first_half_vbv_occupancy
1480         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1481 		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_vbv_occupancy, 15);		//  latter_half_vbv_occupancy
1482         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1483 	}
1484 	else
1485 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // No vbv parameters present
1486 #else
1487 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1488 #endif
1489 	// video_object_layer_shape			= 2 Bits		=	00b	Rectangular shape
1490 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2);
1491 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1492 	// vop_time_increment_solution		= 16 Bits
1493 	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32VopTimeResolution, 16);
1494 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1495 #ifndef MATCH_TO_ENC
1496 	// fixed_vop_rate					= 1 Bits		=	1 Always fixed frame rate
1497 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1498 	// fixed_vop_time_increment			= Variable number of bits based on the time increment resolution.
1499 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, Bits2Code(ui32VopTimeResolution));
1500 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1501 #else
1502 	// fixed_vop_rate					= 1 Bits		=	0
1503 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1504 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1505 #endif
1506 	// video_object_layer_width			= 13 Bits		Picture width in pixel units
1507 	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, Picture_Width_Pixels, 13);
1508 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1509 	// video_object_layer_height		= 13 Bits		Picture height in pixel units
1510 	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, Picture_Height_Pixels, 13);
1511 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1512 	// interlaced						= 1 Bit			= 0 Topaz only encodes progressive frames
1513 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1514 	// obmc_disable						= 1 Bit			= 1 No overlapped MC in Topaz
1515 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1516     // sprite_enable					= 1 Bit			= 0 Not use sprite in Topaz
1517 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1518 	// not_8_bit						= 1	Bit			= 0	8-bit video in Topaz
1519 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1520 	// quant_type						= 1 Bit			= 0 2nd quantization method in Topaz
1521 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1522 	if (bProfile==ASP)
1523 	{
1524 		// quarter_sample				= 1 Bit			= 0 No ?pel MC in Topaz
1525 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1526 	}
1527 
1528 	// complexity_estimation_disable	= 1 Bit			= 1	No complexity estimation in Topaz
1529 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1530 #ifndef MATCH_TO_ENC
1531 	// resync_marker_disable			= 1 Bit			= 0 Always enable resync marker in Topaz
1532 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1533 #else
1534 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1535 #endif
1536     // data_partitioned					= 1 Bit			= 0 No data partitioning in Topaz
1537 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1538     if (bProfile == ASP)
1539 	{
1540 		// newpred_enable				= 1 Bit			= 0 No newpred mode in SP/ASP
1541 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1542 		// reduced_vop_resolution_enable=1 Bit			= 0	No reduced resolution frame in SP/ASP
1543 		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1544     }
1545     // scalability						= 1 Bit			= 0	No scalability in SP/ASP
1546 	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1547 	// byte_aligned_bits
1548    	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1549 	return;
1550 }
1551 
1552 
1553 /* Utility function */
1554 /*
1555   IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1556   {
1557   IMG_UINT8 Bits=32;
1558   if(CodeVal==0)
1559   return 1;
1560   while(!(CodeVal & 0x80000000))
1561   {
1562   CodeVal<<=1;
1563   Bits--;
1564   }
1565   return Bits;
1566   }
1567 */
1568 
1569 /* MPEG 4 VOP (Picture) Header */
tng__MPEG4_writebits_VOP_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_BOOL bIsVOP_coded,IMG_UINT8 VOP_time_increment,SEARCH_RANGE_TYPE sSearch_range,VOP_CODING_TYPE sVopCodingType,IMG_UINT32 VopTimeResolution)1570 static void tng__MPEG4_writebits_VOP_header(
1571     MTX_HEADER_PARAMS *mtx_hdr,
1572     MTX_HEADER_ELEMENT **aui32ElementPointers,
1573     IMG_BOOL    bIsVOP_coded,
1574     IMG_UINT8   VOP_time_increment,
1575     SEARCH_RANGE_TYPE sSearch_range,
1576     VOP_CODING_TYPE sVopCodingType,
1577     IMG_UINT32 VopTimeResolution)
1578 {
1579     IMG_BOOL bIsSyncPoint;
1580     /* Essential we insert the element before we try to fill it! */
1581     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1582 
1583     /* visual_object_sequence_start_code        = 32 Bits       = 0x1B6 */
1584     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 438, 32);
1585 
1586     /* vop_coding_type  = 2 Bits = 0 for I-frame and 1 for P-frame */
1587     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, sVopCodingType, 2);
1588     bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0);
1589 
1590 #ifndef MATCH_TO_ENC
1591     /* modulo_time_base = 1 Bit = 0 As at least  1 synchronization point (I-frame) per second in Topaz */
1592     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1593 #else
1594 
1595     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, bIsSyncPoint  ? 2 : 0 , bIsSyncPoint ? 2 : 1);
1596 
1597 #endif
1598 
1599     /* marker_bit = 1   Bits    = 1      */
1600     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1601 
1602 #ifndef MATCH_TO_ENC
1603     /* vop_time_increment = Variable bits based on resolution
1604      *  = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame
1605      */
1606     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, VOP_time_increment, 5);
1607 #else
1608     /* will chrash here... */
1609     tng__write_upto8bits_elements(
1610         mtx_hdr, aui32ElementPointers,
1611         (VOP_time_increment) % VopTimeResolution,
1612         Bits2Code(VopTimeResolution - 1));
1613 
1614 #endif
1615     /* marker_bit = 1 Bit               = 1      */
1616     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1617 
1618     if (!bIsVOP_coded) {
1619         /* vop_coded    = 1 Bit         = 0 for skipped frame */
1620         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1621 
1622         /* byte_aligned_bits (skipped pictures are byte aligned) */
1623         /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1624          * End of VOP - skipped picture
1625          */
1626         tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4);
1627     } else {
1628         /* vop_coded = 1 Bit            = 1 for normal coded frame */
1629         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1630 
1631         if (sVopCodingType == P_FRAME) {
1632             /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */
1633             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1634         }
1635 
1636         /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */
1637         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 3);
1638 
1639         /* vop_quant = 5 Bits   = x     5-bit frame Q_scale from rate control - GENERATED BY MTX */
1640         /* tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Frame_Q_scale, 5); */
1641         tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1642 
1643         if (sVopCodingType == P_FRAME) {
1644             /* vop_fcode_forward = 3 bits       = 2 for +/-32 and 3 for +/-64 search range  */
1645             tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1646             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, sSearch_range, 3);
1647         }
1648 
1649         /*
1650         **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE
1651         tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1652         video_packet_data ( )                   = 1st  VP that doesn�t have the VP header
1653 
1654         while (nextbits_bytealigned ( ) == resync_marker)
1655         {
1656         video_packet _header( )
1657         video_packet _data( )                   All MB in the slice
1658         }
1659         */
1660     }
1661 }
1662 
1663 /*
1664  * Intermediary functions to build H263 headers
1665  */
H263_writebits_VideoSequenceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 Profile_and_level_indication)1666 static void H263_writebits_VideoSequenceHeader(
1667     MTX_HEADER_PARAMS *mtx_hdr,
1668     MTX_HEADER_ELEMENT **aui32ElementPointers,
1669     IMG_UINT8 Profile_and_level_indication)
1670 {
1671     /* Essential we insert the element before we try to fill it! */
1672     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1673 
1674     /* visual_object_sequence_start_code        = 32 Bits       = 0x1B0 */
1675     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 432, 32);
1676 
1677     /* profile_and_level_indication = 8 Bits =  x SP L0-L3 and SP L4-L5 are supported */
1678     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Profile_and_level_indication, 8);
1679 
1680     /* visual_object_start_code = 32 Bits       = 0x1B5 */
1681 
1682     /* 437 too large for the   tng__write_upto32bits_elements function */
1683     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 437, 32);
1684 
1685     /* is_visual_object_identifier = 1 Bit              = 0 */
1686     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1687 
1688     /* is_visual_object_type    = 4 Bits        = 1 Video ID */
1689     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 4);
1690 
1691     /* video_signal_type = 1 Bit                = 0      */
1692     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1693 
1694     /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */
1695     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 2);
1696 
1697     /* video_object_start_code  =32 Bits        = 0x100 One VO only in a Topaz video stream */
1698     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 256, 32);
1699 
1700     return;
1701 }
1702 
H263_writebits_VideoPictureHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 __maybe_unused FrameRate,IMG_UINT32 PictureWidth,IMG_UINT32 PictureHeight)1703 static void H263_writebits_VideoPictureHeader(
1704     MTX_HEADER_PARAMS *mtx_hdr,
1705     MTX_HEADER_ELEMENT **aui32ElementPointers,
1706     IMG_UINT8 Temporal_Ref,
1707     H263_PICTURE_CODING_TYPE PictureCodingType,
1708     //IMG_UINT8 Q_Scale,
1709     H263_SOURCE_FORMAT_TYPE SourceFormatType,
1710     IMG_UINT8 __maybe_unused FrameRate,
1711     IMG_UINT32 PictureWidth,
1712     IMG_UINT32 PictureHeight)
1713 {
1714     IMG_UINT8 UFEP;
1715 
1716     /* Essential we insert the element before we try to fill it! */
1717     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1718 
1719     /* short_video_start_marker = 22 Bits       = 0x20 Picture start code */
1720     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 32, 22);
1721 
1722     /* temporal_reference = 8 Bits      = 0-255 Each picture increased by 1 */
1723     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Temporal_Ref, 8);
1724 
1725     /* marker_bit = 1 Bit = 1    */
1726     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1727 
1728     /* zero_bit = 1 Bits        = 0      */
1729     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1730 
1731     /* split_screen_indicator   = 1     Bits    = 0     No direct effect on encoding of picture */
1732     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1733 
1734     /* document_camera_indicator= 1     Bits    = 0     No direct effect on encoding of picture */
1735     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1736 
1737     /* full_picture_freeze_release=1 Bits       = 0     No direct effect on encoding of picture */
1738     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1739 
1740     /* source_format                            = 3     Bits    = 1-4   See note */
1741     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, SourceFormatType, 3);
1742 
1743     if (SourceFormatType != 7) {
1744         // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1745         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, PictureCodingType, 1);
1746         // four_reserved_zero_bits      = 4 Bits        = 0
1747         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 4);
1748     } else {
1749         static unsigned char  RTYPE = 0;
1750 
1751         // if I- Frame set Update Full Extended PTYPE to true
1752         if (PictureCodingType == I_FRAME) {
1753             UFEP = 1;
1754         } else {
1755             UFEP = 0;
1756         }
1757         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, UFEP, 3);
1758         if (UFEP == 1) {
1759             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 6, 3);
1760             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1761 
1762             /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1763              *  - Optional Unrestricted Motion Vector (UMV)
1764              *  - Optional Syntax-based Arithmetic Coding (SAC)
1765              *  - Optional Advanced Prediction (AP) mode
1766              *  - Optional Advanced INTRA Coding (AIC) mode
1767              *  - Optional Deblocking Filter (DF) mode
1768              *  - Optional Slice Structured (SS) mode
1769              *  - Optional Reference Picture Selection(RPS) mode.
1770              *  - Optional Independent Segment Decoding (ISD) mode
1771              *  - Optional Alternative INTER VLC (AIV) mode
1772              *  - Optional Modified Quantization (MQ) mode */
1773 
1774             tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 0, 10);
1775             // 10 reserve bits
1776             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 8, 4);
1777             // 4 reserve bits
1778         }
1779         // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1780         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, PictureCodingType, 3);
1781 
1782         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 2);
1783         // two_reserve_bits,      rounding_type,       two_reserve_bits       marker_bit       CPM
1784         // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1785         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, RTYPE, 1);
1786         //2 reserve bits
1787         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 2);
1788         //   - 1 (ON) to prevent start code emulation.
1789         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1 , 1);
1790         // CPM immediately follows the PPTYPE part of the header.
1791         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0 , 1);
1792 
1793 
1794         if (UFEP == 1) {
1795             IMG_UINT16 ui16PWI, ui16PHI;
1796             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 4);
1797             // aspect ratio
1798             //PictureWidth--;
1799             //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureWidth >> 8), 1);
1800             //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureWidth & 0xFF), 8);
1801             //Width = (PWI-1)*4, Height = PHI*4, see H263 spec 5.1.5
1802             ui16PWI = (PictureWidth >> 2) - 1;
1803             tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)ui16PWI, 9);
1804 
1805             tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1806             // marker_bit                               = 1 Bit         = 1
1807             //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureHeight >> 8), 1);
1808             //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureHeight & 0xFF), 8);
1809 
1810             ui16PHI = PictureHeight >> 2;
1811             tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)ui16PHI, 9);
1812             // good up to that point
1813             //  tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1814             // marker_bit                               = 1 Bit         = 1
1815             // just checking
1816         }
1817     }
1818     // vop_quant                                = 5 Bits        = x     5-bit frame Q_scale from rate control - GENERATED BY MTX
1819     //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, ui8Q_Scale, 5);
1820     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_FRAMEQSCALE); // Insert token to tell MTX to insert rate-control value (QScale
1821 										   //is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, FrameQScale))
1822     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1823     // zero_bit                                 = 1 Bit         = 0
1824     // pei                                              = 1 Bit         = 0     No direct effect on encoding of picture
1825     if (SourceFormatType != 7) {
1826         tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1827     }
1828 
1829     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1830     // FOLLOWING SECTION CAN'T BE GENERATED HERE
1831     //gob_data( )
1832     //for(i=1; i<num_gob_in_picture; i++) {
1833     //      gob_header( )
1834     //      gob_data( )
1835     // }
1836     return;
1837 }
1838 
H263_writebits_GOBSliceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** aui32ElementPointers,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)1839 static void H263_writebits_GOBSliceHeader(
1840     MTX_HEADER_PARAMS *mtx_hdr,
1841     MTX_HEADER_ELEMENT **aui32ElementPointers,
1842     IMG_UINT8 GOBNumber,
1843     IMG_UINT8 GOBFrameId)
1844 {
1845     /* Essential we insert the element before we try to fill it! */
1846     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1847 
1848     /* gob_resync_marker                = 17            = 0x1 */
1849     tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 1, 17);
1850 
1851     /* gob_number = 5   = 0-17  It is gob number in a picture */
1852     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOBNumber, 5);
1853 
1854     /* gob_frame_id     = 2 = 0-3       See note */
1855     tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOBFrameId, 2);
1856 
1857     /* quant_scale      = 5     = 1-32  gob (Slice) Q_scale  */
1858     /* tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOB_Q_Scale, 5); */
1859 
1860     /* Insert token to tell MTX to insert rate-control value
1861      *  (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale))
1862      */
1863     tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_SLICEQSCALE);
1864     return;
1865 }
1866 
1867 /*
1868  * High level functions to call when a H263 header is required - HOST ROUTINES
1869  */
1870 //static void tng__H263_getelements_videosequence_header(
1871 //MTX_HEADER_PARAMS *mtx_hdr,
1872 //IMG_UINT8 Profile_and_level_indication)
1873 //{
1874 ///* Builds a single H263 video sequence header from the given parameters */
1875 //
1876 ///* Essential we initialise our header structures before building */
1877 //MTX_HEADER_ELEMENT *This_Element;
1878 //MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1879 //mtx_hdr->Elements=ELEMENTS_EMPTY;
1880 //This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1881 //aui32ElementPointers[0]=This_Element;
1882 //
1883 //H263_writebits_VideoSequenceHeader(mtx_hdr, aui32ElementPointers, Profile_and_level_indication);
1884 //
1885 //mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1886 //}
1887 
1888 //static void tng__H263_getelements_videopicture_header(
1889 //MTX_HEADER_PARAMS *mtx_hdr,
1890 //IMG_UINT8 Temporal_Ref,
1891 //H263_PICTURE_CODING_TYPE PictureCodingType,
1892 //H263_SOURCE_FORMAT_TYPE SourceFormatType,
1893 //IMG_UINT8 FrameRate,
1894 //IMG_UINT16 PictureWidth,
1895 //IMG_UINT16 PictureHeigth)
1896 //{
1897 ///* Essential we initialise our header structures before building */
1898 //MTX_HEADER_ELEMENT *This_Element;
1899 //MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1900 //mtx_hdr->Elements=ELEMENTS_EMPTY;
1901 //This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1902 //aui32ElementPointers[0]=This_Element;
1903 //
1904 //H263_writebits_VideoPictureHeader(
1905 //mtx_hdr, aui32ElementPointers,
1906 //Temporal_Ref,
1907 //PictureCodingType,
1908 //SourceFormatType,
1909 //FrameRate,
1910 //PictureWidth,
1911 //PictureHeigth);
1912 //
1913 //mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1914 //}
1915 
1916 //static void tng__H263_getelements_GOBslice_header(
1917 //MTX_HEADER_PARAMS *mtx_hdr,
1918 //IMG_UINT8 GOBNumber,
1919 //IMG_UINT8 GOBFrameId)
1920 //{
1921 ///* Essential we initialise our header structures before building */
1922 //MTX_HEADER_ELEMENT *This_Element;
1923 //MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1924 //mtx_hdr->Elements=ELEMENTS_EMPTY;
1925 //This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1926 //aui32ElementPointers[0]=This_Element;
1927 //
1928 //H263_writebits_GOBSliceHeader(mtx_hdr, aui32ElementPointers, GOBNumber, GOBFrameId);
1929 //
1930 //mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
1931 //}
1932 
1933 // SEI_INSERTION
tng__H264ES_writebits_AUD_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers)1934 static void tng__H264ES_writebits_AUD_header(
1935     MTX_HEADER_PARAMS *pMTX_Header,
1936     MTX_HEADER_ELEMENT **aui32ElementPointers)
1937 {
1938     // Essential we insert the element before we try to fill it!
1939     tng__insert_element_token(pMTX_Header,
1940         aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1941 
1942     tng__H264_writebits_startcode_prefix_element(pMTX_Header,
1943         aui32ElementPointers, 4); // 00 00 00 01 start code prefix
1944 
1945     tng__write_upto8bits_elements(pMTX_Header,
1946         aui32ElementPointers, 9, 8); // AUD nal_unit_type = 09
1947 
1948     // primary_pic_type  u(3) 0=I slice, 1=P or I slice, 2=P,B or I slice
1949     tng__write_upto8bits_elements(pMTX_Header,
1950         aui32ElementPointers, 2, 3);
1951 
1952     tng__write_upto8bits_elements(pMTX_Header,
1953         aui32ElementPointers, 1 << 4, 5); // rbsp_trailing_bits
1954 
1955     // Write terminator
1956     tng__write_upto8bits_elements(pMTX_Header,
1957         aui32ElementPointers, 0x80, 8);
1958     return;
1959 }
1960 
1961 //#define SEI_NOT_USE_TOKEN_ALIGN
1962 
tng__H264ES_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 __maybe_unused ui32nal_initial_cpb_removal_delay,IMG_UINT32 __maybe_unused 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)1963 static void tng__H264ES_writebits_SEI_buffering_period_header(
1964     MTX_HEADER_PARAMS *pMTX_Header,
1965     MTX_HEADER_ELEMENT **aui32ElementPointers,
1966     IMG_UINT8 ui8NalHrdBpPresentFlag,
1967     IMG_UINT8 ui8nal_cpb_cnt_minus1,
1968     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
1969     IMG_UINT32 __maybe_unused ui32nal_initial_cpb_removal_delay,
1970     IMG_UINT32 __maybe_unused ui32nal_initial_cpb_removal_delay_offset,
1971     IMG_UINT8 ui8VclHrdBpPresentFlag,
1972     IMG_UINT8 ui8vcl_cpb_cnt_minus1,
1973     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
1974     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
1975 {
1976     IMG_UINT8 ui8SchedSelIdx;
1977     IMG_UINT8 ui8PayloadSizeBits;
1978 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1979     IMG_UINT8 ui8Pad;
1980 #endif
1981 
1982     // Essential we insert the element before we try to fill it!
1983     tng__insert_element_token(pMTX_Header,
1984         aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1985 
1986     tng__H264_writebits_startcode_prefix_element(pMTX_Header,
1987         aui32ElementPointers, 3); // 00 00 01 start code prefix
1988 
1989     tng__write_upto8bits_elements(pMTX_Header,
1990         aui32ElementPointers, 6, 8); // nal_unit_type = 06 (SEI Message)
1991 
1992     tng__write_upto8bits_elements(pMTX_Header,
1993         aui32ElementPointers, 0, 8); // SEI payload type (buffering period)
1994 
1995     ui8PayloadSizeBits = 1; // seq_parameter_set_id bitsize = 1
1996     if (ui8NalHrdBpPresentFlag)
1997         ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1)
1998                                * ui8nal_initial_cpb_removal_delay_length * 2);
1999     if (ui8VclHrdBpPresentFlag)
2000         ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1)
2001                                * ui8nal_initial_cpb_removal_delay_length * 2);
2002 
2003     tng__write_upto8bits_elements(pMTX_Header,
2004                                   aui32ElementPointers,
2005                                   ((ui8PayloadSizeBits + 7) / 8),
2006                                   8);
2007     // SEI payload size = No of bytes required for SEI payload
2008     // (including seq_parameter_set_id)
2009 
2010     //seq_parameter_set_id      ue(v) = 0 default? = 1 (binary)
2011     //= sequence parameter set containing HRD attributes
2012     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);
2013 
2014     if (ui8NalHrdBpPresentFlag) {
2015         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++) {
2016             // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access
2017             // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit.
2018             // Delay is based on the time taken for a 90 kHz clock.
2019             // Range >0 and < 90000 * (CPBsize / BitRate)
2020             // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation.
2021             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
2022 
2023             //tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32nal_initial_cpb_removal_delay, ui8nal_initial_cpb_removal_delay_length);
2024             tng__insert_element_token(pMTX_Header,
2025                                       aui32ElementPointers,
2026                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY);
2027 
2028             // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to
2029             // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset
2030             // Delay is based on the time taken for a 90 kHz clock.
2031             // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C
2032 
2033             tng__insert_element_token(pMTX_Header,
2034                                       aui32ElementPointers,
2035                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET);
2036         }
2037     }
2038     if (ui8VclHrdBpPresentFlag) {
2039         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++) {
2040             tng__insert_element_token(pMTX_Header,
2041                                       aui32ElementPointers,
2042                                       ELEMENT_STARTCODE_RAWDATA);
2043             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
2044             tng__write_upto32bits_elements(pMTX_Header,
2045                                            aui32ElementPointers,
2046                                            ui32vcl_initial_cpb_removal_delay,
2047                                            ui8nal_initial_cpb_removal_delay_length);
2048             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required
2049             tng__write_upto32bits_elements(pMTX_Header,
2050                                            aui32ElementPointers,
2051                                            ui32vcl_initial_cpb_removal_delay_offset,
2052                                            ui8nal_initial_cpb_removal_delay_length);
2053         }
2054     }
2055 
2056     // Pad to end of byte
2057 #ifdef SEI_NOT_USE_TOKEN_ALIGN
2058     if (!ui8VclHrdBpPresentFlag)
2059         tng__insert_element_token(pMTX_Header,
2060                                   aui32ElementPointers,
2061                                   ELEMENT_STARTCODE_RAWDATA);
2062     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2063     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2064     if (ui8Pad > 0)
2065         tng__write_upto8bits_elements(pMTX_Header,
2066                                       aui32ElementPointers,
2067                                       1 << (ui8Pad - 1),
2068                                       ui8Pad); // SEI payload type (buffering period)
2069 #else
2070     tng__insert_element_token(pMTX_Header,
2071                               aui32ElementPointers,
2072                               ELEMENT_INSERTBYTEALIGN_H264);
2073     // Tell MTX to insert the byte align field
2074     tng__insert_element_token(pMTX_Header,
2075                               aui32ElementPointers,
2076                               ELEMENT_STARTCODE_RAWDATA);
2077 #endif
2078 
2079     // Write terminator
2080     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8);
2081 
2082     return;
2083 }
2084 
2085 //#define SEI_HOSTCALC_CPB_DPB
2086 
tng__H264ES_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 __maybe_unused ui32cpb_removal_delay,IMG_UINT32 __maybe_unused 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)2087 static void tng__H264ES_writebits_SEI_picture_timing_header(
2088     MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
2089     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2090     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2091     IMG_UINT32 ui32dpb_output_delay_length_minus1,
2092     IMG_UINT32 __maybe_unused ui32cpb_removal_delay,
2093     IMG_UINT32 __maybe_unused ui32dpb_output_delay,
2094     IMG_UINT8 ui8pic_struct_present_flag,
2095     IMG_UINT8 ui8pic_struct,
2096     IMG_UINT8 ui8NumClockTS,
2097     IMG_UINT8 *aui8clock_timestamp_flag,
2098     IMG_UINT8 ui8full_timestamp_flag,
2099     IMG_UINT8 ui8seconds_flag,
2100     IMG_UINT8 ui8minutes_flag,
2101     IMG_UINT8 ui8hours_flag,
2102     IMG_UINT8 ui8seconds_value,
2103     IMG_UINT8 ui8minutes_value,
2104     IMG_UINT8 ui8hours_value,
2105     IMG_UINT8 ui8ct_type,
2106     IMG_UINT8 ui8nuit_field_based_flag,
2107     IMG_UINT8 ui8counting_type,
2108     IMG_UINT8 ui8discontinuity_flag,
2109     IMG_UINT8 ui8cnt_dropped_flag,
2110     IMG_UINT8 ui8n_frames,
2111     IMG_UINT8 ui8time_offset_length,
2112     IMG_INT32 i32time_offset)
2113 {
2114     IMG_UINT8 ui8PayloadSizeBits, ui8Tmp;
2115 #ifdef SEI_NOT_USE_TOKEN_ALIGN
2116     IMG_UINT8 ui8Pad;
2117 #endif
2118 
2119     // Essential we insert the element before we try to fill it!
2120     tng__insert_element_token(pMTX_Header,
2121                               aui32ElementPointers,
2122                               ELEMENT_STARTCODE_RAWDATA);
2123 
2124     tng__H264_writebits_startcode_prefix_element(pMTX_Header,
2125             aui32ElementPointers,
2126             3); // 00 00 01 start code prefix
2127 
2128     tng__write_upto8bits_elements(pMTX_Header,
2129                                   aui32ElementPointers,
2130                                   6, 8); // nal_unit_type = 06 (SEI Message)
2131 
2132     tng__write_upto8bits_elements(pMTX_Header,
2133                                   aui32ElementPointers,
2134                                   1, 8); // SEI payload type (picture timing)
2135 
2136 
2137     // Precalculate the payload bit size
2138     ui8PayloadSizeBits = 0;
2139     if (ui8CpbDpbDelaysPresentFlag)
2140         ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1
2141                               + 1 + ui32dpb_output_delay_length_minus1 + 1;
2142 
2143     if (ui8pic_struct_present_flag) {
2144         ui8PayloadSizeBits += 4;
2145         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
2146             ui8PayloadSizeBits += 1;
2147 
2148             if (aui8clock_timestamp_flag[ui8Tmp]) {
2149                 ui8PayloadSizeBits += 2 + 1 + 5 + 1 + 1 + 1 + 8;
2150                 if (ui8full_timestamp_flag)
2151                     ui8PayloadSizeBits += 6 + 6 + 5;
2152                 else {
2153                     ui8PayloadSizeBits += 1;
2154                     if (ui8seconds_flag) {
2155                         ui8PayloadSizeBits += 6 + 1;
2156                         if (ui8minutes_flag) {
2157                             ui8PayloadSizeBits += 6 + 1;
2158                             if (ui8hours_flag)
2159                                 ui8PayloadSizeBits += 5;
2160                         }
2161                     }
2162                 }
2163 
2164                 if (ui8time_offset_length > 0)
2165                     ui8PayloadSizeBits += ui8time_offset_length;
2166             }
2167         }
2168     }
2169 
2170     tng__write_upto8bits_elements(pMTX_Header,
2171                                   aui32ElementPointers,
2172                                   ((ui8PayloadSizeBits + 7) / 8), 8);
2173     // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id)
2174 
2175 
2176     if (ui8CpbDpbDelaysPresentFlag) {
2177         //SEI_INSERTION
2178 #ifdef SEI_HOSTCALC_CPB_DPB
2179         tng__write_upto32bits_elements(pMTX_Header,
2180                                        aui32ElementPointers,
2181                                        ui32cpb_removal_delay,
2182                                        ui32cpb_removal_delay_length_minus1 + 1); // cpb_removal_delay
2183         tng__write_upto32bits_elements(pMTX_Header,
2184                                        aui32ElementPointers,
2185                                        ui32dpb_output_delay,
2186                                        ui32dpb_output_delay_length_minus1 + 1); // dpb_output_delay
2187 #else
2188         tng__insert_element_token(pMTX_Header,
2189                                   aui32ElementPointers,
2190                                   PTH_SEI_NAL_CPB_REMOVAL_DELAY);
2191         tng__insert_element_token(pMTX_Header,
2192                                   aui32ElementPointers,
2193                                   PTH_SEI_NAL_DPB_OUTPUT_DELAY);
2194 #endif
2195     }
2196 
2197     if (ui8pic_struct_present_flag) {
2198         tng__insert_element_token(pMTX_Header,
2199                                   aui32ElementPointers,
2200                                   ELEMENT_STARTCODE_RAWDATA);
2201         tng__write_upto8bits_elements(pMTX_Header,
2202                                       aui32ElementPointers,
2203                                       ui8pic_struct, 4); // See TRM able D 1 ?Interpretation of pic_struct
2204 
2205         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
2206             tng__write_upto8bits_elements(pMTX_Header,
2207                                           aui32ElementPointers,
2208                                           aui8clock_timestamp_flag[ui8Tmp], 1);
2209 
2210             if (aui8clock_timestamp_flag[ui8Tmp]) {
2211                 tng__write_upto8bits_elements(pMTX_Header,
2212                                               aui32ElementPointers,
2213                                               ui8ct_type, 2);
2214                 // (2=Unknown) See TRM Table D 2 ?Mapping of ct_type to source picture scan
2215                 tng__write_upto8bits_elements(pMTX_Header,
2216                                               aui32ElementPointers,
2217                                               ui8nuit_field_based_flag, 1);
2218                 tng__write_upto8bits_elements(pMTX_Header,
2219                                               aui32ElementPointers,
2220                                               ui8counting_type, 5);
2221                 // See TRM Table D 3 ?Definition of counting_type values
2222                 tng__write_upto8bits_elements(pMTX_Header,
2223                                               aui32ElementPointers,
2224                                               ui8full_timestamp_flag, 1);
2225                 tng__write_upto8bits_elements(pMTX_Header,
2226                                               aui32ElementPointers,
2227                                               ui8discontinuity_flag, 1);
2228                 tng__write_upto8bits_elements(pMTX_Header,
2229                                               aui32ElementPointers,
2230                                               ui8cnt_dropped_flag, 1);
2231                 tng__write_upto8bits_elements(pMTX_Header,
2232                                               aui32ElementPointers,
2233                                               ui8n_frames, 8);
2234 
2235                 if (ui8full_timestamp_flag) {
2236                     tng__write_upto8bits_elements(pMTX_Header,
2237                                                   aui32ElementPointers,
2238                                                   ui8seconds_value, 6); // 0 - 59
2239                     tng__write_upto8bits_elements(pMTX_Header,
2240                                                   aui32ElementPointers,
2241                                                   ui8minutes_value, 6); // 0 - 59
2242                     tng__write_upto8bits_elements(pMTX_Header,
2243                                                   aui32ElementPointers,
2244                                                   ui8hours_value, 5); // 0 - 23
2245                 } else {
2246                     tng__write_upto8bits_elements(pMTX_Header,
2247                                                   aui32ElementPointers,
2248                                                   ui8seconds_flag, 1);
2249 
2250                     if (ui8seconds_flag) {
2251                         tng__write_upto8bits_elements(pMTX_Header,
2252                                                       aui32ElementPointers,
2253                                                       ui8seconds_value, 6); // 0 - 59
2254                         tng__write_upto8bits_elements(pMTX_Header,
2255                                                       aui32ElementPointers,
2256                                                       ui8minutes_flag, 1);
2257 
2258                         if (ui8minutes_flag) {
2259                             tng__write_upto8bits_elements(pMTX_Header,
2260                                                           aui32ElementPointers,
2261                                                           ui8minutes_value, 6); // 0 - 59
2262                             tng__write_upto8bits_elements(pMTX_Header,
2263                                                           aui32ElementPointers,
2264                                                           ui8hours_flag, 1);
2265 
2266                             if (ui8hours_flag)
2267                                 tng__write_upto8bits_elements(pMTX_Header,
2268                                                               aui32ElementPointers,
2269                                                               ui8hours_value, 5); // 0 - 23
2270                         }
2271                     }
2272                 }
2273 
2274                 if (ui8time_offset_length > 0) {
2275                     // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset)
2276                     if (i32time_offset < 0)
2277                         tng__write_upto32bits_elements(pMTX_Header,
2278                                                        aui32ElementPointers,
2279                                                        (IMG_UINT32)((2 ^ ui8time_offset_length) + i32time_offset),
2280                                                        ui8time_offset_length);
2281                     else
2282                         tng__write_upto32bits_elements(pMTX_Header,
2283                                                        aui32ElementPointers,
2284                                                        (IMG_UINT32) i32time_offset,
2285                                                        ui8time_offset_length);
2286                 }
2287             }
2288         }
2289     }
2290 
2291 #ifdef SEI_NOT_USE_TOKEN_ALIGN
2292     // Pad to end of byte
2293     if (!ui8pic_struct_present_flag)
2294         tng__insert_element_token(pMTX_Header,
2295                                   aui32ElementPointers,
2296                                   ELEMENT_STARTCODE_RAWDATA);
2297     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2298     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2299     if (ui8Pad > 0)
2300         tng__write_upto8bits_elements(pMTX_Header,
2301                                       aui32ElementPointers,
2302                                       1 << (ui8Pad - 1),
2303                                       ui8Pad); // SEI payload type (buffering period)
2304 #else
2305     tng__insert_element_token(pMTX_Header,
2306                               aui32ElementPointers,
2307                               ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field
2308     tng__insert_element_token(pMTX_Header,
2309                               aui32ElementPointers,
2310                               ELEMENT_STARTCODE_RAWDATA);
2311 #endif
2312 
2313     // Write terminator
2314     tng__write_upto8bits_elements(pMTX_Header,
2315                                   aui32ElementPointers,
2316                                   0x80, 8);
2317     return;
2318 }
2319 
2320 
2321 
tng__H264ES_prepare_AUD_header(unsigned char * virtual_addr)2322 void tng__H264ES_prepare_AUD_header(unsigned char *virtual_addr)
2323 {
2324     // Essential we initialise our header structures before building
2325     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2326     MTX_HEADER_ELEMENT *This_Element;
2327     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2328     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2329     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2330     aui32ElementPointers[0] = This_Element;
2331 
2332     tng__H264ES_writebits_AUD_header(pMTX_Header, aui32ElementPointers);
2333 
2334     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
2335 }
2336 
2337 
tng__H264ES_prepare_SEI_buffering_period_header(unsigned char * virtual_addr,IMG_UINT8 ui8nal_cpb_cnt_minus1,IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,IMG_UINT8 ui8NalHrdBpPresentFlag,IMG_UINT32 ui32nal_initial_cpb_removal_delay,IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,IMG_UINT8 ui8VclHrdBpPresentFlag,IMG_UINT32 ui32vcl_initial_cpb_removal_delay,IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)2338 void tng__H264ES_prepare_SEI_buffering_period_header(
2339     unsigned char *virtual_addr,
2340     IMG_UINT8 ui8nal_cpb_cnt_minus1,
2341     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
2342     IMG_UINT8 ui8NalHrdBpPresentFlag,
2343     IMG_UINT32 ui32nal_initial_cpb_removal_delay,
2344     IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
2345     IMG_UINT8 ui8VclHrdBpPresentFlag,
2346     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
2347     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
2348 {
2349     // Essential we initialise our header structures before building
2350     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2351     MTX_HEADER_ELEMENT *This_Element;
2352     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2353     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2354     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2355     aui32ElementPointers[0] = This_Element;
2356 
2357     tng__H264ES_writebits_SEI_buffering_period_header(
2358         pMTX_Header, aui32ElementPointers,
2359         ui8NalHrdBpPresentFlag,
2360         ui8nal_cpb_cnt_minus1,
2361         ui8nal_initial_cpb_removal_delay_length,
2362         ui32nal_initial_cpb_removal_delay,
2363         ui32nal_initial_cpb_removal_delay_offset,
2364         ui8VclHrdBpPresentFlag,
2365         ui8nal_cpb_cnt_minus1,
2366         ui32vcl_initial_cpb_removal_delay,
2367         ui32vcl_initial_cpb_removal_delay_offset);
2368 
2369     pMTX_Header->ui32Elements++;
2370     //Has been used as an index, so need to add 1 for a valid element count
2371     return;
2372 }
2373 
tng__H264ES_prepare_SEI_picture_timing_header(unsigned char * virtual_addr,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)2374 void tng__H264ES_prepare_SEI_picture_timing_header(
2375     unsigned char *virtual_addr,
2376     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2377     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2378     IMG_UINT32 ui32dpb_output_delay_length_minus1,
2379     IMG_UINT32 ui32cpb_removal_delay,
2380     IMG_UINT32 ui32dpb_output_delay,
2381     IMG_UINT8 ui8pic_struct_present_flag,
2382     IMG_UINT8 ui8pic_struct,
2383     IMG_UINT8 ui8NumClockTS,
2384     IMG_UINT8 *aui8clock_timestamp_flag,
2385     IMG_UINT8 ui8full_timestamp_flag,
2386     IMG_UINT8 ui8seconds_flag,
2387     IMG_UINT8 ui8minutes_flag,
2388     IMG_UINT8 ui8hours_flag,
2389     IMG_UINT8 ui8seconds_value,
2390     IMG_UINT8 ui8minutes_value,
2391     IMG_UINT8 ui8hours_value,
2392     IMG_UINT8 ui8ct_type,
2393     IMG_UINT8 ui8nuit_field_based_flag,
2394     IMG_UINT8 ui8counting_type,
2395     IMG_UINT8 ui8discontinuity_flag,
2396     IMG_UINT8 ui8cnt_dropped_flag,
2397     IMG_UINT8 ui8n_frames,
2398     IMG_UINT8 ui8time_offset_length,
2399     IMG_INT32 i32time_offset)
2400 {
2401     // Essential we initialise our header structures before building
2402     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2403     MTX_HEADER_ELEMENT *This_Element;
2404     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2405     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2406     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2407     aui32ElementPointers[0] = This_Element;
2408 
2409     tng__H264ES_writebits_SEI_picture_timing_header(
2410         pMTX_Header, aui32ElementPointers,
2411         ui8CpbDpbDelaysPresentFlag,
2412         ui32cpb_removal_delay_length_minus1,
2413         ui32dpb_output_delay_length_minus1,
2414         ui32cpb_removal_delay,
2415         ui32dpb_output_delay,
2416         ui8pic_struct_present_flag,
2417         ui8pic_struct,
2418         ui8NumClockTS,
2419         aui8clock_timestamp_flag,
2420         ui8full_timestamp_flag,
2421         ui8seconds_flag,
2422         ui8minutes_flag,
2423         ui8hours_flag,
2424         ui8seconds_value,
2425         ui8minutes_value,
2426         ui8hours_value,
2427         ui8ct_type,
2428         ui8nuit_field_based_flag,
2429         ui8counting_type,
2430         ui8discontinuity_flag,
2431         ui8cnt_dropped_flag,
2432         ui8n_frames,
2433         ui8time_offset_length,
2434         i32time_offset);
2435 
2436     pMTX_Header->ui32Elements++;
2437     //Has been used as an index, so need to add 1 for a valid element count
2438     return;
2439 }
2440 
tng__H264ES_set_sequence_level_profile(H264_SEQUENCE_HEADER_PARAMS * pSHParams,IMG_UINT8 uiLevel,IMG_UINT8 uiProfile)2441 static void tng__H264ES_set_sequence_level_profile(
2442     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
2443     IMG_UINT8 uiLevel,
2444     IMG_UINT8 uiProfile)
2445 {
2446     switch (uiLevel) {
2447     case 10:
2448         pSHParams->ucLevel =  SH_LEVEL_10;
2449         break;
2450     case 111:
2451         pSHParams->ucLevel =  SH_LEVEL_1B;
2452         break;
2453     case 11:
2454         pSHParams->ucLevel =  SH_LEVEL_11;
2455         break;
2456     case 12:
2457         pSHParams->ucLevel =  SH_LEVEL_12;
2458         break;
2459     case 20:
2460         pSHParams->ucLevel =  SH_LEVEL_20;
2461         break;
2462     case 30:
2463         pSHParams->ucLevel =  SH_LEVEL_30;
2464         break;
2465     case 31:
2466         pSHParams->ucLevel =  SH_LEVEL_31;
2467         break;
2468     case 32:
2469         pSHParams->ucLevel =  SH_LEVEL_32;
2470         break;
2471     case 40:
2472         pSHParams->ucLevel =  SH_LEVEL_40;
2473         break;
2474     case 41:
2475         pSHParams->ucLevel =  SH_LEVEL_41;
2476         break;
2477     case 42:
2478         pSHParams->ucLevel =  SH_LEVEL_42;
2479         break;
2480     default:
2481         pSHParams->ucLevel =  SH_LEVEL_30;
2482         break;
2483     }
2484 
2485     switch (uiProfile) {
2486     case 5:
2487         pSHParams->ucProfile  = SH_PROFILE_BP;
2488         break;
2489     case 6:
2490         pSHParams->ucProfile  = SH_PROFILE_MP;
2491         break;
2492     default:
2493         pSHParams->ucProfile  = SH_PROFILE_MP;
2494         break;
2495     }
2496     return ;
2497 }
2498 
tng__H264ES_prepare_sequence_header(void * pHeaderMemory,H264_VUI_PARAMS * psVUI_Params,H264_CROP_PARAMS * psCropParams,IMG_UINT16 ui16PictureWidth,IMG_UINT16 ui16PictureHeight,IMG_UINT32 ui32CustomQuantMask,IMG_UINT8 ui8ProfileIdc,IMG_UINT8 ui8LevelIdc,IMG_UINT8 ui8FieldCount,IMG_UINT8 ui8MaxNumRefFrames,IMG_BOOL bPpsScaling,IMG_BOOL bUseDefaultScalingList,IMG_BOOL bEnableLossless,IMG_BOOL bASO)2499 void tng__H264ES_prepare_sequence_header(
2500     void *pHeaderMemory,
2501     H264_VUI_PARAMS *psVUI_Params,
2502     H264_CROP_PARAMS *psCropParams,
2503     IMG_UINT16 ui16PictureWidth,
2504     IMG_UINT16 ui16PictureHeight,
2505     IMG_UINT32 ui32CustomQuantMask,
2506     IMG_UINT8 ui8ProfileIdc,
2507     IMG_UINT8 ui8LevelIdc,
2508     IMG_UINT8 ui8FieldCount,
2509     IMG_UINT8 ui8MaxNumRefFrames,
2510     IMG_BOOL  bPpsScaling,
2511     IMG_BOOL  bUseDefaultScalingList,
2512     IMG_BOOL  bEnableLossless,
2513     IMG_BOOL  bASO
2514 )
2515 {
2516     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2517      * Essential we initialise our header structures before building
2518      */
2519     H264_SEQUENCE_HEADER_PARAMS SHParams;
2520     /* Route output elements to memory provided */
2521     MTX_HEADER_PARAMS  *mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2522     MTX_HEADER_ELEMENT *This_Element;
2523     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2524     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2525     This_Element = mtx_hdr->asElementStream;
2526     aui32ElementPointers[0] = This_Element;
2527 
2528     memset(&SHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
2529 
2530     SHParams.ucProfile = ui8ProfileIdc - 5;
2531     SHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
2532     SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
2533     SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
2534     SHParams.gaps_in_frame_num_value = IMG_FALSE;
2535     SHParams.VUI_Params_Present = psVUI_Params->vui_flag;
2536     if (SHParams.VUI_Params_Present)
2537         memcpy(&SHParams.VUI_Params, psVUI_Params, sizeof(H264_VUI_PARAMS));
2538     SHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
2539 
2540     SHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
2541     SHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
2542 
2543 
2544     SHParams.seq_scaling_matrix_present_flag = (ui32CustomQuantMask != 0 && !bPpsScaling);
2545     SHParams.bUseDefaultScalingList = (bUseDefaultScalingList && !bPpsScaling);
2546 
2547     SHParams.max_num_ref_frames = ui8MaxNumRefFrames;
2548     SHParams.bIsLossless = bEnableLossless;
2549     SHParams.log2_max_pic_order_cnt = 6;
2550 #ifdef _TOPAZHP_PDUMP_
2551     tng_trace_seq_header_params(&SHParams);
2552 #endif
2553     tng__H264ES_writebits_sequence_header(mtx_hdr, aui32ElementPointers, &SHParams, psCropParams, NULL, bASO);
2554     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2555 }
2556 
tng__H264ES_writebits_mvc_sequence_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCrop,H264_SCALING_MATRIX_PARAMS __maybe_unused * psScalingMatrix)2557 static void tng__H264ES_writebits_mvc_sequence_header(
2558     MTX_HEADER_PARAMS *pMTX_Header,
2559     MTX_HEADER_ELEMENT **aui32ElementPointers,
2560     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
2561     H264_CROP_PARAMS *psCrop,
2562     H264_SCALING_MATRIX_PARAMS __maybe_unused * psScalingMatrix)
2563 {
2564     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
2565     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
2566 
2567     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2568 
2569     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
2570     // Byte aligned (bit 32)
2571     tng__write_upto8bits_elements(pMTX_Header,
2572                                   aui32ElementPointers, (0 << 7) |                                                        // forbidden_zero_bit=0
2573                                   (0x3 << 5) |                                                                            // nal_ref_idc=01 (may be 11)
2574                                   (15),                                                                                           // nal_unit_type=15
2575                                   8);
2576 
2577     // Byte aligned (bit 40)
2578     // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
2579     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 118, 8);
2580 
2581     // Byte aligned (bit 48)
2582     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (0 << 7) |     // constrain_set0_flag = 1 for MP + BP constraints
2583                                   (0 << 6) |                                                  // constrain_set1_flag  = 1 for MP + BP constraints
2584                                   (0 << 5) |                                                                                              // constrain_set2_flag = always 0 in BP/MP
2585                                   (0 << 4),                                                           // constrain_set3_flag = 1 for level 1b, 0 for others
2586                                   // reserved_zero_4bits = 0
2587                                   8);
2588 
2589     // Byte aligned (bit 56)
2590     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);                  // level_idc (8 bits) = 11 for 1b, 10xlevel for others
2591 
2592     tng__generate_ue(pMTX_Header, aui32ElementPointers, MVC_SPS_ID);                // seq_parameter_Set_id = 1 FOR subset-SPS
2593     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // chroma_format_idc = 1
2594     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_luma_minus8 = 0
2595     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_chroma_minus8 = 0
2596     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->bIsLossless ? 1 : 0, 1); // qpprime_y_zero_transform_bypass_flag = 0
2597 
2598     if (pSHParams->bUseDefaultScalingList || pSHParams->seq_scaling_matrix_present_flag) {
2599         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);         // seq_scaling_matrix_present_flag
2600         if (!pSHParams->bUseDefaultScalingList) {
2601 #ifdef _FIXME_
2602             H264_WriteBits_ScalingLists(pMTX_Header, aui32ElementPointers, psScalingMatrix, IMG_TRUE);
2603 #endif
2604             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
2605         } else {
2606             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);         // seq_scaling_list_present_flag[i] = 0; 0 < i < 8
2607         }
2608     } else {
2609         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // seq_scaling_matrix_present_flag
2610     }
2611 
2612     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // log2_max_frame_num_minus4 = 1
2613     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // pic_order_cnt_type = 0
2614     tng__generate_ue(pMTX_Header, aui32ElementPointers, 2);         // log2_max_pic_order_cnt_Isb_minus4 = 2
2615 
2616     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames); //num_ref_frames ue(2), typically 2
2617     // Bytes aligned (bit 72)
2618     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2619                                   (pSHParams->gaps_in_frame_num_value), // gaps_in_frame_num_value_allowed_Flag   - (1 bit)
2620                                   1);
2621 
2622     ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2623     ///**** ELEMENT BITCOUNT: xx
2624     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1);                          //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
2625     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1);          //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column)
2626     // We don't know the alignment at this point, so will have to use bit writing functions
2627 
2628     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->ucFrame_mbs_only_flag, 1); // frame_mb_only_flag 1=frame encoding, 0=field encoding
2629 
2630     if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
2631         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
2632 
2633     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // direct_8x8_inference_flag=1 in Topaz
2634 
2635     if (psCrop->bClip) {
2636         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
2637         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16LeftCropOffset);
2638         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16RightCropOffset);
2639         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16TopCropOffset);
2640         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16BottomCropOffset);
2641 
2642     } else {
2643         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
2644     }
2645 
2646     ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2647     ///**** ELEMENT BITCOUNT: xx
2648     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2649                                   (pSHParams->VUI_Params_Present),                                        // vui_parameters_present_flag (VUI only in 1st sequence of stream)
2650                                   1);
2651     if (pSHParams->VUI_Params_Present > 0)
2652         tng__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
2653 
2654 
2655     {
2656         int viewIdx = 0;
2657         int numViews = MAX_MVC_VIEWS;
2658         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //bit_equal_to_one
2659 
2660         // sequence parameter set MVC extension
2661         tng__generate_ue(pMTX_Header, aui32ElementPointers, (numViews - 1));     //num_views_minus1
2662         for (viewIdx = 0; viewIdx < numViews; viewIdx++) {
2663             tng__generate_ue(pMTX_Header, aui32ElementPointers, viewIdx);
2664         }
2665 
2666         // anchor references
2667         for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
2668             //tng__generate_ue( pMTX_Header, aui32ElementPointers, 0);     // num_anchor_refs_l0  = 0
2669             tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_anchor_refs_l0  = 1; view-1 refers to view-0
2670             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // anchor_ref_l0 = 0
2671 
2672             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_anchor_refs_l1  = 0
2673         }
2674 
2675         // non-anchor references
2676         for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
2677             tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_non_anchor_refs_l0  = 0
2678             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // non_anchor_refs_l0  = 0
2679 
2680             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_non_anchor_refs_l1  = 0
2681         }
2682 
2683         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_level_values_signaled_minus1  = 0
2684 
2685         //for(levelIdx=0; levelIdx<= 0; levelIdx++)
2686         {
2687             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);          // level_idc (8 bits) = 11 for 1b, 10xlevel for others
2688             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_applicable_ops_minus1  = 0
2689             {
2690                 tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 3); // applicable_ops_temporal_id  = 0
2691                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_target_views_minus1  = 0
2692                 {
2693                     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);              // applicable_op_target_view_id  = 0
2694                 }
2695                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_views_minus1  = 0
2696             }
2697         }
2698 
2699         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2700                                       0,                    // mvc_vui_parameters_present_flag =0
2701                                       1);
2702 
2703         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2704                                       0,                    // additional_extension2_flag =0
2705                                       1);
2706     }
2707 
2708 
2709     // Finally we need to align to the next byte
2710     // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
2711     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
2712 }
2713 
2714 
2715 /*
2716 ******************************************************************************
2717  @Function              H264_PrepareMvcSequenceHeader
2718  @details
2719  Prepare an H264 SPS in a form for the MTX to encode into a bitstream.
2720  @param    pMTX_Header       : pointer to header structure to populate
2721  @param    uiPicWidthInMbs   : picture width in MBs
2722  @param    uiPicHeightInMbs  : picture height in MBs
2723  @param    bVuiParamsPresent : IMG_TRUE if VUI paramters present
2724  @param    psParams          : VUI parameters
2725  @param    psCrop                         : Pointer to crop parameter structure
2726  @param   psSHParams              : Pointer to sequence header params structure
2727  @return   None
2728 ******************************************************************************/
tng__H264ES_prepare_mvc_sequence_header(void * pHeaderMemory,H264_CROP_PARAMS * psCropParams,IMG_UINT16 ui16PictureWidth,IMG_UINT16 ui16PictureHeight,IMG_UINT32 ui32CustomQuantMask,IMG_UINT8 ui8ProfileIdc,IMG_UINT8 ui8LevelIdc,IMG_UINT8 ui8FieldCount,IMG_UINT8 ui8MaxNumRefFrames,IMG_BOOL bPpsScaling,IMG_BOOL bUseDefaultScalingList,IMG_BOOL bEnableLossless,IMG_BOOL __maybe_unused bASO)2729 void tng__H264ES_prepare_mvc_sequence_header(
2730     void *pHeaderMemory,
2731     H264_CROP_PARAMS *psCropParams,
2732     IMG_UINT16 ui16PictureWidth,
2733     IMG_UINT16 ui16PictureHeight,
2734     IMG_UINT32 ui32CustomQuantMask,
2735     IMG_UINT8 ui8ProfileIdc,
2736     IMG_UINT8 ui8LevelIdc,
2737     IMG_UINT8 ui8FieldCount,
2738     IMG_UINT8 ui8MaxNumRefFrames,
2739     IMG_BOOL  bPpsScaling,
2740     IMG_BOOL  bUseDefaultScalingList,
2741     IMG_BOOL  bEnableLossless,
2742     IMG_BOOL  __maybe_unused bASO)
2743 {
2744     H264_SEQUENCE_HEADER_PARAMS sSHParams;
2745     MTX_HEADER_PARAMS * pMTX_Header;
2746     MTX_HEADER_ELEMENT *This_Element;
2747     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2748     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2749 
2750 #if HEADERS_VERBOSE_OUTPUT
2751     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2752     drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2753     drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2754 #endif
2755 
2756     // Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2757     // Essential we initialise our header structures before building
2758     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2759     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2760     aui32ElementPointers[0] = This_Element;
2761 
2762     memset(&sSHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
2763 
2764     sSHParams.ucProfile = ui8ProfileIdc - 5;
2765     sSHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
2766     sSHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
2767     sSHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
2768     sSHParams.gaps_in_frame_num_value = IMG_FALSE;
2769     sSHParams.VUI_Params_Present = IMG_FALSE;
2770     sSHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
2771     sSHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
2772     sSHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
2773     sSHParams.max_num_ref_frames = ui8MaxNumRefFrames;
2774     sSHParams.bIsLossless = bEnableLossless;
2775     sSHParams.log2_max_pic_order_cnt = 6;
2776 #ifdef _TOPAZHP_PDUMP_
2777     tng_trace_seq_header_params(&sSHParams);
2778 #endif
2779     tng__H264ES_writebits_mvc_sequence_header(pMTX_Header, aui32ElementPointers, &sSHParams, psCropParams, NULL);
2780     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
2781     return ;
2782 }
2783 
tng__H264ES_prepare_picture_header(void * pHeaderMemory,IMG_BOOL bCabacEnabled,IMG_BOOL b_8x8transform,IMG_BOOL bIntraConstrained,IMG_INT8 i8CQPOffset,IMG_BOOL bWeightedPrediction,IMG_UINT8 ui8WeightedBiPred,IMG_BOOL bMvcPPS,IMG_BOOL bScalingMatrix,IMG_BOOL bScalingLists)2784 void tng__H264ES_prepare_picture_header(
2785     void *pHeaderMemory,
2786     IMG_BOOL    bCabacEnabled,
2787     IMG_BOOL    b_8x8transform,
2788     IMG_BOOL    bIntraConstrained,
2789     IMG_INT8    i8CQPOffset,
2790     IMG_BOOL    bWeightedPrediction,
2791     IMG_UINT8   ui8WeightedBiPred,
2792     IMG_BOOL    bMvcPPS,
2793     IMG_BOOL    bScalingMatrix,
2794     IMG_BOOL    bScalingLists)
2795 {
2796     MTX_HEADER_PARAMS *pMTX_Header;
2797     H264_PICTURE_HEADER_PARAMS sPHParams;
2798 
2799     /* Route output elements to memory provided */
2800     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2801     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2802      * Essential we initialise our header structures before building
2803      */
2804     MTX_HEADER_ELEMENT *This_Element;
2805     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2806     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2807     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2808     aui32ElementPointers[0] = This_Element;
2809 
2810     memset(&sPHParams, 0, sizeof(H264_PICTURE_HEADER_PARAMS));
2811 
2812     sPHParams.pic_parameter_set_id = bMvcPPS ? MVC_PPS_ID : 0;
2813     sPHParams.seq_parameter_set_id = bMvcPPS ? MVC_SPS_ID : 0;
2814     sPHParams.entropy_coding_mode_flag = bCabacEnabled ? 1 : 0;
2815     sPHParams.weighted_pred_flag = bWeightedPrediction;
2816     sPHParams.weighted_bipred_idc = ui8WeightedBiPred;
2817     sPHParams.chroma_qp_index_offset = i8CQPOffset;
2818     sPHParams.constrained_intra_pred_flag = bIntraConstrained ? 1 : 0;
2819     sPHParams.transform_8x8_mode_flag = b_8x8transform ? 1 : 0;
2820     sPHParams.pic_scaling_matrix_present_flag = bScalingMatrix ? 1 : 0;
2821     sPHParams.bUseDefaultScalingList = !bScalingLists;
2822     sPHParams.second_chroma_qp_index_offset = i8CQPOffset;
2823 #ifdef _TOPAZHP_PDUMP_
2824     tng_trace_pic_header_params(&sPHParams);
2825 #endif
2826     tng__H264ES_writebits_picture_header(pMTX_Header, aui32ElementPointers, &sPHParams, NULL);
2827     /* Has been used as an index, so need to add 1 for a valid element count */
2828     pMTX_Header->ui32Elements++;
2829     return ;
2830 }
2831 
tng__H264_prepare_slice_header(IMG_UINT32 * pHeaderMemory,IMG_BOOL bIntraSlice,IMG_BOOL bInterBSlice,IMG_BOOL bMultiRef,IMG_UINT8 ui8DisableDeblockingFilterIDC,IMG_UINT32 ui32DisplayFrameNumber,IMG_UINT32 ui32FrameNumId,IMG_UINT32 uiFirst_MB_Address,IMG_UINT32 __maybe_unused uiMBSkipRun,IMG_BOOL bCabacEnabled,IMG_BOOL bIsInterlaced,IMG_UINT8 ui8FieldNum,WEIGHTED_PREDICTION_VALUES * pWeightedSetup,IMG_BOOL bIsLongTermRef)2832 void tng__H264_prepare_slice_header(
2833     IMG_UINT32 *pHeaderMemory,
2834     IMG_BOOL        bIntraSlice,
2835     IMG_BOOL        bInterBSlice,
2836     IMG_BOOL        bMultiRef,
2837     IMG_UINT8       ui8DisableDeblockingFilterIDC,
2838     IMG_UINT32      ui32DisplayFrameNumber,
2839     IMG_UINT32      ui32FrameNumId,
2840     IMG_UINT32      uiFirst_MB_Address,
2841     IMG_UINT32      __maybe_unused uiMBSkipRun,
2842     IMG_BOOL        bCabacEnabled,
2843     IMG_BOOL        bIsInterlaced,
2844     IMG_UINT8       ui8FieldNum,
2845     WEIGHTED_PREDICTION_VALUES *pWeightedSetup,
2846     IMG_BOOL        bIsLongTermRef
2847 )
2848 {
2849     H264_SLICE_HEADER_PARAMS SlHParams;
2850     MTX_HEADER_PARAMS *pMTX_Header;
2851     /* Route output elements to memory provided */
2852     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2853 
2854     memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
2855 
2856 
2857     SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
2858     /* pcb -        I think that this is more correct now*/
2859     SlHParams.SliceFrame_Type = bIntraSlice ? (((ui32FrameNumId % (1 << 5)) == 0) ?
2860                                 SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
2861     /*
2862     if (bIntraSlice) {
2863         if ((ui32FrameNumId%(1<<5))==0)
2864             SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
2865         else
2866             SlHParams.SliceFrame_Type = SLHP_I_SLICEFRAME_TYPE;
2867     } else {
2868         if (bInterBSlice)
2869             SlHParams.SliceFrame_Type = SLHP_B_SLICEFRAME_TYPE;
2870         else
2871             SlHParams.SliceFrame_Type = SLHP_P_SLICEFRAME_TYPE;
2872     }
2873     */
2874     SlHParams.Frame_Num_DO   = (IMG_UINT8) ui32FrameNumId % (1 << 5);
2875     SlHParams.Idr_Pic_Id     = (IMG_UINT8)(ui32DisplayFrameNumber & 1);
2876     SlHParams.Picture_Num_DO = (IMG_UINT8)((ui32DisplayFrameNumber % (1 << 5)) * 2);
2877 
2878     SlHParams.First_MB_Address =  uiFirst_MB_Address;
2879     SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
2880     SlHParams.bPiCInterlace = bIsInterlaced;
2881     SlHParams.bFieldType    = ui8FieldNum;
2882     SlHParams.iDebAlphaOffsetDiv2   = 0;
2883     SlHParams.iDebBetaOffsetDiv2    = 0;
2884 
2885     if (bMultiRef)
2886         SlHParams.num_ref_idx_l0_active_minus1 = 1;
2887     else
2888         SlHParams.num_ref_idx_l0_active_minus1 = 0;
2889 
2890     SlHParams.weighted_pred_flag            = pWeightedSetup ? pWeightedSetup->weighted_pred_flag             : 0;
2891     SlHParams.weighted_bipred_idc   = pWeightedSetup ? pWeightedSetup->weighted_bipred_idc            : 0;
2892     SlHParams.luma_log2_weight_denom        = pWeightedSetup ? pWeightedSetup->luma_log2_weight_denom         : 0;
2893     SlHParams.chroma_log2_weight_denom      = pWeightedSetup ? pWeightedSetup->chroma_log2_weight_denom : 0;
2894     SlHParams.luma_weight_l0_flag[0]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][0]                      : 0;
2895     SlHParams.luma_weight_l0[0]             = pWeightedSetup ? pWeightedSetup->weight[0][0]                   : 0;
2896     SlHParams.luma_offset_l0[0]             = pWeightedSetup ? pWeightedSetup->offset[0][0]                   : 0;
2897     SlHParams.chroma_weight_l0_flag[0]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][0]                      : 0;
2898     SlHParams.chromaB_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[1][0]                   : 0;
2899     SlHParams.chromaB_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[1][0]                   : 0;
2900     SlHParams.chromaR_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[2][0]                   : 0;
2901     SlHParams.chromaR_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[2][0]                   : 0;
2902     SlHParams.luma_weight_l0_flag[1]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][1]                      : 0;
2903     SlHParams.luma_weight_l0[1]             = pWeightedSetup ? pWeightedSetup->weight[0][1]                   : 0;
2904     SlHParams.luma_offset_l0[1]             = pWeightedSetup ? pWeightedSetup->offset[0][1]                   : 0;
2905     SlHParams.chroma_weight_l0_flag[1]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][1]                      : 0;
2906     SlHParams.chromaB_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[1][1]                   : 0;
2907     SlHParams.chromaB_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[1][1]                   : 0;
2908     SlHParams.chromaR_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[2][1]                   : 0;
2909     SlHParams.chromaR_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[2][1]                   : 0;
2910 
2911     SlHParams.bIsLongTermRef = bIsLongTermRef;
2912     tng__H264_getelements_slice_header(pMTX_Header, &SlHParams, bCabacEnabled);
2913 
2914     /*
2915         {
2916             IMG_UINT32      *pMTX_Header_Mem = (IMG_UINT32 *)mtx_hdr;
2917             // rhk: first insert normal header.
2918             tng__H264_getelements_slice_header(mtx_hdr, &SlHParams, bCabacEnabled, uiIdrPicId);
2919 
2920             // put a marker to indicate that this is a complex header
2921             // note that first "int" in the buffer is used for number of elements
2922             // which is not going to be more than 255
2923             *pMTX_Header_Mem |= 0x100;
2924 
2925             // rhk: insert skipped frame header at an offset of 128 bytes
2926             pMTX_Header_Mem += (HEADER_SIZE >> 3);  // get a pointer to the second half of memory
2927             mtx_hdr = (MTX_HEADER_PARAMS *)pMTX_Header_Mem;
2928             tng__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun, bCabacEnabled);
2929         }
2930     */
2931 }
2932 
tng__MPEG4_prepare_sequence_header(void * 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)2933 void tng__MPEG4_prepare_sequence_header(
2934     void *pHeaderMemory,
2935     IMG_BOOL bBFrame,
2936     MPEG4_PROFILE_TYPE sProfile,
2937     IMG_UINT8 Profile_and_level_indication,
2938     FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
2939     IMG_UINT32 Picture_Width_Pixels,
2940     IMG_UINT32 Picture_Height_Pixels,
2941     VBVPARAMS * psVBVParams,
2942     IMG_UINT32 VopTimeResolution)
2943 {
2944     MTX_HEADER_PARAMS *mtx_hdr;
2945 
2946     /* Route output elements to memory provided */
2947     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2948     /* Builds a single MPEG4 video sequence header from the given parameters */
2949 
2950     /* Essential we initialise our header structures before building */
2951     MTX_HEADER_ELEMENT *This_Element;
2952     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2953     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2954     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2955     aui32ElementPointers[0] = This_Element;
2956 
2957     tng__MPEG4_writebits_sequence_header(mtx_hdr,
2958         				 aui32ElementPointers,
2959         				 bBFrame,
2960 					 sProfile,
2961        				 	 Profile_and_level_indication,
2962        				 	 sFixed_vop_time_increment,
2963         				 Picture_Width_Pixels,
2964         				 Picture_Height_Pixels,
2965         				 psVBVParams,
2966 					 VopTimeResolution);
2967 
2968     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2969 
2970 }
2971 
tng__MPEG4_prepare_vop_header(IMG_UINT32 * pHeaderMem,IMG_BOOL bIsVOP_coded,IMG_UINT32 VOP_time_increment,IMG_UINT8 sSearch_range,IMG_UINT8 eVop_Coding_Type,IMG_UINT32 VopTimeResolution)2972 void tng__MPEG4_prepare_vop_header(
2973     IMG_UINT32 *pHeaderMem,
2974     IMG_BOOL bIsVOP_coded,
2975     IMG_UINT32 VOP_time_increment,
2976     IMG_UINT8 sSearch_range,
2977     IMG_UINT8 eVop_Coding_Type,
2978     IMG_UINT32 VopTimeResolution)
2979 {
2980     MTX_HEADER_PARAMS *mtx_hdr;
2981 
2982     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2983 
2984     /* Builds a single MPEG4 VOP (picture) header from the given parameters */
2985     /* Essential we initialise our header structures before building */
2986     MTX_HEADER_ELEMENT *This_Element;
2987     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2988     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2989     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2990     aui32ElementPointers[0] = This_Element;
2991 
2992     /* Frame QScale no longer written here as it is inserted by MTX later
2993      * (add as parameter to MTX_Send_Elements_To_VLC)
2994      */
2995     tng__MPEG4_writebits_VOP_header(
2996         mtx_hdr, aui32ElementPointers, bIsVOP_coded,
2997         VOP_time_increment,
2998         sSearch_range,
2999         eVop_Coding_Type,
3000         VopTimeResolution);
3001 
3002     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
3003 
3004 }
3005 
tng__H263_prepare_sequence_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 Profile_and_level_indication)3006 void tng__H263_prepare_sequence_header(
3007     IMG_UINT32 *pHeaderMem,
3008     IMG_UINT8 Profile_and_level_indication)
3009 {
3010     MTX_HEADER_PARAMS *mtx_hdr;
3011 
3012     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3013 
3014     /* Builds a single H263 video sequence header from the given parameters */
3015 
3016     /* Essential we initialise our header structures before building */
3017     MTX_HEADER_ELEMENT *This_Element;
3018     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3019     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3020     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3021     aui32ElementPointers[0] = This_Element;
3022 
3023     H263_writebits_VideoSequenceHeader(mtx_hdr, aui32ElementPointers, Profile_and_level_indication);
3024 
3025     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
3026 
3027 }
3028 
tng__H263_prepare_picture_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 FrameRate,IMG_UINT16 PictureWidth,IMG_UINT16 PictureHeigth)3029 void tng__H263_prepare_picture_header(
3030     IMG_UINT32 *pHeaderMem,
3031     IMG_UINT8 Temporal_Ref,
3032     H263_PICTURE_CODING_TYPE PictureCodingType,
3033     H263_SOURCE_FORMAT_TYPE SourceFormatType,
3034     IMG_UINT8 FrameRate,
3035     IMG_UINT16 PictureWidth,
3036     IMG_UINT16 PictureHeigth)
3037 {
3038     MTX_HEADER_PARAMS *mtx_hdr;
3039 
3040     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3041 
3042     /* Essential we initialise our header structures before building */
3043     MTX_HEADER_ELEMENT *This_Element;
3044     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3045     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3046     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3047     aui32ElementPointers[0] = This_Element;
3048 
3049     H263_writebits_VideoPictureHeader(
3050         mtx_hdr, aui32ElementPointers,
3051         Temporal_Ref,
3052         PictureCodingType,
3053         SourceFormatType,
3054         FrameRate,
3055         PictureWidth,
3056         PictureHeigth);
3057 
3058     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
3059 }
3060 
tng__H263_prepare_GOBslice_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)3061 void tng__H263_prepare_GOBslice_header(
3062     IMG_UINT32 *pHeaderMem,
3063     IMG_UINT8 GOBNumber,
3064     IMG_UINT8 GOBFrameId)
3065 {
3066     MTX_HEADER_PARAMS *mtx_hdr;
3067 
3068     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3069 
3070     /* Essential we initialise our header structures before building */
3071     MTX_HEADER_ELEMENT *This_Element;
3072     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3073     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3074     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3075     aui32ElementPointers[0] = This_Element;
3076 
3077     H263_writebits_GOBSliceHeader(mtx_hdr, aui32ElementPointers, GOBNumber, GOBFrameId);
3078 
3079     mtx_hdr->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3080 
3081     /* silent the warning message */
3082     (void)Show_Bits;
3083     (void)Show_Elements;
3084     /*
3085     (void)tng__H264_writebits_SEI_rbspheader;
3086     (void)tng__H264_getelements_skip_B_slice;
3087     (void)tng__H264_getelements_backward_zero_B_slice;
3088     (void)tng__H264_getelements_rbsp_ATE_only;
3089     (void)tng_MPEG4_getelements_video_packet_header;
3090     */
3091 }
3092 
tng__H264ES_notforsims_writebits_extension_sliceheader(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled,IMG_BOOL bIsIDR)3093 void tng__H264ES_notforsims_writebits_extension_sliceheader(
3094     MTX_HEADER_PARAMS *pMTX_Header,
3095     MTX_HEADER_ELEMENT **aui32ElementPointers,
3096     H264_SLICE_HEADER_PARAMS *pSlHParams,
3097     IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
3098 {
3099     bStartNextRawDataElement = IMG_FALSE;
3100 
3101     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
3102 
3103     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
3104 
3105     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3106     ///**** ELEMENT BITCOUNT: 8
3107 
3108     // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
3109     //(3 bytes when slice is first in a picture without sequence/picture_header before picture
3110     // Byte aligned (bit 32 or 24)
3111     // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
3112     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
3113 
3114     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
3115     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3116 
3117     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 20, 5);    // nal_unit_type for coded_slice_extension
3118 
3119 
3120     //if(nal_unit_type == 14 || nal_unit_type == 20)
3121     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // SVC extension flag
3122 
3123     // nal_unit_header_mvc_extension()
3124     {
3125         if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
3126             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
3127         } else if ((pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) && bIsIDR) {
3128             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
3129         } else {
3130             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // non_idr_flag flag
3131         }
3132 
3133         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 6);   // priority_id flag
3134         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,    1, 10);   // view_id = hardcoded to 1 for dependent view
3135 
3136         //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 3);   // temporal_id flag
3137         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_ID); // temporal_id flag
3138         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ANCHOR_PIC_FLAG); // anchor_pic_flag
3139 
3140         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3141 
3142         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // interview flag is always FALSE for dependent frames
3143 
3144         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // reserved one bit
3145     }
3146 
3147     // slice header
3148     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
3149 
3150     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3151 
3152     ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3153     /* The following is slice parameter set in BP/MP */
3154     //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
3155     tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
3156     // kab: //not clean change from IDR to intra, IDR should have separate flag
3157 
3158     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);  // pic_parameter_set_id = 1 for dependent view
3159 
3160     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
3161     bStartNextRawDataElement = IMG_TRUE;
3162 
3163     if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
3164         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3165 
3166         // interlaced encoding
3167         if (pSlHParams->bPiCInterlace) {
3168             CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3169             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
3170             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3171             //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3172             bStartNextRawDataElement = IMG_TRUE;
3173         }
3174     }
3175 
3176     if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
3177         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3178         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // idr_pic_id ue(v) = 0 (1b) in Topaz
3179     }
3180 
3181     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
3182     bStartNextRawDataElement = IMG_TRUE;
3183 
3184     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3185         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
3186 
3187     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
3188         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NUM_REF_IDX_ACTIVE);
3189         bStartNextRawDataElement = IMG_TRUE;
3190     } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
3191         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3192         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);             // num_ref_idx_active_override_flag (1 bit) = 0 in Topaz
3193     }
3194 
3195     // reference picture list modification
3196     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
3197         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3198         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3199         bStartNextRawDataElement = IMG_TRUE;
3200     }
3201 
3202     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)        {
3203         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3204         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // ref_pic_list_ordering_flag_l1 (1 bit) = 0, no reference picture ordering in Topaz
3205     }
3206 
3207     // WEIGHTED PREDICTION
3208     /*      tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
3209         bStartNextRawDataElement = IMG_TRUE;*/
3210 
3211     if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
3212         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3213         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // no_output_of_prior_pics_flag (1 bit) = 0
3214         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // long_term_reference_flag (1 bit) = 0
3215     } else {
3216         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
3217         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3218         bStartNextRawDataElement = IMG_TRUE;
3219     }
3220 
3221     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
3222                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
3223         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3224         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
3225     }
3226     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
3227     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3228 
3229     ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3230     ///**** ELEMENT BITCOUNT: 11
3231     // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
3232     //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
3233     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
3234     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
3235         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
3236         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
3237     }
3238     //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
3239     // no byte alignment at end of slice headers
3240 }
3241 
3242 
3243 /*****************************************************************************
3244 ******************************************************************************/
tng__H264ES_notforsims_writebits_slice_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled,IMG_BOOL bIsIDR)3245 static void tng__H264ES_notforsims_writebits_slice_header(
3246     MTX_HEADER_PARAMS *pMTX_Header,
3247     MTX_HEADER_ELEMENT **aui32ElementPointers,
3248     H264_SLICE_HEADER_PARAMS *pSlHParams,
3249     IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
3250 {
3251     bStartNextRawDataElement = IMG_FALSE;
3252     unsigned char* pdg = (unsigned char*)pMTX_Header;
3253 
3254     if (pSlHParams->ui16MvcViewIdx == (IMG_UINT16)(NON_MVC_VIEW)) {
3255         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
3256     } else if (pSlHParams->ui16MvcViewIdx == MVC_BASE_VIEW_IDX) {
3257         tng__insert_prefix_nal_header(pMTX_Header, aui32ElementPointers,
3258                                       pSlHParams, bCabacEnabled);
3259         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_MIDHDR);
3260     } else {
3261         //Insert
3262         tng__H264ES_notforsims_writebits_extension_sliceheader(pMTX_Header, aui32ElementPointers,
3263                 pSlHParams, bCabacEnabled, bIsIDR);
3264         return;
3265     }
3266 
3267     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
3268 
3269     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3270     ///**** ELEMENT BITCOUNT: 8
3271 
3272     // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
3273     //(3 bytes when slice is first in a picture without sequence/picture_header before picture
3274     // Byte aligned (bit 32 or 24)
3275     // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
3276 
3277     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
3278 
3279     // nal_ref_idc, 0x03 for IDR slice, for non-IDR slice, fw chose a value
3280     //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 3 : ELEMENT_REFERENCE)), 2);
3281     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE);
3282     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3283 
3284     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),                   // nal_unit_tpye (5 bits) = I-frame IDR, and 1 for  rest
3285                                   5);
3286 
3287     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
3288     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3289 
3290 
3291     ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3292     /* The following is slice parameter set in BP/MP */
3293     //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
3294     tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
3295     // kab: //not clean change from IDR to intra, IDR should have separate flag
3296     if (pSlHParams->ui16MvcViewIdx != (IMG_UINT16)(NON_MVC_VIEW))
3297         tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->ui16MvcViewIdx);  // pic_parameter_set_id = 0
3298     else
3299         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);  // pic_parameter_set_id = 0
3300 
3301     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
3302 
3303     if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
3304         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3305         // interlaced encoding
3306         if (pSlHParams->bPiCInterlace) {
3307             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
3308             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3309             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3310         }
3311 
3312         if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
3313             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_IDR_PIC_ID);       // idr_pic_id ue(v)
3314     }
3315 
3316     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
3317 
3318     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3319         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
3320 
3321     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
3322         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NUM_REF_IDX_ACTIVE); // Insert token to tell MTX to insert override for number of active references
3323     } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
3324         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3325         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // num_ref_idx_active_override_flag (1 bit) = 0
3326     }
3327 
3328     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE &&
3329         pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
3330         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert reference list 0 reordering
3331         if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3332             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L1); // Insert token to tell MTX to insert reference list 1 reordering
3333     }
3334 
3335 
3336     // WEIGHTED PREDICTION
3337     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
3338     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3339 
3340     if (pSlHParams->bReferencePicture && pSlHParams->bIsLongTermRef) {
3341         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
3342 
3343         // Clear any existing long-term reference
3344         tng__generate_ue(pMTX_Header, aui32ElementPointers, 5);                                 // memory_management_control_operation
3345 
3346         // Allow a single long-term reference
3347         tng__generate_ue(pMTX_Header, aui32ElementPointers, 4);                                 // memory_management_control_operation
3348         tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);                                 // max_long_term_frame_idx_plus1
3349 
3350         // Set current picture as the long-term reference
3351         tng__generate_ue(pMTX_Header, aui32ElementPointers, 6);                                 // memory_management_control_operation
3352         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // long_term_frame_idx
3353 
3354         // End
3355         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // memory_management_control_operation
3356     } else {
3357         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
3358         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3359     }
3360 
3361     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
3362                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
3363         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
3364     }
3365     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
3366     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3367 
3368     ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3369     ///**** ELEMENT BITCOUNT: 11
3370     // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
3371     //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
3372     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
3373 
3374     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
3375         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
3376         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
3377     }
3378     //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
3379     // no byte alignment at end of slice headers
3380 }
3381 
3382 /******************************************************************************
3383  @Function              H264_NOTFORSIMS_PrepareSliceHeader
3384  @details
3385  Sim guys, DO NOT EVER USE THIS FUNCTION!
3386  Prepare an H264 slice header in a form for the MTX to encode into a
3387  bitstream.
3388  @param    pMTX_Header        : pointer to header structure to populate
3389  @param    bIntraSlice        : IMG_TRUE if this is an IDR or I slice
3390  @param    bInterBSlice        : IMG_TRUE if this is a B Frame slice
3391  @param    ui8DisableDeblockingFilterIDC : syntax element
3392  @param    ui32FrameNumId      : syntax element (used for references)
3393  @param    uiFirst_MB_Address : first_mb_in_slice syntax element
3394  @param    uiMBSkipRun        : number of MBs to skip
3395  @param    bCabacEnabled      : IMG_TRUE to use CABAC
3396  @param    bIsInterlaced      : IMG_TRUE for interlaced slices
3397  @param    bIsIDR             : IMG_TRUE if this is an IDR slice
3398  @param    bIsLongTermRef     : IMG_TRUE if the frame is to be used as a long-term reference
3399  @return   None
3400 ******************************************************************************/
3401 
tng__H264ES_notforsims_prepare_sliceheader(IMG_UINT8 * slice_mem_p,IMG_UINT32 ui32SliceType,IMG_UINT8 ui8DisableDeblockingFilterIDC,IMG_UINT32 uiFirst_MB_Address,IMG_UINT32 __maybe_unused uiMBSkipRun,IMG_BOOL bCabacEnabled,IMG_BOOL bIsInterlaced,IMG_UINT16 ui16MvcViewIdx,IMG_BOOL bIsLongTermRef)3402 void tng__H264ES_notforsims_prepare_sliceheader(
3403     IMG_UINT8      *slice_mem_p,
3404     IMG_UINT32      ui32SliceType,
3405     IMG_UINT8       ui8DisableDeblockingFilterIDC,
3406     IMG_UINT32      uiFirst_MB_Address,
3407     IMG_UINT32      __maybe_unused uiMBSkipRun,
3408     IMG_BOOL        bCabacEnabled,
3409     IMG_BOOL        bIsInterlaced,
3410     IMG_UINT16      ui16MvcViewIdx,
3411     IMG_BOOL        bIsLongTermRef
3412 )
3413 {
3414     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3415     MTX_HEADER_PARAMS *pMTX_Header = (MTX_HEADER_PARAMS *) &(slice_temp_p->sSliceHdrTmpl);
3416     H264_SLICE_HEADER_PARAMS SlHParams;
3417     MTX_HEADER_ELEMENT *This_Element;
3418     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3419     IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
3420     IMG_BOOL bIntraSlice = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
3421     IMG_BOOL bInterBSlice = (eSliceType == IMG_FRAME_INTER_B);
3422     IMG_BOOL bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
3423 
3424     memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
3425 
3426     SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
3427     /* pcb -  I think that this is more correct now  -- This should also work for IDR-P frames which will be marked as SLHP_P_SLICEFRAME_TYPE */
3428     SlHParams.SliceFrame_Type = bIntraSlice ? (bIsIDR ? SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
3429 
3430     SlHParams.First_MB_Address = uiFirst_MB_Address;
3431     SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
3432     SlHParams.bPiCInterlace = bIsInterlaced;
3433     SlHParams.iDebAlphaOffsetDiv2 = 0;
3434     SlHParams.iDebBetaOffsetDiv2  = 0;
3435     // setup the new flags used for B frame as reference
3436     SlHParams.bReferencePicture = bInterBSlice ? 0 : 1;
3437     SlHParams.ui16MvcViewIdx = ui16MvcViewIdx;
3438     SlHParams.bIsLongTermRef = bIsLongTermRef;
3439     SlHParams.log2_max_pic_order_cnt = 2;
3440     SlHParams.uLongTermRefNum = 0;
3441     SlHParams.bRefIsLongTermRef[0] = 0;
3442     SlHParams.uRefLongTermRefNum[0] = 0;
3443     SlHParams.bRefIsLongTermRef[1] = 0;
3444     SlHParams.uRefLongTermRefNum[1] = 0;
3445     // Builds a single slice header from the given parameters (mid frame)
3446     // Essential we initialise our header structures before building
3447 //    memset(pMTX_Header, 0, 128);
3448     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3449     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3450     aui32ElementPointers[0] = This_Element;
3451 #ifdef _TOPAZHP_PDUMP_
3452     tng_trace_slice_header_params(&SlHParams);
3453 #endif
3454     tng__H264ES_notforsims_writebits_slice_header(pMTX_Header, aui32ElementPointers, &SlHParams, bCabacEnabled, bIsIDR);
3455     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3456 }
3457 
3458 /**************************************************************************************************
3459 * Function:             H263_NOTFORSIMS_PrepareGOBSliceHeader
3460 * Description:  Generates the slice params template
3461 *
3462 ***************************************************************************************************/
3463 
tng__H263ES_notforsims_prepare_gobsliceheader(IMG_UINT8 * slice_mem_p)3464 void tng__H263ES_notforsims_prepare_gobsliceheader(
3465     IMG_UINT8       *slice_mem_p)
3466 {
3467     // Essential we initialise our header structures before building
3468     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3469     MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
3470     MTX_HEADER_ELEMENT *This_Element;
3471     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3472     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3473     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3474     aui32ElementPointers[0] = This_Element;
3475     H263_NOTFORSIMS_WriteBits_GOBSliceHeader(pMTX_Header, aui32ElementPointers);
3476     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3477 }
3478 
3479 /**************************************************************************************************
3480 * Function:             MPEG2_PrepareSliceHeader
3481 * Description:  Generates the slice params template
3482 *
3483 ***************************************************************************************************/
tng__MPEG2_prepare_sliceheader(IMG_UINT8 * slice_mem_p)3484 void tng__MPEG2_prepare_sliceheader(
3485     IMG_UINT8               *slice_mem_p)
3486 {
3487     // Essential we initialise our header structures before building
3488     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3489     MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
3490     MTX_HEADER_ELEMENT *This_Element;
3491     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3492     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3493     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3494     aui32ElementPointers[0] = This_Element;
3495 //      MPEG2_WriteBits_SliceHeader(pMTX_Header, aui32ElementPointers);
3496     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3497 }
3498 
3499 
3500