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) {
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;
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 ui8SBP = (aui32ElementPointers[pMTX_Header->Elements]->Size) & 7;
921 if (ui8SBP > 0)
922 pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8 - (ui8SBP));
923 return;
924 }
925
926
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)927 static void pnw__H264_writebits_slice_header(
928 MTX_HEADER_PARAMS *mtx_hdr,
929 MTX_HEADER_ELEMENT **elt_p,
930 H264_SLICE_HEADER_PARAMS *pSlHParams,
931 IMG_BOOL __maybe_unused bCabacEnabled,
932 IMG_UINT16 uiIdrPicId)
933 {
934 #ifdef USESTATICWHEREPOSSIBLE
935 IMG_UINT32 *p;
936 p = (IMG_UINT32 *) mtx_hdr;
937
938 p[0] = p[1] = 0;
939 p[2] = 40;
940 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) p[3] = 257;
941 else if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) p[3] = 9473;
942 else p[3] = 8449;
943 #else
944 /* -- Begin building the picture header element */
945 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
946
947 pnw__H264_writebits_startcode_prefix_element(
948 mtx_hdr,
949 elt_p,
950 pSlHParams->Start_Code_Prefix_Size_Bytes); /* Can be 3 or 4 bytes - always 4 bytes in our implementations */
951 pnw__H264_writebits_slice_header0(mtx_hdr, elt_p, pSlHParams);
952 #endif
953
954 pnw__H264_writebits_slice_header1(mtx_hdr, elt_p, pSlHParams, uiIdrPicId);
955
956 #if 0
957 if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
958 (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
959 pnw__generate_ue(mtx_hdr, elt_p, 0); /* hard code cabac_init_idc value of 0 */
960 }
961 #endif
962
963 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_SQP); /* MTX fills this value in */
964
965 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
966 pnw__H264_writebits_slice_header2(mtx_hdr, elt_p, pSlHParams);
967
968 /* no byte alignment at end of slice headers */
969 }
970
971
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)972 static void pnw__H264_getelements_skip_P_slice(
973 MTX_HEADER_PARAMS *mtx_hdr,
974 H264_SLICE_HEADER_PARAMS *pSlHParams,
975 IMG_UINT32 MB_No_In_Slice,
976 IMG_BOOL bCabacEnabled)
977 {
978 /* Skipped P-Slice
979 * Ensure pSlHParams is filled with appropriate parameters for a B-slice
980 * Essential we initialise our header structures before building
981 */
982 MTX_HEADER_ELEMENT *This_Element;
983 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
984 mtx_hdr->Elements = ELEMENTS_EMPTY;
985 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
986 elt_p[0] = This_Element;
987
988 /* pnw__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */
989 /* Not sure if this will be required in the final spec */
990 pnw__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, bCabacEnabled, 0);
991 pnw__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */
992
993 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
994 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
995 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
996 }
997
998
999
pnw__H264_getelements_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCropParams)1000 static void pnw__H264_getelements_sequence_header(
1001 MTX_HEADER_PARAMS *mtx_hdr,
1002 H264_SEQUENCE_HEADER_PARAMS *pSHParams,
1003 H264_CROP_PARAMS *psCropParams)
1004 {
1005 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1006 * Essential we initialise our header structures before building
1007 */
1008 MTX_HEADER_ELEMENT *This_Element;
1009 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1010 mtx_hdr->Elements = ELEMENTS_EMPTY;
1011 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1012 elt_p[0] = This_Element;
1013
1014 pnw__H264_writebits_sequence_header(mtx_hdr, elt_p, pSHParams, psCropParams);
1015 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1016 }
1017
1018
1019
pnw__H264_getelements_slice_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_BOOL bCabacEnabled,IMG_UINT16 uiIdrPicId)1020 static void pnw__H264_getelements_slice_header(
1021 MTX_HEADER_PARAMS *mtx_hdr,
1022 H264_SLICE_HEADER_PARAMS *pSlHParams,
1023 IMG_BOOL bCabacEnabled,
1024 IMG_UINT16 uiIdrPicId)
1025 {
1026 /* Builds a single slice header from the given parameters (mid frame)
1027 * Essential we initialise our header structures before building
1028 */
1029 MTX_HEADER_ELEMENT *This_Element;
1030 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1031 mtx_hdr->Elements = ELEMENTS_EMPTY;
1032 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1033 elt_p[0] = This_Element;
1034
1035 /* Not sure if this will be required in the final spec */
1036 /* pnw__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/
1037 pnw__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, bCabacEnabled, uiIdrPicId);
1038
1039 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1040 }
1041
1042
Bits2Code(IMG_UINT32 CodeVal)1043 static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1044 {
1045 IMG_UINT8 Bits = 32;
1046 if (CodeVal == 0)
1047 return 1;
1048 while (!(CodeVal & 0x80000000)) {
1049 CodeVal <<= 1;
1050 Bits--;
1051 }
1052 return Bits;
1053 }
1054
1055 /*
1056 * Intermediary functions to build MPEG4 headers
1057 */
1058 #define MATCH_TO_ENC
1059
1060
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)1061 static void pnw__MPEG4_writebits_sequence_header(
1062 MTX_HEADER_PARAMS *mtx_hdr,
1063 MTX_HEADER_ELEMENT **elt_p,
1064 IMG_BOOL __maybe_unused bBFrame,
1065 MPEG4_PROFILE_TYPE bProfile,
1066 IMG_UINT8 Profile_and_level_indication,
1067 FIXED_VOP_TIME_TYPE __maybe_unused sFixed_vop_time_increment,
1068 IMG_UINT32 Picture_Width_Pixels,
1069 IMG_UINT32 Picture_Height_Pixels,
1070 VBVPARAMS __maybe_unused * sVBVParams,
1071 IMG_UINT32 VopTimeResolution) /* Send NULL pointer if there are no VBVParams */
1072 {
1073 /* Essential we insert the element before we try to fill it! */
1074 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1075
1076 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */
1077 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1078
1079 /* profile_and_level_indication = 8 Bits = SP L0-L3 and SP L4-L5 are supported */
1080 pnw__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1081
1082 /* visual_object_start_code = 32 Bits = 0x1B5 */
1083 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1084 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1085 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1086 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 181, 8);
1087
1088 /* is_visual_object_identifier = 1 Bit = 0 */
1089 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1090
1091 /* visual_object_type = 4 Bits = Video ID = 1 */
1092 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1093
1094 /* video_signal_type = 1 Bit = 1 */
1095 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1096
1097 /* byte_aligned_bits = 2 Bits = 01b (byte_aligned_bits is 2-bit stuffing bit field 01) */
1098 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1099
1100 /* video_object_start_code = 32 Bits = 0x100 One VO only in a Topaz video stream */
1101 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1102 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1103 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1104 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1105
1106 /* video_object_layer_start_code = 32 Bits = 0x120 One VOL only in a Topaz stream */
1107 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1108 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1109 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1110 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 32, 8);
1111
1112 /* random_accessible_vol = 1 Bit = 0 (P-Frame in GOP) */
1113 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1114
1115 if (bProfile == SP) {
1116 /* video_object_type_indication = 8 Bits = 0x01 for SP */
1117 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1118 #ifndef MATCH_TO_ENC
1119 /* is_object_layer_identifier = 1 Bit = 0 for SP */
1120 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1121 #else
1122 /* to match the encoder */
1123
1124 /* is_object_layer_identifier = 1 Bit */
1125 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1126
1127 /* video_object_layer_verid = 4 Bits */
1128 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1129
1130 /* video_object_layer_priority = 3 Bits */
1131 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3); // 0 is reserved...
1132 #endif
1133 } else {
1134 /* video_object_type_indication = 8 Bits = 0x11 for ASP */
1135 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 3, 8);
1136
1137 /* is_object_layer_identifier = 1 Bit = 1 for ASP */
1138 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1139
1140 /* video_object_layer_verid = 4 Bits = 5 is for ASP */
1141 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4);
1142
1143 /* video_object_layer_priority = 3 Bits = 1 (Highest priority) */
1144 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3);
1145 }
1146
1147 /* aspect_ratio_info = 4 Bits =0x1 (Square pixel) */
1148 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1149 #ifndef MATCH_TO_ENC
1150 /* vol_control_parameters = 1 Bit = 1 (Always send VOL control parameters) */
1151 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1152 #else
1153 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1154
1155 #endif
1156
1157 #ifndef MATCH_TO_ENC
1158 /* chroma_format = 2 Bits = 01b (4:2:0) */
1159 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1160
1161 /* low_delay = 1 Bit = 0 with B-frame and 1 without B-frame */
1162 if (bBFrame)
1163 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1164 else
1165 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1166
1167 /* vbv_parameters = 1 Bit =0/1 */
1168 if (sVBVParams) {
1169 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1170
1171 /* For recording, only send vbv parameters in 1st sequence header.
1172 * For video phone, it should be sent more often, such as once per sequence
1173 */
1174 pnw__write_upto32bits_elements(
1175 mtx_hdr,
1176 elt_p,
1177 sVBVParams->First_half_bit_rate,
1178 15); /* first_half_bit_rate */
1179
1180 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1181 pnw__write_upto32bits_elements(
1182 mtx_hdr,
1183 elt_p,
1184 sVBVParams->Latter_half_bit_rate,
1185 15); /* latter_half_bit_rate */
1186
1187 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1188 pnw__write_upto32bits_elements(
1189 mtx_hdr,
1190 elt_p,
1191 sVBVParams->First_half_vbv_buffer_size,
1192 15);/* first_half_vbv_buffer_size */
1193
1194 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1195 pnw__write_upto32bits_elements(
1196 mtx_hdr, elt_p,
1197 sVBVParams->Latter_half_vbv_buffer_size,
1198 15); /* latter_half_vbv_buffer_size */
1199 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1200 pnw__write_upto32bits_elements(
1201 mtx_hdr,
1202 elt_p,
1203 sVBVParams->First_half_vbv_occupancy,
1204 15); /* first_half_vbv_occupancy */
1205 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1206 pnw__write_upto32bits_elements(
1207 mtx_hdr,
1208 elt_p,
1209 sVBVParams->Latter_half_vbv_occupancy,
1210 15); /* latter_half_vbv_occupancy */
1211 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1212 } else
1213 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); /* No vbv parameters present */
1214 #endif
1215 /* video_object_layer_shape = 2 Bits = 00b Rectangular shape */
1216 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1217 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1218
1219 /* vop_time_increment_solution = 16 Bits */
1220 pnw__write_upto32bits_elements(mtx_hdr, elt_p, VopTimeResolution, 16);
1221 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1222
1223 #ifndef MATCH_TO_ENC
1224 /* fixed_vop_rate = 1 Bits = 1 Always fixed frame rate */
1225 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1226
1227 /* fixed_vop_time_increment = Variable number of bits based on the time increment resolution. */
1228 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, Bits2Code(VopTimeResolution - 1));
1229 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1230 #else
1231 /* fixed_vop_rate = 1 Bits = 0 */
1232 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1233 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1234
1235 #endif
1236 /* video_object_layer_width = 13 Bits Picture width in pixel units */
1237 pnw__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Width_Pixels, 13);
1238 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1239
1240 /* video_object_layer_height = 13 Bits Picture height in pixel units */
1241 pnw__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Height_Pixels, 13);
1242 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1243
1244 /* interlaced = 1 Bit = 0 Topaz only encodes progressive frames */
1245 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1246
1247 /* obmc_disable = 1 Bit = 1 No overlapped MC in Topaz */
1248 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1249
1250 /* sprite_enable = 1 Bit = 0 Not use sprite in Topaz */
1251 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1252
1253 /* not_8_bit = 1 Bit = 0 8-bit video in Topaz */
1254 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1255
1256 /* quant_type = 1 Bit = 0 2nd quantization method in Topaz */
1257 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1258
1259 if (bProfile == ASP) {
1260 /* quarter_sample = 1 Bit = 0 No �-pel MC in Topaz */
1261 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1262 }
1263
1264 /* complexity_estimation_disable = 1 Bit = 1 No complexity estimation in Topaz */
1265 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1266 #ifndef MATCH_TO_ENC
1267
1268 /* resync_marker_disable = 1 Bit = 0 Always enable resync marker in Topaz */
1269 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1270 #else
1271 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1272 #endif
1273 /* data_partitioned = 1 Bit = 0 No data partitioning in Topaz */
1274 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1275
1276 if (bProfile == ASP) {
1277 /* newpred_enable = 1 Bit = 0 No newpred mode in SP/ASP */
1278 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1279 /* reduced_vop_resolution_enable=1 Bit = 0 No reduced resolution frame in SP/ASP */
1280 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1281 }
1282
1283 /* scalability = 1 Bit = 0 No scalability in SP/ASP */
1284 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1285
1286 /* byte_aligned_bits */
1287
1288 /* Tell MTX to insert the byte align field
1289 * (we don't know final stream size for alignment at this point)
1290 */
1291 pnw__insert_element_token(
1292 mtx_hdr,
1293 elt_p,
1294 ELEMENT_INSERTBYTEALIGN_MPG4);
1295
1296 return;
1297 }
1298
1299
1300 /* Utility function */
1301 /*
1302 IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1303 {
1304 IMG_UINT8 Bits=32;
1305 if(CodeVal==0)
1306 return 1;
1307 while(!(CodeVal & 0x80000000))
1308 {
1309 CodeVal<<=1;
1310 Bits--;
1311 }
1312 return Bits;
1313 }
1314 */
1315
1316 /* 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)1317 static void pnw__MPEG4_writebits_VOP_header(
1318 MTX_HEADER_PARAMS *mtx_hdr,
1319 MTX_HEADER_ELEMENT **elt_p,
1320 IMG_BOOL bIsVOP_coded,
1321 IMG_UINT8 VOP_time_increment,
1322 SEARCH_RANGE_TYPE sSearch_range,
1323 VOP_CODING_TYPE sVopCodingType,
1324 IMG_UINT32 VopTimeResolution)
1325 {
1326 IMG_BOOL bIsSyncPoint;
1327 /* Essential we insert the element before we try to fill it! */
1328 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1329
1330 /* visual_object_sequence_start_code = 32 Bits = 0x1B6 */
1331 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 438, 32);
1332
1333 /* vop_coding_type = 2 Bits = 0 for I-frame and 1 for P-frame */
1334 pnw__write_upto8bits_elements(mtx_hdr, elt_p, sVopCodingType, 2);
1335 bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0);
1336
1337 #ifndef MATCH_TO_ENC
1338 /* modulo_time_base = 1 Bit = 0 As at least 1 synchronization point (I-frame) per second in Topaz */
1339 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1340 #else
1341
1342 pnw__write_upto8bits_elements(mtx_hdr, elt_p, bIsSyncPoint ? 2 : 0 , bIsSyncPoint ? 2 : 1);
1343
1344 #endif
1345
1346 /* marker_bit = 1 Bits = 1 */
1347 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1348
1349 #ifndef MATCH_TO_ENC
1350 /* vop_time_increment = Variable bits based on resolution
1351 * = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame
1352 */
1353 pnw__write_upto8bits_elements(mtx_hdr, elt_p, VOP_time_increment, 5);
1354 #else
1355 /* will chrash here... */
1356 pnw__write_upto8bits_elements(
1357 mtx_hdr, elt_p,
1358 (VOP_time_increment) % VopTimeResolution,
1359 Bits2Code(VopTimeResolution - 1));
1360
1361 #endif
1362 /* marker_bit = 1 Bit = 1 */
1363 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1364
1365 if (!bIsVOP_coded) {
1366 /* vop_coded = 1 Bit = 0 for skipped frame */
1367 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1368
1369 /* byte_aligned_bits (skipped pictures are byte aligned) */
1370 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1371 * End of VOP - skipped picture
1372 */
1373 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_MPG4);
1374 } else {
1375 /* vop_coded = 1 Bit = 1 for normal coded frame */
1376 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1377
1378 if (sVopCodingType == P_FRAME) {
1379 /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */
1380 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1381 }
1382
1383 /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */
1384 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3);
1385
1386 /* vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX */
1387 /* pnw__write_upto8bits_elements(mtx_hdr, elt_p, Frame_Q_scale, 5); */
1388 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE);
1389
1390 if (sVopCodingType == P_FRAME) {
1391 /* vop_fcode_forward = 3 bits = 2 for +/-32 and 3 for +/-64 search range */
1392 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1393 pnw__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3);
1394 }
1395
1396 /*
1397 **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE
1398 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1399 video_packet_data ( ) = 1st VP that doesn�t have the VP header
1400
1401 while (nextbits_bytealigned ( ) == resync_marker)
1402 {
1403 video_packet _header( )
1404 video_packet _data( ) All MB in the slice
1405 }
1406 */
1407 }
1408 }
1409
1410 #if PSB_MFLD_DUMMY_CODE
1411 /*
1412 * Intermediary functions to build H263 headers
1413 */
H263_writebits_VideoSequenceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 Profile_and_level_indication)1414 static void H263_writebits_VideoSequenceHeader(
1415 MTX_HEADER_PARAMS *mtx_hdr,
1416 MTX_HEADER_ELEMENT **elt_p,
1417 IMG_UINT8 Profile_and_level_indication)
1418 {
1419 /* Essential we insert the element before we try to fill it! */
1420 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1421
1422 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */
1423 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1424
1425 /* profile_and_level_indication = 8 Bits = x SP L0-L3 and SP L4-L5 are supported */
1426 pnw__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1427
1428 /* visual_object_start_code = 32 Bits = 0x1B5 */
1429
1430 /* 437 too large for the pnw__write_upto32bits_elements function */
1431 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 437, 32);
1432
1433 /* is_visual_object_identifier = 1 Bit = 0 */
1434 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1435
1436 /* is_visual_object_type = 4 Bits = 1 Video ID */
1437 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1438
1439 /* video_signal_type = 1 Bit = 0 */
1440 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1441
1442 /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */
1443 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1444
1445 /* video_object_start_code =32 Bits = 0x100 One VO only in a Topaz video stream */
1446 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 256, 32);
1447
1448 return;
1449 }
1450 #endif
1451
1452
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)1453 static void H263_writebits_VideoPictureHeader(
1454 MTX_HEADER_PARAMS *mtx_hdr,
1455 MTX_HEADER_ELEMENT **elt_p,
1456 IMG_UINT8 Temporal_Ref,
1457 H263_PICTURE_CODING_TYPE PictureCodingType,
1458 //IMG_UINT8 Q_Scale,
1459 H263_SOURCE_FORMAT_TYPE SourceFormatType,
1460 IMG_UINT8 FrameRate,
1461 IMG_UINT32 PictureWidth,
1462 IMG_UINT32 PictureHeight)
1463 {
1464 IMG_UINT8 UFEP;
1465 IMG_UINT8 OCPCF = 0;
1466
1467 /* Essential we insert the element before we try to fill it! */
1468 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1469
1470 /* short_video_start_marker = 22 Bits = 0x20 Picture start code */
1471 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 32, 22);
1472
1473 /* temporal_reference = 8 Bits = 0-255 Each picture increased by 1 */
1474 pnw__write_upto8bits_elements(mtx_hdr, elt_p, Temporal_Ref, 8);
1475
1476 /* marker_bit = 1 Bit = 1 */
1477 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1478
1479 /* zero_bit = 1 Bits = 0 */
1480 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1481
1482 /* split_screen_indicator = 1 Bits = 0 No direct effect on encoding of picture */
1483 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1484
1485 /* document_camera_indicator= 1 Bits = 0 No direct effect on encoding of picture */
1486 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1487
1488 /* full_picture_freeze_release=1 Bits = 0 No direct effect on encoding of picture */
1489 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1490
1491 /* source_format = 3 Bits = 1-4 See note */
1492 pnw__write_upto8bits_elements(mtx_hdr, elt_p, SourceFormatType, 3);
1493
1494 /*Write optional Custom Picture Clock Frequency(OCPCF)*/
1495 if (FrameRate == 30 || FrameRate == 0/* unspecified */) {
1496 OCPCF = 0; // 0 for CIF PCF
1497 } else {
1498 OCPCF = 1; //1 for Custom PCF
1499 }
1500
1501 if (SourceFormatType != 7) {
1502 // picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame
1503 pnw__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 1);
1504 // four_reserved_zero_bits = 4 Bits = 0
1505 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4);
1506 } else {
1507 static unsigned char RTYPE = 0;
1508
1509 // if I- Frame set Update Full Extended PTYPE to true
1510 if ((PictureCodingType == I_FRAME) || (SourceFormatType == 7) || OCPCF) {
1511 UFEP = 1;
1512 } else {
1513 UFEP = 0;
1514 }
1515 pnw__write_upto8bits_elements(mtx_hdr, elt_p, UFEP, 3);
1516 if (UFEP == 1) {
1517 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 6, 3);
1518 pnw__write_upto8bits_elements(mtx_hdr, elt_p, OCPCF , 1);
1519
1520 /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1521 * - Optional Unrestricted Motion Vector (UMV)
1522 * - Optional Syntax-based Arithmetic Coding (SAC)
1523 * - Optional Advanced Prediction (AP) mode
1524 * - Optional Advanced INTRA Coding (AIC) mode
1525 * - Optional Deblocking Filter (DF) mode
1526 * - Optional Slice Structured (SS) mode
1527 * - Optional Reference Picture Selection(RPS) mode.
1528 * - Optional Independent Segment Decoding (ISD) mode
1529 * - Optional Alternative INTER VLC (AIV) mode
1530 * - Optional Modified Quantization (MQ) mode */
1531
1532 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 0, 10);
1533 // 10 reserve bits
1534 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 8, 4);
1535 // 4 reserve bits
1536 }
1537 // picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame
1538 pnw__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 3);
1539
1540 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1541 // two_reserve_bits, rounding_type, two_reserve_bits marker_bit CPM
1542 // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1543 pnw__write_upto8bits_elements(mtx_hdr, elt_p, RTYPE, 1);
1544 //2 reserve bits
1545 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1546 // - 1 (ON) to prevent start code emulation.
1547 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1 , 1);
1548 // CPM immediately follows the PPTYPE part of the header.
1549 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0 , 1);
1550
1551
1552 if (UFEP == 1) {
1553 IMG_UINT16 ui16PWI, ui16PHI;
1554 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1555 // aspect ratio
1556 //PictureWidth--;
1557 //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth >> 8), 1);
1558 //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth & 0xFF), 8);
1559 //Width = (PWI-1)*4, Height = PHI*4, see H263 spec 5.1.5
1560 ui16PWI = (PictureWidth >> 2) - 1;
1561 pnw__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PWI, 9);
1562
1563 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1564 // marker_bit = 1 Bit = 1
1565 //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeight >> 8), 1);
1566 //pnw__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeight & 0xFF), 8);
1567
1568 ui16PHI = PictureHeight >> 2;
1569 pnw__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PHI, 9);
1570 // good up to that point
1571 // pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1572 // marker_bit = 1 Bit = 1
1573 // just checking
1574 if (OCPCF == 1) {
1575 //IMG_UINT8 CPCFC;
1576 //CPCFC = (IMG_UINT8)(1800/(IMG_UINT16)FrameRate);
1577 /* you can use the table for division */
1578 //CPCFC <<= 1; /* for Clock Conversion Code */
1579 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1580 // Clock Divisor : 7 bits The natural binary representation of the value of the clock divisor.
1581 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 1800000 / (FrameRate * 1000), 7);
1582 }
1583 }
1584 if (OCPCF == 1) {
1585 IMG_UINT8 ui8ETR; // extended Temporal reference
1586 // Two MSBs of 10 bit temporal_reference : value 0
1587 ui8ETR = Temporal_Ref >> 8;
1588
1589 pnw__write_upto8bits_elements(mtx_hdr, elt_p, ui8ETR, 2);
1590 /* Two MSBs of temporal_reference */
1591 }
1592 }
1593 // vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX
1594 //pnw__write_upto8bits_elements(mtx_hdr, elt_p, ui8Q_Scale, 5);
1595 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))
1596 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1597 // zero_bit = 1 Bit = 0
1598 // pei = 1 Bit = 0 No direct effect on encoding of picture
1599 if (SourceFormatType != 7) {
1600 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1601 }
1602
1603 pnw__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1604 // FOLLOWING SECTION CAN'T BE GENERATED HERE
1605 //gob_data( )
1606 //for(i=1; i<num_gob_in_picture; i++) {
1607 // gob_header( )
1608 // gob_data( )
1609 // }
1610 return;
1611 }
1612
H263_writebits_GOBSliceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)1613 static void H263_writebits_GOBSliceHeader(
1614 MTX_HEADER_PARAMS *mtx_hdr,
1615 MTX_HEADER_ELEMENT **elt_p,
1616 IMG_UINT8 GOBNumber,
1617 IMG_UINT8 GOBFrameId)
1618 {
1619 /* Essential we insert the element before we try to fill it! */
1620 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1621
1622 /* gob_resync_marker = 17 = 0x1 */
1623 pnw__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17);
1624
1625 /* gob_number = 5 = 0-17 It is gob number in a picture */
1626 pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOBNumber, 5);
1627
1628 /* gob_frame_id = 2 = 0-3 See note */
1629 pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOBFrameId, 2);
1630
1631 /* quant_scale = 5 = 1-32 gob (Slice) Q_scale */
1632 /* pnw__write_upto8bits_elements(mtx_hdr, elt_p, GOB_Q_Scale, 5); */
1633
1634 /* Insert token to tell MTX to insert rate-control value
1635 * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale))
1636 */
1637 pnw__insert_element_token(mtx_hdr, elt_p, ELEMENT_SLICEQSCALE);
1638 return;
1639 }
1640
1641 /*
1642 * High level functions to call when a H263 header is required - HOST ROUTINES
1643 */
1644
1645 // SEI_INSERTION
1646 #if PSB_MFLD_DUMMY_CODE
pnw__H264_writebits_AUD_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers)1647 static void pnw__H264_writebits_AUD_header(
1648 MTX_HEADER_PARAMS *pMTX_Header,
1649 MTX_HEADER_ELEMENT **aui32ElementPointers)
1650 {
1651 // Essential we insert the element before we try to fill it!
1652 pnw__insert_element_token(pMTX_Header,
1653 aui32ElementPointers,
1654 ELEMENT_STARTCODE_RAWDATA);
1655
1656 pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1657 aui32ElementPointers, 4); // 00 00 00 01 start code prefix
1658
1659 pnw__write_upto8bits_elements(pMTX_Header,
1660 aui32ElementPointers,
1661 9,
1662 8); // AUD nal_unit_type = 09
1663
1664 // primary_pic_type u(3) 0=I slice, 1=P or I slice, 2=P,B or I slice
1665 pnw__write_upto8bits_elements(pMTX_Header,
1666 aui32ElementPointers,
1667 2,
1668 3);
1669
1670 pnw__write_upto8bits_elements(pMTX_Header,
1671 aui32ElementPointers,
1672 1 << 4, 5); // rbsp_trailing_bits
1673
1674 // Write terminator
1675 pnw__write_upto8bits_elements(pMTX_Header,
1676 aui32ElementPointers, 0x80, 8);
1677 return;
1678 }
1679 #endif
1680 #define SEI_NOT_USE_TOKEN_ALIGN
1681
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)1682 static void pnw__H264_writebits_SEI_buffering_period_header(
1683 MTX_HEADER_PARAMS *pMTX_Header,
1684 MTX_HEADER_ELEMENT **aui32ElementPointers,
1685 IMG_UINT8 ui8NalHrdBpPresentFlag,
1686 IMG_UINT8 ui8nal_cpb_cnt_minus1,
1687 IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
1688 IMG_UINT32 ui32nal_initial_cpb_removal_delay,
1689 IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
1690 IMG_UINT8 ui8VclHrdBpPresentFlag,
1691 IMG_UINT8 ui8vcl_cpb_cnt_minus1,
1692 IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
1693 IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
1694 {
1695 IMG_UINT8 ui8SchedSelIdx;
1696 IMG_UINT8 ui8PayloadSizeBits;
1697 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1698 IMG_UINT8 ui8Pad;
1699 #endif
1700 // Essential we insert the element before we try to fill it!
1701 pnw__insert_element_token(pMTX_Header,
1702 aui32ElementPointers,
1703 ELEMENT_STARTCODE_RAWDATA);
1704
1705 pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1706 aui32ElementPointers,
1707 4); // 00 00 01 start code prefix
1708
1709 pnw__write_upto8bits_elements(pMTX_Header,
1710 aui32ElementPointers,
1711 6, 8); // nal_unit_type = 06 (SEI Message)
1712
1713 pnw__write_upto8bits_elements(pMTX_Header,
1714 aui32ElementPointers,
1715 0, 8); // SEI payload type (buffering period)
1716
1717 ui8PayloadSizeBits = 1; // seq_parameter_set_id bitsize = 1
1718 if (ui8NalHrdBpPresentFlag)
1719 ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1)
1720 * ui8nal_initial_cpb_removal_delay_length * 2);
1721 if (ui8VclHrdBpPresentFlag)
1722 ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1)
1723 * ui8nal_initial_cpb_removal_delay_length * 2);
1724
1725 pnw__write_upto8bits_elements(pMTX_Header,
1726 aui32ElementPointers,
1727 ((ui8PayloadSizeBits + 7) / 8),
1728 8);
1729 // SEI payload size = No of bytes required for SEI payload
1730 // (including seq_parameter_set_id)
1731
1732 //seq_parameter_set_id ue(v) = 0 default? = 1 (binary)
1733 //= sequence parameter set containing HRD attributes
1734 pnw__generate_ue(pMTX_Header, aui32ElementPointers, 0);
1735
1736 if (ui8NalHrdBpPresentFlag) {
1737 for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++) {
1738 // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access
1739 // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit.
1740 // Delay is based on the time taken for a 90 kHz clock.
1741 // Range >0 and < 90000 * (CPBsize / BitRate)
1742 // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation.
1743 // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
1744
1745 pnw__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,
1746 ui32nal_initial_cpb_removal_delay,
1747 ui8nal_initial_cpb_removal_delay_length);
1748
1749 /*
1750 pnw__insert_element_token(pMTX_Header,
1751 aui32ElementPointers,
1752 BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY);*/
1753
1754 // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to
1755 // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset
1756 // Delay is based on the time taken for a 90 kHz clock.
1757 // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C
1758
1759 pnw__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,
1760 ui32nal_initial_cpb_removal_delay_offset,
1761 ui8nal_initial_cpb_removal_delay_length);
1762
1763 /*pnw__insert_element_token(pMTX_Header,
1764 aui32ElementPointers,
1765 BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET);*/
1766
1767 }
1768 }
1769 if (ui8VclHrdBpPresentFlag) {
1770 for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++) {
1771 pnw__insert_element_token(pMTX_Header,
1772 aui32ElementPointers,
1773 ELEMENT_STARTCODE_RAWDATA);
1774 // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
1775 pnw__write_upto32bits_elements(pMTX_Header,
1776 aui32ElementPointers,
1777 ui32vcl_initial_cpb_removal_delay,
1778 ui8nal_initial_cpb_removal_delay_length);
1779 // pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required
1780 pnw__write_upto32bits_elements(pMTX_Header,
1781 aui32ElementPointers,
1782 ui32vcl_initial_cpb_removal_delay_offset,
1783 ui8nal_initial_cpb_removal_delay_length);
1784 }
1785 }
1786
1787 // Pad to end of byte
1788 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1789 if (!ui8VclHrdBpPresentFlag)
1790 pnw__insert_element_token(pMTX_Header,
1791 aui32ElementPointers,
1792 ELEMENT_STARTCODE_RAWDATA);
1793 ui8Pad = (ui8PayloadSizeBits + 7) / 8;
1794 ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
1795 if (ui8Pad > 0)
1796 pnw__write_upto8bits_elements(pMTX_Header,
1797 aui32ElementPointers,
1798 1 << (ui8Pad - 1),
1799 ui8Pad); // SEI payload type (buffering period)
1800 #else
1801 pnw__write_upto8bits_elements(pMTX_Header,
1802 aui32ElementPointers,
1803 1, 1); // rbsp_trailing_bits
1804
1805 pnw__insert_element_token(pMTX_Header,
1806 aui32ElementPointers,
1807 ELEMENT_INSERTBYTEALIGN_H264);
1808 // Tell MTX to insert the byte align field
1809 pnw__insert_element_token(pMTX_Header,
1810 aui32ElementPointers,
1811 ELEMENT_STARTCODE_RAWDATA);
1812 #endif
1813
1814 // Write terminator
1815 pnw__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8);
1816
1817 return;
1818 }
1819
1820 #define SEI_HOSTCALC_CPB_DPB
1821
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)1822 static void pnw__H264_writebits_SEI_picture_timing_header(
1823 MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1824 IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
1825 IMG_UINT32 ui32cpb_removal_delay_length_minus1,
1826 IMG_UINT32 ui32dpb_output_delay_length_minus1,
1827 IMG_UINT32 ui32cpb_removal_delay,
1828 IMG_UINT32 ui32dpb_output_delay,
1829 IMG_UINT8 ui8pic_struct_present_flag,
1830 IMG_UINT8 __maybe_unused ui8pic_struct,
1831 IMG_UINT8 __maybe_unused ui8NumClockTS,
1832 IMG_UINT8 __maybe_unused * aui8clock_timestamp_flag,
1833 IMG_UINT8 __maybe_unused ui8full_timestamp_flag,
1834 IMG_UINT8 __maybe_unused ui8seconds_flag,
1835 IMG_UINT8 __maybe_unused ui8minutes_flag,
1836 IMG_UINT8 __maybe_unused ui8hours_flag,
1837 IMG_UINT8 __maybe_unused ui8seconds_value,
1838 IMG_UINT8 __maybe_unused ui8minutes_value,
1839 IMG_UINT8 __maybe_unused ui8hours_value,
1840 IMG_UINT8 __maybe_unused ui8ct_type,
1841 IMG_UINT8 __maybe_unused ui8nuit_field_based_flag,
1842 IMG_UINT8 __maybe_unused ui8counting_type,
1843 IMG_UINT8 __maybe_unused ui8discontinuity_flag,
1844 IMG_UINT8 __maybe_unused ui8cnt_dropped_flag,
1845 IMG_UINT8 __maybe_unused ui8n_frames,
1846 IMG_UINT8 __maybe_unused ui8time_offset_length,
1847 IMG_UINT32 __maybe_unused i32time_offset)
1848 {
1849 IMG_UINT8 ui8PayloadSizeBits, ui8Tmp;
1850 #ifdef SEI_NOT_USE_TOKEN_ALIGN
1851 IMG_UINT8 ui8Pad;
1852 #endif
1853
1854 // Essential we insert the element before we try to fill it!
1855 pnw__insert_element_token(pMTX_Header,
1856 aui32ElementPointers,
1857 ELEMENT_STARTCODE_RAWDATA);
1858
1859 pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
1860 aui32ElementPointers,
1861 4); // 00 00 01 start code prefix
1862
1863 pnw__write_upto8bits_elements(pMTX_Header,
1864 aui32ElementPointers,
1865 6, 8); // nal_unit_type = 06 (SEI Message)
1866
1867 pnw__write_upto8bits_elements(pMTX_Header,
1868 aui32ElementPointers,
1869 1, 8); // SEI payload type (picture timing)
1870
1871
1872 // Precalculate the payload bit size
1873 ui8PayloadSizeBits = 0;
1874 if (ui8CpbDpbDelaysPresentFlag)
1875 ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1
1876 + 1 + ui32dpb_output_delay_length_minus1 + 1;
1877
1878 #if 0
1879 if (ui8pic_struct_present_flag) {
1880 ui8PayloadSizeBits += 4;
1881 for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
1882 ui8PayloadSizeBits += 1;
1883
1884 if (aui8clock_timestamp_flag[ui8Tmp]) {
1885 ui8PayloadSizeBits += 2 + 1 + 5 + 1 + 1 + 1 + 8;
1886 if (ui8full_timestamp_flag)
1887 ui8PayloadSizeBits += 6 + 6 + 5;
1888 else {
1889 ui8PayloadSizeBits += 1;
1890 if (ui8seconds_flag) {
1891 ui8PayloadSizeBits += 6 + 1;
1892 if (ui8minutes_flag) {
1893 ui8PayloadSizeBits += 6 + 1;
1894 if (ui8hours_flag)
1895 ui8PayloadSizeBits += 5;
1896 }
1897 }
1898 }
1899
1900 if (ui8time_offset_length > 0)
1901 ui8PayloadSizeBits += ui8time_offset_length;
1902 }
1903 }
1904 }
1905 #endif
1906
1907 pnw__write_upto8bits_elements(pMTX_Header,
1908 aui32ElementPointers,
1909 ((ui8PayloadSizeBits + 7) / 8), 8);
1910 // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id)
1911
1912
1913 if (ui8CpbDpbDelaysPresentFlag) {
1914 //SEI_INSERTION
1915 #ifdef SEI_HOSTCALC_CPB_DPB
1916 pnw__write_upto32bits_elements(pMTX_Header,
1917 aui32ElementPointers,
1918 ui32cpb_removal_delay,
1919 ui32cpb_removal_delay_length_minus1 + 1); // cpb_removal_delay
1920 pnw__write_upto32bits_elements(pMTX_Header,
1921 aui32ElementPointers,
1922 ui32dpb_output_delay,
1923 ui32dpb_output_delay_length_minus1 + 1); // dpb_output_delay
1924 #else
1925 pnw__insert_element_token(pMTX_Header,
1926 aui32ElementPointers,
1927 PTH_SEI_NAL_CPB_REMOVAL_DELAY);
1928 pnw__insert_element_token(pMTX_Header,
1929 aui32ElementPointers,
1930 PTH_SEI_NAL_DPB_OUTPUT_DELAY);
1931 #endif
1932 }
1933
1934 #if 0
1935 if (ui8pic_struct_present_flag) {
1936 pnw__insert_element_token(pMTX_Header,
1937 aui32ElementPointers,
1938 ELEMENT_STARTCODE_RAWDATA);
1939 pnw__write_upto8bits_elements(pMTX_Header,
1940 aui32ElementPointers,
1941 ui8pic_struct, 4); // See TRM able D 1 � Interpretation of pic_struct
1942
1943 for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
1944 pnw__write_upto8bits_elements(pMTX_Header,
1945 aui32ElementPointers,
1946 aui8clock_timestamp_flag[ui8Tmp], 1);
1947
1948 if (aui8clock_timestamp_flag[ui8Tmp]) {
1949 pnw__write_upto8bits_elements(pMTX_Header,
1950 aui32ElementPointers,
1951 ui8ct_type, 2);
1952 // (2=Unknown) See TRM Table D 2 � Mapping of ct_type to source picture scan
1953 pnw__write_upto8bits_elements(pMTX_Header,
1954 aui32ElementPointers,
1955 ui8nuit_field_based_flag, 1);
1956 pnw__write_upto8bits_elements(pMTX_Header,
1957 aui32ElementPointers,
1958 ui8counting_type, 5);
1959 // See TRM Table D 3 � Definition of counting_type values
1960 pnw__write_upto8bits_elements(pMTX_Header,
1961 aui32ElementPointers,
1962 ui8full_timestamp_flag, 1);
1963 pnw__write_upto8bits_elements(pMTX_Header,
1964 aui32ElementPointers,
1965 ui8discontinuity_flag, 1);
1966 pnw__write_upto8bits_elements(pMTX_Header,
1967 aui32ElementPointers,
1968 ui8cnt_dropped_flag, 1);
1969 pnw__write_upto8bits_elements(pMTX_Header,
1970 aui32ElementPointers,
1971 ui8n_frames, 8);
1972
1973 if (ui8full_timestamp_flag) {
1974 pnw__write_upto8bits_elements(pMTX_Header,
1975 aui32ElementPointers,
1976 ui8seconds_value, 6); // 0 - 59
1977 pnw__write_upto8bits_elements(pMTX_Header,
1978 aui32ElementPointers,
1979 ui8minutes_value, 6); // 0 - 59
1980 pnw__write_upto8bits_elements(pMTX_Header,
1981 aui32ElementPointers,
1982 ui8hours_value, 5); // 0 - 23
1983 } else {
1984 pnw__write_upto8bits_elements(pMTX_Header,
1985 aui32ElementPointers,
1986 ui8seconds_flag, 1);
1987
1988 if (ui8seconds_flag) {
1989 pnw__write_upto8bits_elements(pMTX_Header,
1990 aui32ElementPointers,
1991 ui8seconds_value, 6); // 0 - 59
1992 pnw__write_upto8bits_elements(pMTX_Header,
1993 aui32ElementPointers,
1994 ui8minutes_flag, 1);
1995
1996 if (ui8minutes_flag) {
1997 pnw__write_upto8bits_elements(pMTX_Header,
1998 aui32ElementPointers,
1999 ui8minutes_value, 6); // 0 - 59
2000 pnw__write_upto8bits_elements(pMTX_Header,
2001 aui32ElementPointers,
2002 ui8hours_flag, 1);
2003
2004 if (ui8hours_flag)
2005 pnw__write_upto8bits_elements(pMTX_Header,
2006 aui32ElementPointers,
2007 ui8hours_value, 5); // 0 - 23
2008 }
2009 }
2010 }
2011
2012 if (ui8time_offset_length > 0) {
2013 // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset)
2014 if ((int)i32time_offset < 0)
2015 pnw__write_upto32bits_elements(pMTX_Header,
2016 aui32ElementPointers,
2017 (IMG_UINT32)((2 ^ ui8time_offset_length) + i32time_offset),
2018 ui8time_offset_length);
2019 else
2020 pnw__write_upto32bits_elements(pMTX_Header,
2021 aui32ElementPointers,
2022 (IMG_UINT32) i32time_offset,
2023 ui8time_offset_length);
2024 }
2025 }
2026 }
2027 }
2028 #endif
2029
2030 #ifdef SEI_NOT_USE_TOKEN_ALIGN
2031 // Pad to end of byte
2032 if (!ui8pic_struct_present_flag)
2033 pnw__insert_element_token(pMTX_Header,
2034 aui32ElementPointers,
2035 ELEMENT_STARTCODE_RAWDATA);
2036 ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2037 ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2038 if (ui8Pad > 0)
2039 pnw__write_upto8bits_elements(pMTX_Header,
2040 aui32ElementPointers,
2041 1 << (ui8Pad - 1),
2042 ui8Pad); // SEI payload type (buffering period)
2043 #else
2044 pnw__insert_element_token(pMTX_Header,
2045 aui32ElementPointers,
2046 ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field
2047 pnw__insert_element_token(pMTX_Header,
2048 aui32ElementPointers,
2049 ELEMENT_STARTCODE_RAWDATA);
2050 #endif
2051
2052 // Write terminator
2053 pnw__write_upto8bits_elements(pMTX_Header,
2054 aui32ElementPointers,
2055 0x80, 8);
2056 return;
2057 }
2058
pnw__H264_writebits_SEI_FPA_header(MTX_HEADER_PARAMS * pMTX_Header,MTX_HEADER_ELEMENT ** aui32ElementPointers,char * sei_data_buf,IMG_UINT32 data_size)2059 static void pnw__H264_writebits_SEI_FPA_header(
2060 MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
2061 char* sei_data_buf, IMG_UINT32 data_size)
2062 {
2063 IMG_UINT8 i;
2064
2065 // Essential we insert the element before we try to fill it!
2066 pnw__insert_element_token(pMTX_Header,
2067 aui32ElementPointers,
2068 ELEMENT_STARTCODE_RAWDATA);
2069
2070 pnw__H264_writebits_startcode_prefix_element(pMTX_Header,
2071 aui32ElementPointers,
2072 4); // 00 00 01 start code prefix
2073
2074 for (i = 0; i < data_size; i++)
2075 pnw__write_upto8bits_elements(pMTX_Header,
2076 aui32ElementPointers,
2077 sei_data_buf[i], 8); //sei_data_buf (SEI Message)
2078 // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
2079 //pnw__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
2080
2081 return;
2082 }
2083
2084
2085 #if PSB_MFLD_DUMMY_CODE
pnw__H264_prepare_AUD_header(MTX_HEADER_PARAMS * pMTX_Header)2086 void pnw__H264_prepare_AUD_header(MTX_HEADER_PARAMS * pMTX_Header)
2087 {
2088 // Essential we initialise our header structures before building
2089 MTX_HEADER_ELEMENT *This_Element;
2090 MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2091 pMTX_Header->Elements = ELEMENTS_EMPTY;
2092 This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2093 aui32ElementPointers[0] = This_Element;
2094
2095 pnw__H264_writebits_AUD_header(pMTX_Header, aui32ElementPointers);
2096
2097 pMTX_Header->Elements++; //Has been used as an index, so need to add 1 for a valid element count
2098 }
2099 #endif
2100
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)2101 void pnw__H264_prepare_SEI_buffering_period_header(
2102 MTX_HEADER_PARAMS * pMTX_Header,
2103 IMG_UINT8 ui8NalHrdBpPresentFlag,
2104 IMG_UINT8 ui8nal_cpb_cnt_minus1,
2105 IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
2106 IMG_UINT32 ui32nal_initial_cpb_removal_delay,
2107 IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
2108 IMG_UINT8 ui8VclHrdBpPresentFlag,
2109 IMG_UINT8 ui8vcl_cpb_cnt_minus1,
2110 IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
2111 IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
2112 {
2113 // Essential we initialise our header structures before building
2114 MTX_HEADER_ELEMENT *This_Element;
2115 MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2116 pMTX_Header->Elements = ELEMENTS_EMPTY;
2117 This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2118 aui32ElementPointers[0] = This_Element;
2119
2120 pnw__H264_writebits_SEI_buffering_period_header(
2121 pMTX_Header, aui32ElementPointers,
2122 ui8NalHrdBpPresentFlag,
2123 ui8nal_cpb_cnt_minus1,
2124 ui8nal_initial_cpb_removal_delay_length,
2125 ui32nal_initial_cpb_removal_delay,
2126 ui32nal_initial_cpb_removal_delay_offset,
2127 ui8VclHrdBpPresentFlag,
2128 ui8vcl_cpb_cnt_minus1,
2129 ui32vcl_initial_cpb_removal_delay,
2130 ui32vcl_initial_cpb_removal_delay_offset);
2131
2132 pMTX_Header->Elements++;
2133 //Has been used as an index, so need to add 1 for a valid element count
2134 return;
2135 }
2136
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)2137 void pnw__H264_prepare_SEI_picture_timing_header(
2138 MTX_HEADER_PARAMS * pMTX_Header,
2139 IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2140 IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2141 IMG_UINT32 ui32dpb_output_delay_length_minus1,
2142 IMG_UINT32 ui32cpb_removal_delay,
2143 IMG_UINT32 ui32dpb_output_delay,
2144 IMG_UINT8 ui8pic_struct_present_flag,
2145 IMG_UINT8 ui8pic_struct,
2146 IMG_UINT8 ui8NumClockTS,
2147 IMG_UINT8 *aui8clock_timestamp_flag,
2148 IMG_UINT8 ui8full_timestamp_flag,
2149 IMG_UINT8 ui8seconds_flag,
2150 IMG_UINT8 ui8minutes_flag,
2151 IMG_UINT8 ui8hours_flag,
2152 IMG_UINT8 ui8seconds_value,
2153 IMG_UINT8 ui8minutes_value,
2154 IMG_UINT8 ui8hours_value,
2155 IMG_UINT8 ui8ct_type,
2156 IMG_UINT8 ui8nuit_field_based_flag,
2157 IMG_UINT8 ui8counting_type,
2158 IMG_UINT8 ui8discontinuity_flag,
2159 IMG_UINT8 ui8cnt_dropped_flag,
2160 IMG_UINT8 ui8n_frames,
2161 IMG_UINT8 ui8time_offset_length,
2162 IMG_INT32 i32time_offset)
2163 {
2164 // Essential we initialise our header structures before building
2165 MTX_HEADER_ELEMENT *This_Element;
2166 MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2167 pMTX_Header->Elements = ELEMENTS_EMPTY;
2168 This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2169 aui32ElementPointers[0] = This_Element;
2170
2171 pnw__H264_writebits_SEI_picture_timing_header(
2172 pMTX_Header, aui32ElementPointers,
2173 ui8CpbDpbDelaysPresentFlag,
2174 ui32cpb_removal_delay_length_minus1,
2175 ui32dpb_output_delay_length_minus1,
2176 ui32cpb_removal_delay,
2177 ui32dpb_output_delay,
2178 ui8pic_struct_present_flag,
2179 ui8pic_struct,
2180 ui8NumClockTS,
2181 aui8clock_timestamp_flag,
2182 ui8full_timestamp_flag,
2183 ui8seconds_flag,
2184 ui8minutes_flag,
2185 ui8hours_flag,
2186 ui8seconds_value,
2187 ui8minutes_value,
2188 ui8hours_value,
2189 ui8ct_type,
2190 ui8nuit_field_based_flag,
2191 ui8counting_type,
2192 ui8discontinuity_flag,
2193 ui8cnt_dropped_flag,
2194 ui8n_frames,
2195 ui8time_offset_length,
2196 i32time_offset);
2197
2198 pMTX_Header->Elements++;
2199 //Has been used as an index, so need to add 1 for a valid element count
2200 return;
2201 }
2202
2203 #if PSB_MFLD_DUMMY_CODE
pnw__H264_prepare_SEI_FPA_header(MTX_HEADER_PARAMS * pMTX_Header,char * sei_data_buf,IMG_UINT32 data_size)2204 void pnw__H264_prepare_SEI_FPA_header(
2205 MTX_HEADER_PARAMS * pMTX_Header,
2206 char* sei_data_buf,
2207 IMG_UINT32 data_size)
2208 {
2209 // Essential we initialise our header structures before building
2210 MTX_HEADER_ELEMENT *This_Element;
2211 MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2212 pMTX_Header->Elements = ELEMENTS_EMPTY;
2213 This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2214 aui32ElementPointers[0] = This_Element;
2215
2216 pnw__H264_writebits_SEI_FPA_header(
2217 pMTX_Header, aui32ElementPointers,
2218 sei_data_buf, data_size);
2219
2220 pMTX_Header->Elements++;
2221 //Has been used as an index, so need to add 1 for a valid element count
2222 return;
2223 }
2224 #endif
2225
2226
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)2227 void pnw__H264_prepare_sequence_header(
2228 unsigned char *pHeaderMemory,
2229 IMG_UINT32 uiPicWidthInMbs,
2230 IMG_UINT32 uiPicHeightInMbs,
2231 IMG_BOOL VUI_present, H264_VUI_PARAMS *VUI_params,
2232 H264_CROP_PARAMS *psCropParams,
2233 IMG_UINT8 uiLevel,
2234 IMG_UINT8 uiProfile)
2235 {
2236 H264_SEQUENCE_HEADER_PARAMS SHParams;
2237 MTX_HEADER_PARAMS *mtx_hdr;
2238
2239 /* Route output elements to memory provided */
2240 memset(&SHParams, 0, sizeof(SHParams));
2241 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2242
2243 /* Setup Sequence Header information */
2244
2245
2246 switch (uiProfile) {
2247 case 5:
2248 SHParams.ucProfile = SH_PROFILE_BP;
2249 break;
2250 case 6:
2251 SHParams.ucProfile = SH_PROFILE_MP;
2252 break;
2253 default:
2254 SHParams.ucProfile = SH_PROFILE_MP;
2255 break;
2256 }
2257
2258 switch (uiLevel) {
2259 case 10:
2260 SHParams.ucLevel = SH_LEVEL_1;
2261 break;
2262 case 111:
2263 SHParams.ucLevel = SH_LEVEL_1B;
2264 break;
2265 case 11:
2266 SHParams.ucLevel = SH_LEVEL_11;
2267 break;
2268 case 12:
2269 SHParams.ucLevel = SH_LEVEL_12;
2270 break;
2271 case 20:
2272 SHParams.ucLevel = SH_LEVEL_2;
2273 break;
2274 case 30:
2275 SHParams.ucLevel = SH_LEVEL_3;
2276 break;
2277 case 31:
2278 SHParams.ucLevel = SH_LEVEL_31;
2279 break;
2280 case 32:
2281 SHParams.ucLevel = SH_LEVEL_32;
2282 break;
2283 case 40:
2284 SHParams.ucLevel = SH_LEVEL_4;
2285 break;
2286 case 41:
2287 SHParams.ucLevel = SH_LEVEL_41;
2288 break;
2289 case 42:
2290 SHParams.ucLevel = SH_LEVEL_42;
2291 break;
2292 default:
2293 SHParams.ucLevel = SH_LEVEL_3;
2294 break;
2295 }
2296
2297 SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)(uiPicWidthInMbs - 1);
2298 SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)(uiPicHeightInMbs - 1);
2299 SHParams.VUI_Params_Present = VUI_present;
2300 if (VUI_present)
2301 SHParams.VUI_Params = *VUI_params;
2302 SHParams.gaps_in_frame_num_value = IMG_FALSE;
2303 SHParams.ucFrame_mbs_only_flag = IMG_TRUE;
2304
2305 /* All picture header information is static
2306 * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway)
2307 */
2308
2309 /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug
2310 * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0;
2311 */
2312
2313 #if HEADERS_VERBOSE_OUTPUT
2314 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2315 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2316 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2317 #endif
2318
2319 /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */
2320 pnw__H264_getelements_sequence_header(mtx_hdr, &SHParams, psCropParams);
2321 }
2322
pnw__H264_prepare_picture_header(unsigned char * pHeaderMemory,IMG_BOOL bCabacEnabled,IMG_INT8 CQPOffset)2323 void pnw__H264_prepare_picture_header(unsigned char *pHeaderMemory, IMG_BOOL bCabacEnabled, IMG_INT8 CQPOffset)
2324 {
2325 MTX_HEADER_PARAMS *mtx_hdr;
2326
2327 /* Route output elements to memory provided */
2328 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2329
2330
2331 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2332 * Essential we initialise our header structures before building
2333 */
2334 MTX_HEADER_ELEMENT *This_Element;
2335 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2336 mtx_hdr->Elements = ELEMENTS_EMPTY;
2337 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2338 elt_p[0] = This_Element;
2339
2340 pnw__H264_writebits_picture_header(mtx_hdr, elt_p, bCabacEnabled,
2341 0, 0,
2342 CQPOffset, CQPOffset);
2343 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2344 }
2345
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)2346 void pnw__H264_prepare_slice_header(
2347 unsigned char *pHeaderMemory,
2348 IMG_BOOL bIntraSlice,
2349 IMG_UINT32 uiDisableDeblockingFilterIDC,
2350 IMG_UINT32 uiFrameNumber,
2351 IMG_UINT32 uiFirst_MB_Address,
2352 IMG_UINT32 uiMBSkipRun,
2353 IMG_BOOL bCabacEnabled,
2354 IMG_BOOL bForceIDR,
2355 IMG_BOOL bUsesLongTermRef,
2356 IMG_BOOL bIsLongTermRef,
2357 IMG_UINT16 uiIdrPicId)
2358 {
2359 H264_SLICE_HEADER_PARAMS SlHParams;
2360 MTX_HEADER_PARAMS *mtx_hdr;
2361
2362 memset(&SlHParams, 0, sizeof(SlHParams));
2363
2364 /* Route output elements to memory provided */
2365 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2366
2367 SlHParams.Start_Code_Prefix_Size_Bytes = 4;
2368 SlHParams.UsesLongTermRef = bUsesLongTermRef;
2369 SlHParams.IsLongTermRef = bIsLongTermRef;
2370
2371 if (bForceIDR || (uiFrameNumber == 0)) {
2372 drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ: Generate a IDR slice\n");
2373 SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
2374 } else
2375 SlHParams.SliceFrame_Type = bIntraSlice ? SLHP_I_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE;
2376
2377 /*SlHParams.SliceFrame_Type = bIntraSlice ? (((uiFrameNumber%(1<<5))==0) ? SLHP_IDR_SLICEFRAME_TYPE :SLHP_I_SLICEFRAME_TYPE ) : SLHP_P_SLICEFRAME_TYPE;*/
2378 SlHParams.Frame_Num_DO = (IMG_UINT8) uiFrameNumber % (1 << 5);
2379 SlHParams.Picture_Num_DO = (IMG_UINT8)(SlHParams.Frame_Num_DO * 2);
2380
2381
2382 SlHParams.First_MB_Address = uiFirst_MB_Address;
2383 SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) uiDisableDeblockingFilterIDC;
2384
2385 {
2386 IMG_UINT32 *pMTX_Header_Mem = (IMG_UINT32 *)mtx_hdr;
2387 // rhk: first insert normal header.
2388 pnw__H264_getelements_slice_header(mtx_hdr, &SlHParams, bCabacEnabled, uiIdrPicId);
2389
2390 // put a marker to indicate that this is a complex header
2391 // note that first "int" in the buffer is used for number of elements
2392 // which is not going to be more than 255
2393 *pMTX_Header_Mem |= 0x100;
2394
2395 // rhk: insert skipped frame header at an offset of 128 bytes
2396 pMTX_Header_Mem += (HEADER_SIZE >> 3); // get a pointer to the second half of memory
2397 mtx_hdr = (MTX_HEADER_PARAMS *)pMTX_Header_Mem;
2398 pnw__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun, bCabacEnabled);
2399 }
2400
2401 }
2402
2403
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)2404 void pnw__MPEG4_prepare_sequence_header(
2405 unsigned char *pHeaderMemory,
2406 IMG_BOOL bBFrame,
2407 MPEG4_PROFILE_TYPE sProfile,
2408 IMG_UINT8 Profile_and_level_indication,
2409 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
2410 IMG_UINT32 Picture_Width_Pixels,
2411 IMG_UINT32 Picture_Height_Pixels,
2412 VBVPARAMS * psVBVParams,
2413 IMG_UINT32 VopTimeResolution)
2414 {
2415 MTX_HEADER_PARAMS *mtx_hdr;
2416
2417 /* Route output elements to memory provided */
2418 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2419 /* Builds a single MPEG4 video sequence header from the given parameters */
2420
2421 /* Essential we initialise our header structures before building */
2422 MTX_HEADER_ELEMENT *This_Element;
2423 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2424 mtx_hdr->Elements = ELEMENTS_EMPTY;
2425 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2426 elt_p[0] = This_Element;
2427
2428 pnw__MPEG4_writebits_sequence_header(
2429 mtx_hdr,
2430 elt_p,
2431 bBFrame, sProfile,
2432 Profile_and_level_indication,
2433 sFixed_vop_time_increment,
2434 Picture_Width_Pixels,
2435 Picture_Height_Pixels,
2436 psVBVParams, VopTimeResolution);
2437
2438 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2439
2440 }
2441
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)2442 void pnw__MPEG4_prepare_vop_header(
2443 unsigned char *pHeaderMem,
2444 IMG_BOOL bIsVOP_coded,
2445 IMG_UINT32 VOP_time_increment,
2446 IMG_UINT8 sSearch_range,
2447 IMG_UINT8 eVop_Coding_Type,
2448 IMG_UINT32 VopTimeResolution)
2449 {
2450 MTX_HEADER_PARAMS *mtx_hdr;
2451
2452 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2453
2454 /* Builds a single MPEG4 VOP (picture) header from the given parameters */
2455 /* Essential we initialise our header structures before building */
2456 MTX_HEADER_ELEMENT *This_Element;
2457 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2458 mtx_hdr->Elements = ELEMENTS_EMPTY;
2459 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2460 elt_p[0] = This_Element;
2461
2462 /* Frame QScale no longer written here as it is inserted by MTX later
2463 * (add as parameter to MTX_Send_Elements_To_VLC)
2464 */
2465 pnw__MPEG4_writebits_VOP_header(
2466 mtx_hdr, elt_p, bIsVOP_coded,
2467 VOP_time_increment,
2468 sSearch_range,
2469 eVop_Coding_Type,
2470 VopTimeResolution);
2471
2472 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2473
2474 }
2475
2476
2477 #if PSB_MFLD_DUMMY_CODE
pnw__H263_prepare_sequence_header(unsigned char * pHeaderMem,IMG_UINT8 Profile_and_level_indication)2478 void pnw__H263_prepare_sequence_header(
2479 unsigned char *pHeaderMem,
2480 IMG_UINT8 Profile_and_level_indication)
2481 {
2482 MTX_HEADER_PARAMS *mtx_hdr;
2483
2484 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2485
2486 /* Builds a single H263 video sequence header from the given parameters */
2487
2488 /* Essential we initialise our header structures before building */
2489 MTX_HEADER_ELEMENT *This_Element;
2490 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2491 mtx_hdr->Elements = ELEMENTS_EMPTY;
2492 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2493 elt_p[0] = This_Element;
2494
2495 H263_writebits_VideoSequenceHeader(mtx_hdr, elt_p, Profile_and_level_indication);
2496
2497 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2498
2499 }
2500 #endif
2501
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)2502 void pnw__H263_prepare_picture_header(
2503 unsigned char *pHeaderMem,
2504 IMG_UINT8 Temporal_Ref,
2505 H263_PICTURE_CODING_TYPE PictureCodingType,
2506 H263_SOURCE_FORMAT_TYPE SourceFormatType,
2507 IMG_UINT8 FrameRate,
2508 IMG_UINT16 PictureWidth,
2509 IMG_UINT16 PictureHeigth)
2510 {
2511 MTX_HEADER_PARAMS *mtx_hdr;
2512
2513 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2514
2515 /* Essential we initialise our header structures before building */
2516 MTX_HEADER_ELEMENT *This_Element;
2517 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2518 mtx_hdr->Elements = ELEMENTS_EMPTY;
2519 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2520 elt_p[0] = This_Element;
2521
2522 H263_writebits_VideoPictureHeader(
2523 mtx_hdr, elt_p,
2524 Temporal_Ref,
2525 PictureCodingType,
2526 SourceFormatType,
2527 FrameRate,
2528 PictureWidth,
2529 PictureHeigth);
2530
2531 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2532 }
2533
pnw__H263_prepare_GOBslice_header(unsigned char * pHeaderMem,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)2534 void pnw__H263_prepare_GOBslice_header(
2535 unsigned char *pHeaderMem,
2536 IMG_UINT8 GOBNumber,
2537 IMG_UINT8 GOBFrameId)
2538 {
2539 MTX_HEADER_PARAMS *mtx_hdr;
2540
2541 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2542
2543 /* Essential we initialise our header structures before building */
2544 MTX_HEADER_ELEMENT *This_Element;
2545 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2546 mtx_hdr->Elements = ELEMENTS_EMPTY;
2547 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2548 elt_p[0] = This_Element;
2549
2550 H263_writebits_GOBSliceHeader(mtx_hdr, elt_p, GOBNumber, GOBFrameId);
2551
2552 mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
2553
2554 /*
2555 (void)pnw__H264_writebits_SEI_rbspheader;
2556 (void)pnw__H264_getelements_skip_B_slice;
2557 (void)pnw__H264_getelements_backward_zero_B_slice;
2558 (void)pnw__H264_getelements_rbsp_ATE_only;
2559 (void)pnw_MPEG4_getelements_video_packet_header;
2560 */
2561 }
2562
2563