tng_hostheader.c revision f7e2fd14e8565af238ab58d537df352ffbd479cd
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 *    Edward Lin <edward.lin@intel.com>
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 "tng_hostheader.h"
38#ifdef _TOPAZHP_PDUMP_
39#include "tng_trace.h"
40#endif
41/* Global stores the latest QP information for the DoHeader()
42 * routine, should be filled in by the rate control algorithm.
43 */
44#define HEADERS_VERBOSE_OUTPUT 0
45
46/* #define USESTATICWHEREPOSSIBLE 1 */
47
48#define MAXNUMBERELEMENTS 16
49
50/* SOME USEFUL TEST FUNCTIONS */
51#ifndef TOPAZ_MTX_HW
52static void Show_Bits(
53    IMG_UINT8 *ucBitStream,
54    IMG_UINT32 ByteStartBit,
55    IMG_UINT32 Bits)
56{
57    return ;
58#if 0
59    char Txt[1024];
60    IMG_UINT32 uiByteSize;
61    IMG_UINT32 uiLp, uiBt, Bcnt;
62    Bcnt = 0;
63    uiByteSize = (Bits + ByteStartBit + 7) >> 3;
64    for (uiLp = 0; uiLp < uiByteSize; uiLp++) {
65        snprintf(Txt, strlen(" "), " ");
66        for (uiBt = 128; uiBt >= 1; uiBt = uiBt >> 1) {
67            Bcnt++;
68            if (Bcnt > Bits + ByteStartBit || Bcnt <= ByteStartBit)
69                snprintf(Txt, sizeof(Txt), "%sX", Txt);
70            else
71                snprintf(Txt, sizeof(Txt), "%s%i", Txt, (ucBitStream[uiLp] & uiBt) > 0);
72        }
73
74        snprintf(Txt, sizeof(Txt), "%s ", Txt);
75        //printf(Txt);
76        if ((uiLp + 1) % 8 == 0) printf("\n");
77    }
78
79    printf("\n\n");
80#endif
81}
82#endif
83
84#ifndef TOPAZ_MTX_HW
85
86static void Show_Elements(
87    MTX_HEADER_PARAMS *mtx_hdr,
88    MTX_HEADER_ELEMENT **aui32ElementPointers)
89{
90    return ;
91#if 0
92    IMG_UINT8 f;
93    IMG_UINT32 TotalByteSize;
94    IMG_UINT32 RTotalByteSize;
95
96    RTotalByteSize = TotalByteSize = 0;
97    for (f = 0; f < mtx_hdr->ui32Elements; f++) {
98#if HEADERS_VERBOSE_OUTPUT
99        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Encoding Element [%i] - Type:%i\n", f, aui32ElementPointers[f]->Element_Type);
100#endif
101        if (aui32ElementPointers[f]->Element_Type == ELEMENT_STARTCODE_RAWDATA ||
102            aui32ElementPointers[f]->Element_Type == ELEMENT_RAWDATA) {
103            TotalByteSize = aui32ElementPointers[f]->ui8Size;
104#if HEADERS_VERBOSE_OUTPUT
105            drv_debug_msg(VIDEO_DEBUG_GENERAL, "Writing %i RAW bits to element.\n", aui32ElementPointers[f]->ui8Size);
106            Show_Bits((IMG_UINT8 *)(&aui32ElementPointers[f]->ui8Size) + 1, 0, TotalByteSize);
107#endif
108            TotalByteSize += 8;
109
110            RTotalByteSize += (((IMG_UINT32)((TotalByteSize + 7) / 8)) * 8);
111            RTotalByteSize += 32;
112        } else {
113            TotalByteSize = 0;
114            switch (aui32ElementPointers[f]->Element_Type) {
115            case ELEMENT_QP:
116#if HEADERS_VERBOSE_OUTPUT
117                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_QP (H264)- for MTX to generate and insert this value\n");
118#endif
119                break;
120            case ELEMENT_SQP:
121#if HEADERS_VERBOSE_OUTPUT
122                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SQP (H264)- for MTX to generate and insert this value\n");
123#endif
124                break;
125            case ELEMENT_FRAMEQSCALE:
126#if HEADERS_VERBOSE_OUTPUT
127                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_FRAMEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
128#endif
129                break;
130            case ELEMENT_SLICEQSCALE:
131#if HEADERS_VERBOSE_OUTPUT
132                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_SLICEQSCALE (H263/MPEG4) - for MTX to generate and insert this value\n");
133#endif
134                break;
135            case ELEMENT_INSERTBYTEALIGN_H264:
136#if HEADERS_VERBOSE_OUTPUT
137                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_H264 -  MTX to generate 'rbsp_trailing_bits()' field\n");
138#endif
139                break;
140            case ELEMENT_INSERTBYTEALIGN_MPG4:
141#if HEADERS_VERBOSE_OUTPUT
142                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert token ELEMENT_INSERTBYTEALIGN_MPG4 -  MTX to generate MPEG4 'byte_aligned_bits' field\n");
143#endif
144                break;
145            default:
146                break;
147            }
148
149            RTotalByteSize += 32;
150#if HEADERS_VERBOSE_OUTPUT
151            drv_debug_msg(VIDEO_DEBUG_GENERAL, "No RAW bits\n\n");
152#endif
153        }
154    }
155
156    /* TotalByteSize=TotalByteSize+32+(&aui32ElementPointers[f-1]->Element_Type-&aui32ElementPointers[0]->Element_Type)*8; */
157
158#if HEADERS_VERBOSE_OUTPUT
159    drv_debug_msg(VIDEO_DEBUG_GENERAL, "\nCombined ELEMENTS Stream:\n");
160    Show_Bits((IMG_UINT8 *) mtx_hdr->asElementStream, 0, RTotalByteSize);
161#endif
162#endif //0
163}
164#endif
165
166static void tng_print(unsigned char *ptmp, int num)
167{
168    int tmp;
169    do {
170      for(tmp=0;tmp < num;tmp++) {
171        if(tmp%8==0)
172            drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\t\t");
173       drv_debug_msg(VIDEO_DEBUG_GENERAL, "\t0x%02x", ptmp[tmp]);
174     }
175     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\t\t}\n");
176    } while (0);
177}
178
179/**
180 * Header Writing Functions
181 * Low level bit writing and ue, se functions
182 * HOST CODE
183 */
184static void tng__write_upto8bits_elements(
185    MTX_HEADER_PARAMS *pMTX_Header,
186    MTX_HEADER_ELEMENT **aui32ElementPointers,
187    IMG_UINT8 ui8WriteBits,
188    IMG_UINT16 ui16BitCnt)
189{
190    // This is the core function to write bits/bytes to a header stream, it writes them directly to ELEMENT structures.
191    IMG_UINT8 *pui8WriteBytes;
192    IMG_UINT8 *pui8SizeBits;
193    union {
194        IMG_UINT32 UI16Input;
195        IMG_UINT8 UI8Input[2];
196    } InputVal;
197    IMG_UINT8 ui8OutByteIndex;
198    IMG_INT16 i16Shift;
199    if (ui16BitCnt==0)
200        return ;
201
202//    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: mtx_hdr->ui32Elments overflow (%d)\n", __FUNCTION__, pMTX_Header->ui32Elements);
203    /* WA for klockwork */
204
205//    if (pMTX_Header->ui32Elements >= MAXNUMBERELEMENTS) {
206//        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: mtx_hdr->ui32Elments overflow (%d)\n", __FUNCTION__, pMTX_Header->ui32Elements);
207//        return;
208//    }
209    // First ensure that unused bits  in ui8WriteBits are zeroed
210    ui8WriteBits &= (0x00ff >> (8 - ui16BitCnt));
211    InputVal.UI16Input=0;
212    pui8SizeBits=&(aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size); //Pointer to the bit count field
213    pui8WriteBytes=&(aui32ElementPointers[pMTX_Header->ui32Elements]->aui8Bits); //Pointer to the space where header bits are to be written
214    ui8OutByteIndex=(pui8SizeBits[0] / 8);
215    if (!(pui8SizeBits[0]&7)) {
216        if (pui8SizeBits[0]>=120) {
217            //Element maximum bits send to element, time to start a new one
218            pMTX_Header->ui32Elements++; // Increment element index
219            aui32ElementPointers[pMTX_Header->ui32Elements]=(MTX_HEADER_ELEMENT *) &pui8WriteBytes[15]; //Element pointer set to position of next element (120/8 = 15 bytes)
220            aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type=ELEMENT_RAWDATA; //Write ELEMENT_TYPE
221            aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size=0; // Set new element size (bits) to zero
222            tng__write_upto8bits_elements(pMTX_Header,aui32ElementPointers, ui8WriteBits, ui16BitCnt); // Begin writing to the new element
223        return ;//(IMG_UINT32) ui16BitCnt;
224        }
225        pui8WriteBytes[ui8OutByteIndex]=0; // Beginning a new byte, clear byte
226    }
227    i16Shift=(IMG_INT16) ((8-ui16BitCnt)-(pui8SizeBits[0]&7));
228    if (i16Shift>=0) {
229        ui8WriteBits <<= i16Shift;
230        pui8WriteBytes[ui8OutByteIndex]|=ui8WriteBits;
231        pui8SizeBits[0]=pui8SizeBits[0]+ui16BitCnt;
232    } else {
233        InputVal.UI8Input[1]=(IMG_UINT8) ui8WriteBits+256;
234        InputVal.UI16Input >>= -i16Shift;
235        pui8WriteBytes[ui8OutByteIndex]|=InputVal.UI8Input[1];
236
237        pui8SizeBits[0]=pui8SizeBits[0]+ui16BitCnt;
238        pui8SizeBits[0]=pui8SizeBits[0]-((IMG_UINT8) -i16Shift);
239        InputVal.UI8Input[0]=InputVal.UI8Input[0] >> (8+i16Shift);
240        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, InputVal.UI8Input[0],(IMG_UINT16) -i16Shift);
241    }
242    return ;//(IMG_UINT32) ui16BitCnt;
243}
244
245static void tng__write_upto32bits_elements(
246    MTX_HEADER_PARAMS *pMTX_Header,
247    MTX_HEADER_ELEMENT **aui32ElementPointers,
248    IMG_UINT32 ui32WriteBits,
249    IMG_UINT32 ui32BitCnt)
250{
251    IMG_UINT32 ui32BitLp;
252    IMG_UINT32 ui32EndByte;
253    IMG_UINT8 ui8Bytes[4];
254    drv_debug_msg(VIDEO_DEBUG_GENERAL, "WBS(32) bits %x, cnt = %d\n", ui32WriteBits, ui32BitCnt);
255    for (ui32BitLp=0; ui32BitLp<4; ui32BitLp++) {
256        ui8Bytes[ui32BitLp]=(IMG_UINT8) (ui32WriteBits & 255);
257        ui32WriteBits = ui32WriteBits >> 8;
258    }
259
260    ui32EndByte=((ui32BitCnt+7)/8);
261    if ((ui32BitCnt)%8)
262        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32EndByte-1], (IMG_UINT8) ((ui32BitCnt)%8));
263    else
264        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32EndByte-1], 8);
265    if (ui32EndByte>1)
266        for (ui32BitLp=ui32EndByte-1; ui32BitLp>0; ui32BitLp--) {
267            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Bytes[ui32BitLp-1], 8);
268        }
269    return ;//ui32BitCnt;
270}
271
272static void tng__generate_ue(
273    MTX_HEADER_PARAMS *pMTX_Header,
274    MTX_HEADER_ELEMENT **aui32ElementPointers,
275    IMG_UINT32 uiVal)
276{
277    IMG_UINT32 uiLp;
278    IMG_UINT8 ucZeros;
279    IMG_UINT32 uiChunk;
280
281    for (uiLp=1, ucZeros=0;  (uiLp-1) < uiVal ; uiLp=uiLp+uiLp, ucZeros++)
282        uiVal=uiVal-uiLp;
283    // ucZeros = number of preceding zeros required
284    // uiVal = value to append after zeros and 1 bit
285    //** Write preceding zeros
286    for (uiLp=(IMG_UINT32) ucZeros; uiLp+1>8; uiLp-=8)
287        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
288    //** Write zeros and 1 bit set
289    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) 1, (IMG_UINT8) (uiLp+1));
290    //** Write Numeric part
291    while (ucZeros>8) {
292        ucZeros-=8;
293        uiChunk=(uiVal >> ucZeros);
294        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) uiChunk, 8);
295        uiVal=uiVal-(uiChunk << ucZeros);
296    }
297    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8) uiVal, ucZeros);
298
299    return ;//ui32BitCnter;
300}
301
302static void tng__generate_se(
303    MTX_HEADER_PARAMS *pMTX_Header,
304    MTX_HEADER_ELEMENT **aui32ElementPointers,
305    int iVal)
306{
307    IMG_UINT32 uiCodeNum;
308
309    if (iVal > 0)
310        uiCodeNum=(IMG_UINT32) (iVal+iVal-1);
311    else
312        uiCodeNum=(IMG_UINT32) (-iVal-iVal);
313    tng__generate_ue(pMTX_Header, aui32ElementPointers, uiCodeNum);
314    return ;//ui32BitCnter;
315}
316
317
318static void tng__insert_element_token(
319    MTX_HEADER_PARAMS *pMTX_Header,
320    MTX_HEADER_ELEMENT **aui32ElementPointers,
321    HEADER_ELEMENT_TYPE ui32Token)
322{
323    IMG_UINT8 ui8Offset = 0;
324    IMG_UINT8 *ui8P = NULL;
325
326    /* WA for klockwork */
327    if ((pMTX_Header->ui32Elements != ELEMENTS_EMPTY) &&
328        (pMTX_Header->ui32Elements >= MAXNUMBERELEMENTS)) {
329        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s: mtx_hdr->ui32Elments overflow\n", __FUNCTION__);
330        return;
331    }
332
333
334    if (pMTX_Header->ui32Elements!=ELEMENTS_EMPTY) {
335        if (aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_STARTCODE_RAWDATA ||
336            aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_RAWDATA ||
337            aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type==ELEMENT_STARTCODE_MIDHDR) {
338            //Add a new element aligned to word boundary
339            //Find RAWBit size in bytes (rounded to word boundary))
340            ui8Offset=aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size+8+31; // NumberofRawbits (excluding size of bit count field)+ size of the bitcount field
341            ui8Offset/=32; //Now contains rawbits size in words
342            ui8Offset+=1; //Now contains rawbits+element_type size in words
343            ui8Offset*=4; //Convert to number of bytes (total size of structure in bytes, aligned to word boundary).
344        } else {
345            ui8Offset=4;
346        }
347        pMTX_Header->ui32Elements++;
348        ui8P=(IMG_UINT8 *) aui32ElementPointers[pMTX_Header->ui32Elements-1];
349        ui8P+=ui8Offset;
350        aui32ElementPointers[pMTX_Header->ui32Elements]=(MTX_HEADER_ELEMENT *) ui8P;
351    }
352    else
353        pMTX_Header->ui32Elements=0;
354
355    aui32ElementPointers[pMTX_Header->ui32Elements]->Element_Type=ui32Token;
356    aui32ElementPointers[pMTX_Header->ui32Elements]->ui8Size=0;
357}
358
359/*
360 * Intermediary functions to build H264 headers
361 */
362static void tng__H264_writebits_startcode_prefix_element(
363    MTX_HEADER_PARAMS *pMTX_Header,
364    MTX_HEADER_ELEMENT **aui32ElementPointers,
365    IMG_UINT32 ui32ByteSize)
366{
367    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
368    IMG_UINT32 ui32Lp;
369    // Byte aligned (bit 0)
370    //(3 bytes in slice header when slice is first in a picture without sequence/picture_header before picture
371
372    for (ui32Lp=0;ui32Lp<ui32ByteSize-1;ui32Lp++)
373        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
374    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
375    // Byte aligned (bit 32 or 24)
376    return;
377}
378
379// helper function to start new raw data block
380static IMG_BOOL bStartNextRawDataElement = IMG_FALSE;
381static void CheckStartRawDataElement(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers)
382{
383    if(bStartNextRawDataElement)
384    {
385        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
386        bStartNextRawDataElement = IMG_FALSE;
387    }
388}
389
390
391static void tng__insert_prefix_nal_header(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
392        H264_SLICE_HEADER_PARAMS *pSlHParams, IMG_BOOL bCabacEnabled)
393{
394    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
395
396    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
397    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
398
399    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,        0, 1);   // forbidden_zero_bit
400
401    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
402    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
403
404    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 14, 5);    // nal unit type
405
406    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // SVC extension flag
407
408    // nal_unit_header_mvc_extension()
409    {
410        if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
411            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
412        } else {
413            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // non_idr_flag flag
414        }
415
416        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 6);   // priority_id flag
417        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,    0, 10);   // view_id flag
418
419        //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 3);   // temporal_id flag
420        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_ID); // temporal_id flag
421
422        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ANCHOR_PIC_FLAG); // anchor_pic_flag
423
424        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
425
426        if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
427            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // interview flag
428        } else {
429            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // interview flag
430        }
431
432        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // reserved one bit
433    }
434
435}
436
437static void tng__H264_writebits_VUI_params(
438    MTX_HEADER_PARAMS *pMTX_Header,
439    MTX_HEADER_ELEMENT **aui32ElementPointers,
440    H264_VUI_PARAMS *VUIParams)
441{
442	// Builds VUI Params for the Sequence Header (only present in the 1st sequence of stream)
443	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
444	(0 << 4) |	// aspect_ratio_info_present_flag = 0 in Topaz
445	(0 << 3) |	// overscan_info_present_flag (1 bit) = 0 in Topaz
446	(0 << 2) |	// video_signal_type_present_flag (1 bit) = 0 in Topaz
447	(0 << 1) |	// chroma_loc_info_present_flag (1 bit) = 0 in Topaz
448	(1),												// timing_info_present_flag (1 bit) = 1 in Topaz
449	5);
450	// num_units_in_tick (32 bits) = 1 in Topaz
451        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->num_units_in_tick, 32);
452
453	// time_scale (32 bits) = frame rate
454	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->Time_Scale, 32);
455	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// fixed_frame_rate_flag (1 bit) = 1 in Topaz
456	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// nal_hrd_parameters_present_flag (1 bit) = 1 in Topaz
457	//** Definitions for nal_hrd_parameters() contained in VUI structure for Topaz
458	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// cpb_cnt_minus1 ue(v) = 0 in Topaz = 1b
459	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 4);	// bit_rate_scale (4 bits) = 0 in Topaz
460	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 2, 4);	// cpb_size_scale (4 bits) = 2 in Topaz
461
462	tng__generate_ue(pMTX_Header, aui32ElementPointers, VUIParams->bit_rate_value_minus1); // bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2]
463	tng__generate_ue(pMTX_Header, aui32ElementPointers, VUIParams->cbp_size_value_minus1); // cpb_size_value_minus1[0] ue(v) = (CPB_Bits_Size/16)-1   where CPB_Bits_Size = 1.5 * Bitrate  [RANGE:0 to (2^32)-2]
464	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->CBR,1);// cbr_flag[0] (1 bit) = 0 for VBR, 1 for CBR
465	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->initial_cpb_removal_delay_length_minus1, 5); // initial_cpb_removal_delay_length_minus1 (5 bits) = ???
466	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->cpb_removal_delay_length_minus1, 5); // cpb_removal_delay_length_minus1 (5 bits) = ???
467	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->dpb_output_delay_length_minus1, 5); // dpb_output_delay_length_minus1 (5 bits) = ???
468	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, VUIParams->time_offset_length, 5); // time_offst_length (5 bits) = ???
469	///** End of nal_hrd_parameters()
470	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// vcl_hrd_parameters_present_flag (1 bit) = 0 in Topaz
471	//if( nal_hrd_parameters_present_flag  ||  vcl_hrd_parameters_present_flag )
472	//FIX for BRN23039
473	//	low_delay_hrd_flag
474	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// low_delay_hrd_flag
475
476	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// pic_struct_present_flag (1 bit) = 0 in Topaz
477	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);	// bitstream_restriction_flag (1 bit) = 0 in Topaz
478}
479
480
481static void tng__H264ES_writebits_picture_header(
482    MTX_HEADER_PARAMS *pMTX_Header,
483    MTX_HEADER_ELEMENT **aui32ElementPointers,
484    H264_PICTURE_HEADER_PARAMS *pPHParams,
485    H264_SCALING_MATRIX_PARAMS * psScalingMatrix)
486{
487#ifdef _TOPAZHP_TRACE_
488    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pic_parameter_set_id = %d\n",__FUNCTION__, pPHParams->pic_parameter_set_id);
489    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: seq_parameter_set_id = %d\n",__FUNCTION__, pPHParams->seq_parameter_set_id);
490    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: entropy_coding_mode_flag = %d\n",__FUNCTION__, pPHParams->entropy_coding_mode_flag);
491    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: weighted_pred_flag = %d\n",__FUNCTION__, pPHParams->weighted_pred_flag);
492    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: weighted_bipred_idc = %d\n",__FUNCTION__, pPHParams->weighted_bipred_idc);
493    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: chroma_qp_index_offset = %d\n",__FUNCTION__, pPHParams->chroma_qp_index_offset);
494    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: constrained_intra_pred_flag = %d\n",__FUNCTION__, pPHParams->constrained_intra_pred_flag);
495    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: transform_8x8_mode_flag = %d\n",__FUNCTION__, pPHParams->transform_8x8_mode_flag);
496    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: pic_scaling_matrix_present_flag = %d\n",__FUNCTION__, pPHParams->pic_scaling_matrix_present_flag);
497    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: bUseDefaultScalingList = %d\n",__FUNCTION__, pPHParams->bUseDefaultScalingList);
498    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: second_chroma_qp_index_offset = %d\n",__FUNCTION__, pPHParams->second_chroma_qp_index_offset);
499#endif
500    //**-- Begin building the picture header element
501    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
502    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
503
504    ///* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE *///
505    ///**** ELEMENT BITCOUNT: 18
506
507    // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
508    // Byte aligned (bit 32)
509    tng__write_upto8bits_elements(pMTX_Header,
510                                  aui32ElementPointers,
511                                  (0 << 7) |    // forbidden_zero_bit
512                                  (1 << 5) |    // nal_ref_idc (2 bits) = 1
513                                  (8),  // nal_unit_tpye (5 bits) = 8
514                                  8);
515   // Byte aligned (bit 40)
516    tng__generate_ue(pMTX_Header, aui32ElementPointers, pPHParams->pic_parameter_set_id);  // pic_parameter_set_id ue(v)
517    tng__generate_ue(pMTX_Header, aui32ElementPointers, pPHParams->seq_parameter_set_id);  // seq_parameter_set_id ue(v)
518    tng__write_upto8bits_elements(pMTX_Header,
519                                  aui32ElementPointers,
520                                  (pPHParams->entropy_coding_mode_flag << 4) |    // entropy_coding_mode_flag (1 bit) 0 for CAVLC
521                                  (0 << 3) |                                                                      // pic_order_present_flag (1 bit) = 0
522                                  (1 << 2) |                                                                      // num_slice_group_minus1 ue(v) = 0 in Topaz
523                                  (1 << 1) |                                                                      // num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz
524                                  (1),                                                                                    // num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz
525                                  5);
526    // WEIGHTED PREDICTION
527    tng__write_upto8bits_elements(pMTX_Header,
528        aui32ElementPointers,
529        (pPHParams->weighted_pred_flag << 2) |  // weighted_pred_flag (1 bit)
530        (pPHParams->weighted_bipred_idc),           // weighted_bipred_flag (2 bits)
531        3);
532
533    //MTX fills this value in
534    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_QP);
535    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
536
537    ///**** GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE ****///
538    ///**** ELEMENT BITCOUNT: 5
539    //The following field will be generated as a special case by MTX - so not here
540    // tng__generate_se(pMTX_Header, pPHParams->pic_init_qp_minus26); // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz
541    // pic_int_qs_minus26 se(v) = 0 in Topaz
542    tng__generate_se(pMTX_Header, aui32ElementPointers, 0);
543
544    // chroma_qp_index_offset se(v) = 0 in Topaz
545    tng__generate_se(pMTX_Header, aui32ElementPointers, pPHParams->chroma_qp_index_offset);
546
547    // deblocking_filter_control_present_flag (1 bit) = 1 in Topaz
548    // constrained_intra_pred_Flag (1 bit) = 0 in Topaz
549    // redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz
550    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (1 << 2) |
551                                  (pPHParams->constrained_intra_pred_flag << 1) |
552                                  (0),
553                                  3);
554
555    if (pPHParams->transform_8x8_mode_flag ||
556        (pPHParams->second_chroma_qp_index_offset != pPHParams->chroma_qp_index_offset) ||
557        pPHParams->pic_scaling_matrix_present_flag) {
558        // 8x8 transform flag
559        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pPHParams->transform_8x8_mode_flag, 1);
560        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
561        // second_chroma_qp_index_offset se(v) = 0 in Topaz
562        tng__generate_se(pMTX_Header, aui32ElementPointers, pPHParams->second_chroma_qp_index_offset);
563    }
564
565    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
566    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s: end\n",__FUNCTION__);
567
568    return;
569}
570
571static void tng__H264ES_writebits_scalinglists(
572    MTX_HEADER_PARAMS *pMTX_Header,
573    MTX_HEADER_ELEMENT **aui32ElementPointers,
574    H264_SCALING_MATRIX_PARAMS * psScalingMatrix,
575    IMG_BOOL bWrite8x8)
576{
577	// Used by H264_WriteBits_SequenceHeader and H264_WriteBits_PictureHeader
578	IMG_UINT32	ui32List, ui32Index;
579	IMG_INT32	i32CurScale, i32DeltaScale;
580
581	if (!psScalingMatrix)
582	{
583		tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CUSTOM_QUANT);
584		return;
585	}
586
587	for (ui32List = 0; ui32List < 6; ui32List++)
588	{
589		if (psScalingMatrix->ui32ListMask & (1 << ui32List))
590		{
591			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_list_present_flag[ui32List] = 1
592
593			i32CurScale = 8;
594			for (ui32Index = 0; ui32Index < 16; ui32Index++)
595			{
596				i32DeltaScale = ((IMG_INT32)psScalingMatrix->ui8ScalingLists4x4[ui32List][ui32Index]) - i32CurScale;
597				i32CurScale += i32DeltaScale;
598				tng__generate_se(pMTX_Header, aui32ElementPointers, i32DeltaScale); 	// delta_scale
599			}
600		}
601		else
602		{
603			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); 	// seq_scaling_list_present_flag[ui32List] = 0
604		}
605	}
606
607	if (!bWrite8x8) return;
608
609	for (; ui32List < 8; ui32List++)
610	{
611		if (psScalingMatrix->ui32ListMask & (1 << ui32List))
612		{
613			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_list_present_flag[ui32List] = 1
614
615			i32CurScale = 8;
616			for (ui32Index = 0; ui32Index < 64; ui32Index++)
617			{
618				i32DeltaScale = ((IMG_INT32)psScalingMatrix->ui8ScalingLists8x8[ui32List - 6][ui32Index]) - i32CurScale;
619				i32CurScale += i32DeltaScale;
620				tng__generate_se(pMTX_Header, aui32ElementPointers, i32DeltaScale);		// delta_scale
621			}
622		}
623		else
624		{
625			tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); 	// seq_scaling_list_present_flag[ui32List] = 0
626		}
627	}
628
629}
630
631static void tng__H264ES_writebits_sequence_header(
632    MTX_HEADER_PARAMS *pMTX_Header,
633    MTX_HEADER_ELEMENT **aui32ElementPointers,
634    H264_SEQUENCE_HEADER_PARAMS *pSHParams,
635    H264_CROP_PARAMS *psCrop,
636    H264_SCALING_MATRIX_PARAMS * psScalingMatrix,
637    IMG_BOOL8 bASO)
638{
639    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
640    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
641
642
643    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
644    // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
645    // Byte aligned (bit 32)
646    tng__write_upto8bits_elements(pMTX_Header,
647        aui32ElementPointers,(0 << 7) | // forbidden_zero_bit=0
648	(0x3 << 5) | // nal_ref_idc=01 (may be 11)
649	(7), // nal_unit_type=00111
650        8);
651    // Byte aligned (bit 40)
652    switch (pSHParams->ucProfile) {
653        case SH_PROFILE_BP:
654	    // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP)
655            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 66, 8);
656
657            // Byte	aligned	(bit 48)
658            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
659                (1 << 7) |    // constraint_set0_flag = 1 for BP constraints
660                ((bASO ? 0 : 1) << 6) |    // constraint_set1_flag = 1 for MP constraints
661                (1 << 5) |    // constraint_set2_flag = 1 for EP constraints
662                ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4),  // constraint_set3_flag = 1 for level 1b, 0 for others
663                // reserved_zero_4bits = 0
664                8);
665            break;
666        case SH_PROFILE_MP:
667            // profile_idc = 8 bits = 77 for MP (PROFILE_IDC_MP)
668            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 77, 8);
669
670            // Byte aligned (bit 48)
671            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
672                (0 << 7) | // constraint_set0_flag = 0 for no BP constraints
673                (1 << 6) | // constraint_set1_flag = 1 for MP constraints
674                (1 << 5) | // constraint_set2_flag = 1 for EP constraints
675                ((pSHParams->ucLevel==SH_LEVEL_1B ? 1:0) << 4),    // constraint_set3_flag = 1 for level 1b, 0 for others
676                // reserved_zero_4bits = 0
677                8);
678            break;
679        case SH_PROFILE_HP:
680            // profile_idc = 8 bits = 100 for HP (PROFILE_IDC_HP)
681            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 100, 8);
682            // Byte aligned (bit 48)
683            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
684                (0 << 7) | // constraint_set0_flag = 0 for no BP constraints
685                (0 << 6) | // constraint_set1_flag = 0 for no MP constraints
686                (0 << 5) | // constraint_set2_flag = 0 for no EP constraints
687                (0 << 4),  // constraint_set3_flag = 0
688                // reserved_zero_4bits = 0
689                8);
690            break;
691        case SH_PROFILE_H444P:
692            // profile_idc = 8 bits = 244 for H444P (PROFILE_IDC_H444P)
693            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 244, 8);
694
695            // Byte aligned (bit 48)
696            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
697                (0 << 7) |      // constraint_set0_flag = 0 for no BP constraints
698                (0 << 6) |      // constraint_set1_flag = 0 for no MP constraints
699                (0 << 5) |      // constraint_set2_flag = 0 for no EP constraints
700                (0 << 4),	        // constraint_set3_flag = 0
701                // reserved_zero_4bits = 0
702                8);
703            break;
704	}
705
706
707    // Byte aligned (bit 56)
708    // level_idc (8 bits) = 11 for 1b, 10xlevel for others
709    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);
710    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);		// seq_parameter_set_id = 0
711
712    if ((pSHParams->ucProfile == SH_PROFILE_HP) || (pSHParams->ucProfile == SH_PROFILE_H444P)) {
713        tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);    // chroma_format_idc = 1
714        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);    // bit_depth_luma_minus8 = 0
715        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);    // bit_depth_chroma_minus8 = 0
716        // qpprime_y_zero_transform_bypass_flag = 1 if lossless
717        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->bIsLossless?1:0, 1);
718        if (pSHParams->bUseDefaultScalingList || pSHParams->seq_scaling_matrix_present_flag) {
719            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); 	// seq_scaling_matrix_present_flag
720            if (!pSHParams->bUseDefaultScalingList) {
721                tng__H264ES_writebits_scalinglists(pMTX_Header, aui32ElementPointers, psScalingMatrix, IMG_TRUE);
722                tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
723            } else {
724                // seq_scaling_list_present_flag[i] = 0; 0 < i < 8
725                tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
726            }
727        } else {
728            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);  // seq_scaling_matrix_present_flag
729        }
730    }
731
732    tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);  // log2_max_frame_num_minus4 = 1
733    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);  // pic_order_cnt_type = 0
734    // log2_max_pic_order_cnt_Isb_minus4 = 2
735    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->log2_max_pic_order_cnt - 4);
736    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames); //num_ref_frames ue(2), typically 2
737    // Bytes aligned (bit 72)
738    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
739        (pSHParams->gaps_in_frame_num_value), // gaps_in_frame_num_value_allowed_Flag	- (1 bit)
740        1);
741    ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
742    ///**** ELEMENT BITCOUNT: xx
743    //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
744    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1);
745    //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column)
746    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1);
747    // We don't know the alignment at this point, so will have to use bit writing functions
748    // frame_mb_only_flag 1=frame encoding, 0=field encoding
749    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,pSHParams->ucFrame_mbs_only_flag,1);
750    if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
751        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1); // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
752
753    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1); // direct_8x8_inference_flag=1 in Topaz
754    if (psCrop->bClip) {
755        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,1,1);
756        tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16LeftCropOffset);
757	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16RightCropOffset);
758	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16TopCropOffset);
759	tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16BottomCropOffset);
760    } else {
761        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,0,1);
762    }
763
764    ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
765    ///**** ELEMENT BITCOUNT: xx
766    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
767        (pSHParams->VUI_Params_Present), // vui_parameters_present_flag (VUI only in 1st sequence of stream)
768        1);
769
770    if (pSHParams->VUI_Params_Present > 0)
771        tng__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
772
773
774    // Finally we need to align to the next byte
775    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
776    // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
777
778    //tng_print(pMTX_Header, 64);
779    return;
780}
781
782
783static void tng__H264ES_writebits_slice_header(
784    MTX_HEADER_PARAMS *pMTX_Header,
785    MTX_HEADER_ELEMENT **aui32ElementPointers,
786    H264_SLICE_HEADER_PARAMS *pSlHParams,
787    IMG_BOOL bCabacEnabled
788)
789{
790    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
791    //Can be 3 or 4 bytes - always 4 bytes in our implementations
792    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes);
793
794    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
795    ///**** ELEMENT BITCOUNT: 8
796
797    // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
798    //(3 bytes when slice is first in a picture without sequence/picture_header before picture
799    // Byte aligned (bit 32 or 24)
800    // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
801    tng__write_upto8bits_elements(pMTX_Header,
802                                  aui32ElementPointers, (0 << 7) |                // forbidden_zero_bit
803                                  ((pSlHParams->bReferencePicture) << 5) |        // nal_ref_idc (2 bits)
804                                  ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),    // nal_unit_tpye (5 bits) = I-frame IDR, and 1 for  rest
805                                  8);
806
807    //MTX fills this value in
808    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR);
809    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
810
811    ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
812    /* The following is slice parameter set in BP/MP */
813    //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
814    tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
815    // kab: //not clean change from IDR to intra, IDR should have separate flag
816    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
817                                  (1 << 5) |                                                                                                                                             //pic_parameter_set_id, ue(v) = 0  (=1b) in Topaz
818                                  pSlHParams->Frame_Num_DO,                                                                                                               //frame_num (5 bits) = frame nuo. in decoding order
819                                  6);
820
821    // interlaced encoding
822    if (pSlHParams->bPiCInterlace) {
823        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
824        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->bFieldType, 1); // bottom_field_flag (0=top field, 1=bottom field)
825    }
826
827    if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
828        tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Idr_Pic_Id);    // idr_pic_id ue(v)
829
830    if (pSlHParams->bPiCInterlace)
831        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSlHParams->Picture_Num_DO + pSlHParams->bFieldType), pSlHParams->log2_max_pic_order_cnt);                    // pic_order_cnt_lsb (6 bits) - picture no in display order
832    else
833        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->Picture_Num_DO, pSlHParams->log2_max_pic_order_cnt);                       // pic_order_cnt_lsb (6 bits) - picture no in display order
834
835
836    if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
837        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->direct_spatial_mv_pred_flag, 1);// direct_spatial_mv_pred_flag (1 bit)
838    if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE || pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
839        if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE && pSlHParams->num_ref_idx_l0_active_minus1 > 0) { //Do we have more then one reference picture?
840            //Override amount of ref pics to be only 1 in L0 direction
841            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
842            tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->num_ref_idx_l0_active_minus1);
843        } else
844            // num_ref_idx_active_override_flag (1 bit) = 0 in Topaz
845            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
846    }
847    if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
848        if ((pSlHParams->diff_ref_pic_num[0] || pSlHParams->bRefIsLongTermRef[0])
849            || ((pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) && (pSlHParams->num_ref_idx_l0_active_minus1 > 0))) {
850            //Specifiy first ref pic in L0
851            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //ref_pic_list_modification_flag_l0
852
853            if (pSlHParams->bRefIsLongTermRef[0]) {
854                tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
855                tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[0]); // long_term_pic_num
856            } else if (pSlHParams->diff_ref_pic_num[0] == 0) {
857                // Can't use 0, so use MaxPicNum which will wrap to 0
858                tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add to)
859                tng__generate_ue(pMTX_Header, aui32ElementPointers, 31); // abs_diff_minus_1
860            } else if (pSlHParams->diff_ref_pic_num[0] < 0) {
861                tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
862                tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[0] - 1); // abs_diff_minus_1
863            } else {
864                tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
865                tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[0] - 1); // abs_diff_minus_1
866            }
867
868            if ((pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) && pSlHParams->SliceFrame_Type != SLHP_B_SLICEFRAME_TYPE) { //potentially second reference picture on P
869                if (pSlHParams->bRefIsLongTermRef[1]) {
870                    tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
871                    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[1]); // long_term_pic_num
872                } else if (pSlHParams->diff_ref_pic_num[1] < 0) {
873                    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
874                    tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
875                } else {
876                    tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
877                    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
878                }
879            }
880
881            tng__generate_ue(pMTX_Header, aui32ElementPointers, 3); // mod_of_pic_num = 3 (no more changes)
882        } else
883            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // ref_pic_list_ordering_flag_I0 (1 bit) = 0, no reference picture ordering in Topaz
884    }
885    if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
886        if (pSlHParams->diff_ref_pic_num[1] || pSlHParams->bRefIsLongTermRef[1]) {
887            //Specifiy first ref pic in L1
888            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //ref_pic_list_modification_flag_l1
889
890            if (pSlHParams->bRefIsLongTermRef[1]) {
891                tng__generate_ue(pMTX_Header, aui32ElementPointers, 2); // mod_of_pic_num = 2 (long term ref)
892                tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uRefLongTermRefNum[1]); // long_term_pic_num
893            } else if (pSlHParams->diff_ref_pic_num[1] < 0) {
894                tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // mod_of_pic_num = 0 (subtract from)
895                tng__generate_ue(pMTX_Header, aui32ElementPointers, -pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
896            } else {
897                tng__generate_ue(pMTX_Header, aui32ElementPointers, 1); // mod_of_pic_num = 1 (add too)
898                tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->diff_ref_pic_num[1] - 1); // abs_diff_minus_1
899            }
900
901            tng__generate_ue(pMTX_Header, aui32ElementPointers, 3); // mod_of_pic_num = 3 (no more changes)
902        } else
903            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // ref_pic_list_ordering_flag_I1 (1 bit) = 0, no reference picture ordering in Topaz
904    }
905    if (pSlHParams->weighted_pred_flag &&
906        ((pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) || (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE))
907        && (pSlHParams->weighted_bipred_idc == 1)) {
908        int i;
909        tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->luma_log2_weight_denom);
910        tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->chroma_log2_weight_denom); // Always do chroma
911        for (i = 0; i < (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE ? 2 : (pSlHParams->num_ref_idx_l0_active_minus1 + 1)); i++) { // Either 1 or 2
912            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->luma_weight_l0_flag[i], 1);
913            if (pSlHParams->luma_weight_l0_flag[i]) {
914                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->luma_weight_l0[i]);
915                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->luma_offset_l0[i]);
916            }
917            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->chroma_weight_l0_flag[i], 1);
918            if (pSlHParams->chroma_weight_l0_flag[i]) {
919                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaB_weight_l0[i]);
920                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaB_offset_l0[i]);
921                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaR_weight_l0[i]);
922                tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->chromaR_offset_l0[i]);
923            }
924        }
925    }
926
927    if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
928        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // no_output_of_prior_pics_flag (1 bit) = 0
929        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSlHParams->bIsLongTermRef ? 1 : 0, 1);  // long_term_reference_flag (1 bit) = 0
930    } else if (pSlHParams->bReferencePicture) {
931        if (pSlHParams->bIsLongTermRef) {
932            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
933
934            // Allow a single long-term reference
935            tng__generate_ue(pMTX_Header, aui32ElementPointers, 4);                                 // memory_management_control_operation
936            tng__generate_ue(pMTX_Header, aui32ElementPointers, 2);                                 // max_long_term_frame_idx_plus1
937
938            // Set current picture as the long-term reference
939            tng__generate_ue(pMTX_Header, aui32ElementPointers, 6);                                 // memory_management_control_operation
940            tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->uLongTermRefNum);                                       // long_term_frame_idx
941
942            // End
943            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // memory_management_control_operation
944        } else
945            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
946    }
947
948    if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
949                          (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
950        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
951    }
952    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
953    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
954
955    ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
956    ///**** ELEMENT BITCOUNT: 11
957    // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
958    //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
959    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
960    if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
961        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
962        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
963    }
964    //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
965    // no byte alignment at end of slice headers
966    return ;
967}
968
969
970static void tng__H264_getelements_skip_P_slice(
971    MTX_HEADER_PARAMS *mtx_hdr,
972    H264_SLICE_HEADER_PARAMS *pSlHParams,
973    IMG_UINT32 MB_No_In_Slice,
974    IMG_BOOL bCabacEnabled)
975{
976    /* Skipped P-Slice
977     * Ensure pSlHParams is filled with appropriate parameters for a B-slice
978     * Essential we initialise our header structures before building
979     */
980    MTX_HEADER_ELEMENT *This_Element;
981    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
982    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
983    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
984    aui32ElementPointers[0] = This_Element;
985
986    /* tng__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */
987    /* Not sure if this will be required in the final spec */
988    tng__H264ES_writebits_slice_header(mtx_hdr, aui32ElementPointers, pSlHParams, bCabacEnabled);
989    tng__generate_ue(mtx_hdr, aui32ElementPointers, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */
990
991    /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */
992    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
993    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
994}
995
996
997#if 0
998static void tng__H264_getelements_sequence_header(
999    MTX_HEADER_PARAMS *mtx_hdr,
1000    H264_SEQUENCE_HEADER_PARAMS *pSHParams,
1001    H264_CROP_PARAMS *psCropParams)
1002{
1003    /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1004     * Essential we initialise our header structures before building
1005     */
1006    MTX_HEADER_ELEMENT *This_Element;
1007    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1008    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
1009    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1010    aui32ElementPointers[0] = This_Element;
1011
1012    tng__H264ES_writebits_sequence_header(mtx_hdr, aui32ElementPointers, pSHParams, psCropParams, NULL);
1013    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1014}
1015#endif
1016
1017//static void tng__H264_getelements_picture_header(MTX_HEADER_PARAMS *mtx_hdr)
1018//{
1019///* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
1020//* Essential we initialise our header structures before building
1021//*/
1022//MTX_HEADER_ELEMENT *This_Element;
1023//MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1024//mtx_hdr->Elements=ELEMENTS_EMPTY;
1025//This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1026//aui32ElementPointers[0]=This_Element;
1027//
1028//tng__H264ES_writebits_picture_header(mtx_hdr, aui32ElementPointers);
1029//mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
1030//}
1031
1032
1033static void tng__H264_getelements_slice_header(
1034    MTX_HEADER_PARAMS *pMTX_Header,
1035    H264_SLICE_HEADER_PARAMS *pSlHParams,
1036    IMG_BOOL bCabacEnabled
1037)
1038{
1039    /* Builds a single slice header from the given parameters (mid frame)
1040     * Essential we initialise our header structures before building
1041     */
1042    MTX_HEADER_ELEMENT *This_Element;
1043    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1044    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
1045    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1046    aui32ElementPointers[0] = This_Element;
1047
1048    /* Not sure if this will be required in the final spec */
1049    /* tng__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/
1050    tng__H264ES_writebits_slice_header(pMTX_Header, aui32ElementPointers, pSlHParams, bCabacEnabled);
1051
1052    pMTX_Header->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1053}
1054
1055void H263_NOTFORSIMS_WriteBits_VideoPictureHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1056					   H263_PICTURE_CODING_TYPE PictureCodingType,
1057					   //IMG_UINT8 ui8Q_Scale,
1058					   H263_SOURCE_FORMAT_TYPE SourceFormatType,
1059					   IMG_UINT8 ui8FrameRate,
1060					   IMG_UINT32 ui32PictureWidth,
1061					   IMG_UINT32 ui32PictureHeight
1062					   )
1063{
1064    IMG_UINT8 UFEP;
1065
1066    // Essential we insert the element before we try to fill it!
1067    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1068
1069    // short_video_start_marker	= 22 Bits	= 0x20 Picture start code
1070    tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 32, 22);
1071
1072    // temporal_reference		= 8 Bits	= 0-255	Each picture increased by 1
1073    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_REFERENCE);
1074    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1075
1076    // marker_bit				= 1 Bit		= 1
1077    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1078
1079    // zero_bit					= 1 Bits	= 0
1080    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1081
1082    // split_screen_indicator	= 1	Bits	= 0	No direct effect on encoding of picture
1083    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1084
1085    // document_camera_indicator= 1	Bits	= 0	No direct effect on encoding of picture
1086    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1087
1088    // full_picture_freeze_release=1 Bits	= 0	No direct effect on encoding of picture
1089    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1090
1091    // source_format				= 3	Bits	= 1-4	See note
1092    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, SourceFormatType, 3);
1093
1094    if (SourceFormatType != 7)
1095    {
1096	// picture_coding_type		= 1 Bit		= 0/1	0 for I-frame and 1 for P-frame
1097	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, PictureCodingType, 1);
1098	// four_reserved_zero_bits	= 4 Bits	= 0
1099	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 4);
1100    }
1101    // the else block is for PLUSPTYPE header insertion.
1102    else
1103    {
1104	static IMG_UINT8 RTYPE = 0;
1105
1106        // if I- Frame set Update Full Extended PTYPE to true
1107	if (PictureCodingType == I_FRAME)
1108	{
1109	    UFEP = 1;
1110	}
1111	else
1112	{
1113	    UFEP = 0;
1114	}
1115
1116        // write UFEP of 3 bits.
1117	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, UFEP, 3);
1118
1119        // if UFEP was present( if it was 1).
1120        // Optional part of PPTYPE.
1121	if (UFEP == 1)
1122	{
1123	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 6, 3);
1124	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1125
1126            /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1127               - Optional Unrestricted Motion Vector (UMV)
1128               - Optional Syntax-based Arithmetic Coding (SAC)
1129               - Optional Advanced Prediction (AP) mode
1130               - Optional Advanced INTRA Coding (AIC) mode
1131               - Optional Deblocking Filter (DF) mode
1132               - Optional Slice Structured (SS) mode
1133               - Optional Reference Picture Selection(RPS) mode.
1134               - Optional Independent Segment Decoding (ISD) mode
1135               - Optional Alternative INTER VLC (AIV) mode
1136               - Optional Modified Quantization (MQ) mode
1137            */
1138	    tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 0, 10); // 10 reserve bits
1139
1140            /* 4 reserve bits
1141               - 1 (ON) to prevent start code emulation.
1142               - 0  Reserved(shall be 0).
1143               - 0  Reserved(shall be 0).
1144               - 0  Reserved(shall be 0).
1145            */
1146	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 8, 4);	// 4 reserve bits
1147	}
1148        // Optional Part of PPTYPE ends.
1149
1150        // Mandatory part of PPTYPE starts.(MPPTYPE)
1151        // picture_coding_type		= 1 Bit		= 0/1	0 for I-frame and 1 for P-frame
1152	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, PictureCodingType, 3 );
1153
1154        /*
1155            - Optional Reference Picture Resampling (RPR) mode ( OFF) : 0
1156            - Optional Reference Picture Resampling (RPR) mode (OFF) : 0
1157         */
1158	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 , 2);
1159
1160        // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1161        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, RTYPE, 1);
1162
1163        /* 2 reserve bits
1164           - 0  Reserved(shall be 0).
1165           - 0  Reserved(shall be 0).
1166        */
1167        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2);
1168
1169        //   - 1 (ON) to prevent start code emulation.
1170        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1 , 1);
1171		// Mandatory part of PTYPE ends.
1172
1173        // CPM immediately follows the PPTYPE part of the header.
1174        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 ,1);
1175
1176        /* Custom Picture Format (CPFMT) */
1177        /* if UFEP was present and Source Format type was 7(custom format) */
1178	if (UFEP == 1)
1179	{
1180	    IMG_UINT16 ui16PWI,ui16PHI;
1181
1182            // aspect ratio 4 bits value = 0010 (12:11)
1183			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x01, 4);
1184            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 2, 4);
1185
1186            // Picture Width Indication 9 bits.
1187			//ui16PictureWidth --;
1188			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureWidth >> 8), 1);
1189			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureWidth & 0xFF), 8);
1190            ui16PWI = (ui32PictureWidth >> 2) - 1;
1191            tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,ui16PWI, 9);
1192
1193            // Marker bit 1bit = 1 to prevent start code emulation.
1194	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1195
1196            // Picture Height Indication 9 bits.
1197			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureHeigth >> 8), 1);
1198			//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (IMG_UINT8)(ui16PictureHeigth & 0xFF), 8);
1199            ui16PHI = ui32PictureHeight >> 2;
1200            tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,ui16PHI, 9);
1201            // good up to that point
1202	}
1203    }
1204    // 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))
1205    // vop_quant				= 5 Bits	= x	5-bit frame Q_scale from rate control - GENERATED BY MTX
1206    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1207
1208    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1209
1210    // if it was not PLUSPTYPE i.e for standard format size insert CPM bit here.
1211    if (SourceFormatType != 7)
1212    {
1213        // cpm	= 1 Bit		= 0	No direct effect on encoding of picture
1214        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0 ,1);
1215    }
1216    // pei						= 1 Bit		= 0	No direct effect on encoding of picture
1217    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1218
1219    return;
1220}
1221
1222void MPEG4_NOTFORSIMS_WriteBits_VOPHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
1223							IMG_BOOL	bIsVOP_coded,
1224							SEARCH_RANGE_TYPE sSearch_range,
1225							VOP_CODING_TYPE sVopCodingType)
1226{
1227    // Essential we insert the element before we try to fill it!
1228    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1229    // visual_object_sequence_start_code	= 32 Bits	= 0x1B6
1230    tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 438, 32);
1231    // vop_coding_type						= 2 Bits	= 0 for I-frame and 1 for P-frame
1232    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, sVopCodingType, 2);
1233
1234    // modulo_time_base
1235    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_MODULO_TIME_BASE);
1236    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1237
1238    // marker_bit							= 1	Bits	= 1
1239    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1240
1241    // vop_time_increment
1242    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VOP_TIME_INCREMENT);
1243    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1244
1245    // marker_bit							= 1 Bit		= 1
1246    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1247
1248    if (!bIsVOP_coded)
1249    {
1250	// vop_coded						= 1 Bit		= 0 for skipped frame
1251	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1252       	// byte_aligned_bits (skipped pictures are byte aligned)
1253	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1254	// End of VOP - skipped picture
1255    } else {
1256	// vop_coded						= 1 Bit		= 1 for normal coded frame
1257	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1258	if (sVopCodingType == P_FRAME)
1259	{
1260	    // vop_rounding_type			= 1 Bit		= 0 vop_rounding_type is 0 in Topaz
1261	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1262	}
1263	// intra_dc_vlc_thr					= 3 Bits	= 0 Use intra DC VLC in Topaz
1264	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 3);
1265	// vop_quant				= 5 Bits	= x	5-bit frame Q_scale from rate control - GENERATED BY MTX
1266	//tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, Frame_Q_scale, 5);
1267	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1268	if (sVopCodingType == P_FRAME)
1269	{
1270	    // vop_fcode_forward			= 3 bits	= 2 for +/-32 and 3 for +/-64 search range
1271	    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1272	    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, sSearch_range, 3);
1273	}
1274    }
1275}
1276/**************************************************************************************************
1277 * * Function:         H263_GeneratePicHdrTemplate
1278 * * Description:      Generates the h.263 picture header template
1279 * *
1280 * ***************************************************************************************************/
1281void tng__H263_notforsims_prepare_video_pictureheader(
1282    MTX_HEADER_PARAMS* pMTX_Header,
1283    H263_PICTURE_CODING_TYPE ePictureCodingType,
1284    H263_SOURCE_FORMAT_TYPE eSourceFormatType,
1285    IMG_UINT8 ui8FrameRate,
1286    IMG_UINT32 ui32PictureWidth,
1287    IMG_UINT32 ui32PictureHeigth )
1288{
1289    // Essential we initialise our header structures before building
1290    MTX_HEADER_ELEMENT *This_Element;
1291    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1292    pMTX_Header->ui32Elements=ELEMENTS_EMPTY;
1293    This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1294    aui32ElementPointers[0]=This_Element;
1295
1296    H263_NOTFORSIMS_WriteBits_VideoPictureHeader(
1297               pMTX_Header,
1298               aui32ElementPointers,
1299               ePictureCodingType,
1300               eSourceFormatType,
1301               ui8FrameRate,
1302               ui32PictureWidth,
1303               ui32PictureHeigth );
1304
1305    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
1306}
1307
1308/**************************************************************************************************
1309 * * Function:         MPEG4_GeneratePicHdrTemplate
1310 * * Description:      Generates the MPEG4 picture header template
1311 * *
1312 * ***************************************************************************************************/
1313void tng__MPEG4_notforsims_prepare_vop_header(
1314    MTX_HEADER_PARAMS* pMTX_Header,
1315    IMG_BOOL bIsVOP_coded,
1316    SEARCH_RANGE_TYPE eSearch_range,
1317    VOP_CODING_TYPE eVop_Coding_Type)
1318{
1319    //Builds a single MPEG4 VOP (picture) header from the given parameters
1320    //Essential we initialise our header structures before building
1321    MTX_HEADER_ELEMENT *This_Element;
1322    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1323    pMTX_Header->ui32Elements=ELEMENTS_EMPTY;
1324    This_Element=(MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
1325    aui32ElementPointers[0]=This_Element;
1326
1327    //Frame QScale no longer written here as it is inserted by MTX later (add as parameter to MTX_Send_Elements_To_VLC)
1328    MPEG4_NOTFORSIMS_WriteBits_VOPHeader(
1329	pMTX_Header,
1330	aui32ElementPointers,
1331	bIsVOP_coded,
1332	eSearch_range,
1333	eVop_Coding_Type);
1334
1335    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
1336}
1337
1338void H263_NOTFORSIMS_WriteBits_GOBSliceHeader(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers)
1339{
1340       // Essential we insert the element before we try to fill it!
1341       tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1342    // gob_resync_marker               = 17            = 0x1
1343       tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 1, 17);
1344
1345       // gob_number                           = 5                     = 0-17  It is gob number in a picture
1346       tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICE_NUM); // Insert token to tell MTX to insert gob_number
1347
1348    // gob_frame_id                            = 2                     = 0-3   See note
1349       tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_GOB_FRAME_ID); // Insert token to tell MTX to insert gob_frame_id
1350
1351       tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
1352
1353       // quant_scale                          = 5                     = 1-32  gob (Slice) Q_scale
1354       // tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8GOB_Q_Scale, 5);
1355       tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEQSCALE); // Insert token to tell MTX to insert rate-control value (QScale is sent as an argument
1356}
1357
1358
1359
1360static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1361{
1362    IMG_UINT8 Bits = 32;
1363    if (CodeVal == 0)
1364        return 1;
1365    while (!(CodeVal & 0x80000000)) {
1366        CodeVal <<= 1;
1367        Bits--;
1368    }
1369    return Bits;
1370}
1371
1372/*
1373 * Intermediary functions to build MPEG4 headers
1374 */
1375#define MATCH_TO_ENC
1376
1377
1378static void tng__MPEG4_writebits_sequence_header(
1379    MTX_HEADER_PARAMS *pMTX_Header,
1380    MTX_HEADER_ELEMENT **aui32ElementPointers,
1381    IMG_BOOL bBFrame,
1382    MPEG4_PROFILE_TYPE bProfile,
1383    IMG_UINT8 ui8Profile_and_level_indication,
1384    FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
1385    IMG_UINT32 Picture_Width_Pixels,
1386    IMG_UINT32 Picture_Height_Pixels,
1387    VBVPARAMS *sVBVParams, IMG_UINT32 ui32VopTimeResolution) /* Send NULL pointer if there are no VBVParams */
1388{
1389	// Essential we insert the element before we try to fill it!
1390	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1391	// visual_object_sequence_start_code	= 32 Bits	= 0x1B0
1392	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, 432, 32);
1393	//profile_and_level_indication			= 8 Bits	= SP L0-L3 and SP L4-L5 are supported
1394	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ui8Profile_and_level_indication, 8);
1395
1396	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1397	// visual_object_start_code				= 32 Bits	= 0x1B5
1398	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1399	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1400	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1401	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 181, 8);
1402	// is_visual_object_identifier			= 1 Bit 	= 0
1403	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1404	// visual_object_type					= 4 Bits	= Video ID = 1
1405	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1406	// video_signal_type					= 1 Bit		= 1
1407	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1408	// byte_aligned_bits					= 2 Bits	= 01b (byte_aligned_bits is 2-bit stuffing bit field 01)
1409	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 2);
1410
1411	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1412	//video_object_start_code				= 32 Bits	= 0x100 One VO only in a Topaz video stream
1413	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1414	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1415	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1416	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1417
1418	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1419	// video_object_layer_start_code		= 32 Bits	= 0x120 One VOL only in a Topaz stream
1420	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1421	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);
1422	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1423	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 32, 8);
1424	// random_accessible_vol				= 1 Bit		= 0 (P-Frame in GOP)
1425	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1426	if (bProfile == SP)
1427	{
1428		// video_object_type_indication			= 8 Bits	= 0x01 for SP
1429		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 8);
1430#ifndef MATCH_TO_ENC
1431		// is_object_layer_identifier			= 1 Bit		= 0 for SP
1432		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1433#else
1434	// to match the encoder
1435		// is_object_layer_identifier			= 1 Bit
1436		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1437		// video_object_layer_verid				= 4 Bits
1438		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1439        // video_object_layer_priority			= 3 Bits
1440		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 3);  // 0 is reserved...
1441#endif
1442	}
1443	else
1444	{
1445		// video_object_type_indication			= 8 Bits	= 0x11 for ASP
1446		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 3, 8);
1447		// is_object_layer_identifier			= 1 Bit		= 1 for ASP
1448		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1449		// video_object_layer_verid				= 4 Bits	= 5 is for ASP
1450		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 5, 4);
1451        // video_object_layer_priority			= 3 Bits	= 1 (Highest priority)
1452		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 3);
1453	}
1454	// aspect_ratio_info						= 4 Bits	=0x1 (Square pixel)
1455	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 4);
1456#if !defined(MATCH_TO_ENC) || !defined (EXCLUDE_VOL_CONTROL_PARAMS)
1457	// vol_control_parameters					= 1 Bit		= 1 (Always send VOL control parameters)
1458	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1459
1460    // chroma_format							= 2 Bits	= 01b (4:2:0)
1461	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 2);
1462	// low_delay							= 1 Bit			= 0 with B-frame and 1 without B-frame
1463	if (bBFrame)
1464		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1465	else
1466		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1467    // vbv_parameters						= 1 Bit			=0/1
1468	if (sVBVParams)
1469	{
1470		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1471		 //For recording, only send vbv parameters in 1st sequence header. For video phone, it should be sent more often, such as once per sequence
1472		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_bit_rate, 15);			// first_half_bit_rate
1473        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1474		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_bit_rate, 15);			// latter_half_bit_rate
1475        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1476		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_vbv_buffer_size, 15);	// first_half_vbv_buffer_size
1477        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1478        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_vbv_buffer_size, 3);	//  latter_half_vbv_buffer_size
1479        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->First_half_vbv_occupancy, 11);		//  first_half_vbv_occupancy
1480        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1481		tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, sVBVParams->Latter_half_vbv_occupancy, 15);		//  latter_half_vbv_occupancy
1482        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);	// Marker Bit = 1
1483	}
1484	else
1485		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // No vbv parameters present
1486#else
1487	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1488#endif
1489	// video_object_layer_shape			= 2 Bits		=	00b	Rectangular shape
1490	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 2);
1491	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1492	// vop_time_increment_solution		= 16 Bits
1493	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32VopTimeResolution, 16);
1494	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1495#ifndef MATCH_TO_ENC
1496	// fixed_vop_rate					= 1 Bits		=	1 Always fixed frame rate
1497	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1498	// fixed_vop_time_increment			= Variable number of bits based on the time increment resolution.
1499	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, Bits2Code(ui32VopTimeResolution));
1500	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1501#else
1502	// fixed_vop_rate					= 1 Bits		=	0
1503	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1504	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1505#endif
1506	// video_object_layer_width			= 13 Bits		Picture width in pixel units
1507	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, Picture_Width_Pixels, 13);
1508	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1509	// video_object_layer_height		= 13 Bits		Picture height in pixel units
1510	tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, Picture_Height_Pixels, 13);
1511	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);		// Marker Bit = 1
1512	// interlaced						= 1 Bit			= 0 Topaz only encodes progressive frames
1513	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1514	// obmc_disable						= 1 Bit			= 1 No overlapped MC in Topaz
1515	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1516    // sprite_enable					= 1 Bit			= 0 Not use sprite in Topaz
1517	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1518	// not_8_bit						= 1	Bit			= 0	8-bit video in Topaz
1519	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1520	// quant_type						= 1 Bit			= 0 2nd quantization method in Topaz
1521	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1522	if (bProfile==ASP)
1523	{
1524		// quarter_sample				= 1 Bit			= 0 No ?pel MC in Topaz
1525		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1526	}
1527
1528	// complexity_estimation_disable	= 1 Bit			= 1	No complexity estimation in Topaz
1529	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1530#ifndef MATCH_TO_ENC
1531	// resync_marker_disable			= 1 Bit			= 0 Always enable resync marker in Topaz
1532	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1533#else
1534	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
1535#endif
1536    // data_partitioned					= 1 Bit			= 0 No data partitioning in Topaz
1537	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1538    if (bProfile == ASP)
1539	{
1540		// newpred_enable				= 1 Bit			= 0 No newpred mode in SP/ASP
1541		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1542		// reduced_vop_resolution_enable=1 Bit			= 0	No reduced resolution frame in SP/ASP
1543		tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1544    }
1545    // scalability						= 1 Bit			= 0	No scalability in SP/ASP
1546	tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
1547	// byte_aligned_bits
1548   	tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4); // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1549	return;
1550}
1551
1552
1553/* Utility function */
1554/*
1555  IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal)
1556  {
1557  IMG_UINT8 Bits=32;
1558  if(CodeVal==0)
1559  return 1;
1560  while(!(CodeVal & 0x80000000))
1561  {
1562  CodeVal<<=1;
1563  Bits--;
1564  }
1565  return Bits;
1566  }
1567*/
1568
1569/* MPEG 4 VOP (Picture) Header */
1570static void tng__MPEG4_writebits_VOP_header(
1571    MTX_HEADER_PARAMS *mtx_hdr,
1572    MTX_HEADER_ELEMENT **aui32ElementPointers,
1573    IMG_BOOL    bIsVOP_coded,
1574    IMG_UINT8   VOP_time_increment,
1575    SEARCH_RANGE_TYPE sSearch_range,
1576    VOP_CODING_TYPE sVopCodingType,
1577    IMG_UINT32 VopTimeResolution)
1578{
1579    IMG_BOOL bIsSyncPoint;
1580    /* Essential we insert the element before we try to fill it! */
1581    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1582
1583    /* visual_object_sequence_start_code        = 32 Bits       = 0x1B6 */
1584    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 438, 32);
1585
1586    /* vop_coding_type  = 2 Bits = 0 for I-frame and 1 for P-frame */
1587    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, sVopCodingType, 2);
1588    bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0);
1589
1590#ifndef MATCH_TO_ENC
1591    /* modulo_time_base = 1 Bit = 0 As at least  1 synchronization point (I-frame) per second in Topaz */
1592    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1593#else
1594
1595    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, bIsSyncPoint  ? 2 : 0 , bIsSyncPoint ? 2 : 1);
1596
1597#endif
1598
1599    /* marker_bit = 1   Bits    = 1      */
1600    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1601
1602#ifndef MATCH_TO_ENC
1603    /* vop_time_increment = Variable bits based on resolution
1604     *  = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame
1605     */
1606    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, VOP_time_increment, 5);
1607#else
1608    /* will chrash here... */
1609    tng__write_upto8bits_elements(
1610        mtx_hdr, aui32ElementPointers,
1611        (VOP_time_increment) % VopTimeResolution,
1612        Bits2Code(VopTimeResolution - 1));
1613
1614#endif
1615    /* marker_bit = 1 Bit               = 1      */
1616    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1617
1618    if (!bIsVOP_coded) {
1619        /* vop_coded    = 1 Bit         = 0 for skipped frame */
1620        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1621
1622        /* byte_aligned_bits (skipped pictures are byte aligned) */
1623        /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
1624         * End of VOP - skipped picture
1625         */
1626        tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_MPG4);
1627    } else {
1628        /* vop_coded = 1 Bit            = 1 for normal coded frame */
1629        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1630
1631        if (sVopCodingType == P_FRAME) {
1632            /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */
1633            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1634        }
1635
1636        /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */
1637        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 3);
1638
1639        /* vop_quant = 5 Bits   = x     5-bit frame Q_scale from rate control - GENERATED BY MTX */
1640        /* tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Frame_Q_scale, 5); */
1641        tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_FRAMEQSCALE);
1642
1643        if (sVopCodingType == P_FRAME) {
1644            /* vop_fcode_forward = 3 bits       = 2 for +/-32 and 3 for +/-64 search range  */
1645            tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1646            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, sSearch_range, 3);
1647        }
1648
1649        /*
1650        **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE
1651        tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1652        video_packet_data ( )                   = 1st  VP that doesn�t have the VP header
1653
1654        while (nextbits_bytealigned ( ) == resync_marker)
1655        {
1656        video_packet _header( )
1657        video_packet _data( )                   All MB in the slice
1658        }
1659        */
1660    }
1661}
1662
1663/*
1664 * Intermediary functions to build H263 headers
1665 */
1666static void H263_writebits_VideoSequenceHeader(
1667    MTX_HEADER_PARAMS *mtx_hdr,
1668    MTX_HEADER_ELEMENT **aui32ElementPointers,
1669    IMG_UINT8 Profile_and_level_indication)
1670{
1671    /* Essential we insert the element before we try to fill it! */
1672    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1673
1674    /* visual_object_sequence_start_code        = 32 Bits       = 0x1B0 */
1675    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 432, 32);
1676
1677    /* profile_and_level_indication = 8 Bits =  x SP L0-L3 and SP L4-L5 are supported */
1678    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Profile_and_level_indication, 8);
1679
1680    /* visual_object_start_code = 32 Bits       = 0x1B5 */
1681
1682    /* 437 too large for the   tng__write_upto32bits_elements function */
1683    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 437, 32);
1684
1685    /* is_visual_object_identifier = 1 Bit              = 0 */
1686    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1687
1688    /* is_visual_object_type    = 4 Bits        = 1 Video ID */
1689    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 4);
1690
1691    /* video_signal_type = 1 Bit                = 0      */
1692    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1693
1694    /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */
1695    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 2);
1696
1697    /* video_object_start_code  =32 Bits        = 0x100 One VO only in a Topaz video stream */
1698    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 256, 32);
1699
1700    return;
1701}
1702
1703static void H263_writebits_VideoPictureHeader(
1704    MTX_HEADER_PARAMS *mtx_hdr,
1705    MTX_HEADER_ELEMENT **aui32ElementPointers,
1706    IMG_UINT8 Temporal_Ref,
1707    H263_PICTURE_CODING_TYPE PictureCodingType,
1708    //IMG_UINT8 Q_Scale,
1709    H263_SOURCE_FORMAT_TYPE SourceFormatType,
1710    IMG_UINT8 FrameRate,
1711    IMG_UINT32 PictureWidth,
1712    IMG_UINT32 PictureHeight)
1713{
1714    IMG_UINT8 UFEP;
1715
1716    /* Essential we insert the element before we try to fill it! */
1717    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1718
1719    /* short_video_start_marker = 22 Bits       = 0x20 Picture start code */
1720    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 32, 22);
1721
1722    /* temporal_reference = 8 Bits      = 0-255 Each picture increased by 1 */
1723    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, Temporal_Ref, 8);
1724
1725    /* marker_bit = 1 Bit = 1    */
1726    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1727
1728    /* zero_bit = 1 Bits        = 0      */
1729    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1730
1731    /* split_screen_indicator   = 1     Bits    = 0     No direct effect on encoding of picture */
1732    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1733
1734    /* document_camera_indicator= 1     Bits    = 0     No direct effect on encoding of picture */
1735    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1736
1737    /* full_picture_freeze_release=1 Bits       = 0     No direct effect on encoding of picture */
1738    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1739
1740    /* source_format                            = 3     Bits    = 1-4   See note */
1741    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, SourceFormatType, 3);
1742
1743    if (SourceFormatType != 7) {
1744        // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1745        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, PictureCodingType, 1);
1746        // four_reserved_zero_bits      = 4 Bits        = 0
1747        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 4);
1748    } else {
1749        static unsigned char  RTYPE = 0;
1750
1751        // if I- Frame set Update Full Extended PTYPE to true
1752        if (PictureCodingType == I_FRAME) {
1753            UFEP = 1;
1754        } else {
1755            UFEP = 0;
1756        }
1757        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, UFEP, 3);
1758        if (UFEP == 1) {
1759            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 6, 3);
1760            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1761
1762            /* 10 reserve bits ( Optional support for the encoding). All are OFF(0).
1763             *  - Optional Unrestricted Motion Vector (UMV)
1764             *  - Optional Syntax-based Arithmetic Coding (SAC)
1765             *  - Optional Advanced Prediction (AP) mode
1766             *  - Optional Advanced INTRA Coding (AIC) mode
1767             *  - Optional Deblocking Filter (DF) mode
1768             *  - Optional Slice Structured (SS) mode
1769             *  - Optional Reference Picture Selection(RPS) mode.
1770             *  - Optional Independent Segment Decoding (ISD) mode
1771             *  - Optional Alternative INTER VLC (AIV) mode
1772             *  - Optional Modified Quantization (MQ) mode */
1773
1774            tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 0, 10);
1775            // 10 reserve bits
1776            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 8, 4);
1777            // 4 reserve bits
1778        }
1779        // picture_coding_type          = 1 Bit         = 0/1   0 for I-frame and 1 for P-frame
1780        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, PictureCodingType, 3);
1781
1782        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 2);
1783        // two_reserve_bits,      rounding_type,       two_reserve_bits       marker_bit       CPM
1784        // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames.
1785        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, RTYPE, 1);
1786        //2 reserve bits
1787        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 2);
1788        //   - 1 (ON) to prevent start code emulation.
1789        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1 , 1);
1790        // CPM immediately follows the PPTYPE part of the header.
1791        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0 , 1);
1792
1793
1794        if (UFEP == 1) {
1795            IMG_UINT16 ui16PWI, ui16PHI;
1796            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 4);
1797            // aspect ratio
1798            //PictureWidth--;
1799            //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureWidth >> 8), 1);
1800            //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureWidth & 0xFF), 8);
1801            //Width = (PWI-1)*4, Height = PHI*4, see H263 spec 5.1.5
1802            ui16PWI = (PictureWidth >> 2) - 1;
1803            tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)ui16PWI, 9);
1804
1805            tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1806            // marker_bit                               = 1 Bit         = 1
1807            //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureHeight >> 8), 1);
1808            //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)(PictureHeight & 0xFF), 8);
1809
1810            ui16PHI = PictureHeight >> 2;
1811            tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, (IMG_UINT8)ui16PHI, 9);
1812            // good up to that point
1813            //  tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 1, 1);
1814            // marker_bit                               = 1 Bit         = 1
1815            // just checking
1816        }
1817    }
1818    // vop_quant                                = 5 Bits        = x     5-bit frame Q_scale from rate control - GENERATED BY MTX
1819    //tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, ui8Q_Scale, 5);
1820    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_FRAMEQSCALE); // Insert token to tell MTX to insert rate-control value (QScale
1821										   //is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, FrameQScale))
1822    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_RAWDATA);
1823    // zero_bit                                 = 1 Bit         = 0
1824    // pei                                              = 1 Bit         = 0     No direct effect on encoding of picture
1825    if (SourceFormatType != 7) {
1826        tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1827    }
1828
1829    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, 0, 1);
1830    // FOLLOWING SECTION CAN'T BE GENERATED HERE
1831    //gob_data( )
1832    //for(i=1; i<num_gob_in_picture; i++) {
1833    //      gob_header( )
1834    //      gob_data( )
1835    // }
1836    return;
1837}
1838
1839static void H263_writebits_GOBSliceHeader(
1840    MTX_HEADER_PARAMS *mtx_hdr,
1841    MTX_HEADER_ELEMENT **aui32ElementPointers,
1842    IMG_UINT8 GOBNumber,
1843    IMG_UINT8 GOBFrameId)
1844{
1845    /* Essential we insert the element before we try to fill it! */
1846    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1847
1848    /* gob_resync_marker                = 17            = 0x1 */
1849    tng__write_upto32bits_elements(mtx_hdr, aui32ElementPointers, 1, 17);
1850
1851    /* gob_number = 5   = 0-17  It is gob number in a picture */
1852    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOBNumber, 5);
1853
1854    /* gob_frame_id     = 2 = 0-3       See note */
1855    tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOBFrameId, 2);
1856
1857    /* quant_scale      = 5     = 1-32  gob (Slice) Q_scale  */
1858    /* tng__write_upto8bits_elements(mtx_hdr, aui32ElementPointers, GOB_Q_Scale, 5); */
1859
1860    /* Insert token to tell MTX to insert rate-control value
1861     *  (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale))
1862     */
1863    tng__insert_element_token(mtx_hdr, aui32ElementPointers, ELEMENT_SLICEQSCALE);
1864    return;
1865}
1866
1867/*
1868 * High level functions to call when a H263 header is required - HOST ROUTINES
1869 */
1870//static void tng__H263_getelements_videosequence_header(
1871//MTX_HEADER_PARAMS *mtx_hdr,
1872//IMG_UINT8 Profile_and_level_indication)
1873//{
1874///* Builds a single H263 video sequence header from the given parameters */
1875//
1876///* Essential we initialise our header structures before building */
1877//MTX_HEADER_ELEMENT *This_Element;
1878//MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1879//mtx_hdr->Elements=ELEMENTS_EMPTY;
1880//This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1881//aui32ElementPointers[0]=This_Element;
1882//
1883//H263_writebits_VideoSequenceHeader(mtx_hdr, aui32ElementPointers, Profile_and_level_indication);
1884//
1885//mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1886//}
1887
1888//static void tng__H263_getelements_videopicture_header(
1889//MTX_HEADER_PARAMS *mtx_hdr,
1890//IMG_UINT8 Temporal_Ref,
1891//H263_PICTURE_CODING_TYPE PictureCodingType,
1892//H263_SOURCE_FORMAT_TYPE SourceFormatType,
1893//IMG_UINT8 FrameRate,
1894//IMG_UINT16 PictureWidth,
1895//IMG_UINT16 PictureHeigth)
1896//{
1897///* Essential we initialise our header structures before building */
1898//MTX_HEADER_ELEMENT *This_Element;
1899//MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1900//mtx_hdr->Elements=ELEMENTS_EMPTY;
1901//This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1902//aui32ElementPointers[0]=This_Element;
1903//
1904//H263_writebits_VideoPictureHeader(
1905//mtx_hdr, aui32ElementPointers,
1906//Temporal_Ref,
1907//PictureCodingType,
1908//SourceFormatType,
1909//FrameRate,
1910//PictureWidth,
1911//PictureHeigth);
1912//
1913//mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
1914//}
1915
1916//static void tng__H263_getelements_GOBslice_header(
1917//MTX_HEADER_PARAMS *mtx_hdr,
1918//IMG_UINT8 GOBNumber,
1919//IMG_UINT8 GOBFrameId)
1920//{
1921///* Essential we initialise our header structures before building */
1922//MTX_HEADER_ELEMENT *This_Element;
1923//MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
1924//mtx_hdr->Elements=ELEMENTS_EMPTY;
1925//This_Element=(MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
1926//aui32ElementPointers[0]=This_Element;
1927//
1928//H263_writebits_GOBSliceHeader(mtx_hdr, aui32ElementPointers, GOBNumber, GOBFrameId);
1929//
1930//mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count
1931//}
1932
1933// SEI_INSERTION
1934static void tng__H264ES_writebits_AUD_header(
1935    MTX_HEADER_PARAMS *pMTX_Header,
1936    MTX_HEADER_ELEMENT **aui32ElementPointers)
1937{
1938    // Essential we insert the element before we try to fill it!
1939    tng__insert_element_token(pMTX_Header,
1940        aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1941
1942    tng__H264_writebits_startcode_prefix_element(pMTX_Header,
1943        aui32ElementPointers, 4); // 00 00 00 01 start code prefix
1944
1945    tng__write_upto8bits_elements(pMTX_Header,
1946        aui32ElementPointers, 9, 8); // AUD nal_unit_type = 09
1947
1948    // primary_pic_type  u(3) 0=I slice, 1=P or I slice, 2=P,B or I slice
1949    tng__write_upto8bits_elements(pMTX_Header,
1950        aui32ElementPointers, 2, 3);
1951
1952    tng__write_upto8bits_elements(pMTX_Header,
1953        aui32ElementPointers, 1 << 4, 5); // rbsp_trailing_bits
1954
1955    // Write terminator
1956    tng__write_upto8bits_elements(pMTX_Header,
1957        aui32ElementPointers, 0x80, 8);
1958    return;
1959}
1960
1961static void tng__H264ES_writebits_SEI_buffering_period_header(
1962    MTX_HEADER_PARAMS *pMTX_Header,
1963    MTX_HEADER_ELEMENT **aui32ElementPointers,
1964    IMG_UINT8 ui8NalHrdBpPresentFlag,
1965    IMG_UINT8 ui8nal_cpb_cnt_minus1,
1966    IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
1967    IMG_UINT32 ui32nal_initial_cpb_removal_delay,
1968    IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
1969    IMG_UINT8 ui8VclHrdBpPresentFlag,
1970    IMG_UINT8 ui8vcl_cpb_cnt_minus1,
1971    IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
1972    IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
1973{
1974    IMG_UINT8 ui8SchedSelIdx;
1975    IMG_UINT8 ui8PayloadSizeBits;
1976#ifdef SEI_NOT_USE_TOKEN_ALIGN
1977    IMG_UINT8 ui8Pad;
1978#endif
1979    // Essential we insert the element before we try to fill it!
1980    tng__insert_element_token(pMTX_Header,
1981        aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
1982
1983    tng__H264_writebits_startcode_prefix_element(pMTX_Header,
1984        aui32ElementPointers, 3); // 00 00 01 start code prefix
1985
1986    tng__write_upto8bits_elements(pMTX_Header,
1987        aui32ElementPointers, 6, 8); // nal_unit_type = 06 (SEI Message)
1988
1989    tng__write_upto8bits_elements(pMTX_Header,
1990        aui32ElementPointers, 0, 8); // SEI payload type (buffering period)
1991
1992    ui8PayloadSizeBits = 1; // seq_parameter_set_id bitsize = 1
1993    if (ui8NalHrdBpPresentFlag)
1994        ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1)
1995                               * ui8nal_initial_cpb_removal_delay_length * 2);
1996    if (ui8VclHrdBpPresentFlag)
1997        ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1)
1998                               * ui8nal_initial_cpb_removal_delay_length * 2);
1999
2000    tng__write_upto8bits_elements(pMTX_Header,
2001                                  aui32ElementPointers,
2002                                  ((ui8PayloadSizeBits + 7) / 8),
2003                                  8);
2004    // SEI payload size = No of bytes required for SEI payload
2005    // (including seq_parameter_set_id)
2006
2007    //seq_parameter_set_id      ue(v) = 0 default? = 1 (binary)
2008    //= sequence parameter set containing HRD attributes
2009    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);
2010
2011    if (ui8NalHrdBpPresentFlag) {
2012        for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++) {
2013            // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access
2014            // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit.
2015            // Delay is based on the time taken for a 90 kHz clock.
2016            // Range >0 and < 90000 * (CPBsize / BitRate)
2017            // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation.
2018            // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
2019
2020            //tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32nal_initial_cpb_removal_delay, ui8nal_initial_cpb_removal_delay_length);
2021            tng__insert_element_token(pMTX_Header,
2022                                      aui32ElementPointers,
2023                                      BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY);
2024
2025            // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to
2026            // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset
2027            // Delay is based on the time taken for a 90 kHz clock.
2028            // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C
2029
2030            tng__insert_element_token(pMTX_Header,
2031                                      aui32ElementPointers,
2032                                      BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET);
2033        }
2034    }
2035    if (ui8VclHrdBpPresentFlag) {
2036        for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++) {
2037            tng__insert_element_token(pMTX_Header,
2038                                      aui32ElementPointers,
2039                                      ELEMENT_STARTCODE_RAWDATA);
2040            // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
2041            tng__write_upto32bits_elements(pMTX_Header,
2042                                           aui32ElementPointers,
2043                                           ui32vcl_initial_cpb_removal_delay,
2044                                           ui8nal_initial_cpb_removal_delay_length);
2045            // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required
2046            tng__write_upto32bits_elements(pMTX_Header,
2047                                           aui32ElementPointers,
2048                                           ui32vcl_initial_cpb_removal_delay_offset,
2049                                           ui8nal_initial_cpb_removal_delay_length);
2050        }
2051    }
2052
2053    // Pad to end of byte
2054#ifdef SEI_NOT_USE_TOKEN_ALIGN
2055    if (!ui8VclHrdBpPresentFlag)
2056        tng__insert_element_token(pMTX_Header,
2057                                  aui32ElementPointers,
2058                                  ELEMENT_STARTCODE_RAWDATA);
2059    ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2060    ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2061    if (ui8Pad > 0)
2062        tng__write_upto8bits_elements(pMTX_Header,
2063                                      aui32ElementPointers,
2064                                      1 << (ui8Pad - 1),
2065                                      ui8Pad); // SEI payload type (buffering period)
2066#else
2067    tng__insert_element_token(pMTX_Header,
2068                              aui32ElementPointers,
2069                              ELEMENT_INSERTBYTEALIGN_H264);
2070    // Tell MTX to insert the byte align field
2071    tng__insert_element_token(pMTX_Header,
2072                              aui32ElementPointers,
2073                              ELEMENT_STARTCODE_RAWDATA);
2074#endif
2075
2076    // Write terminator
2077    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8);
2078
2079    return;
2080}
2081
2082
2083static void tng__H264ES_writebits_SEI_picture_timing_header(
2084    MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
2085    IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2086    IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2087    IMG_UINT32 ui32dpb_output_delay_length_minus1,
2088    IMG_UINT32 ui32cpb_removal_delay,
2089    IMG_UINT32 ui32dpb_output_delay,
2090    IMG_UINT8 ui8pic_struct_present_flag,
2091    IMG_UINT8 ui8pic_struct,
2092    IMG_UINT8 ui8NumClockTS,
2093    IMG_UINT8 *aui8clock_timestamp_flag,
2094    IMG_UINT8 ui8full_timestamp_flag,
2095    IMG_UINT8 ui8seconds_flag,
2096    IMG_UINT8 ui8minutes_flag,
2097    IMG_UINT8 ui8hours_flag,
2098    IMG_UINT8 ui8seconds_value,
2099    IMG_UINT8 ui8minutes_value,
2100    IMG_UINT8 ui8hours_value,
2101    IMG_UINT8 ui8ct_type,
2102    IMG_UINT8 ui8nuit_field_based_flag,
2103    IMG_UINT8 ui8counting_type,
2104    IMG_UINT8 ui8discontinuity_flag,
2105    IMG_UINT8 ui8cnt_dropped_flag,
2106    IMG_UINT8 ui8n_frames,
2107    IMG_UINT8 ui8time_offset_length,
2108    IMG_INT32 i32time_offset)
2109{
2110    IMG_UINT8 ui8PayloadSizeBits, ui8Tmp;
2111#ifdef SEI_NOT_USE_TOKEN_ALIGN
2112    IMG_UINT8 ui8Pad;
2113#endif
2114
2115    // Essential we insert the element before we try to fill it!
2116    tng__insert_element_token(pMTX_Header,
2117                              aui32ElementPointers,
2118                              ELEMENT_STARTCODE_RAWDATA);
2119
2120    tng__H264_writebits_startcode_prefix_element(pMTX_Header,
2121            aui32ElementPointers,
2122            3); // 00 00 01 start code prefix
2123
2124    tng__write_upto8bits_elements(pMTX_Header,
2125                                  aui32ElementPointers,
2126                                  6, 8); // nal_unit_type = 06 (SEI Message)
2127
2128    tng__write_upto8bits_elements(pMTX_Header,
2129                                  aui32ElementPointers,
2130                                  1, 8); // SEI payload type (picture timing)
2131
2132
2133    // Precalculate the payload bit size
2134    ui8PayloadSizeBits = 0;
2135    if (ui8CpbDpbDelaysPresentFlag)
2136        ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1
2137                              + 1 + ui32dpb_output_delay_length_minus1 + 1;
2138
2139    if (ui8pic_struct_present_flag) {
2140        ui8PayloadSizeBits += 4;
2141        for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
2142            ui8PayloadSizeBits += 1;
2143
2144            if (aui8clock_timestamp_flag[ui8Tmp]) {
2145                ui8PayloadSizeBits += 2 + 1 + 5 + 1 + 1 + 1 + 8;
2146                if (ui8full_timestamp_flag)
2147                    ui8PayloadSizeBits += 6 + 6 + 5;
2148                else {
2149                    ui8PayloadSizeBits += 1;
2150                    if (ui8seconds_flag) {
2151                        ui8PayloadSizeBits += 6 + 1;
2152                        if (ui8minutes_flag) {
2153                            ui8PayloadSizeBits += 6 + 1;
2154                            if (ui8hours_flag)
2155                                ui8PayloadSizeBits += 5;
2156                        }
2157                    }
2158                }
2159
2160                if (ui8time_offset_length > 0)
2161                    ui8PayloadSizeBits += ui8time_offset_length;
2162            }
2163        }
2164    }
2165
2166    tng__write_upto8bits_elements(pMTX_Header,
2167                                  aui32ElementPointers,
2168                                  ((ui8PayloadSizeBits + 7) / 8), 8);
2169    // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id)
2170
2171
2172    if (ui8CpbDpbDelaysPresentFlag) {
2173        //SEI_INSERTION
2174#ifdef SEI_HOSTCALC_CPB_DPB
2175        tng__write_upto32bits_elements(pMTX_Header,
2176                                       aui32ElementPointers,
2177                                       ui32cpb_removal_delay,
2178                                       ui32cpb_removal_delay_length_minus1 + 1); // cpb_removal_delay
2179        tng__write_upto32bits_elements(pMTX_Header,
2180                                       aui32ElementPointers,
2181                                       ui32dpb_output_delay,
2182                                       ui32dpb_output_delay_length_minus1 + 1); // dpb_output_delay
2183#else
2184        tng__insert_element_token(pMTX_Header,
2185                                  aui32ElementPointers,
2186                                  PTH_SEI_NAL_CPB_REMOVAL_DELAY);
2187        tng__insert_element_token(pMTX_Header,
2188                                  aui32ElementPointers,
2189                                  PTH_SEI_NAL_DPB_OUTPUT_DELAY);
2190#endif
2191    }
2192
2193    if (ui8pic_struct_present_flag) {
2194        tng__insert_element_token(pMTX_Header,
2195                                  aui32ElementPointers,
2196                                  ELEMENT_STARTCODE_RAWDATA);
2197        tng__write_upto8bits_elements(pMTX_Header,
2198                                      aui32ElementPointers,
2199                                      ui8pic_struct, 4); // See TRM able D 1 ?Interpretation of pic_struct
2200
2201        for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
2202            tng__write_upto8bits_elements(pMTX_Header,
2203                                          aui32ElementPointers,
2204                                          aui8clock_timestamp_flag[ui8Tmp], 1);
2205
2206            if (aui8clock_timestamp_flag[ui8Tmp]) {
2207                tng__write_upto8bits_elements(pMTX_Header,
2208                                              aui32ElementPointers,
2209                                              ui8ct_type, 2);
2210                // (2=Unknown) See TRM Table D 2 ?Mapping of ct_type to source picture scan
2211                tng__write_upto8bits_elements(pMTX_Header,
2212                                              aui32ElementPointers,
2213                                              ui8nuit_field_based_flag, 1);
2214                tng__write_upto8bits_elements(pMTX_Header,
2215                                              aui32ElementPointers,
2216                                              ui8counting_type, 5);
2217                // See TRM Table D 3 ?Definition of counting_type values
2218                tng__write_upto8bits_elements(pMTX_Header,
2219                                              aui32ElementPointers,
2220                                              ui8full_timestamp_flag, 1);
2221                tng__write_upto8bits_elements(pMTX_Header,
2222                                              aui32ElementPointers,
2223                                              ui8discontinuity_flag, 1);
2224                tng__write_upto8bits_elements(pMTX_Header,
2225                                              aui32ElementPointers,
2226                                              ui8cnt_dropped_flag, 1);
2227                tng__write_upto8bits_elements(pMTX_Header,
2228                                              aui32ElementPointers,
2229                                              ui8n_frames, 8);
2230
2231                if (ui8full_timestamp_flag) {
2232                    tng__write_upto8bits_elements(pMTX_Header,
2233                                                  aui32ElementPointers,
2234                                                  ui8seconds_value, 6); // 0 - 59
2235                    tng__write_upto8bits_elements(pMTX_Header,
2236                                                  aui32ElementPointers,
2237                                                  ui8minutes_value, 6); // 0 - 59
2238                    tng__write_upto8bits_elements(pMTX_Header,
2239                                                  aui32ElementPointers,
2240                                                  ui8hours_value, 5); // 0 - 23
2241                } else {
2242                    tng__write_upto8bits_elements(pMTX_Header,
2243                                                  aui32ElementPointers,
2244                                                  ui8seconds_flag, 1);
2245
2246                    if (ui8seconds_flag) {
2247                        tng__write_upto8bits_elements(pMTX_Header,
2248                                                      aui32ElementPointers,
2249                                                      ui8seconds_value, 6); // 0 - 59
2250                        tng__write_upto8bits_elements(pMTX_Header,
2251                                                      aui32ElementPointers,
2252                                                      ui8minutes_flag, 1);
2253
2254                        if (ui8minutes_flag) {
2255                            tng__write_upto8bits_elements(pMTX_Header,
2256                                                          aui32ElementPointers,
2257                                                          ui8minutes_value, 6); // 0 - 59
2258                            tng__write_upto8bits_elements(pMTX_Header,
2259                                                          aui32ElementPointers,
2260                                                          ui8hours_flag, 1);
2261
2262                            if (ui8hours_flag)
2263                                tng__write_upto8bits_elements(pMTX_Header,
2264                                                              aui32ElementPointers,
2265                                                              ui8hours_value, 5); // 0 - 23
2266                        }
2267                    }
2268                }
2269
2270                if (ui8time_offset_length > 0) {
2271                    // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset)
2272                    if (i32time_offset < 0)
2273                        tng__write_upto32bits_elements(pMTX_Header,
2274                                                       aui32ElementPointers,
2275                                                       (IMG_UINT32)((2 ^ ui8time_offset_length) + i32time_offset),
2276                                                       ui8time_offset_length);
2277                    else
2278                        tng__write_upto32bits_elements(pMTX_Header,
2279                                                       aui32ElementPointers,
2280                                                       (IMG_UINT32) i32time_offset,
2281                                                       ui8time_offset_length);
2282                }
2283            }
2284        }
2285    }
2286
2287#ifdef SEI_NOT_USE_TOKEN_ALIGN
2288    // Pad to end of byte
2289    if (!ui8pic_struct_present_flag)
2290        tng__insert_element_token(pMTX_Header,
2291                                  aui32ElementPointers,
2292                                  ELEMENT_STARTCODE_RAWDATA);
2293    ui8Pad = (ui8PayloadSizeBits + 7) / 8;
2294    ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
2295    if (ui8Pad > 0)
2296        tng__write_upto8bits_elements(pMTX_Header,
2297                                      aui32ElementPointers,
2298                                      1 << (ui8Pad - 1),
2299                                      ui8Pad); // SEI payload type (buffering period)
2300#else
2301    tng__insert_element_token(pMTX_Header,
2302                              aui32ElementPointers,
2303                              ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field
2304    tng__insert_element_token(pMTX_Header,
2305                              aui32ElementPointers,
2306                              ELEMENT_STARTCODE_RAWDATA);
2307#endif
2308
2309    // Write terminator
2310    tng__write_upto8bits_elements(pMTX_Header,
2311                                  aui32ElementPointers,
2312                                  0x80, 8);
2313    return;
2314}
2315
2316
2317
2318void tng__H264ES_prepare_AUD_header(unsigned char *virtual_addr)
2319{
2320    // Essential we initialise our header structures before building
2321    MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2322    MTX_HEADER_ELEMENT *This_Element;
2323    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2324    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2325    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2326    aui32ElementPointers[0] = This_Element;
2327
2328    tng__H264ES_writebits_AUD_header(pMTX_Header, aui32ElementPointers);
2329
2330    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
2331}
2332
2333
2334void tng__H264ES_prepare_SEI_buffering_period_header(
2335    unsigned char *virtual_addr,
2336    IMG_UINT8 ui8nal_cpb_cnt_minus1,
2337    IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
2338    IMG_UINT8 ui8NalHrdBpPresentFlag,
2339    IMG_UINT32 ui32nal_initial_cpb_removal_delay,
2340    IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
2341    IMG_UINT8 ui8VclHrdBpPresentFlag,
2342    IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
2343    IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
2344{
2345    // Essential we initialise our header structures before building
2346    MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2347    MTX_HEADER_ELEMENT *This_Element;
2348    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2349    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2350    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2351    aui32ElementPointers[0] = This_Element;
2352
2353    tng__H264ES_writebits_SEI_buffering_period_header(
2354        pMTX_Header, aui32ElementPointers,
2355        ui8NalHrdBpPresentFlag,
2356        ui8nal_cpb_cnt_minus1,
2357        ui8nal_initial_cpb_removal_delay_length,
2358        ui32nal_initial_cpb_removal_delay,
2359        ui32nal_initial_cpb_removal_delay_offset,
2360        ui8VclHrdBpPresentFlag,
2361        ui8nal_cpb_cnt_minus1,
2362        ui32vcl_initial_cpb_removal_delay,
2363        ui32vcl_initial_cpb_removal_delay_offset);
2364
2365    pMTX_Header->ui32Elements++;
2366    //Has been used as an index, so need to add 1 for a valid element count
2367    return;
2368}
2369
2370void tng__H264ES_prepare_SEI_picture_timing_header(
2371    unsigned char *virtual_addr,
2372    IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
2373    IMG_UINT32 ui32cpb_removal_delay_length_minus1,
2374    IMG_UINT32 ui32dpb_output_delay_length_minus1,
2375    IMG_UINT32 ui32cpb_removal_delay,
2376    IMG_UINT32 ui32dpb_output_delay,
2377    IMG_UINT8 ui8pic_struct_present_flag,
2378    IMG_UINT8 ui8pic_struct,
2379    IMG_UINT8 ui8NumClockTS,
2380    IMG_UINT8 *aui8clock_timestamp_flag,
2381    IMG_UINT8 ui8full_timestamp_flag,
2382    IMG_UINT8 ui8seconds_flag,
2383    IMG_UINT8 ui8minutes_flag,
2384    IMG_UINT8 ui8hours_flag,
2385    IMG_UINT8 ui8seconds_value,
2386    IMG_UINT8 ui8minutes_value,
2387    IMG_UINT8 ui8hours_value,
2388    IMG_UINT8 ui8ct_type,
2389    IMG_UINT8 ui8nuit_field_based_flag,
2390    IMG_UINT8 ui8counting_type,
2391    IMG_UINT8 ui8discontinuity_flag,
2392    IMG_UINT8 ui8cnt_dropped_flag,
2393    IMG_UINT8 ui8n_frames,
2394    IMG_UINT8 ui8time_offset_length,
2395    IMG_INT32 i32time_offset)
2396{
2397    // Essential we initialise our header structures before building
2398    MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
2399    MTX_HEADER_ELEMENT *This_Element;
2400    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2401    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2402    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2403    aui32ElementPointers[0] = This_Element;
2404
2405    tng__H264ES_writebits_SEI_picture_timing_header(
2406        pMTX_Header, aui32ElementPointers,
2407        ui8CpbDpbDelaysPresentFlag,
2408        ui32cpb_removal_delay_length_minus1,
2409        ui32dpb_output_delay_length_minus1,
2410        ui32cpb_removal_delay,
2411        ui32dpb_output_delay,
2412        ui8pic_struct_present_flag,
2413        ui8pic_struct,
2414        ui8NumClockTS,
2415        aui8clock_timestamp_flag,
2416        ui8full_timestamp_flag,
2417        ui8seconds_flag,
2418        ui8minutes_flag,
2419        ui8hours_flag,
2420        ui8seconds_value,
2421        ui8minutes_value,
2422        ui8hours_value,
2423        ui8ct_type,
2424        ui8nuit_field_based_flag,
2425        ui8counting_type,
2426        ui8discontinuity_flag,
2427        ui8cnt_dropped_flag,
2428        ui8n_frames,
2429        ui8time_offset_length,
2430        i32time_offset);
2431
2432    pMTX_Header->ui32Elements++;
2433    //Has been used as an index, so need to add 1 for a valid element count
2434    return;
2435}
2436
2437static void tng__H264ES_set_sequence_level_profile(
2438    H264_SEQUENCE_HEADER_PARAMS *pSHParams,
2439    IMG_UINT8 uiLevel,
2440    IMG_UINT8 uiProfile)
2441{
2442    switch (uiLevel) {
2443    case 10:
2444        pSHParams->ucLevel =  SH_LEVEL_10;
2445        break;
2446    case 111:
2447        pSHParams->ucLevel =  SH_LEVEL_1B;
2448        break;
2449    case 11:
2450        pSHParams->ucLevel =  SH_LEVEL_11;
2451        break;
2452    case 12:
2453        pSHParams->ucLevel =  SH_LEVEL_12;
2454        break;
2455    case 20:
2456        pSHParams->ucLevel =  SH_LEVEL_20;
2457        break;
2458    case 30:
2459        pSHParams->ucLevel =  SH_LEVEL_30;
2460        break;
2461    case 31:
2462        pSHParams->ucLevel =  SH_LEVEL_31;
2463        break;
2464    case 32:
2465        pSHParams->ucLevel =  SH_LEVEL_32;
2466        break;
2467    case 40:
2468        pSHParams->ucLevel =  SH_LEVEL_40;
2469        break;
2470    case 41:
2471        pSHParams->ucLevel =  SH_LEVEL_41;
2472        break;
2473    case 42:
2474        pSHParams->ucLevel =  SH_LEVEL_42;
2475        break;
2476    default:
2477        pSHParams->ucLevel =  SH_LEVEL_30;
2478        break;
2479    }
2480
2481    switch (uiProfile) {
2482    case 5:
2483        pSHParams->ucProfile  = SH_PROFILE_BP;
2484        break;
2485    case 6:
2486        pSHParams->ucProfile  = SH_PROFILE_MP;
2487        break;
2488    default:
2489        pSHParams->ucProfile  = SH_PROFILE_MP;
2490        break;
2491    }
2492    return ;
2493}
2494
2495void tng__H264ES_prepare_sequence_header(
2496    void *pHeaderMemory,
2497    H264_VUI_PARAMS *psVUI_Params,
2498    H264_CROP_PARAMS *psCropParams,
2499    IMG_UINT16 ui16PictureWidth,
2500    IMG_UINT16 ui16PictureHeight,
2501    IMG_UINT32 ui32CustomQuantMask,
2502    IMG_UINT8 ui8ProfileIdc,
2503    IMG_UINT8 ui8LevelIdc,
2504    IMG_UINT8 ui8FieldCount,
2505    IMG_UINT8 ui8MaxNumRefFrames,
2506    IMG_BOOL  bPpsScaling,
2507    IMG_BOOL  bUseDefaultScalingList,
2508    IMG_BOOL  bEnableLossless,
2509    IMG_BOOL  bASO
2510)
2511{
2512    /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2513     * Essential we initialise our header structures before building
2514     */
2515    H264_SEQUENCE_HEADER_PARAMS SHParams;
2516    /* Route output elements to memory provided */
2517    MTX_HEADER_PARAMS  *mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2518    MTX_HEADER_ELEMENT *This_Element;
2519    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2520    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2521    This_Element = mtx_hdr->asElementStream;
2522    aui32ElementPointers[0] = This_Element;
2523
2524    memset(&SHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
2525
2526    SHParams.ucProfile = ui8ProfileIdc - 5;
2527    SHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
2528    SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
2529    SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
2530    SHParams.gaps_in_frame_num_value = IMG_FALSE;
2531    SHParams.VUI_Params_Present = psVUI_Params->vui_flag;
2532    if (SHParams.VUI_Params_Present)
2533        memcpy(&SHParams.VUI_Params, psVUI_Params, sizeof(H264_VUI_PARAMS));
2534    SHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
2535
2536    SHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
2537    SHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
2538
2539
2540    SHParams.seq_scaling_matrix_present_flag = (ui32CustomQuantMask != 0 && !bPpsScaling);
2541    SHParams.bUseDefaultScalingList = (bUseDefaultScalingList && !bPpsScaling);
2542
2543    SHParams.max_num_ref_frames = ui8MaxNumRefFrames;
2544    SHParams.bIsLossless = bEnableLossless;
2545    SHParams.log2_max_pic_order_cnt = 6;
2546#ifdef _TOPAZHP_PDUMP_
2547    tng_trace_seq_header_params(&SHParams);
2548#endif
2549    tng__H264ES_writebits_sequence_header(mtx_hdr, aui32ElementPointers, &SHParams, psCropParams, NULL, bASO);
2550    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2551}
2552
2553static void tng__H264ES_writebits_mvc_sequence_header(
2554    MTX_HEADER_PARAMS *pMTX_Header,
2555    MTX_HEADER_ELEMENT **aui32ElementPointers,
2556    H264_SEQUENCE_HEADER_PARAMS *pSHParams,
2557    H264_CROP_PARAMS *psCrop,
2558    H264_SCALING_MATRIX_PARAMS * psScalingMatrix)
2559{
2560    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
2561    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
2562
2563    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2564
2565    // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
2566    // Byte aligned (bit 32)
2567    tng__write_upto8bits_elements(pMTX_Header,
2568                                  aui32ElementPointers, (0 << 7) |                                                        // forbidden_zero_bit=0
2569                                  (0x3 << 5) |                                                                            // nal_ref_idc=01 (may be 11)
2570                                  (15),                                                                                           // nal_unit_type=15
2571                                  8);
2572
2573    // Byte aligned (bit 40)
2574    // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
2575    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 118, 8);
2576
2577    // Byte aligned (bit 48)
2578    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (0 << 7) |     // constrain_set0_flag = 1 for MP + BP constraints
2579                                  (0 << 6) |                                                  // constrain_set1_flag  = 1 for MP + BP constraints
2580                                  (0 << 5) |                                                                                              // constrain_set2_flag = always 0 in BP/MP
2581                                  (0 << 4),                                                           // constrain_set3_flag = 1 for level 1b, 0 for others
2582                                  // reserved_zero_4bits = 0
2583                                  8);
2584
2585    // Byte aligned (bit 56)
2586    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);                  // level_idc (8 bits) = 11 for 1b, 10xlevel for others
2587
2588    tng__generate_ue(pMTX_Header, aui32ElementPointers, MVC_SPS_ID);                // seq_parameter_Set_id = 1 FOR subset-SPS
2589    tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // chroma_format_idc = 1
2590    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_luma_minus8 = 0
2591    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_chroma_minus8 = 0
2592    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->bIsLossless ? 1 : 0, 1); // qpprime_y_zero_transform_bypass_flag = 0
2593
2594    if (pSHParams->bUseDefaultScalingList || pSHParams->seq_scaling_matrix_present_flag) {
2595        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);         // seq_scaling_matrix_present_flag
2596        if (!pSHParams->bUseDefaultScalingList) {
2597#ifdef _FIXME_
2598            H264_WriteBits_ScalingLists(pMTX_Header, aui32ElementPointers, psScalingMatrix, IMG_TRUE);
2599#endif
2600            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
2601        } else {
2602            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);         // seq_scaling_list_present_flag[i] = 0; 0 < i < 8
2603        }
2604    } else {
2605        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // seq_scaling_matrix_present_flag
2606    }
2607
2608    tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // log2_max_frame_num_minus4 = 1
2609    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // pic_order_cnt_type = 0
2610    tng__generate_ue(pMTX_Header, aui32ElementPointers, 2);         // log2_max_pic_order_cnt_Isb_minus4 = 2
2611
2612    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames); //num_ref_frames ue(2), typically 2
2613    // Bytes aligned (bit 72)
2614    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2615                                  (pSHParams->gaps_in_frame_num_value), // gaps_in_frame_num_value_allowed_Flag   - (1 bit)
2616                                  1);
2617
2618    ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2619    ///**** ELEMENT BITCOUNT: xx
2620    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucWidth_in_mbs_minus1);                          //pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row)
2621    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->ucHeight_in_maps_units_minus1);          //pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column)
2622    // We don't know the alignment at this point, so will have to use bit writing functions
2623
2624    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->ucFrame_mbs_only_flag, 1); // frame_mb_only_flag 1=frame encoding, 0=field encoding
2625
2626    if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
2627        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
2628
2629    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // direct_8x8_inference_flag=1 in Topaz
2630
2631    if (psCrop->bClip) {
2632        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
2633        tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16LeftCropOffset);
2634        tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16RightCropOffset);
2635        tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16TopCropOffset);
2636        tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16BottomCropOffset);
2637
2638    } else {
2639        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
2640    }
2641
2642    ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
2643    ///**** ELEMENT BITCOUNT: xx
2644    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2645                                  (pSHParams->VUI_Params_Present),                                        // vui_parameters_present_flag (VUI only in 1st sequence of stream)
2646                                  1);
2647    if (pSHParams->VUI_Params_Present > 0)
2648        tng__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
2649
2650
2651    {
2652        int viewIdx = 0;
2653        int numViews = MAX_MVC_VIEWS;
2654        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //bit_equal_to_one
2655
2656        // sequence parameter set MVC extension
2657        tng__generate_ue(pMTX_Header, aui32ElementPointers, (numViews - 1));     //num_views_minus1
2658        for (viewIdx = 0; viewIdx < numViews; viewIdx++) {
2659            tng__generate_ue(pMTX_Header, aui32ElementPointers, viewIdx);
2660        }
2661
2662        // anchor references
2663        for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
2664            //tng__generate_ue( pMTX_Header, aui32ElementPointers, 0);     // num_anchor_refs_l0  = 0
2665            tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_anchor_refs_l0  = 1; view-1 refers to view-0
2666            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // anchor_ref_l0 = 0
2667
2668            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_anchor_refs_l1  = 0
2669        }
2670
2671        // non-anchor references
2672        for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
2673            tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_non_anchor_refs_l0  = 0
2674            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // non_anchor_refs_l0  = 0
2675
2676            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_non_anchor_refs_l1  = 0
2677        }
2678
2679        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_level_values_signaled_minus1  = 0
2680
2681        //for(levelIdx=0; levelIdx<= 0; levelIdx++)
2682        {
2683            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (pSHParams->ucLevel == SH_LEVEL_1B) ? 11 : (IMG_UINT8)pSHParams->ucLevel, 8);          // level_idc (8 bits) = 11 for 1b, 10xlevel for others
2684            tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_applicable_ops_minus1  = 0
2685            {
2686                tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 3); // applicable_ops_temporal_id  = 0
2687                tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_target_views_minus1  = 0
2688                {
2689                    tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);              // applicable_op_target_view_id  = 0
2690                }
2691                tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_views_minus1  = 0
2692            }
2693        }
2694
2695        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2696                                      0,                    // mvc_vui_parameters_present_flag =0
2697                                      1);
2698
2699        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
2700                                      0,                    // additional_extension2_flag =0
2701                                      1);
2702    }
2703
2704
2705    // Finally we need to align to the next byte
2706    // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
2707    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
2708}
2709
2710
2711/*
2712******************************************************************************
2713 @Function              H264_PrepareMvcSequenceHeader
2714 @details
2715 Prepare an H264 SPS in a form for the MTX to encode into a bitstream.
2716 @param    pMTX_Header       : pointer to header structure to populate
2717 @param    uiPicWidthInMbs   : picture width in MBs
2718 @param    uiPicHeightInMbs  : picture height in MBs
2719 @param    bVuiParamsPresent : IMG_TRUE if VUI paramters present
2720 @param    psParams          : VUI parameters
2721 @param    psCrop                         : Pointer to crop parameter structure
2722 @param   psSHParams              : Pointer to sequence header params structure
2723 @return   None
2724******************************************************************************/
2725void tng__H264ES_prepare_mvc_sequence_header(
2726    void *pHeaderMemory,
2727    H264_CROP_PARAMS *psCropParams,
2728    IMG_UINT16 ui16PictureWidth,
2729    IMG_UINT16 ui16PictureHeight,
2730    IMG_UINT32 ui32CustomQuantMask,
2731    IMG_UINT8 ui8ProfileIdc,
2732    IMG_UINT8 ui8LevelIdc,
2733    IMG_UINT8 ui8FieldCount,
2734    IMG_UINT8 ui8MaxNumRefFrames,
2735    IMG_BOOL  bPpsScaling,
2736    IMG_BOOL  bUseDefaultScalingList,
2737    IMG_BOOL  bEnableLossless,
2738    IMG_BOOL  bASO)
2739{
2740    H264_SEQUENCE_HEADER_PARAMS sSHParams;
2741    MTX_HEADER_PARAMS * pMTX_Header;
2742    MTX_HEADER_ELEMENT *This_Element;
2743    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2744    pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2745
2746#if HEADERS_VERBOSE_OUTPUT
2747    drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
2748    drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
2749    drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
2750#endif
2751
2752    // Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2753    // Essential we initialise our header structures before building
2754    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2755    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2756    aui32ElementPointers[0] = This_Element;
2757
2758    memset(&sSHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
2759
2760    sSHParams.ucProfile = ui8ProfileIdc - 5;
2761    sSHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
2762    sSHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
2763    sSHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
2764    sSHParams.gaps_in_frame_num_value = IMG_FALSE;
2765    sSHParams.VUI_Params_Present = IMG_FALSE;
2766    sSHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
2767    sSHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
2768    sSHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
2769    sSHParams.max_num_ref_frames = ui8MaxNumRefFrames;
2770    sSHParams.bIsLossless = bEnableLossless;
2771    sSHParams.log2_max_pic_order_cnt = 6;
2772#ifdef _TOPAZHP_PDUMP_
2773    tng_trace_seq_header_params(&sSHParams);
2774#endif
2775    tng__H264ES_writebits_mvc_sequence_header(pMTX_Header, aui32ElementPointers, &sSHParams, psCropParams, NULL);
2776    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
2777    return ;
2778}
2779
2780void tng__H264ES_prepare_picture_header(
2781    void *pHeaderMemory,
2782    IMG_BOOL    bCabacEnabled,
2783    IMG_BOOL    b_8x8transform,
2784    IMG_BOOL    bIntraConstrained,
2785    IMG_INT8    i8CQPOffset,
2786    IMG_BOOL    bWeightedPrediction,
2787    IMG_UINT8   ui8WeightedBiPred,
2788    IMG_BOOL    bMvcPPS,
2789    IMG_BOOL    bScalingMatrix,
2790    IMG_BOOL    bScalingLists)
2791{
2792    MTX_HEADER_PARAMS *pMTX_Header;
2793    H264_PICTURE_HEADER_PARAMS sPHParams;
2794
2795    /* Route output elements to memory provided */
2796    pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2797    /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
2798     * Essential we initialise our header structures before building
2799     */
2800    MTX_HEADER_ELEMENT *This_Element;
2801    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2802    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
2803    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
2804    aui32ElementPointers[0] = This_Element;
2805
2806    memset(&sPHParams, 0, sizeof(H264_PICTURE_HEADER_PARAMS));
2807
2808    sPHParams.pic_parameter_set_id = bMvcPPS ? MVC_PPS_ID : 0;
2809    sPHParams.seq_parameter_set_id = bMvcPPS ? MVC_SPS_ID : 0;
2810    sPHParams.entropy_coding_mode_flag = bCabacEnabled ? 1 : 0;
2811    sPHParams.weighted_pred_flag = bWeightedPrediction;
2812    sPHParams.weighted_bipred_idc = ui8WeightedBiPred;
2813    sPHParams.chroma_qp_index_offset = i8CQPOffset;
2814    sPHParams.constrained_intra_pred_flag = bIntraConstrained ? 1 : 0;
2815    sPHParams.transform_8x8_mode_flag = b_8x8transform ? 1 : 0;
2816    sPHParams.pic_scaling_matrix_present_flag = bScalingMatrix ? 1 : 0;
2817    sPHParams.bUseDefaultScalingList = !bScalingLists;
2818    sPHParams.second_chroma_qp_index_offset = i8CQPOffset;
2819#ifdef _TOPAZHP_PDUMP_
2820    tng_trace_pic_header_params(&sPHParams);
2821#endif
2822    tng__H264ES_writebits_picture_header(pMTX_Header, aui32ElementPointers, &sPHParams, NULL);
2823    /* Has been used as an index, so need to add 1 for a valid element count */
2824    pMTX_Header->ui32Elements++;
2825    return ;
2826}
2827
2828void tng__H264_prepare_slice_header(
2829    IMG_UINT32 *pHeaderMemory,
2830    IMG_BOOL        bIntraSlice,
2831    IMG_BOOL        bInterBSlice,
2832    IMG_BOOL        bMultiRef,
2833    IMG_UINT8       ui8DisableDeblockingFilterIDC,
2834    IMG_UINT32      ui32DisplayFrameNumber,
2835    IMG_UINT32      ui32FrameNumId,
2836    IMG_UINT32      uiFirst_MB_Address,
2837    IMG_UINT32      uiMBSkipRun,
2838    IMG_BOOL        bCabacEnabled,
2839    IMG_BOOL        bIsInterlaced,
2840    IMG_UINT8       ui8FieldNum,
2841    WEIGHTED_PREDICTION_VALUES *pWeightedSetup,
2842    IMG_BOOL        bIsLongTermRef
2843)
2844{
2845    H264_SLICE_HEADER_PARAMS SlHParams;
2846    MTX_HEADER_PARAMS *pMTX_Header;
2847    /* Route output elements to memory provided */
2848    pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
2849
2850    memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
2851
2852
2853    SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
2854    /* pcb -        I think that this is more correct now*/
2855    SlHParams.SliceFrame_Type = bIntraSlice ? (((ui32FrameNumId % (1 << 5)) == 0) ?
2856                                SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
2857    /*
2858    if (bIntraSlice) {
2859        if ((ui32FrameNumId%(1<<5))==0)
2860            SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
2861        else
2862            SlHParams.SliceFrame_Type = SLHP_I_SLICEFRAME_TYPE;
2863    } else {
2864        if (bInterBSlice)
2865            SlHParams.SliceFrame_Type = SLHP_B_SLICEFRAME_TYPE;
2866        else
2867            SlHParams.SliceFrame_Type = SLHP_P_SLICEFRAME_TYPE;
2868    }
2869    */
2870    SlHParams.Frame_Num_DO   = (IMG_UINT8) ui32FrameNumId % (1 << 5);
2871    SlHParams.Idr_Pic_Id     = (IMG_UINT8)(ui32DisplayFrameNumber & 1);
2872    SlHParams.Picture_Num_DO = (IMG_UINT8)((ui32DisplayFrameNumber % (1 << 5)) * 2);
2873
2874    SlHParams.First_MB_Address =  uiFirst_MB_Address;
2875    SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
2876    SlHParams.bPiCInterlace = bIsInterlaced;
2877    SlHParams.bFieldType    = ui8FieldNum;
2878    SlHParams.iDebAlphaOffsetDiv2   = 0;
2879    SlHParams.iDebBetaOffsetDiv2    = 0;
2880
2881    if (bMultiRef)
2882        SlHParams.num_ref_idx_l0_active_minus1 = 1;
2883    else
2884        SlHParams.num_ref_idx_l0_active_minus1 = 0;
2885
2886    SlHParams.weighted_pred_flag            = pWeightedSetup ? pWeightedSetup->weighted_pred_flag             : 0;
2887    SlHParams.weighted_bipred_idc   = pWeightedSetup ? pWeightedSetup->weighted_bipred_idc            : 0;
2888    SlHParams.luma_log2_weight_denom        = pWeightedSetup ? pWeightedSetup->luma_log2_weight_denom         : 0;
2889    SlHParams.chroma_log2_weight_denom      = pWeightedSetup ? pWeightedSetup->chroma_log2_weight_denom : 0;
2890    SlHParams.luma_weight_l0_flag[0]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][0]                      : 0;
2891    SlHParams.luma_weight_l0[0]             = pWeightedSetup ? pWeightedSetup->weight[0][0]                   : 0;
2892    SlHParams.luma_offset_l0[0]             = pWeightedSetup ? pWeightedSetup->offset[0][0]                   : 0;
2893    SlHParams.chroma_weight_l0_flag[0]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][0]                      : 0;
2894    SlHParams.chromaB_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[1][0]                   : 0;
2895    SlHParams.chromaB_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[1][0]                   : 0;
2896    SlHParams.chromaR_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[2][0]                   : 0;
2897    SlHParams.chromaR_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[2][0]                   : 0;
2898    SlHParams.luma_weight_l0_flag[1]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][1]                      : 0;
2899    SlHParams.luma_weight_l0[1]             = pWeightedSetup ? pWeightedSetup->weight[0][1]                   : 0;
2900    SlHParams.luma_offset_l0[1]             = pWeightedSetup ? pWeightedSetup->offset[0][1]                   : 0;
2901    SlHParams.chroma_weight_l0_flag[1]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][1]                      : 0;
2902    SlHParams.chromaB_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[1][1]                   : 0;
2903    SlHParams.chromaB_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[1][1]                   : 0;
2904    SlHParams.chromaR_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[2][1]                   : 0;
2905    SlHParams.chromaR_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[2][1]                   : 0;
2906
2907    SlHParams.bIsLongTermRef = bIsLongTermRef;
2908    tng__H264_getelements_slice_header(pMTX_Header, &SlHParams, bCabacEnabled);
2909
2910    /*
2911        {
2912            IMG_UINT32      *pMTX_Header_Mem = (IMG_UINT32 *)mtx_hdr;
2913            // rhk: first insert normal header.
2914            tng__H264_getelements_slice_header(mtx_hdr, &SlHParams, bCabacEnabled, uiIdrPicId);
2915
2916            // put a marker to indicate that this is a complex header
2917            // note that first "int" in the buffer is used for number of elements
2918            // which is not going to be more than 255
2919            *pMTX_Header_Mem |= 0x100;
2920
2921            // rhk: insert skipped frame header at an offset of 128 bytes
2922            pMTX_Header_Mem += (HEADER_SIZE >> 3);  // get a pointer to the second half of memory
2923            mtx_hdr = (MTX_HEADER_PARAMS *)pMTX_Header_Mem;
2924            tng__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun, bCabacEnabled);
2925        }
2926    */
2927}
2928
2929void tng__MPEG4_prepare_sequence_header(
2930    void *pHeaderMemory,
2931    IMG_BOOL bBFrame,
2932    MPEG4_PROFILE_TYPE sProfile,
2933    IMG_UINT8 Profile_and_level_indication,
2934    FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
2935    IMG_UINT32 Picture_Width_Pixels,
2936    IMG_UINT32 Picture_Height_Pixels,
2937    VBVPARAMS * psVBVParams,
2938    IMG_UINT32 VopTimeResolution)
2939{
2940    MTX_HEADER_PARAMS *mtx_hdr;
2941
2942    /* Route output elements to memory provided */
2943    mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
2944    /* Builds a single MPEG4 video sequence header from the given parameters */
2945
2946    /* Essential we initialise our header structures before building */
2947    MTX_HEADER_ELEMENT *This_Element;
2948    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2949    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2950    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2951    aui32ElementPointers[0] = This_Element;
2952
2953    tng__MPEG4_writebits_sequence_header(mtx_hdr,
2954        				 aui32ElementPointers,
2955        				 bBFrame,
2956					 sProfile,
2957       				 	 Profile_and_level_indication,
2958       				 	 sFixed_vop_time_increment,
2959        				 Picture_Width_Pixels,
2960        				 Picture_Height_Pixels,
2961        				 psVBVParams,
2962					 VopTimeResolution);
2963
2964    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2965
2966}
2967
2968void tng__MPEG4_prepare_vop_header(
2969    IMG_UINT32 *pHeaderMem,
2970    IMG_BOOL bIsVOP_coded,
2971    IMG_UINT32 VOP_time_increment,
2972    IMG_UINT8 sSearch_range,
2973    IMG_UINT8 eVop_Coding_Type,
2974    IMG_UINT32 VopTimeResolution)
2975{
2976    MTX_HEADER_PARAMS *mtx_hdr;
2977
2978    mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
2979
2980    /* Builds a single MPEG4 VOP (picture) header from the given parameters */
2981    /* Essential we initialise our header structures before building */
2982    MTX_HEADER_ELEMENT *This_Element;
2983    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
2984    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
2985    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
2986    aui32ElementPointers[0] = This_Element;
2987
2988    /* Frame QScale no longer written here as it is inserted by MTX later
2989     * (add as parameter to MTX_Send_Elements_To_VLC)
2990     */
2991    tng__MPEG4_writebits_VOP_header(
2992        mtx_hdr, aui32ElementPointers, bIsVOP_coded,
2993        VOP_time_increment,
2994        sSearch_range,
2995        eVop_Coding_Type,
2996        VopTimeResolution);
2997
2998    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
2999
3000}
3001
3002void tng__H263_prepare_sequence_header(
3003    IMG_UINT32 *pHeaderMem,
3004    IMG_UINT8 Profile_and_level_indication)
3005{
3006    MTX_HEADER_PARAMS *mtx_hdr;
3007
3008    mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3009
3010    /* Builds a single H263 video sequence header from the given parameters */
3011
3012    /* Essential we initialise our header structures before building */
3013    MTX_HEADER_ELEMENT *This_Element;
3014    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3015    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3016    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3017    aui32ElementPointers[0] = This_Element;
3018
3019    H263_writebits_VideoSequenceHeader(mtx_hdr, aui32ElementPointers, Profile_and_level_indication);
3020
3021    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
3022
3023}
3024
3025void tng__H263_prepare_picture_header(
3026    IMG_UINT32 *pHeaderMem,
3027    IMG_UINT8 Temporal_Ref,
3028    H263_PICTURE_CODING_TYPE PictureCodingType,
3029    H263_SOURCE_FORMAT_TYPE SourceFormatType,
3030    IMG_UINT8 FrameRate,
3031    IMG_UINT16 PictureWidth,
3032    IMG_UINT16 PictureHeigth)
3033{
3034    MTX_HEADER_PARAMS *mtx_hdr;
3035
3036    mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3037
3038    /* Essential we initialise our header structures before building */
3039    MTX_HEADER_ELEMENT *This_Element;
3040    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3041    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3042    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3043    aui32ElementPointers[0] = This_Element;
3044
3045    H263_writebits_VideoPictureHeader(
3046        mtx_hdr, aui32ElementPointers,
3047        Temporal_Ref,
3048        PictureCodingType,
3049        SourceFormatType,
3050        FrameRate,
3051        PictureWidth,
3052        PictureHeigth);
3053
3054    mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
3055}
3056
3057void tng__H263_prepare_GOBslice_header(
3058    IMG_UINT32 *pHeaderMem,
3059    IMG_UINT8 GOBNumber,
3060    IMG_UINT8 GOBFrameId)
3061{
3062    MTX_HEADER_PARAMS *mtx_hdr;
3063
3064    mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
3065
3066    /* Essential we initialise our header structures before building */
3067    MTX_HEADER_ELEMENT *This_Element;
3068    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3069    mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
3070    This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
3071    aui32ElementPointers[0] = This_Element;
3072
3073    H263_writebits_GOBSliceHeader(mtx_hdr, aui32ElementPointers, GOBNumber, GOBFrameId);
3074
3075    mtx_hdr->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3076
3077    /* silent the warning message */
3078    (void)Show_Bits;
3079    (void)Show_Elements;
3080    /*
3081    (void)tng__H264_writebits_SEI_rbspheader;
3082    (void)tng__H264_getelements_skip_B_slice;
3083    (void)tng__H264_getelements_backward_zero_B_slice;
3084    (void)tng__H264_getelements_rbsp_ATE_only;
3085    (void)tng_MPEG4_getelements_video_packet_header;
3086    */
3087}
3088
3089void tng__H264ES_notforsims_writebits_extension_sliceheader(
3090    MTX_HEADER_PARAMS *pMTX_Header,
3091    MTX_HEADER_ELEMENT **aui32ElementPointers,
3092    H264_SLICE_HEADER_PARAMS *pSlHParams,
3093    IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
3094{
3095    bStartNextRawDataElement = IMG_FALSE;
3096
3097    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
3098
3099    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
3100
3101    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3102    ///**** ELEMENT BITCOUNT: 8
3103
3104    // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
3105    //(3 bytes when slice is first in a picture without sequence/picture_header before picture
3106    // Byte aligned (bit 32 or 24)
3107    // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
3108    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
3109
3110    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
3111    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3112
3113    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 20, 5);    // nal_unit_type for coded_slice_extension
3114
3115
3116    //if(nal_unit_type == 14 || nal_unit_type == 20)
3117    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // SVC extension flag
3118
3119    // nal_unit_header_mvc_extension()
3120    {
3121        if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
3122            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
3123        } else if ((pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) && bIsIDR) {
3124            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
3125        } else {
3126            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // non_idr_flag flag
3127        }
3128
3129        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 6);   // priority_id flag
3130        tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,    1, 10);   // view_id = hardcoded to 1 for dependent view
3131
3132        //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 3);   // temporal_id flag
3133        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_ID); // temporal_id flag
3134        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ANCHOR_PIC_FLAG); // anchor_pic_flag
3135
3136        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3137
3138        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // interview flag is always FALSE for dependent frames
3139
3140        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // reserved one bit
3141    }
3142
3143    // slice header
3144    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
3145
3146    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3147
3148    ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3149    /* The following is slice parameter set in BP/MP */
3150    //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
3151    tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
3152    // kab: //not clean change from IDR to intra, IDR should have separate flag
3153
3154    tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);  // pic_parameter_set_id = 1 for dependent view
3155
3156    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
3157    bStartNextRawDataElement = IMG_TRUE;
3158
3159    if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
3160        //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3161
3162        // interlaced encoding
3163        if (pSlHParams->bPiCInterlace) {
3164            CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3165            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
3166            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3167            //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3168            bStartNextRawDataElement = IMG_TRUE;
3169        }
3170    }
3171
3172    if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
3173        CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3174        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // idr_pic_id ue(v) = 0 (1b) in Topaz
3175    }
3176
3177    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
3178    bStartNextRawDataElement = IMG_TRUE;
3179
3180    if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3181        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
3182
3183    if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
3184        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NUM_REF_IDX_ACTIVE);
3185        bStartNextRawDataElement = IMG_TRUE;
3186    } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
3187        CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3188        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);             // num_ref_idx_active_override_flag (1 bit) = 0 in Topaz
3189    }
3190
3191    // reference picture list modification
3192    if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
3193        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3194        //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3195        bStartNextRawDataElement = IMG_TRUE;
3196    }
3197
3198    if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)        {
3199        CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3200        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // ref_pic_list_ordering_flag_l1 (1 bit) = 0, no reference picture ordering in Topaz
3201    }
3202
3203    // WEIGHTED PREDICTION
3204    /*      tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
3205        bStartNextRawDataElement = IMG_TRUE;*/
3206
3207    if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
3208        CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3209        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // no_output_of_prior_pics_flag (1 bit) = 0
3210        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // long_term_reference_flag (1 bit) = 0
3211    } else {
3212        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
3213        //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3214        bStartNextRawDataElement = IMG_TRUE;
3215    }
3216
3217    if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
3218                          (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
3219        CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
3220        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
3221    }
3222    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
3223    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3224
3225    ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3226    ///**** ELEMENT BITCOUNT: 11
3227    // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
3228    //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
3229    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
3230    if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
3231        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
3232        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
3233    }
3234    //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
3235    // no byte alignment at end of slice headers
3236}
3237
3238
3239/*****************************************************************************
3240******************************************************************************/
3241static void tng__H264ES_notforsims_writebits_slice_header(
3242    MTX_HEADER_PARAMS *pMTX_Header,
3243    MTX_HEADER_ELEMENT **aui32ElementPointers,
3244    H264_SLICE_HEADER_PARAMS *pSlHParams,
3245    IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
3246{
3247    bStartNextRawDataElement = IMG_FALSE;
3248    unsigned char* pdg = (unsigned char*)pMTX_Header;
3249
3250    if (pSlHParams->ui16MvcViewIdx == (IMG_UINT16)(NON_MVC_VIEW)) {
3251        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
3252    } else if (pSlHParams->ui16MvcViewIdx == MVC_BASE_VIEW_IDX) {
3253        tng__insert_prefix_nal_header(pMTX_Header, aui32ElementPointers,
3254                                      pSlHParams, bCabacEnabled);
3255        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_MIDHDR);
3256    } else {
3257        //Insert
3258        tng__H264ES_notforsims_writebits_extension_sliceheader(pMTX_Header, aui32ElementPointers,
3259                pSlHParams, bCabacEnabled, bIsIDR);
3260        return;
3261    }
3262
3263    tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, pSlHParams->ui8Start_Code_Prefix_Size_Bytes); //Can be 3 or 4 bytes - always 4 bytes in our implementations
3264
3265    ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3266    ///**** ELEMENT BITCOUNT: 8
3267
3268    // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
3269    //(3 bytes when slice is first in a picture without sequence/picture_header before picture
3270    // Byte aligned (bit 32 or 24)
3271    // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
3272
3273    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
3274
3275    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
3276    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3277
3278    tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),                   // nal_unit_tpye (5 bits) = I-frame IDR, and 1 for  rest
3279                                  5);
3280
3281    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
3282    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3283
3284
3285    ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3286    /* The following is slice parameter set in BP/MP */
3287    //tng__generate_ue(pMTX_Header, aui32ElementPointers, (IMG_UINT32) pSlHParams->First_MB_Address);                               //first_mb_in_slice = First MB address in slice: ue(Range 0 -  1619)
3288    tng__generate_ue(pMTX_Header, aui32ElementPointers, (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
3289    // kab: //not clean change from IDR to intra, IDR should have separate flag
3290    if (pSlHParams->ui16MvcViewIdx != (IMG_UINT16)(NON_MVC_VIEW))
3291        tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->ui16MvcViewIdx);  // pic_parameter_set_id = 0
3292    else
3293        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);  // pic_parameter_set_id = 0
3294
3295    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
3296
3297    if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
3298        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3299        // interlaced encoding
3300        if (pSlHParams->bPiCInterlace) {
3301            tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
3302            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
3303            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3304        }
3305
3306        if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
3307            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_IDR_PIC_ID);       // idr_pic_id ue(v)
3308    }
3309
3310    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
3311
3312    if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3313        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
3314
3315    if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
3316        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NUM_REF_IDX_ACTIVE); // Insert token to tell MTX to insert override for number of active references
3317    } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
3318        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3319        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // num_ref_idx_active_override_flag (1 bit) = 0
3320    }
3321
3322    if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE &&
3323        pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
3324        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert reference list 0 reordering
3325        if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
3326            tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L1); // Insert token to tell MTX to insert reference list 1 reordering
3327    }
3328
3329
3330    // WEIGHTED PREDICTION
3331    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
3332    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3333
3334    if (pSlHParams->bReferencePicture && pSlHParams->bIsLongTermRef) {
3335        tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
3336
3337        // Clear any existing long-term reference
3338        tng__generate_ue(pMTX_Header, aui32ElementPointers, 5);                                 // memory_management_control_operation
3339
3340        // Allow a single long-term reference
3341        tng__generate_ue(pMTX_Header, aui32ElementPointers, 4);                                 // memory_management_control_operation
3342        tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);                                 // max_long_term_frame_idx_plus1
3343
3344        // Set current picture as the long-term reference
3345        tng__generate_ue(pMTX_Header, aui32ElementPointers, 6);                                 // memory_management_control_operation
3346        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // long_term_frame_idx
3347
3348        // End
3349        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // memory_management_control_operation
3350    } else {
3351        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
3352        tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3353    }
3354
3355    if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
3356                          (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
3357        tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
3358    }
3359    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
3360    tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
3361
3362    ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
3363    ///**** ELEMENT BITCOUNT: 11
3364    // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
3365    //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
3366    tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
3367
3368    if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
3369        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
3370        tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
3371    }
3372    //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
3373    // no byte alignment at end of slice headers
3374}
3375
3376/******************************************************************************
3377 @Function              H264_NOTFORSIMS_PrepareSliceHeader
3378 @details
3379 Sim guys, DO NOT EVER USE THIS FUNCTION!
3380 Prepare an H264 slice header in a form for the MTX to encode into a
3381 bitstream.
3382 @param    pMTX_Header        : pointer to header structure to populate
3383 @param    bIntraSlice        : IMG_TRUE if this is an IDR or I slice
3384 @param    bInterBSlice        : IMG_TRUE if this is a B Frame slice
3385 @param    ui8DisableDeblockingFilterIDC : syntax element
3386 @param    ui32FrameNumId      : syntax element (used for references)
3387 @param    uiFirst_MB_Address : first_mb_in_slice syntax element
3388 @param    uiMBSkipRun        : number of MBs to skip
3389 @param    bCabacEnabled      : IMG_TRUE to use CABAC
3390 @param    bIsInterlaced      : IMG_TRUE for interlaced slices
3391 @param    bIsIDR             : IMG_TRUE if this is an IDR slice
3392 @param    bIsLongTermRef     : IMG_TRUE if the frame is to be used as a long-term reference
3393 @return   None
3394******************************************************************************/
3395
3396void tng__H264ES_notforsims_prepare_sliceheader(
3397    IMG_UINT8      *slice_mem_p,
3398    IMG_UINT32      ui32SliceType,
3399    IMG_UINT8       ui8DisableDeblockingFilterIDC,
3400    IMG_UINT32      uiFirst_MB_Address,
3401    IMG_UINT32      uiMBSkipRun,
3402    IMG_BOOL        bCabacEnabled,
3403    IMG_BOOL        bIsInterlaced,
3404    IMG_UINT16      ui16MvcViewIdx,
3405    IMG_BOOL        bIsLongTermRef
3406)
3407{
3408    SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3409    MTX_HEADER_PARAMS *pMTX_Header = (MTX_HEADER_PARAMS *) &(slice_temp_p->sSliceHdrTmpl);
3410    H264_SLICE_HEADER_PARAMS SlHParams;
3411    MTX_HEADER_ELEMENT *This_Element;
3412    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3413    IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
3414    IMG_BOOL bIntraSlice = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
3415    IMG_BOOL bInterBSlice = (eSliceType == IMG_FRAME_INTER_B);
3416    IMG_BOOL bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
3417
3418    memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
3419
3420    SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
3421    /* pcb -  I think that this is more correct now  -- This should also work for IDR-P frames which will be marked as SLHP_P_SLICEFRAME_TYPE */
3422    SlHParams.SliceFrame_Type = bIntraSlice ? (bIsIDR ? SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
3423
3424    SlHParams.First_MB_Address = uiFirst_MB_Address;
3425    SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
3426    SlHParams.bPiCInterlace = bIsInterlaced;
3427    SlHParams.iDebAlphaOffsetDiv2 = 0;
3428    SlHParams.iDebBetaOffsetDiv2  = 0;
3429    // setup the new flags used for B frame as reference
3430    SlHParams.bReferencePicture = bInterBSlice ? 0 : 1;
3431    SlHParams.ui16MvcViewIdx = ui16MvcViewIdx;
3432    SlHParams.bIsLongTermRef = bIsLongTermRef;
3433    SlHParams.log2_max_pic_order_cnt = 2;
3434    SlHParams.uLongTermRefNum = 0;
3435    SlHParams.bRefIsLongTermRef[0] = 0;
3436    SlHParams.uRefLongTermRefNum[0] = 0;
3437    SlHParams.bRefIsLongTermRef[1] = 0;
3438    SlHParams.uRefLongTermRefNum[1] = 0;
3439    // Builds a single slice header from the given parameters (mid frame)
3440    // Essential we initialise our header structures before building
3441//    memset(pMTX_Header, 0, 128);
3442    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3443    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3444    aui32ElementPointers[0] = This_Element;
3445#ifdef _TOPAZHP_PDUMP_
3446    tng_trace_slice_header_params(&SlHParams);
3447#endif
3448    tng__H264ES_notforsims_writebits_slice_header(pMTX_Header, aui32ElementPointers, &SlHParams, bCabacEnabled, bIsIDR);
3449    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3450}
3451
3452/**************************************************************************************************
3453* Function:             H263_NOTFORSIMS_PrepareGOBSliceHeader
3454* Description:  Generates the slice params template
3455*
3456***************************************************************************************************/
3457
3458void tng__H263ES_notforsims_prepare_gobsliceheader(
3459    IMG_UINT8       *slice_mem_p)
3460{
3461    // Essential we initialise our header structures before building
3462    SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3463    MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
3464    MTX_HEADER_ELEMENT *This_Element;
3465    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3466    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3467    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3468    aui32ElementPointers[0] = This_Element;
3469    H263_NOTFORSIMS_WriteBits_GOBSliceHeader(pMTX_Header, aui32ElementPointers);
3470    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3471}
3472
3473/**************************************************************************************************
3474* Function:             MPEG2_PrepareSliceHeader
3475* Description:  Generates the slice params template
3476*
3477***************************************************************************************************/
3478void tng__MPEG2_prepare_sliceheader(
3479    IMG_UINT8               *slice_mem_p)
3480{
3481    // Essential we initialise our header structures before building
3482    SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
3483    MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
3484    MTX_HEADER_ELEMENT *This_Element;
3485    MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
3486    pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
3487    This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
3488    aui32ElementPointers[0] = This_Element;
3489//      MPEG2_WriteBits_SliceHeader(pMTX_Header, aui32ElementPointers);
3490    pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
3491}
3492
3493
3494