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 * Zeng Li <zeng.li@intel.com>
27 * Shengquan Yuan <shengquan.yuan@intel.com>
28 * Binglin Chen <binglin.chen@intel.com>
29 *
30 */
31
32
33 #include <stdio.h>
34 #include <string.h>
35 #include "img_types.h"
36 #include "psb_def.h"
37 #include "lnc_hostheader.h"
38 #include "psb_drv_debug.h"
39
40
41 /* Global stores the latest QP information for the DoHeader()
42 * routine, should be filled in by the rate control algorithm.
43 */
44 #define HEADERS_VERBOSE_OUTPUT 0
45
46 /* #define USESTATICWHEREPOSSIBLE 1 */
47
48 #define MAXNUMBERELEMENTS 16
49
50
51 /* SOME USEFUL TEST FUNCTIONS */
52 #ifndef TOPAZ_MTX_HW
Show_Bits(IMG_UINT8 * ucBitStream,IMG_UINT32 ByteStartBit,IMG_UINT32 Bits)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 #ifndef TOPAZ_MTX_HW
83
Show_Elements(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)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 *) pMTX_Header->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 */
lnc__write_upto8bits_elements(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 wrt_bits,IMG_UINT16 bit_cnt)167 static void lnc__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 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, InputVal.UI8Input[0], (IMG_UINT16) - Shift);
244 }
245 }
246
lnc__write_upto32bits_elements(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 wrt_bits,IMG_UINT32 bit_cnt)247 static void lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[EndByte-1], (IMG_UINT8)((bit_cnt) % 8));
266 else
267 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[BitLp-1], 8);
272 }
273 }
274
lnc__generate_ue(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 uiVal)275 static void lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
294
295 /* Write zeros and 1 bit set */
296 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiChunk, 8);
303 uiVal = uiVal - (uiChunk << ucZeros);
304 }
305
306 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiVal, ucZeros);
307 }
308
309
lnc__generate_se(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,int iVal)310 static void lnc__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 lnc__generate_ue(mtx_hdr, elt_p, uiCodeNum);
323 }
324
325
lnc__insert_element_token(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,HEADER_ELEMENT_TYPE Token)326 static void lnc__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 if (elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_STARTCODE_RAWDATA
336 || elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_RAWDATA) {
337 /*Add a new element aligned to word boundary
338 *Find RAWBit size in bytes (rounded to word boundary))
339 */
340
341 /* NumberofRawbits (excluding size of bit count field)+ size of the bitcount field */
342 Offset = elt_p[mtx_hdr->Elements]->Size + 8 + 31;
343 Offset /= 32;/* Now contains rawbits size in words */
344 Offset += 1;/* Now contains rawbits+element_type size in words */
345 Offset *= 4;/* Convert to number of bytes (total size of structure in bytes, aligned to word boundary) */
346 } else {
347 Offset = 4;
348 }
349
350 mtx_hdr->Elements++;
351 P = (IMG_UINT8 *) elt_p[mtx_hdr->Elements-1];
352 P += Offset;
353 elt_p[mtx_hdr->Elements] = (MTX_HEADER_ELEMENT *) P;
354 } else
355 mtx_hdr->Elements = 0;
356
357 elt_p[mtx_hdr->Elements]->Element_Type = Token;
358 elt_p[mtx_hdr->Elements]->Size = 0;
359 }
360
361 /*
362 * Intermediary functions to build H264 headers
363 */
lnc__H264_writebits_startcode_prefix_element(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 ByteSize)364 static void lnc__H264_writebits_startcode_prefix_element(
365 MTX_HEADER_PARAMS *mtx_hdr,
366 MTX_HEADER_ELEMENT **elt_p,
367 IMG_UINT32 ByteSize)
368 {
369 /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */
370 IMG_UINT32 Lp;
371
372 /*
373 * Byte aligned (bit 0)
374 * (3 bytes in slice header when slice is first in a picture
375 * without sequence/picture_header before picture
376 */
377
378 for (Lp = 0; Lp < ByteSize - 1; Lp++)
379 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
380
381 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
382
383 /* Byte aligned (bit 32 or 24) */
384 return;
385 }
386
lnc__H264_writebits_sequence_header0(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SEQUENCE_HEADER_PARAMS * pSHParams)387 static void lnc__H264_writebits_sequence_header0(
388 MTX_HEADER_PARAMS *mtx_hdr,
389 MTX_HEADER_ELEMENT **elt_p,
390 H264_SEQUENCE_HEADER_PARAMS *pSHParams)
391 {
392 /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */
393
394 /* 4 Byte StartCodePrefix Pregenerated in: lnc__H264_writebits_startcode_prefix_element()
395 * Byte aligned (bit 32)
396 */
397 lnc__write_upto8bits_elements(
398 mtx_hdr,
399 elt_p, (0 << 7) |/* forbidden_zero_bit=0 */
400 (0x3 << 5) |/* nal_ref_idc=01 (may be 11) */
401 (7), /* nal_unit_type=00111 */
402 8);
403
404
405 /* Byte aligned (bit 40)
406 * profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
407 */
408 lnc__write_upto8bits_elements(
409 mtx_hdr,
410 elt_p,
411 (pSHParams->ucProfile == SH_PROFILE_BP ? 66 : 77),
412 8);
413
414 /* Byte aligned (bit 48) */
415 lnc__write_upto8bits_elements(
416 mtx_hdr,
417 elt_p,
418 (1 << 7) |/* constrain_set0_flag = 0 for MP, 1 for BP */
419 (1 << 6) |/* constrain_set1_flag = 0 for BP, 1 for MP */
420 (0 << 5) | /* constrain_set2_flag = always 0 in BP/MP */
421 ((pSHParams->ucLevel == SH_LEVEL_1B ? 1 : 0) << 4), /* constrain_set3_flag = 1 for level 1b, 0 for others */
422 /* reserved_zero_4bits = 0 */
423 8);
424
425 /* Byte aligned (bit 56) */
426 lnc__write_upto8bits_elements(
427 mtx_hdr,
428 elt_p,
429 (IMG_UINT8)((pSHParams->ucLevel > 100) ? (pSHParams->ucLevel - 100) : pSHParams->ucLevel) ,
430 8);/* level_idc (8 bits) = 11 for 1b, 10xlevel for others */
431
432 /* Byte aligned (bit 64) */
433 lnc__write_upto8bits_elements(
434 mtx_hdr, elt_p, (1 << 7) | /* seq_parameter_Set_id = 0 in Topaz -> ue(0)= 1b */
435 (2 << 4) | /* log2_max_frame_num_minus4 = 1 in Topaz -> ue(1)= 010b */
436 (1 << 3) | /* pic_order_cnt_type = 0 in Topaz -> ue(0)= 1b */
437 (3), /* log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz -> ue(2)= 011b */
438 8);
439 }
440
lnc__H264_writebits_sequence_header1(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCropParams)441 static void lnc__H264_writebits_sequence_header1(
442 MTX_HEADER_PARAMS *mtx_hdr,
443 MTX_HEADER_ELEMENT **elt_p,
444 H264_SEQUENCE_HEADER_PARAMS *pSHParams,
445 H264_CROP_PARAMS *psCropParams)
446 {
447 /* GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE
448 * ELEMENT BITCOUNT: xx
449 * pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
450 */
451 /* max_num_ref_frames = 1 ue(1) = 010b */
452 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucMax_num_ref_frames);
453 /* gaps_in_frame_num_value_allowed_Flag - (1 bit) - Not supported
454 * in Topaz (0) */
455 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
456
457 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucWidth_in_mbs_minus1);
458
459 /* pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column) */
460 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucHeight_in_maps_units_minus1);
461
462 /* We don't know the alignment at this point, so will have to use bit writing functions */
463 lnc__write_upto8bits_elements(
464 mtx_hdr, elt_p,
465 (1 << 2) | /* frame_mb_only_flag (always 1) */
466 (1 << 1), /* direct_8x8_inference_flag=1 in Topaz */
467 2);
468
469 if (psCropParams && psCropParams->bClip) {
470 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
471 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->LeftCropOffset);
472 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->RightCropOffset);
473 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->TopCropOffset);
474 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->BottomCropOffset);
475
476 } else {
477 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
478 }
479 }
480
481
lnc__H264_writebits_VUI_params(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_VUI_PARAMS * VUIParams)482 static void lnc__H264_writebits_VUI_params(
483 MTX_HEADER_PARAMS *mtx_hdr,
484 MTX_HEADER_ELEMENT **elt_p,
485 H264_VUI_PARAMS *VUIParams)
486 {
487 /* Builds VUI Params for the Sequence Header (only present in the 1st sequence of stream) */
488 lnc__write_upto8bits_elements(
489 mtx_hdr, elt_p,
490 (0 << 4) | /* aspect_ratio_info_present_flag = 0 in Topaz */
491 (0 << 3) | /* overscan_info_present_flag (1 bit) = 0 in Topaz */
492 (0 << 2) | /* video_signal_type_present_flag (1 bit) = 0 in Topaz */
493 (0 << 1) | /* chroma_loc_info_present_flag (1 bit) = 0 in Topaz */
494 (1),/* timing_info_present_flag (1 bit) = 1 in Topaz */
495 5);
496
497 /* num_units_in_tick (32 bits) = 1 in Topaz */
498 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
499 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
500 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
501 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
502
503 /* time_scale (32 bits) = frame rate */
504 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
505 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
506 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
507 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) VUIParams->Time_Scale, 8);
508
509 /* fixed_frame_rate_flag (1 bit) = 1 in Topaz */
510 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
511 /* nal_hrd_parameters_present_flag (1 bit) = 1 in Topaz */
512 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
513
514 /** Definitions for nal_hrd_parameters() contained in VUI structure for Topaz
515 * cpb_cnt_minus1 ue(v) = 0 in Topaz = 1b
516 */
517 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
518 /* bit_rate_scale (4 bits) = 0 in Topaz, cpb_size_scale (4 bits) = 0 in Topaz */
519 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 2, 8);
520
521 /* bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2] */
522 lnc__generate_ue(mtx_hdr, elt_p, VUIParams->bit_rate_value_minus1);
523 /* cpb_size_value_minus1[0] ue(v) = (CPB_Bits_Size/16)-1
524 * where CPB_Bits_Size = 1.5 * Bitrate [RANGE:0 to (2^32)-2]
525 */
526 lnc__generate_ue(mtx_hdr, elt_p, VUIParams->cbp_size_value_minus1);
527
528 /* cbr_flag[0] (1 bit) = 0 for VBR, 1 for CBR */
529 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VUIParams->CBR, 1);
530
531 lnc__write_upto8bits_elements(
532 mtx_hdr, elt_p,
533 VUIParams->initial_cpb_removal_delay_length_minus1,
534 5); /* initial_cpb_removal_delay_length_minus1 (5 bits) = ??? */
535
536 lnc__write_upto8bits_elements(
537 mtx_hdr,
538 elt_p,
539 VUIParams->cpb_removal_delay_length_minus1,
540 5); /* cpb_removal_delay_length_minus1 (5 bits) = ??? */
541
542 lnc__write_upto8bits_elements(
543 mtx_hdr, elt_p,
544 VUIParams->dpb_output_delay_length_minus1,
545 5); /* dpb_output_delay_length_minus1 (5 bits) = ??? */
546
547 lnc__write_upto8bits_elements(
548 mtx_hdr,
549 elt_p,
550 VUIParams->time_offset_length,
551 5); /* time_offst_length (5 bits) = ??? */
552
553 /* End of nal_hrd_parameters() */
554
555 lnc__write_upto8bits_elements(
556 mtx_hdr,
557 elt_p,
558 0, 1);/* vcl_hrd_parameters_present_flag (1 bit) = 0 in Topaz */
559
560 /* if( nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag )
561 * FIX for BRN23039
562 * low_delay_hrd_flag
563 */
564 lnc__write_upto8bits_elements(
565 mtx_hdr, elt_p,
566 0, 1);/* low_delay_hrd_flag */
567
568
569 lnc__write_upto8bits_elements(
570 mtx_hdr, elt_p,
571 0, 1);/* pic_struct_present_flag (1 bit) = 0 in Topaz */
572
573 lnc__write_upto8bits_elements(
574 mtx_hdr, elt_p,
575 0, 1);/* bitstream_restriction_flag (1 bit) = 0 in Topaz */
576 }
577
lnc__H264_writebits_sequence_header2(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SEQUENCE_HEADER_PARAMS * pSHParams)578 static void lnc__H264_writebits_sequence_header2(
579 MTX_HEADER_PARAMS *mtx_hdr,
580 MTX_HEADER_ELEMENT **elt_p,
581 H264_SEQUENCE_HEADER_PARAMS *pSHParams)
582 {
583 /* GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE
584 * ELEMENT BITCOUNT: xx
585 */
586 IMG_UINT8 SBP;
587 lnc__write_upto8bits_elements(
588 mtx_hdr, elt_p,
589 (pSHParams->VUI_Params_Present),/* vui_parameters_present_flag (VUI only in 1st sequence of stream) */
590 1);
591
592 if (pSHParams->VUI_Params_Present > 0)
593 lnc__H264_writebits_VUI_params(mtx_hdr, elt_p, &(pSHParams->VUI_Params));
594
595 /* Finally we need to align to the next byte
596 * We know the size of the data in the sequence header (no MTX variables)
597 * and start is byte aligned, so it's possible to add this field here rather than
598 * MTX ELEMENT_INSERTBYTEALIGN_H264 command.
599 */
600
601 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
602 SBP = (elt_p[mtx_hdr->Elements]->Size) & 7;
603
604 if (SBP > 0) lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8 - (SBP));
605 }
606
lnc__H264_writebits_picture_header0(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)607 static void lnc__H264_writebits_picture_header0(
608 MTX_HEADER_PARAMS *mtx_hdr,
609 MTX_HEADER_ELEMENT **elt_p)
610 {
611 /* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE
612 * ELEMENT BITCOUNT: 18
613 */
614
615 /* 4 Byte StartCodePrefix Pregenerated in: lnc__H264_writebits_startcode_prefix_element()
616 * Byte aligned (bit 32)
617 */
618 lnc__write_upto8bits_elements(
619 mtx_hdr,
620 elt_p, (0 << 7) | /* forbidden_zero_bit */
621 (1 << 5) | /* nal_ref_idc (2 bits) = 1 */
622 (8),/* nal_unit_tpye (5 bits) = 8 */
623 8);
624
625 /* Byte aligned (bit 40) */
626 lnc__write_upto8bits_elements(
627 mtx_hdr,
628 elt_p,
629 (1 << 7) | /* pic_parameter_set_id ue(v) = 0 in Topaz */
630 (1 << 6) | /* seq_parameter_set_id ue(v) = 0 in Topaz */
631 (0 << 5) | /* entropy_coding_mode_flag (1 bit) 0 for CAVLC */
632 (0 << 4) | /* pic_order_present_flag (1 bit) = 0 */
633 (1 << 3) | /* num_slice_group_minus1 ue(v) = 0 in Topaz */
634 (1 << 2) | /* num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz */
635 (1 << 1) | /* num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz */
636 (0), /* weighted_pred_flag (1 bit) = 0 in Topaz */
637 8);
638
639 /* Byte aligned (bit 48) */
640 lnc__write_upto8bits_elements(
641 mtx_hdr,
642 elt_p, 0,
643 2);/* weighted_bipred_flag (2 bits) = 0 in Topaz */
644 }
645
lnc__H264_writebits_picture_header1(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)646 static void lnc__H264_writebits_picture_header1(
647 MTX_HEADER_PARAMS *mtx_hdr,
648 MTX_HEADER_ELEMENT **elt_p)
649 {
650 /* GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE
651 * ELEMENT BITCOUNT: 5
652 */
653
654 /* The following field will be generated as a special case by MTX - so not here
655 * lnc__generate_se(mtx_hdr, pPHParams->pic_init_qp_minus26); // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz
656 */
657 lnc__generate_se(mtx_hdr, elt_p, 0); /* pic_int_qs_minus26 se(v) = 0 in Topaz */
658 lnc__generate_se(mtx_hdr, elt_p, 0); /* chroma_qp_index_offset se(v) = 0 in Topaz */
659
660 lnc__write_upto8bits_elements(
661 mtx_hdr,
662 elt_p,
663 (1 << 2) | /* deblocking_filter_control_present_flag (1 bit) = 1 in Topaz */
664 (0 << 1) | /* constrained_intra_pred_Flag (1 bit) = 0 in Topaz */
665 (0), /* redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz */
666 3);
667
668 /* Byte align is done using an element command (MTX elements in this structure, we don't know it's size) */
669 }
670
671
lnc__H264_writebits_slice_header0(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams)672 static void lnc__H264_writebits_slice_header0(
673 MTX_HEADER_PARAMS *mtx_hdr,
674 MTX_HEADER_ELEMENT **elt_p,
675 H264_SLICE_HEADER_PARAMS *pSlHParams)
676 {
677 /* GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
678 * ELEMENT BITCOUNT: 8
679 *
680 * StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
681 * (3 bytes when slice is first in a picture without sequence/picture_header before picture
682 * Byte aligned (bit 32 or 24)
683 * NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
684 */
685 lnc__write_upto8bits_elements(
686 mtx_hdr, elt_p,
687 (0 << 7) |/* forbidden_zero_bit */
688 ((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 */
689 ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),/* nal_unit_tpye (5 bits) = I-frame IDR, and 1 for rest */
690 8);
691 }
692
693
lnc__H264_writebits_slice_header1(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT16 uiIdrPicId)694 static void lnc__H264_writebits_slice_header1(
695 MTX_HEADER_PARAMS *mtx_hdr,
696 MTX_HEADER_ELEMENT **elt_p,
697 H264_SLICE_HEADER_PARAMS *pSlHParams,
698 IMG_UINT16 uiIdrPicId)
699 {
700 /* GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
701 * The following is slice parameter set in BP/MP
702 */
703
704 /* first_mb_in_slice = First MB address in slice: ue(Range 0 - 1619) */
705 lnc__generate_ue(mtx_hdr, elt_p, (IMG_UINT32) pSlHParams->First_MB_Address);
706
707 lnc__generate_ue(
708 mtx_hdr, elt_p,
709 (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 */
710
711 /* kab: not clean change from IDR to intra, IDR should have separate flag */
712
713 lnc__write_upto8bits_elements(
714 mtx_hdr, elt_p,
715 (1 << 5) | /* pic_parameter_set_id, ue(v) = 0 (=1b) in Topaz */
716 pSlHParams->Frame_Num_DO,/* frame_num (5 bits) = frame nuo. in decoding order */
717 6);
718
719 /* frame_mb_only_flag is always 1, so no need for field_pic_flag or bottom_field_flag */
720 if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
721 lnc__generate_ue(mtx_hdr, elt_p, uiIdrPicId);
722
723 /* kab: Idr_pic_id only for IDR, not nessesarely for all I pictures */
724
725 /* if (pic_order_cnt_type == 0) //Note: (pic_order_cnt_type always 0 in Topaz) */
726 lnc__write_upto8bits_elements(
727 mtx_hdr, elt_p,
728 pSlHParams->Picture_Num_DO,
729 6); /* pic_order_cnt_lsb (6 bits) - picture no in display order */
730
731 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
732 lnc__write_upto8bits_elements(
733 mtx_hdr,
734 elt_p,
735 0,
736 1);/* direct_spatial_mv_pred_flag (1 bit) = 0, spatial direct mode not supported in Topaz */
737
738 if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE || pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
739 lnc__write_upto8bits_elements(
740 mtx_hdr,
741 elt_p,
742 0,
743 1);/* num_ref_idx_active_override_flag (1 bit) = 0 in Topaz */
744
745 if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE &&
746 pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
747 if (pSlHParams->bUsesLongTermRef) {
748 /* ref_pic_list_ordering_flag_IO (1 bit) = 1, L0
749 * reference picture ordering */
750 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
751
752 /* modification_of_pic_nums_idc = 2 */
753 lnc__generate_ue(mtx_hdr, elt_p, 2);
754 /* long_term_pic_num = 0 */
755 lnc__generate_ue(mtx_hdr, elt_p, 0);
756 /* modification_of_pic_nums_idc = 3 */
757 lnc__generate_ue(mtx_hdr, elt_p, 3);
758 } else {
759 /* ref_pic_list_ordering_flag_IO (1 bit) = 0, no
760 * L0 reference picture ordering */
761 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
762 }
763 }
764
765 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
766 lnc__write_upto8bits_elements(
767 mtx_hdr,
768 elt_p,
769 0,
770 1); /* ref_pic_list_ordering_flag_I1 (1 bit) = 0, no L1 reference picture ordering in Topaz */
771
772 if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
773 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);/* no_output_of_prior_pics_flag (1 bit) = 0 */
774 lnc__write_upto8bits_elements(mtx_hdr, elt_p, pSlHParams->bIsLongTermRef ? 1 : 0, 1);/* long_term_reference_flag (1 bit) */
775 } else if (pSlHParams->bIsLongTermRef) {
776 /* adaptive_ref_pic_marking_mode_flag (1 bit) = 1 */
777 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
778 /* allow a single long-term reference */
779 /* memory_management_control_operation */
780 lnc__generate_ue(mtx_hdr, elt_p, 4);
781 /* max_long_term_frame_idx_plus1 */
782 lnc__generate_ue(mtx_hdr, elt_p, 1);
783 /* set current picture as the long-term reference */
784 /* memory_management_control_operation */
785 lnc__generate_ue(mtx_hdr, elt_p, 6);
786 /* long_term_frame_idx */
787 lnc__generate_ue(mtx_hdr, elt_p, 0);
788 /* END */
789 lnc__generate_ue(mtx_hdr, elt_p, 0);
790 } else {
791 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);/* adaptive_ref_pic_marking_mode_flag (1 bit) = 0 */
792 }
793 }
794
795
lnc__H264_writebits_slice_header2(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams)796 static void lnc__H264_writebits_slice_header2(
797 MTX_HEADER_PARAMS *mtx_hdr,
798 MTX_HEADER_ELEMENT **elt_p,
799 H264_SLICE_HEADER_PARAMS *pSlHParams)
800 {
801 /* GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE
802 * ELEMENT BITCOUNT: 11
803 */
804
805 #if 0
806 /* Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here */
807
808 /* slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26) */
809 /* pucHS=lnc__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); */
810 #endif
811
812 lnc__generate_ue(
813 mtx_hdr,
814 elt_p,
815 pSlHParams->Disable_Deblocking_Filter_Idc); /* disable_deblocking_filter_idc ue(v) = 2? */
816
817 if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
818 lnc__generate_se(mtx_hdr, elt_p, 0); /* slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz */
819 lnc__generate_se(mtx_hdr, elt_p, 0); /* slice_beta_offset_div2 se(v) = 0 (1b) in Topaz */
820 }
821
822 /* num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
823 * no byte alignment at end of slice headers
824 */
825 }
826
827
828
lnc__H264_writebits_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCropParams)829 static void lnc__H264_writebits_sequence_header(
830 MTX_HEADER_PARAMS *mtx_hdr,
831 MTX_HEADER_ELEMENT **elt_p,
832 H264_SEQUENCE_HEADER_PARAMS *pSHParams,
833 H264_CROP_PARAMS *psCropParams)
834 {
835 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
836
837 lnc__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4);
838 lnc__H264_writebits_sequence_header0(mtx_hdr, elt_p, pSHParams);
839 lnc__H264_writebits_sequence_header1(mtx_hdr, elt_p, pSHParams, psCropParams);
840 lnc__H264_writebits_sequence_header2(mtx_hdr, elt_p, pSHParams);
841 }
842
843
lnc__H264_writebits_picture_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)844 static void lnc__H264_writebits_picture_header(
845 MTX_HEADER_PARAMS *mtx_hdr,
846 MTX_HEADER_ELEMENT **elt_p)
847 {
848 /* Begin building the picture header element */
849 #ifdef USESTATICWHEREPOSSIBLE
850 IMG_UINT32 *p;
851 p = (IMG_UINT32 *) mtx_hdr;
852 p[0] = 3;
853 p[1] = 0;
854 p[2] = 50;
855 p[3] = 13510657;
856 p[4] = 2;
857 p[5] = 1;
858 p[6] = 57349;
859 p[7] = 6;
860 #else
861 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
862
863 lnc__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4);
864 lnc__H264_writebits_picture_header0(mtx_hdr, elt_p);
865
866 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_QP); /* MTX fills this value in */
867
868 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
869 lnc__H264_writebits_picture_header1(mtx_hdr, elt_p);
870
871 /* Tell MTX to insert the byte align field */
872 /* (we don't know final stream size for alignment at this point) */
873 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
874 #endif
875
876 }
877
878
lnc__H264_writebits_slice_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT16 uiIdrPicId)879 static void lnc__H264_writebits_slice_header(
880 MTX_HEADER_PARAMS *mtx_hdr,
881 MTX_HEADER_ELEMENT **elt_p,
882 H264_SLICE_HEADER_PARAMS *pSlHParams,
883 IMG_UINT16 uiIdrPicId)
884 {
885 #ifdef USESTATICWHEREPOSSIBLE
886 IMG_UINT32 *p;
887 p = (IMG_UINT32 *) mtx_hdr;
888
889 p[0] = p[1] = 0;
890 p[2] = 40;
891 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) p[3] = 257;
892 else if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) p[3] = 9473;
893 else p[3] = 8449;
894 #else
895 /* -- Begin building the picture header element */
896 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
897
898 lnc__H264_writebits_startcode_prefix_element(
899 mtx_hdr,
900 elt_p,
901 pSlHParams->Start_Code_Prefix_Size_Bytes); /* Can be 3 or 4 bytes - always 4 bytes in our implementations */
902 lnc__H264_writebits_slice_header0(mtx_hdr, elt_p, pSlHParams);
903 #endif
904
905 lnc__H264_writebits_slice_header1(mtx_hdr, elt_p, pSlHParams, uiIdrPicId);
906 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_SQP); //MTX fills this value in
907
908 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
909 lnc__H264_writebits_slice_header2(mtx_hdr, elt_p, pSlHParams);
910
911 /* no byte alignment at end of slice headers */
912 }
913
914
lnc__H264_writebits_endofsequence_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)915 static void lnc__H264_writebits_endofsequence_header(
916 MTX_HEADER_PARAMS *mtx_hdr,
917 MTX_HEADER_ELEMENT **elt_p)
918 {
919 /* GENERATES THE FIRST ELEMENT OF THE H264_ENDOFSEQUENCE_HEADER() STRUCTURE */
920 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
921
922 /* Byte aligned (bit 32) */
923 lnc__write_upto8bits_elements(
924 mtx_hdr,
925 elt_p,
926 (0 << 7) |/* forbidden_zero_bit=0 */
927 (0 << 5) |/* nal_ref_idc=0 for nal_unit_type=10 */
928 (10),/* nal_unit_type=10 */
929 8);
930 }
931
932
lnc__H264_writebits_SEI_rbspheader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT32 Initial_cpb_removal_delay)933 static void lnc__H264_writebits_SEI_rbspheader(
934 MTX_HEADER_PARAMS *mtx_hdr,
935 MTX_HEADER_ELEMENT **elt_p,
936 IMG_UINT32 Initial_cpb_removal_delay)
937 {
938 /* Byte aligned (bit 32) */
939 lnc__H264_writebits_startcode_prefix_element(
940 mtx_hdr, elt_p, 4);/* 32 bit start code prefix */
941
942 lnc__write_upto8bits_elements(
943 mtx_hdr,
944 elt_p,
945 (0 << 7) |/* forbidden_zero_bit */
946 (1 << 5) |/* nal_ref_idc (2 bits) = 1 */
947 (6),/* nal_unit_tpye (5 bits) = 6 (SEI packet) */
948 8);
949
950 /* last_payload_type_byte (8 bits) = 0 for buffering period */
951 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
952
953 /* last_payload_size_byte (8 bits) = 41 as SEI_message length is 41-bit */
954 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 41, 8);
955
956 /* sequence_parameter_set_id ue(0) = 1b sequence_parameter_set_id=0 in Topaz */
957 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
958
959 /* Initial_cpb_removal_delay (20 bits) x is initial cpb delay of each sequence */
960 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Initial_cpb_removal_delay, 20);
961 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
962 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
963
964 /* Initial_cpb_removal_delay_offset (20 bits) 0x10101 (It won't be used in Topaz) */
965 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4);
966
967 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
968 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
969 }
970
971
lnc__H264_writebits_endofstream_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p)972 static void lnc__H264_writebits_endofstream_header(
973 MTX_HEADER_PARAMS *mtx_hdr,
974 MTX_HEADER_ELEMENT **elt_p)
975 {
976 /* GENERATES THE FIRST ELEMENT OF THE H264_ENDOFSTREAM_HEADER() STRUCTURE */
977 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
978 /* Byte aligned (bit 32) */
979 lnc__write_upto8bits_elements(
980 mtx_hdr,
981 elt_p,
982 (0 << 7) |/* forbidden_zero_bit=0 */
983 (0 << 5) |/* nal_ref_idc=0 for nal_unit_type=11 */
984 (11),/* nal_unit_type=11 */
985 8);
986 }
987
988 /*
989 * High level functions to call when a H264 header is required
990 */
lnc__H264_getelements_skip_B_slice(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT8 MB_No_In_Slice)991 static void lnc__H264_getelements_skip_B_slice(
992 MTX_HEADER_PARAMS *mtx_hdr,
993 H264_SLICE_HEADER_PARAMS *pSlHParams,
994 IMG_UINT8 MB_No_In_Slice)
995 {
996 /* Skipped P-Slice
997 * Ensure pSlHParams is filled with appropriate parameters for a P-slice
998 * Essential we initialise our header structures before building
999 */
1000 MTX_HEADER_ELEMENT *This_Element;
1001 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1002 mtx_hdr->Elements = ELEMENTS_EMPTY;
1003 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1004 elt_p[0] = This_Element;
1005
1006 /* Not sure if this will be required in the final spec
1007 * lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);
1008 */
1009 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, 0);
1010
1011 /* mb_skip_run = mb_no_in_slice */
1012 lnc__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice);
1013
1014 /* Tell MTX to insert the byte align field
1015 * (we don't know final stream size for alignment at this point)
1016 */
1017 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
1018
1019 /* Has been used as an index, so need to add 1 for a valid element count */
1020 mtx_hdr->Elements++;
1021 }
1022
lnc__H264_getelements_backward_zero_B_slice(MTX_HEADER_PARAMS * mtx_hdr,IMG_UINT8 MB_No_In_Slice)1023 static void lnc__H264_getelements_backward_zero_B_slice(
1024 MTX_HEADER_PARAMS *mtx_hdr,
1025 IMG_UINT8 MB_No_In_Slice)
1026 {
1027 /* Skipped P-Slice
1028 * Ensure pSlHParams is filled with appropriate parameters for a P-slice
1029 * Essential we initialise our header structures before building
1030 */
1031 IMG_UINT8 Lp;
1032 MTX_HEADER_ELEMENT *This_Element;
1033 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1034 mtx_hdr->Elements = ELEMENTS_EMPTY;
1035 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1036 elt_p[0] = This_Element;
1037
1038 for (Lp = 0; Lp < MB_No_In_Slice; Lp++) {
1039 /* mb_skip_run = ue(0) = 1b */
1040 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1041 /* backward_zero_B_mb() - all static */
1042 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 15, 5);
1043 }
1044
1045 /* Tell MTX to insert the byte align field
1046 * (we don't know final stream size for alignment at this point)
1047 */
1048 lnc__insert_element_token(
1049 mtx_hdr,
1050 elt_p,
1051 ELEMENT_INSERTBYTEALIGN_H264);
1052
1053 /* Has been used as an index, so need to add 1 for a valid element count */
1054 mtx_hdr->Elements++;
1055 }
1056
1057
lnc__H264_getelements_rbsp_ATE_only(MTX_HEADER_PARAMS * mtx_hdr)1058 static void lnc__H264_getelements_rbsp_ATE_only(MTX_HEADER_PARAMS *mtx_hdr)
1059 {
1060 /* Skipped P-Slice
1061 * Ensure pSlHParams is filled with appropriate parameters for a P-slice
1062 * Essential we initialise our header structures before building
1063 */
1064 MTX_HEADER_ELEMENT *This_Element;
1065 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1066 mtx_hdr->Elements = ELEMENTS_EMPTY;
1067 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1068 elt_p[0] = This_Element;
1069
1070 /* Tell MTX to insert the byte align field
1071 * (we don't know final stream size for alignment at this point)
1072 */
1073 lnc__insert_element_token(
1074 mtx_hdr,
1075 elt_p,
1076 ELEMENT_INSERTBYTEALIGN_H264);
1077
1078 /* Has been used as an index, so need to add 1 for a valid element count */
1079 mtx_hdr->Elements++;
1080 }
1081
1082
lnc__H264_getelements_skip_P_slice(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT32 MB_No_In_Slice)1083 static void lnc__H264_getelements_skip_P_slice(
1084 MTX_HEADER_PARAMS *mtx_hdr,
1085 H264_SLICE_HEADER_PARAMS *pSlHParams,
1086 IMG_UINT32 MB_No_In_Slice)
1087 {
1088 /* Skipped P-Slice
1089 * Ensure pSlHParams is filled with appropriate parameters for a B-slice
1090 * Essential we initialise our header structures before building
1091 */
1092 MTX_HEADER_ELEMENT *This_Element;
1093 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1094 mtx_hdr->Elements = ELEMENTS_EMPTY;
1095 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1096 elt_p[0] = This_Element;
1097
1098 /* lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */
1099 /* Not sure if this will be required in the final spec */
1100 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, 0);
1101 lnc__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */
1102
1103 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
1104 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264);
1105 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1106 }
1107
1108
1109
lnc__H264_getelements_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SEQUENCE_HEADER_PARAMS * pSHParams,H264_CROP_PARAMS * psCropParams)1110 static void lnc__H264_getelements_sequence_header(
1111 MTX_HEADER_PARAMS *mtx_hdr,
1112 H264_SEQUENCE_HEADER_PARAMS *pSHParams,
1113 H264_CROP_PARAMS *psCropParams)
1114 {
1115 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1116 * Essential we initialise our header structures before building
1117 */
1118 MTX_HEADER_ELEMENT *This_Element;
1119 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1120 mtx_hdr->Elements = ELEMENTS_EMPTY;
1121 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1122 elt_p[0] = This_Element;
1123
1124 lnc__H264_writebits_sequence_header(mtx_hdr, elt_p, pSHParams, psCropParams);
1125 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1126 }
1127
1128
lnc__H264_getelements_picture_header(MTX_HEADER_PARAMS * mtx_hdr)1129 static void lnc__H264_getelements_picture_header(MTX_HEADER_PARAMS *mtx_hdr)
1130 {
1131 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1132 * Essential we initialise our header structures before building
1133 */
1134 MTX_HEADER_ELEMENT *This_Element;
1135 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1136 mtx_hdr->Elements = ELEMENTS_EMPTY;
1137 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1138 elt_p[0] = This_Element;
1139
1140 lnc__H264_writebits_picture_header(mtx_hdr, elt_p);
1141 mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
1142 }
1143
1144
lnc__H264_getelements_slice_header(MTX_HEADER_PARAMS * mtx_hdr,H264_SLICE_HEADER_PARAMS * pSlHParams,IMG_UINT16 uiIdrPicId)1145 static void lnc__H264_getelements_slice_header(
1146 MTX_HEADER_PARAMS *mtx_hdr,
1147 H264_SLICE_HEADER_PARAMS *pSlHParams,
1148 IMG_UINT16 uiIdrPicId)
1149 {
1150 /* Builds a single slice header from the given parameters (mid frame)
1151 * Essential we initialise our header structures before building
1152 */
1153 MTX_HEADER_ELEMENT *This_Element;
1154 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1155 mtx_hdr->Elements = ELEMENTS_EMPTY;
1156 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1157 elt_p[0] = This_Element;
1158
1159 /* Not sure if this will be required in the final spec */
1160 /* lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/
1161 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, uiIdrPicId);
1162
1163 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1164 }
1165
1166
lnc__H264_getelements_endofsequence_header(MTX_HEADER_PARAMS * mtx_hdr)1167 static void lnc__H264_getelements_endofsequence_header(
1168 MTX_HEADER_PARAMS *mtx_hdr)
1169 {
1170 /* Builds a single endofsequence header from the given parameters (mid frame) */
1171
1172 /* Essential we initialise our header structures before building */
1173 MTX_HEADER_ELEMENT *This_Element;
1174 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1175 mtx_hdr->Elements = ELEMENTS_EMPTY;
1176 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1177 elt_p[0] = This_Element;
1178
1179 lnc__H264_writebits_endofsequence_header(mtx_hdr, elt_p);
1180 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1181 }
1182
1183
1184
lnc__H264_getelements_endofstream_header(MTX_HEADER_PARAMS * mtx_hdr)1185 static void lnc__H264_getelements_endofstream_header(MTX_HEADER_PARAMS *mtx_hdr)
1186 {
1187 /* Builds a single endofstream header from the given parameters (mid frame) */
1188
1189 /* Essential we initialise our header structures before building */
1190 MTX_HEADER_ELEMENT *This_Element;
1191 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1192 mtx_hdr->Elements = ELEMENTS_EMPTY;
1193 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1194 elt_p[0] = This_Element;
1195
1196 lnc__H264_writebits_endofstream_header(mtx_hdr, elt_p);
1197 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1198 }
1199
Bits2Code(IMG_UINT32 CodeVal)1200 static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1201 {
1202 IMG_UINT8 Bits = 32;
1203 if (CodeVal == 0)
1204 return 1;
1205 while (!(CodeVal & 0x80000000)) {
1206 CodeVal <<= 1;
1207 Bits--;
1208 }
1209 return Bits;
1210 }
1211
1212 /*
1213 * Intermediary functions to build MPEG4 headers
1214 */
1215 #define MATCH_TO_ENC
1216
1217
lnc__MPEG4_writebits_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_BOOL bBFrame,MPEG4_PROFILE_TYPE bProfile,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 * sVBVParams,IMG_UINT32 VopTimeResolution)1218 static void lnc__MPEG4_writebits_sequence_header(
1219 MTX_HEADER_PARAMS *mtx_hdr,
1220 MTX_HEADER_ELEMENT **elt_p,
1221 IMG_BOOL bBFrame,
1222 MPEG4_PROFILE_TYPE bProfile,
1223 IMG_UINT8 Profile_and_level_indication,
1224 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
1225 IMG_UINT32 Picture_Width_Pixels,
1226 IMG_UINT32 Picture_Height_Pixels,
1227 VBVPARAMS *sVBVParams, IMG_UINT32 VopTimeResolution) /* Send NULL pointer if there are no VBVParams */
1228 {
1229 /* Essential we insert the element before we try to fill it! */
1230 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1231
1232 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */
1233 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1234
1235 /* profile_and_level_indication = 8 Bits = SP L0-L3 and SP L4-L5 are supported */
1236 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1237
1238 /* visual_object_start_code = 32 Bits = 0x1B5 */
1239 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1240 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1241 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1242 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 181, 8);
1243
1244 /* is_visual_object_identifier = 1 Bit = 0 */
1245 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1246
1247 /* visual_object_type = 4 Bits = Video ID = 1 */
1248 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1249
1250 /* video_signal_type = 1 Bit = 1 */
1251 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1252
1253 /* byte_aligned_bits = 2 Bits = 01b (byte_aligned_bits is 2-bit stuffing bit field 01) */
1254 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1255
1256 /* video_object_start_code = 32 Bits = 0x100 One VO only in a Topaz video stream */
1257 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1258 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1259 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1260 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1261
1262 /* video_object_layer_start_code = 32 Bits = 0x120 One VOL only in a Topaz stream */
1263 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1264 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8);
1265 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1266 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 32, 8);
1267
1268 /* random_accessible_vol = 1 Bit = 0 (P-Frame in GOP) */
1269 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1270
1271 if (bProfile == SP) {
1272 /* video_object_type_indication = 8 Bits = 0x01 for SP */
1273 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8);
1274 #ifndef MATCH_TO_ENC
1275 /* is_object_layer_identifier = 1 Bit = 0 for SP */
1276 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1277 #else
1278 /* to match the encoder */
1279
1280 /* is_object_layer_identifier = 1 Bit */
1281 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1282
1283 /* video_object_layer_verid = 4 Bits */
1284 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1285
1286 /* video_object_layer_priority = 3 Bits */
1287 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3); // 0 is reserved...
1288 #endif
1289 } else {
1290 /* video_object_type_indication = 8 Bits = 0x11 for ASP */
1291 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 3, 8);
1292
1293 /* is_object_layer_identifier = 1 Bit = 1 for ASP */
1294 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1295
1296 /* video_object_layer_verid = 4 Bits = 5 is for ASP */
1297 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4);
1298
1299 /* video_object_layer_priority = 3 Bits = 1 (Highest priority) */
1300 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3);
1301 }
1302
1303 /* aspect_ratio_info = 4 Bits =0x1 (Square pixel) */
1304 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1305 #ifndef MATCH_TO_ENC
1306 /* vol_control_parameters = 1 Bit = 1 (Always send VOL control parameters) */
1307 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1308 #else
1309 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1310
1311 #endif
1312
1313 #ifndef MATCH_TO_ENC
1314 /* chroma_format = 2 Bits = 01b (4:2:0) */
1315 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1316
1317 /* low_delay = 1 Bit = 0 with B-frame and 1 without B-frame */
1318 if (bBFrame)
1319 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1320 else
1321 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1322
1323 /* vbv_parameters = 1 Bit =0/1 */
1324 if (sVBVParams) {
1325 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1326
1327 /* For recording, only send vbv parameters in 1st sequence header.
1328 * For video phone, it should be sent more often, such as once per sequence
1329 */
1330 lnc__write_upto32bits_elements(
1331 mtx_hdr,
1332 elt_p,
1333 sVBVParams->First_half_bit_rate,
1334 15); /* first_half_bit_rate */
1335
1336 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1337 lnc__write_upto32bits_elements(
1338 mtx_hdr,
1339 elt_p,
1340 sVBVParams->Latter_half_bit_rate,
1341 15); /* latter_half_bit_rate */
1342
1343 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1344 lnc__write_upto32bits_elements(
1345 mtx_hdr,
1346 elt_p,
1347 sVBVParams->First_half_vbv_buffer_size,
1348 15);/* first_half_vbv_buffer_size */
1349
1350 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1351 lnc__write_upto32bits_elements(
1352 mtx_hdr, elt_p,
1353 sVBVParams->Latter_half_vbv_buffer_size,
1354 15); /* latter_half_vbv_buffer_size */
1355 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1356 lnc__write_upto32bits_elements(
1357 mtx_hdr,
1358 elt_p,
1359 sVBVParams->First_half_vbv_occupancy,
1360 15); /* first_half_vbv_occupancy */
1361 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1362 lnc__write_upto32bits_elements(
1363 mtx_hdr,
1364 elt_p,
1365 sVBVParams->Latter_half_vbv_occupancy,
1366 15); /* latter_half_vbv_occupancy */
1367 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */
1368 } else
1369 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); /* No vbv parameters present */
1370 #endif
1371 /* video_object_layer_shape = 2 Bits = 00b Rectangular shape */
1372 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1373 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1374
1375 /* vop_time_increment_solution = 16 Bits */
1376 lnc__write_upto32bits_elements(mtx_hdr, elt_p, VopTimeResolution, 16);
1377 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1378
1379 #ifndef MATCH_TO_ENC
1380 /* fixed_vop_rate = 1 Bits = 1 Always fixed frame rate */
1381 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1382
1383 /* fixed_vop_time_increment = Variable number of bits based on the time increment resolution. */
1384 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, Bits2Code(VopTimeResolution - 1));
1385 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1386 #else
1387 /* fixed_vop_rate = 1 Bits = 0 */
1388 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1389 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1390
1391 #endif
1392 /* video_object_layer_width = 13 Bits Picture width in pixel units */
1393 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Width_Pixels, 13);
1394 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1395
1396 /* video_object_layer_height = 13 Bits Picture height in pixel units */
1397 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Height_Pixels, 13);
1398 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */
1399
1400 /* interlaced = 1 Bit = 0 Topaz only encodes progressive frames */
1401 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1402
1403 /* obmc_disable = 1 Bit = 1 No overlapped MC in Topaz */
1404 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1405
1406 /* sprite_enable = 1 Bit = 0 Not use sprite in Topaz */
1407 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1408
1409 /* not_8_bit = 1 Bit = 0 8-bit video in Topaz */
1410 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1411
1412 /* quant_type = 1 Bit = 0 2nd quantization method in Topaz */
1413 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1414
1415 if (bProfile == ASP) {
1416 /* quarter_sample = 1 Bit = 0 No �-pel MC in Topaz */
1417 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1418 }
1419
1420 /* complexity_estimation_disable = 1 Bit = 1 No complexity estimation in Topaz */
1421 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1422 #ifndef MATCH_TO_ENC
1423
1424 /* resync_marker_disable = 1 Bit = 0 Always enable resync marker in Topaz */
1425 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1426 #else
1427 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1428 #endif
1429 /* data_partitioned = 1 Bit = 0 No data partitioning in Topaz */
1430 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1431
1432 if (bProfile == ASP) {
1433 /* newpred_enable = 1 Bit = 0 No newpred mode in SP/ASP */
1434 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1435 /* reduced_vop_resolution_enable=1 Bit = 0 No reduced resolution frame in SP/ASP */
1436 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1437 }
1438
1439 /* scalability = 1 Bit = 0 No scalability in SP/ASP */
1440 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1441
1442 /* byte_aligned_bits */
1443
1444 /* Tell MTX to insert the byte align field
1445 * (we don't know final stream size for alignment at this point)
1446 */
1447 lnc__insert_element_token(
1448 mtx_hdr,
1449 elt_p,
1450 ELEMENT_INSERTBYTEALIGN_MPG4);
1451
1452 return;
1453 }
1454
1455
1456 /* Utility function */
1457 /*
1458 IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1459 {
1460 IMG_UINT8 Bits=32;
1461 if(CodeVal==0)
1462 return 1;
1463 while(!(CodeVal & 0x80000000))
1464 {
1465 CodeVal<<=1;
1466 Bits--;
1467 }
1468 return Bits;
1469 }
1470 */
1471
1472 /* MPEG 4 VOP (Picture) Header */
lnc__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)1473 static void lnc__MPEG4_writebits_VOP_header(
1474 MTX_HEADER_PARAMS *mtx_hdr,
1475 MTX_HEADER_ELEMENT **elt_p,
1476 IMG_BOOL bIsVOP_coded,
1477 IMG_UINT8 VOP_time_increment,
1478 SEARCH_RANGE_TYPE sSearch_range,
1479 VOP_CODING_TYPE sVopCodingType,
1480 IMG_UINT32 VopTimeResolution)
1481 {
1482 IMG_BOOL bIsSyncPoint;
1483 /* Essential we insert the element before we try to fill it! */
1484 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1485
1486 /* visual_object_sequence_start_code = 32 Bits = 0x1B6 */
1487 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 438, 32);
1488
1489 /* vop_coding_type = 2 Bits = 0 for I-frame and 1 for P-frame */
1490 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sVopCodingType, 2);
1491 bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0);
1492
1493 #ifndef MATCH_TO_ENC
1494 /* modulo_time_base = 1 Bit = 0 As at least 1 synchronization point (I-frame) per second in Topaz */
1495 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1496 #else
1497
1498 lnc__write_upto8bits_elements(mtx_hdr, elt_p, bIsSyncPoint ? 2 : 0 , bIsSyncPoint ? 2 : 1);
1499
1500 #endif
1501
1502 /* marker_bit = 1 Bits = 1 */
1503 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1504
1505 #ifndef MATCH_TO_ENC
1506 /* vop_time_increment = Variable bits based on resolution
1507 * = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame
1508 */
1509 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VOP_time_increment, 5);
1510 #else
1511 /* will chrash here... */
1512 lnc__write_upto8bits_elements(
1513 mtx_hdr, elt_p,
1514 (VOP_time_increment) % VopTimeResolution,
1515 Bits2Code(VopTimeResolution - 1));
1516
1517 #endif
1518 /* marker_bit = 1 Bit = 1 */
1519 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1520
1521 if (!bIsVOP_coded) {
1522 /* vop_coded = 1 Bit = 0 for skipped frame */
1523 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1524
1525 /* byte_aligned_bits (skipped pictures are byte aligned) */
1526 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1527 * End of VOP - skipped picture
1528 */
1529 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_MPG4);
1530 } else {
1531 /* vop_coded = 1 Bit = 1 for normal coded frame */
1532 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1533
1534 if (sVopCodingType == P_FRAME) {
1535 /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */
1536 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1537 }
1538
1539 /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */
1540 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3);
1541
1542 /* vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX */
1543 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, Frame_Q_scale, 5); */
1544 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE);
1545
1546 if (sVopCodingType == P_FRAME) {
1547 /* vop_fcode_forward = 3 bits = 2 for +/-32 and 3 for +/-64 search range */
1548 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1549 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3);
1550 }
1551
1552 /*
1553 **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE
1554 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1555 video_packet_data ( ) = 1st VP that doesn�t have the VP header
1556
1557 while (nextbits_bytealigned ( ) == resync_marker)
1558 {
1559 video_packet _header( )
1560 video_packet _data( ) All MB in the slice
1561 }
1562 */
1563 }
1564 }
1565
1566
1567 /* MPEG 4 Video Packet (Slice) Header */
lnc__MPEG4_writebits_videopacket_header(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,VOP_CODING_TYPE eVop_Coding_Type,IMG_UINT8 Fcode,IMG_UINT32 MBNumber,IMG_UINT32 MBNumberlength,IMG_BOOL bHeader_Extension_Code,IMG_UINT8 VOP_Time_Increment,SEARCH_RANGE_TYPE sSearch_range)1568 static void lnc__MPEG4_writebits_videopacket_header(
1569 MTX_HEADER_PARAMS *mtx_hdr,
1570 MTX_HEADER_ELEMENT **elt_p,
1571 VOP_CODING_TYPE eVop_Coding_Type,
1572 IMG_UINT8 Fcode,
1573 IMG_UINT32 MBNumber,
1574 IMG_UINT32 MBNumberlength,
1575 IMG_BOOL bHeader_Extension_Code,
1576 IMG_UINT8 VOP_Time_Increment,
1577 SEARCH_RANGE_TYPE sSearch_range)
1578 {
1579 /* Essential we insert the element before we try to fill it! */
1580 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1581
1582 if (eVop_Coding_Type == I_FRAME) {
1583 /* resync_marker = 17 bit =0x1 17-bit for I-frame */
1584 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17);
1585 } else {
1586 /* resync_marker = 17 bit =0x1 (16+fcode) bits for P-frame */
1587 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 16 + Fcode);
1588 }
1589
1590 /* macroblock_number = 1-14 bits = ?????? */
1591 lnc__write_upto32bits_elements(mtx_hdr, elt_p, MBNumber, MBNumberlength);
1592
1593 /* quant_scale = 5 bits =1-32 VP (Slice) Q_scale
1594 * lnc__write_upto8bits_elements(mtx_hdr, elt_p, VP_Slice_Q_Scale, 5);
1595 */
1596 lnc__insert_element_token(
1597 mtx_hdr, elt_p,
1598 ELEMENT_SLICEQSCALE); /* Insert token to tell MTX to insert rate-control value */
1599
1600 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); /* Begin writing rawdata again */
1601
1602 if (bHeader_Extension_Code) {
1603 /* header_extension_code = 1bit = 1 picture header parameters are repeated */
1604 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1605
1606 /* modulo_time_base = 1 bit = 0 The same as it is in the current picture header */
1607 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1608
1609 /* marker_bit = 1 bit = 1 */
1610 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1611
1612 /* vop_time_increment = 5 bits = 0-30 The same as it is in the current picture header */
1613 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VOP_Time_Increment, 5);
1614
1615 /* marker_bit = 1 bit = 1 */
1616 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1617
1618 /* vop_coding_type= 2 bits = 0/1 The same as it is in the current picture header */
1619 lnc__write_upto8bits_elements(mtx_hdr, elt_p, eVop_Coding_Type, 2);
1620
1621 /* intra_dc_vlc_thr = 3 bits = 0 The same as it is in the current picture header */
1622 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3);
1623
1624 if (eVop_Coding_Type == P_FRAME) {
1625 /* vop_fcode_forward = 3 bits = 2/3 The same as it is in the current picture header */
1626 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3);
1627 }
1628 } else {
1629 /* header_extension_code = 1 bits =0 picture header parameters are NOT repeated */
1630 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1631 }
1632 }
1633
1634 /*
1635 * High level functions to call when a MPEG4 header is required - HOST ROUTINES
1636 */
lnc__MPEG4_getelements_sequence_header(MTX_HEADER_PARAMS * mtx_hdr,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 * sVBVParams,IMG_UINT32 VopTimeResolution)1637 static void lnc__MPEG4_getelements_sequence_header(
1638 MTX_HEADER_PARAMS *mtx_hdr,
1639 IMG_BOOL bBFrame,
1640 MPEG4_PROFILE_TYPE sProfile,
1641 IMG_UINT8 Profile_and_level_indication,
1642 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
1643 IMG_UINT32 Picture_Width_Pixels,
1644 IMG_UINT32 Picture_Height_Pixels,
1645 VBVPARAMS *sVBVParams,
1646 IMG_UINT32 VopTimeResolution) /* NULL pointer if there are no VBVParams */
1647 {
1648 /* Builds a single MPEG4 video sequence header from the given parameters */
1649
1650 /* Essential we initialise our header structures before building */
1651 MTX_HEADER_ELEMENT *This_Element;
1652 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1653 mtx_hdr->Elements = ELEMENTS_EMPTY;
1654 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1655 elt_p[0] = This_Element;
1656
1657 lnc__MPEG4_writebits_sequence_header(
1658 mtx_hdr,
1659 elt_p,
1660 bBFrame, sProfile,
1661 Profile_and_level_indication,
1662 sFixed_vop_time_increment,
1663 Picture_Width_Pixels,
1664 Picture_Height_Pixels,
1665 sVBVParams, VopTimeResolution);
1666
1667 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1668 }
1669
1670
1671 /* MPEG 4 VOP (Picture) Header */
lnc__MPEG4_getelements_VOP_header(MTX_HEADER_PARAMS * mtx_hdr,IMG_BOOL bIsVOP_coded,IMG_UINT8 VOP_time_increment,SEARCH_RANGE_TYPE sSearch_range,VOP_CODING_TYPE sVopCodingType,IMG_UINT32 VopTimeResolution)1672 static void lnc__MPEG4_getelements_VOP_header(
1673 MTX_HEADER_PARAMS *mtx_hdr,
1674 IMG_BOOL bIsVOP_coded,
1675 IMG_UINT8 VOP_time_increment,
1676 SEARCH_RANGE_TYPE sSearch_range,
1677 VOP_CODING_TYPE sVopCodingType,
1678 IMG_UINT32 VopTimeResolution)
1679 {
1680 /* Builds a single MPEG4 VOP (picture) header from the given parameters */
1681
1682 /* Essential we initialise our header structures before building */
1683 MTX_HEADER_ELEMENT *This_Element;
1684 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1685 mtx_hdr->Elements = ELEMENTS_EMPTY;
1686 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1687 elt_p[0] = This_Element;
1688
1689 /* Frame QScale no longer written here as it is inserted by MTX later
1690 * (add as parameter to MTX_Send_Elements_To_VLC)
1691 */
1692 lnc__MPEG4_writebits_VOP_header(
1693 mtx_hdr, elt_p, bIsVOP_coded,
1694 VOP_time_increment,
1695 sSearch_range,
1696 sVopCodingType, VopTimeResolution);
1697
1698 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1699 }
1700
1701
lnc_MPEG4_getelements_video_packet_header(MTX_HEADER_PARAMS * mtx_hdr,VOP_CODING_TYPE eVop_Coding_Type,IMG_UINT8 Fcode,IMG_UINT32 MBNumber,IMG_UINT32 MBNumberlength,IMG_BOOL bHeader_Extension_Code,IMG_UINT8 VOP_Time_Increment,SEARCH_RANGE_TYPE sSearch_range)1702 static void lnc_MPEG4_getelements_video_packet_header(
1703 MTX_HEADER_PARAMS *mtx_hdr,
1704 VOP_CODING_TYPE eVop_Coding_Type,
1705 IMG_UINT8 Fcode,
1706 IMG_UINT32 MBNumber,
1707 IMG_UINT32 MBNumberlength,
1708 IMG_BOOL bHeader_Extension_Code,
1709 IMG_UINT8 VOP_Time_Increment,
1710 SEARCH_RANGE_TYPE sSearch_range)
1711 {
1712 /* Builds a single MPEG4 video packet (slice) header from the given parameters */
1713
1714 /* Essential we initialise our header structures before building */
1715 MTX_HEADER_ELEMENT *This_Element;
1716 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
1717 mtx_hdr->Elements = ELEMENTS_EMPTY;
1718 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1719 elt_p[0] = This_Element;
1720
1721 /* Slice QScale no longer written here as it is inserted by MTX later
1722 * (add as parameter when sending to VLC)
1723 */
1724 lnc__MPEG4_writebits_videopacket_header(
1725 mtx_hdr, elt_p, eVop_Coding_Type,
1726 Fcode, MBNumber, MBNumberlength,
1727 bHeader_Extension_Code, VOP_Time_Increment, sSearch_range);
1728
1729 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1730 }
1731
1732 /*
1733 * Intermediary functions to build H263 headers
1734 */
H263_writebits_VideoSequenceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 Profile_and_level_indication)1735 static void H263_writebits_VideoSequenceHeader(
1736 MTX_HEADER_PARAMS *mtx_hdr,
1737 MTX_HEADER_ELEMENT **elt_p,
1738 IMG_UINT8 Profile_and_level_indication)
1739 {
1740 /* Essential we insert the element before we try to fill it! */
1741 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1742
1743 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */
1744 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32);
1745
1746 /* profile_and_level_indication = 8 Bits = x SP L0-L3 and SP L4-L5 are supported */
1747 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8);
1748
1749 /* visual_object_start_code = 32 Bits = 0x1B5 */
1750
1751 /* 437 too large for the lnc__write_upto32bits_elements function */
1752 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 437, 32);
1753
1754 /* is_visual_object_identifier = 1 Bit = 0 */
1755 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1756
1757 /* is_visual_object_type = 4 Bits = 1 Video ID */
1758 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1759
1760 /* video_signal_type = 1 Bit = 0 */
1761 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1762
1763 /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */
1764 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2);
1765
1766 /* video_object_start_code =32 Bits = 0x100 One VO only in a Topaz video stream */
1767 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 256, 32);
1768
1769 return;
1770 }
1771
1772
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_UINT16 PictureWidth,IMG_UINT16 PictureHeight,IMG_UINT8 * OptionalCustomPCF)1773 static void H263_writebits_VideoPictureHeader(
1774 MTX_HEADER_PARAMS *mtx_hdr,
1775 MTX_HEADER_ELEMENT **elt_p,
1776 IMG_UINT8 Temporal_Ref,
1777 H263_PICTURE_CODING_TYPE PictureCodingType,
1778 //IMG_UINT8 Q_Scale,
1779 H263_SOURCE_FORMAT_TYPE SourceFormatType,
1780 IMG_UINT8 FrameRate,
1781 IMG_UINT16 PictureWidth,
1782 IMG_UINT16 PictureHeight,
1783 IMG_UINT8 *OptionalCustomPCF)
1784 {
1785 IMG_UINT8 UFEP;
1786
1787 #ifdef USESTATICWHEREPOSSIBLE
1788 IMG_UINT16 *p;
1789
1790 p = (IMG_UINT16 *) mtx_hdr;
1791 p[0] = p[1] = p[2] = p[3] = 0;
1792 p[4] = 38;
1793 p[5] = 32768 | ((Temporal_Ref >> 6) << 8);
1794 p[6] = ((Temporal_Ref & 63) << 2) | 2 | (SourceFormatType << 10);
1795 #else
1796
1797 /* Essential we insert the element before we try to fill it! */
1798 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1799
1800 /* short_video_start_marker = 22 Bits = 0x20 Picture start code */
1801 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 32, 22);
1802
1803 /* temporal_reference = 8 Bits = 0-255 Each picture increased by 1 */
1804 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Temporal_Ref, 8);
1805
1806 /* marker_bit = 1 Bit = 1 */
1807 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1808
1809 /* zero_bit = 1 Bits = 0 */
1810 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1811
1812 /* split_screen_indicator = 1 Bits = 0 No direct effect on encoding of picture */
1813 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1814
1815 /* document_camera_indicator= 1 Bits = 0 No direct effect on encoding of picture */
1816 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1817
1818 /* full_picture_freeze_release=1 Bits = 0 No direct effect on encoding of picture */
1819 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1820
1821 /* source_format = 3 Bits = 1-4 See note */
1822 lnc__write_upto8bits_elements(mtx_hdr, elt_p, SourceFormatType, 3);
1823 #endif
1824
1825
1826 /*Write optional Custom Picture Clock Frequency(OCPCF)*/
1827 if (FrameRate == 30 || FrameRate == 0/* unspecified */) {
1828 *OptionalCustomPCF = 0; // 0 for CIF PCF
1829 } else {
1830 *OptionalCustomPCF = 1; //1 for Custom PCF
1831 }
1832
1833
1834 if (SourceFormatType != 7) {
1835 /* picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame */
1836 lnc__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 1);
1837
1838 /* four_reserved_zero_bits = 4 Bits = 0 */
1839 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4);
1840 } else {
1841 static IMG_UINT8 RTYPE = 0;
1842
1843 // if I- Frame set Update Full Extended PTYPE to true
1844 if ((PictureCodingType == I_FRAME) || (SourceFormatType == 7) || *OptionalCustomPCF) {
1845 UFEP = 1;
1846 } else {
1847 UFEP = 0;
1848
1849 // RTYPE can be set to 1 only in case of P or PB picture.
1850 //RTYPE ^= 1;
1851 }
1852
1853 // write UFEP of 3 bits.
1854 lnc__write_upto8bits_elements(mtx_hdr, elt_p, UFEP, 3);
1855
1856 // if UFEP was present( if it was 1).
1857 // Optional part of PPTYPE.
1858 if (UFEP == 1) {
1859 // write souce_format_optional. value = 110 (custom source format).
1860 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 6, 3);
1861 /* souce_format_optional */
1862
1863 lnc__write_upto8bits_elements(mtx_hdr, elt_p, *OptionalCustomPCF , 1);
1864 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 0, 10);
1865 /* 10 reserve bits */
1866 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 8, 4);
1867 /* 4 reserve bits */
1868 }
1869 /* picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame */
1870 lnc__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 3);
1871
1872 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1873 /* two_reserve_bits, rounding_type, two_reserve_bits marker_bit CPM */
1874
1875 // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1876 lnc__write_upto8bits_elements(mtx_hdr, elt_p, RTYPE, 1);
1877 //2 reserve bits
1878 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2);
1879 // - 1 (ON) to prevent start code emulation.
1880 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1 , 1);
1881 // CPM immediately follows the PPTYPE part of the header.
1882 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0 , 1);
1883
1884 if (UFEP == 1) {
1885 IMG_UINT16 ui16PWI, ui16PHI;
1886
1887 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4);
1888 /* aspect ratio */
1889 //PictureWidth --;
1890 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth >> 8), 1);
1891 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth & 0xFF), 8);
1892
1893 ui16PWI = (PictureWidth >> 2) - 1;
1894 lnc__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PWI, 9);
1895 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1896 /* marker_bit = 1 Bit = 1 */
1897 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeigth >> 8), 1);
1898 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeigth & 0xFF), 8);
1899 /* good up to that point */
1900 ui16PHI = PictureHeight >> 2;
1901 lnc__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PHI, 9);
1902
1903 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); */
1904 /* marker_bit = 1 Bit = 1 */
1905 /* just checking */
1906 if (*OptionalCustomPCF == 1) {
1907 //IMG_UINT8 CPCFC;
1908 //CPCFC = (IMG_UINT8)(1800/(IMG_UINT16)FrameRate);
1909 /* you can use the table for division */
1910 //CPCFC <<= 1; /* for Clock Conversion Code */
1911 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);
1912 // Clock Divisor : 7 bits The natural binary representation of the value of the clock divisor.
1913 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1800000 / (FrameRate * 1000), 7);
1914 }
1915 }
1916 if (*OptionalCustomPCF == 1) {
1917 IMG_UINT8 ui8ETR; // extended Temporal reference
1918 // Two MSBs of 10 bit temporal_reference : value 0
1919 ui8ETR = Temporal_Ref >> 8;
1920
1921 lnc__write_upto8bits_elements(mtx_hdr, elt_p, ui8ETR, 2);
1922 /* Two MSBs of temporal_reference */
1923 }
1924 }
1925 /* vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX */
1926 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, Q_Scale, 5); */
1927
1928 /* Insert token to tell MTX to insert rate-control value
1929 * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, FrameQScale))
1930 */
1931 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE);
1932
1933
1934 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA);
1935
1936 /* zero_bit = 1 Bit = 0
1937 * pei = 1 Bit = 0 No direct effect on encoding of picture
1938 */
1939 if (SourceFormatType != 7) {
1940 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1941 }
1942
1943 /*
1944 FOLLOWING SECTION CAN'T BE GENERATED HERE
1945 gob_data( )
1946 for(i=1; i<num_gob_in_picture; i++) {
1947 gob_header( )
1948 gob_data( )
1949 }
1950 */
1951 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);
1952 return;
1953 }
1954
1955
H263_writebits_GOBSliceHeader(MTX_HEADER_PARAMS * mtx_hdr,MTX_HEADER_ELEMENT ** elt_p,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)1956 static void H263_writebits_GOBSliceHeader(
1957 MTX_HEADER_PARAMS *mtx_hdr,
1958 MTX_HEADER_ELEMENT **elt_p,
1959 IMG_UINT8 GOBNumber,
1960 IMG_UINT8 GOBFrameId)
1961 {
1962 #ifdef USESTATICWHEREPOSSIBLE
1963 IMG_UINT16 *p;
1964 p = (IMG_UINT16 *) mtx_hdr;
1965 /*
1966 p[0]=1;
1967 p[1]=p[2]=p[3]=0;
1968 */
1969 *(int *)mtx_hdr = 1;
1970 p[4] = 24;
1971 p[5] = (128 | ((GOBNumber & 31) << 2) | (GOBFrameId & 3)) << 8;
1972 p[6] = 5;
1973 #else
1974 /* Essential we insert the element before we try to fill it! */
1975 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA);
1976
1977 /* gob_resync_marker = 17 = 0x1 */
1978 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17);
1979
1980 /* gob_number = 5 = 0-17 It is gob number in a picture */
1981 lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOBNumber, 5);
1982
1983 /* gob_frame_id = 2 = 0-3 See note */
1984 lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOBFrameId, 2);
1985
1986 /* quant_scale = 5 = 1-32 gob (Slice) Q_scale */
1987 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOB_Q_Scale, 5); */
1988
1989 /* Insert token to tell MTX to insert rate-control value
1990 * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale))
1991 */
1992 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_SLICEQSCALE);
1993 #endif
1994 }
1995
1996 /*
1997 * High level functions to call when a H263 header is required - HOST ROUTINES
1998 */
lnc__H263_getelements_videosequence_header(MTX_HEADER_PARAMS * mtx_hdr,IMG_UINT8 Profile_and_level_indication)1999 static void lnc__H263_getelements_videosequence_header(
2000 MTX_HEADER_PARAMS *mtx_hdr,
2001 IMG_UINT8 Profile_and_level_indication)
2002 {
2003 /* Builds a single H263 video sequence header from the given parameters */
2004
2005 /* Essential we initialise our header structures before building */
2006 MTX_HEADER_ELEMENT *This_Element;
2007 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2008 mtx_hdr->Elements = ELEMENTS_EMPTY;
2009 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2010 elt_p[0] = This_Element;
2011
2012 H263_writebits_VideoSequenceHeader(mtx_hdr, elt_p, Profile_and_level_indication);
2013
2014 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2015 }
2016
lnc__H263_getelements_videopicture_header(MTX_HEADER_PARAMS * mtx_hdr,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 FrameRate,IMG_UINT16 PictureWidth,IMG_UINT16 PictureHeight,IMG_UINT8 * OptionalCustomPCF)2017 static void lnc__H263_getelements_videopicture_header(
2018 MTX_HEADER_PARAMS *mtx_hdr,
2019 IMG_UINT8 Temporal_Ref,
2020 H263_PICTURE_CODING_TYPE PictureCodingType,
2021 H263_SOURCE_FORMAT_TYPE SourceFormatType,
2022 IMG_UINT8 FrameRate,
2023 IMG_UINT16 PictureWidth,
2024 IMG_UINT16 PictureHeight,
2025 IMG_UINT8 *OptionalCustomPCF)
2026 {
2027 /* Essential we initialise our header structures before building */
2028 MTX_HEADER_ELEMENT *This_Element;
2029 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2030 mtx_hdr->Elements = ELEMENTS_EMPTY;
2031 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2032 elt_p[0] = This_Element;
2033
2034 H263_writebits_VideoPictureHeader(
2035 mtx_hdr, elt_p,
2036 Temporal_Ref,
2037 PictureCodingType,
2038 SourceFormatType,
2039 FrameRate,
2040 PictureWidth,
2041 PictureHeight,
2042 OptionalCustomPCF);
2043 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2044 }
2045
lnc__H263_getelements_GOBslice_header(MTX_HEADER_PARAMS * mtx_hdr,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)2046 static void lnc__H263_getelements_GOBslice_header(
2047 MTX_HEADER_PARAMS *mtx_hdr,
2048 IMG_UINT8 GOBNumber,
2049 IMG_UINT8 GOBFrameId)
2050 {
2051 /* Essential we initialise our header structures before building */
2052 MTX_HEADER_ELEMENT *This_Element;
2053 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS];
2054 mtx_hdr->Elements = ELEMENTS_EMPTY;
2055 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2056 elt_p[0] = This_Element;
2057
2058 H263_writebits_GOBSliceHeader(mtx_hdr, elt_p, GOBNumber, GOBFrameId);
2059
2060 mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
2061 }
2062
2063
2064
lnc__H264_prepare_sequence_header(IMG_UINT32 * pHeaderMemory,IMG_UINT32 uiMaxNumRefFrames,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)2065 void lnc__H264_prepare_sequence_header(
2066 IMG_UINT32 *pHeaderMemory,
2067 IMG_UINT32 uiMaxNumRefFrames,
2068 IMG_UINT32 uiPicWidthInMbs,
2069 IMG_UINT32 uiPicHeightInMbs,
2070 IMG_BOOL VUI_present, H264_VUI_PARAMS *VUI_params,
2071 H264_CROP_PARAMS *psCropParams,
2072 IMG_UINT8 uiLevel,
2073 IMG_UINT8 uiProfile)
2074 {
2075 H264_SEQUENCE_HEADER_PARAMS SHParams;
2076 MTX_HEADER_PARAMS *mtx_hdr;
2077
2078 memset(&SHParams, 0, sizeof(SHParams));
2079
2080 /* Route output elements to memory provided */
2081 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2082
2083 /* Setup Sequence Header information */
2084 switch (uiProfile) {
2085 case 5:
2086 SHParams.ucProfile = SH_PROFILE_BP;
2087 break;
2088 case 6:
2089 SHParams.ucProfile = SH_PROFILE_MP;
2090 break;
2091 default:
2092 SHParams.ucProfile = SH_PROFILE_MP;
2093 break;
2094 }
2095
2096 switch (uiLevel) {
2097 case 10:
2098 SHParams.ucLevel = SH_LEVEL_1;
2099 break;
2100 case 111:
2101 SHParams.ucLevel = SH_LEVEL_1B;
2102 break;
2103 case 11:
2104 SHParams.ucLevel = SH_LEVEL_11;
2105 break;
2106 case 12:
2107 SHParams.ucLevel = SH_LEVEL_12;
2108 break;
2109 case 20:
2110 SHParams.ucLevel = SH_LEVEL_2;
2111 break;
2112 case 30:
2113 SHParams.ucLevel = SH_LEVEL_3;
2114 break;
2115 case 31:
2116 SHParams.ucLevel = SH_LEVEL_31;
2117 break;
2118 default:
2119 SHParams.ucLevel = SH_LEVEL_3;
2120 break;
2121 }
2122
2123 SHParams.ucMax_num_ref_frames = uiMaxNumRefFrames;
2124 SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)(uiPicWidthInMbs - 1);
2125 SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)(uiPicHeightInMbs - 1);
2126 SHParams.VUI_Params_Present = VUI_present;
2127 if (VUI_present)
2128 SHParams.VUI_Params = *VUI_params;
2129
2130 /* All picture header information is static
2131 * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway)
2132 */
2133
2134 /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug
2135 * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0;
2136 */
2137
2138 #if HEADERS_VERBOSE_OUTPUT
2139 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2140 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2141 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2142 #endif
2143
2144 /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */
2145 lnc__H264_getelements_sequence_header(mtx_hdr, &SHParams, psCropParams);
2146 }
2147
lnc__H264_prepare_picture_header(IMG_UINT32 * pHeaderMemory)2148 void lnc__H264_prepare_picture_header(IMG_UINT32 *pHeaderMemory)
2149 {
2150 MTX_HEADER_PARAMS *mtx_hdr;
2151
2152
2153 /* Route output elements to memory provided */
2154 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2155
2156 /* All picture header information is static
2157 * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway)
2158 */
2159
2160 /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug
2161 * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0;
2162 */
2163
2164 #if HEADERS_VERBOSE_OUTPUT
2165 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2166 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2167 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2168 #endif
2169
2170 /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */
2171 lnc__H264_getelements_picture_header(mtx_hdr);
2172 }
2173
lnc__H264_prepare_slice_header(IMG_UINT32 * pHeaderMemory,IMG_BOOL bIntraSlice,IMG_UINT32 uiDisableDeblockingFilterIDC,IMG_UINT32 uiFrameNumber,IMG_UINT32 uiFirst_MB_Address,IMG_UINT32 uiMBSkipRun,IMG_UINT32 force_idr,IMG_BOOL bUsesLongTermRef,IMG_BOOL bIsLongTermRef,IMG_UINT16 uiIdrPicId)2174 void lnc__H264_prepare_slice_header(
2175 IMG_UINT32 *pHeaderMemory,
2176 IMG_BOOL bIntraSlice,
2177 IMG_UINT32 uiDisableDeblockingFilterIDC,
2178 IMG_UINT32 uiFrameNumber,
2179 IMG_UINT32 uiFirst_MB_Address,
2180 IMG_UINT32 uiMBSkipRun,
2181 IMG_UINT32 force_idr,
2182 IMG_BOOL bUsesLongTermRef,
2183 IMG_BOOL bIsLongTermRef,
2184 IMG_UINT16 uiIdrPicId)
2185 {
2186 H264_SLICE_HEADER_PARAMS SlHParams;
2187 MTX_HEADER_PARAMS *mtx_hdr;
2188
2189 /* Route output elements to memory provided */
2190 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2191
2192 SlHParams.Start_Code_Prefix_Size_Bytes = 4;
2193
2194 /* pcb - I think that this is more correct now*/
2195 if (force_idr)
2196 SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
2197 else
2198 SlHParams.SliceFrame_Type = bIntraSlice ? SLHP_I_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE;
2199
2200 SlHParams.Frame_Num_DO = (IMG_UINT8) uiFrameNumber % (1 << 5);
2201 SlHParams.Picture_Num_DO = (IMG_UINT8)(SlHParams.Frame_Num_DO * 2);
2202
2203 SlHParams.bUsesLongTermRef = bUsesLongTermRef;
2204 SlHParams.bIsLongTermRef = bIsLongTermRef;
2205
2206 SlHParams.First_MB_Address = uiFirst_MB_Address;
2207 SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) uiDisableDeblockingFilterIDC;
2208
2209 if (uiMBSkipRun)
2210 lnc__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun);
2211 else
2212 lnc__H264_getelements_slice_header(mtx_hdr, &SlHParams, uiIdrPicId);
2213 }
2214
lnc__H264_prepare_eodofstream_header(IMG_UINT32 * pHeaderMemory)2215 void lnc__H264_prepare_eodofstream_header(IMG_UINT32 *pHeaderMemory)
2216 {
2217 MTX_HEADER_PARAMS *mtx_hdr;
2218
2219 /* Route output elements to memory provided */
2220 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2221
2222 lnc__H264_getelements_endofstream_header(mtx_hdr);
2223 }
2224
lnc__H264_prepare_endofpicture_header(IMG_UINT32 * pHeaderMemory)2225 void lnc__H264_prepare_endofpicture_header(IMG_UINT32 *pHeaderMemory)
2226 {
2227 MTX_HEADER_PARAMS *mtx_hdr;
2228
2229 /* Route output elements to memory provided */
2230 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2231
2232 /* H264_GetElements_EndOfPicture_Header(MTX_Header); */
2233 }
2234
lnc__H264_prepare_endofsequence_header(IMG_UINT32 * pHeaderMemory)2235 void lnc__H264_prepare_endofsequence_header(IMG_UINT32 *pHeaderMemory)
2236 {
2237 MTX_HEADER_PARAMS *mtx_hdr;
2238
2239 /* Route output elements to memory provided */
2240 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2241
2242 lnc__H264_getelements_endofsequence_header(mtx_hdr);
2243 }
2244
lnc__MPEG4_prepare_sequence_header(IMG_UINT32 * 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,IMG_BOOL bVBVPresent,IMG_UINT32 First_half_bit_rate,IMG_UINT32 Latter_half_bit_rate,IMG_UINT32 First_half_vbv_buffer_size,IMG_UINT32 Latter_half_vbv_buffer_size,IMG_UINT32 First_half_vbv_occupancy,IMG_UINT32 Latter_half_vbv_occupancy,IMG_UINT32 VopTimeResolution)2245 void lnc__MPEG4_prepare_sequence_header(
2246 IMG_UINT32 *pHeaderMemory,
2247 IMG_BOOL bBFrame,
2248 MPEG4_PROFILE_TYPE sProfile,
2249 IMG_UINT8 Profile_and_level_indication,
2250 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
2251 IMG_UINT32 Picture_Width_Pixels,
2252 IMG_UINT32 Picture_Height_Pixels,
2253 IMG_BOOL bVBVPresent,
2254 IMG_UINT32 First_half_bit_rate,
2255 IMG_UINT32 Latter_half_bit_rate,
2256 IMG_UINT32 First_half_vbv_buffer_size,
2257 IMG_UINT32 Latter_half_vbv_buffer_size,
2258 IMG_UINT32 First_half_vbv_occupancy,
2259 IMG_UINT32 Latter_half_vbv_occupancy,
2260 IMG_UINT32 VopTimeResolution)
2261 {
2262 MTX_HEADER_PARAMS *mtx_hdr;
2263 VBVPARAMS sVBVParams;
2264
2265 sVBVParams.First_half_bit_rate = First_half_bit_rate;
2266 sVBVParams.Latter_half_bit_rate = Latter_half_bit_rate;
2267 sVBVParams.First_half_vbv_buffer_size = First_half_vbv_buffer_size;
2268 sVBVParams.Latter_half_vbv_buffer_size = Latter_half_vbv_buffer_size;
2269 sVBVParams.First_half_vbv_occupancy = First_half_vbv_occupancy;
2270 sVBVParams.Latter_half_vbv_occupancy = Latter_half_vbv_occupancy;
2271
2272 /* Route output elements to memory provided */
2273 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2274
2275 if (bVBVPresent)
2276 lnc__MPEG4_getelements_sequence_header(
2277 mtx_hdr, bBFrame, sProfile,
2278 Profile_and_level_indication,
2279 sFixed_vop_time_increment,
2280 Picture_Width_Pixels, Picture_Height_Pixels,
2281 &sVBVParams, VopTimeResolution);
2282 else
2283 lnc__MPEG4_getelements_sequence_header(
2284 mtx_hdr, bBFrame, sProfile,
2285 Profile_and_level_indication,
2286 sFixed_vop_time_increment,
2287 Picture_Width_Pixels, Picture_Height_Pixels,
2288 NULL, VopTimeResolution);/* NULL pointer if there are no VBVParams */
2289 }
2290
lnc__MPEG4_prepare_vop_header(IMG_UINT32 * pHeaderMem,IMG_BOOL bIsVOP_coded,IMG_UINT32 VOP_time_increment,IMG_UINT8 sSearch_range,IMG_UINT8 eVop_Coding_Type,IMG_UINT32 VopTimeResolution)2291 void lnc__MPEG4_prepare_vop_header(
2292 IMG_UINT32 *pHeaderMem,
2293 IMG_BOOL bIsVOP_coded,
2294 IMG_UINT32 VOP_time_increment,
2295 IMG_UINT8 sSearch_range,
2296 IMG_UINT8 eVop_Coding_Type,
2297 IMG_UINT32 VopTimeResolution)
2298 {
2299 MTX_HEADER_PARAMS *mtx_hdr;
2300
2301 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2302
2303 /* Frame QScale (and Slice QScale in the slice case)
2304 * no longer written here as it is inserted by MTX later
2305 * (add as parameter to MTX_Send_Elements_To_VLC)
2306 */
2307 lnc__MPEG4_getelements_VOP_header(
2308 mtx_hdr,
2309 bIsVOP_coded,
2310 VOP_time_increment,
2311 sSearch_range,
2312 eVop_Coding_Type, VopTimeResolution);
2313 }
2314
lnc__H263_prepare_sequence_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 Profile_and_level_indication)2315 void lnc__H263_prepare_sequence_header(
2316 IMG_UINT32 *pHeaderMem,
2317 IMG_UINT8 Profile_and_level_indication)
2318 {
2319 MTX_HEADER_PARAMS *mtx_hdr;
2320
2321 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2322
2323 lnc__H263_getelements_videosequence_header(mtx_hdr, Profile_and_level_indication);
2324 }
2325
lnc__H263_prepare_picture_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 Temporal_Ref,H263_PICTURE_CODING_TYPE PictureCodingType,H263_SOURCE_FORMAT_TYPE SourceFormatType,IMG_UINT8 FrameRate,IMG_UINT16 PictureWidth,IMG_UINT16 PictureHeight,IMG_UINT8 * OptionalCustomPCF)2326 void lnc__H263_prepare_picture_header(
2327 IMG_UINT32 *pHeaderMem,
2328 IMG_UINT8 Temporal_Ref,
2329 H263_PICTURE_CODING_TYPE PictureCodingType,
2330 H263_SOURCE_FORMAT_TYPE SourceFormatType,
2331 IMG_UINT8 FrameRate,
2332 IMG_UINT16 PictureWidth,
2333 IMG_UINT16 PictureHeight,
2334 IMG_UINT8 *OptionalCustomPCF)
2335 {
2336 MTX_HEADER_PARAMS *mtx_hdr;
2337
2338 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2339 lnc__H263_getelements_videopicture_header(
2340 mtx_hdr,
2341 Temporal_Ref,
2342 PictureCodingType,
2343 SourceFormatType,
2344 FrameRate,
2345 PictureWidth,
2346 PictureHeight,
2347 OptionalCustomPCF);
2348 }
2349
lnc__H263_prepare_GOBslice_header(IMG_UINT32 * pHeaderMem,IMG_UINT8 GOBNumber,IMG_UINT8 GOBFrameId)2350 void lnc__H263_prepare_GOBslice_header(
2351 IMG_UINT32 *pHeaderMem,
2352 IMG_UINT8 GOBNumber,
2353 IMG_UINT8 GOBFrameId)
2354 {
2355 MTX_HEADER_PARAMS *mtx_hdr;
2356
2357 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2358
2359 lnc__H263_getelements_GOBslice_header(
2360 mtx_hdr,
2361 GOBNumber,
2362 GOBFrameId);
2363
2364 /* silent the warning message */
2365 (void)Show_Bits;
2366 (void)Show_Elements;
2367 (void)lnc__H264_writebits_SEI_rbspheader;
2368 (void)lnc__H264_getelements_skip_B_slice;
2369 (void)lnc__H264_getelements_backward_zero_B_slice;
2370 (void)lnc__H264_getelements_rbsp_ATE_only;
2371 (void)lnc_MPEG4_getelements_video_packet_header;
2372 }
2373
2374