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