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