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