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