Home | History | Annotate | Download | only in src
      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 (at) intel.com>
     27  *    Zeng Li <zeng.li (at) intel.com>
     28  *    Edward Lin <edward.lin (at) 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
     52 static void Show_Bits(
     53     IMG_UINT8 __maybe_unused * ucBitStream,
     54     IMG_UINT32 __maybe_unused ByteStartBit,
     55     IMG_UINT32 __maybe_unused 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 
     86 static void Show_Elements(
     87     MTX_HEADER_PARAMS __maybe_unused * mtx_hdr,
     88     MTX_HEADER_ELEMENT __maybe_unused ** 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 
    166 static 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  */
    184 static 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 
    245 static 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 
    272 static 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 
    302 static 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 
    318 static 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  */
    362 static 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
    380 static IMG_BOOL bStartNextRawDataElement = IMG_FALSE;
    381 static 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 
    391 static void tng__insert_prefix_nal_header(MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
    392         H264_SLICE_HEADER_PARAMS *pSlHParams, IMG_BOOL __maybe_unused 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 
    437 static 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 
    481 static 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 __maybe_unused * 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                                   (3 << 5) |    // nal_ref_idc (2 bits) = 0x3
    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 
    571 static 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 
    631 static 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 __maybe_unused 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=0x3
    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                 (0 << 6) |    // constraint_set1_flag = 0 for MP constraints
    661                 (0 << 5) |    // constraint_set2_flag = 0 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                 (0 << 5) | // constraint_set2_flag = 0 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 
    783 static 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 
    970 static 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
    998 static 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 
   1033 static 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 
   1055 void 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 __maybe_unused 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 
   1222 void 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  * ***************************************************************************************************/
   1281 void 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  * ***************************************************************************************************/
   1313 void 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 
   1338 void 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 
   1360 static 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 
   1378 static 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 __maybe_unused 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 */
   1570 static 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 doesnt 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  */
   1666 static 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 
   1703 static 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 __maybe_unused 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 
   1839 static 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
   1934 static 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 
   1961 //#define SEI_NOT_USE_TOKEN_ALIGN
   1962 
   1963 static void tng__H264ES_writebits_SEI_buffering_period_header(
   1964     MTX_HEADER_PARAMS *pMTX_Header,
   1965     MTX_HEADER_ELEMENT **aui32ElementPointers,
   1966     IMG_UINT8 ui8NalHrdBpPresentFlag,
   1967     IMG_UINT8 ui8nal_cpb_cnt_minus1,
   1968     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
   1969     IMG_UINT32 __maybe_unused ui32nal_initial_cpb_removal_delay,
   1970     IMG_UINT32 __maybe_unused ui32nal_initial_cpb_removal_delay_offset,
   1971     IMG_UINT8 ui8VclHrdBpPresentFlag,
   1972     IMG_UINT8 ui8vcl_cpb_cnt_minus1,
   1973     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
   1974     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
   1975 {
   1976     IMG_UINT8 ui8SchedSelIdx;
   1977     IMG_UINT8 ui8PayloadSizeBits;
   1978 #ifdef SEI_NOT_USE_TOKEN_ALIGN
   1979     IMG_UINT8 ui8Pad;
   1980 #endif
   1981 
   1982     // Essential we insert the element before we try to fill it!
   1983     tng__insert_element_token(pMTX_Header,
   1984         aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
   1985 
   1986     tng__H264_writebits_startcode_prefix_element(pMTX_Header,
   1987         aui32ElementPointers, 3); // 00 00 01 start code prefix
   1988 
   1989     tng__write_upto8bits_elements(pMTX_Header,
   1990         aui32ElementPointers, 6, 8); // nal_unit_type = 06 (SEI Message)
   1991 
   1992     tng__write_upto8bits_elements(pMTX_Header,
   1993         aui32ElementPointers, 0, 8); // SEI payload type (buffering period)
   1994 
   1995     ui8PayloadSizeBits = 1; // seq_parameter_set_id bitsize = 1
   1996     if (ui8NalHrdBpPresentFlag)
   1997         ui8PayloadSizeBits += ((ui8nal_cpb_cnt_minus1 + 1)
   1998                                * ui8nal_initial_cpb_removal_delay_length * 2);
   1999     if (ui8VclHrdBpPresentFlag)
   2000         ui8PayloadSizeBits += ((ui8vcl_cpb_cnt_minus1 + 1)
   2001                                * ui8nal_initial_cpb_removal_delay_length * 2);
   2002 
   2003     tng__write_upto8bits_elements(pMTX_Header,
   2004                                   aui32ElementPointers,
   2005                                   ((ui8PayloadSizeBits + 7) / 8),
   2006                                   8);
   2007     // SEI payload size = No of bytes required for SEI payload
   2008     // (including seq_parameter_set_id)
   2009 
   2010     //seq_parameter_set_id      ue(v) = 0 default? = 1 (binary)
   2011     //= sequence parameter set containing HRD attributes
   2012     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);
   2013 
   2014     if (ui8NalHrdBpPresentFlag) {
   2015         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8nal_cpb_cnt_minus1; ui8SchedSelIdx++) {
   2016             // ui32nal_initial_cpb_removal_delay = delay between time of arrival in CODED PICTURE BUFFER of coded data of this access
   2017             // unit and time of removal from CODED PICTURE BUFFER of the coded data of the same access unit.
   2018             // Delay is based on the time taken for a 90 kHz clock.
   2019             // Range >0 and < 90000 * (CPBsize / BitRate)
   2020             // For the 1st buffering period after HARDWARE REFERENCE DECODER initialisation.
   2021             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NAL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
   2022 
   2023             //tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers, ui32nal_initial_cpb_removal_delay, ui8nal_initial_cpb_removal_delay_length);
   2024             tng__insert_element_token(pMTX_Header,
   2025                                       aui32ElementPointers,
   2026                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY);
   2027 
   2028             // ui32nal_initial_cpb_removal_delay_offset = used for the SchedSelIdx-th CPB in combination with the cpb_removal_delay to
   2029             // specify the initial delivery time of coded access units to the CODED PICTURE BUFFER initial_cpb_removal_delay_offset
   2030             // Delay is based on the time taken for a 90 kHz clock.
   2031             // NOT USED BY DECODERS and is needed only for the delivery scheduler (HSS) specified in Annex C
   2032 
   2033             tng__insert_element_token(pMTX_Header,
   2034                                       aui32ElementPointers,
   2035                                       BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_OFFSET);
   2036         }
   2037     }
   2038     if (ui8VclHrdBpPresentFlag) {
   2039         for (ui8SchedSelIdx = 0; ui8SchedSelIdx <= ui8vcl_cpb_cnt_minus1; ui8SchedSelIdx++) {
   2040             tng__insert_element_token(pMTX_Header,
   2041                                       aui32ElementPointers,
   2042                                       ELEMENT_STARTCODE_RAWDATA);
   2043             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY); // Eventually use this if firmware value required
   2044             tng__write_upto32bits_elements(pMTX_Header,
   2045                                            aui32ElementPointers,
   2046                                            ui32vcl_initial_cpb_removal_delay,
   2047                                            ui8nal_initial_cpb_removal_delay_length);
   2048             // tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_VCL_INIT_CPB_REMOVAL_DELAY_CPB); // Eventually use this if firmware value required
   2049             tng__write_upto32bits_elements(pMTX_Header,
   2050                                            aui32ElementPointers,
   2051                                            ui32vcl_initial_cpb_removal_delay_offset,
   2052                                            ui8nal_initial_cpb_removal_delay_length);
   2053         }
   2054     }
   2055 
   2056     // Pad to end of byte
   2057 #ifdef SEI_NOT_USE_TOKEN_ALIGN
   2058     if (!ui8VclHrdBpPresentFlag)
   2059         tng__insert_element_token(pMTX_Header,
   2060                                   aui32ElementPointers,
   2061                                   ELEMENT_STARTCODE_RAWDATA);
   2062     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
   2063     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
   2064     if (ui8Pad > 0)
   2065         tng__write_upto8bits_elements(pMTX_Header,
   2066                                       aui32ElementPointers,
   2067                                       1 << (ui8Pad - 1),
   2068                                       ui8Pad); // SEI payload type (buffering period)
   2069 #else
   2070     tng__insert_element_token(pMTX_Header,
   2071                               aui32ElementPointers,
   2072                               ELEMENT_INSERTBYTEALIGN_H264);
   2073     // Tell MTX to insert the byte align field
   2074     tng__insert_element_token(pMTX_Header,
   2075                               aui32ElementPointers,
   2076                               ELEMENT_STARTCODE_RAWDATA);
   2077 #endif
   2078 
   2079     // Write terminator
   2080     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0x80, 8);
   2081 
   2082     return;
   2083 }
   2084 
   2085 //#define SEI_HOSTCALC_CPB_DPB
   2086 
   2087 static void tng__H264ES_writebits_SEI_picture_timing_header(
   2088     MTX_HEADER_PARAMS *pMTX_Header, MTX_HEADER_ELEMENT **aui32ElementPointers,
   2089     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
   2090     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
   2091     IMG_UINT32 ui32dpb_output_delay_length_minus1,
   2092     IMG_UINT32 __maybe_unused ui32cpb_removal_delay,
   2093     IMG_UINT32 __maybe_unused ui32dpb_output_delay,
   2094     IMG_UINT8 ui8pic_struct_present_flag,
   2095     IMG_UINT8 ui8pic_struct,
   2096     IMG_UINT8 ui8NumClockTS,
   2097     IMG_UINT8 *aui8clock_timestamp_flag,
   2098     IMG_UINT8 ui8full_timestamp_flag,
   2099     IMG_UINT8 ui8seconds_flag,
   2100     IMG_UINT8 ui8minutes_flag,
   2101     IMG_UINT8 ui8hours_flag,
   2102     IMG_UINT8 ui8seconds_value,
   2103     IMG_UINT8 ui8minutes_value,
   2104     IMG_UINT8 ui8hours_value,
   2105     IMG_UINT8 ui8ct_type,
   2106     IMG_UINT8 ui8nuit_field_based_flag,
   2107     IMG_UINT8 ui8counting_type,
   2108     IMG_UINT8 ui8discontinuity_flag,
   2109     IMG_UINT8 ui8cnt_dropped_flag,
   2110     IMG_UINT8 ui8n_frames,
   2111     IMG_UINT8 ui8time_offset_length,
   2112     IMG_INT32 i32time_offset)
   2113 {
   2114     IMG_UINT8 ui8PayloadSizeBits, ui8Tmp;
   2115 #ifdef SEI_NOT_USE_TOKEN_ALIGN
   2116     IMG_UINT8 ui8Pad;
   2117 #endif
   2118 
   2119     // Essential we insert the element before we try to fill it!
   2120     tng__insert_element_token(pMTX_Header,
   2121                               aui32ElementPointers,
   2122                               ELEMENT_STARTCODE_RAWDATA);
   2123 
   2124     tng__H264_writebits_startcode_prefix_element(pMTX_Header,
   2125             aui32ElementPointers,
   2126             3); // 00 00 01 start code prefix
   2127 
   2128     tng__write_upto8bits_elements(pMTX_Header,
   2129                                   aui32ElementPointers,
   2130                                   6, 8); // nal_unit_type = 06 (SEI Message)
   2131 
   2132     tng__write_upto8bits_elements(pMTX_Header,
   2133                                   aui32ElementPointers,
   2134                                   1, 8); // SEI payload type (picture timing)
   2135 
   2136 
   2137     // Precalculate the payload bit size
   2138     ui8PayloadSizeBits = 0;
   2139     if (ui8CpbDpbDelaysPresentFlag)
   2140         ui8PayloadSizeBits += ui32cpb_removal_delay_length_minus1
   2141                               + 1 + ui32dpb_output_delay_length_minus1 + 1;
   2142 
   2143     if (ui8pic_struct_present_flag) {
   2144         ui8PayloadSizeBits += 4;
   2145         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
   2146             ui8PayloadSizeBits += 1;
   2147 
   2148             if (aui8clock_timestamp_flag[ui8Tmp]) {
   2149                 ui8PayloadSizeBits += 2 + 1 + 5 + 1 + 1 + 1 + 8;
   2150                 if (ui8full_timestamp_flag)
   2151                     ui8PayloadSizeBits += 6 + 6 + 5;
   2152                 else {
   2153                     ui8PayloadSizeBits += 1;
   2154                     if (ui8seconds_flag) {
   2155                         ui8PayloadSizeBits += 6 + 1;
   2156                         if (ui8minutes_flag) {
   2157                             ui8PayloadSizeBits += 6 + 1;
   2158                             if (ui8hours_flag)
   2159                                 ui8PayloadSizeBits += 5;
   2160                         }
   2161                     }
   2162                 }
   2163 
   2164                 if (ui8time_offset_length > 0)
   2165                     ui8PayloadSizeBits += ui8time_offset_length;
   2166             }
   2167         }
   2168     }
   2169 
   2170     tng__write_upto8bits_elements(pMTX_Header,
   2171                                   aui32ElementPointers,
   2172                                   ((ui8PayloadSizeBits + 7) / 8), 8);
   2173     // SEI payload size = No of bytes required for SEI payload (including seq_parameter_set_id)
   2174 
   2175 
   2176     if (ui8CpbDpbDelaysPresentFlag) {
   2177         //SEI_INSERTION
   2178 #ifdef SEI_HOSTCALC_CPB_DPB
   2179         tng__write_upto32bits_elements(pMTX_Header,
   2180                                        aui32ElementPointers,
   2181                                        ui32cpb_removal_delay,
   2182                                        ui32cpb_removal_delay_length_minus1 + 1); // cpb_removal_delay
   2183         tng__write_upto32bits_elements(pMTX_Header,
   2184                                        aui32ElementPointers,
   2185                                        ui32dpb_output_delay,
   2186                                        ui32dpb_output_delay_length_minus1 + 1); // dpb_output_delay
   2187 #else
   2188         tng__insert_element_token(pMTX_Header,
   2189                                   aui32ElementPointers,
   2190                                   PTH_SEI_NAL_CPB_REMOVAL_DELAY);
   2191         tng__insert_element_token(pMTX_Header,
   2192                                   aui32ElementPointers,
   2193                                   PTH_SEI_NAL_DPB_OUTPUT_DELAY);
   2194 #endif
   2195     }
   2196 
   2197     if (ui8pic_struct_present_flag) {
   2198         tng__insert_element_token(pMTX_Header,
   2199                                   aui32ElementPointers,
   2200                                   ELEMENT_STARTCODE_RAWDATA);
   2201         tng__write_upto8bits_elements(pMTX_Header,
   2202                                       aui32ElementPointers,
   2203                                       ui8pic_struct, 4); // See TRM able D 1 ?Interpretation of pic_struct
   2204 
   2205         for (ui8Tmp = 0; ui8Tmp < ui8NumClockTS ; ui8Tmp++) {
   2206             tng__write_upto8bits_elements(pMTX_Header,
   2207                                           aui32ElementPointers,
   2208                                           aui8clock_timestamp_flag[ui8Tmp], 1);
   2209 
   2210             if (aui8clock_timestamp_flag[ui8Tmp]) {
   2211                 tng__write_upto8bits_elements(pMTX_Header,
   2212                                               aui32ElementPointers,
   2213                                               ui8ct_type, 2);
   2214                 // (2=Unknown) See TRM Table D 2 ?Mapping of ct_type to source picture scan
   2215                 tng__write_upto8bits_elements(pMTX_Header,
   2216                                               aui32ElementPointers,
   2217                                               ui8nuit_field_based_flag, 1);
   2218                 tng__write_upto8bits_elements(pMTX_Header,
   2219                                               aui32ElementPointers,
   2220                                               ui8counting_type, 5);
   2221                 // See TRM Table D 3 ?Definition of counting_type values
   2222                 tng__write_upto8bits_elements(pMTX_Header,
   2223                                               aui32ElementPointers,
   2224                                               ui8full_timestamp_flag, 1);
   2225                 tng__write_upto8bits_elements(pMTX_Header,
   2226                                               aui32ElementPointers,
   2227                                               ui8discontinuity_flag, 1);
   2228                 tng__write_upto8bits_elements(pMTX_Header,
   2229                                               aui32ElementPointers,
   2230                                               ui8cnt_dropped_flag, 1);
   2231                 tng__write_upto8bits_elements(pMTX_Header,
   2232                                               aui32ElementPointers,
   2233                                               ui8n_frames, 8);
   2234 
   2235                 if (ui8full_timestamp_flag) {
   2236                     tng__write_upto8bits_elements(pMTX_Header,
   2237                                                   aui32ElementPointers,
   2238                                                   ui8seconds_value, 6); // 0 - 59
   2239                     tng__write_upto8bits_elements(pMTX_Header,
   2240                                                   aui32ElementPointers,
   2241                                                   ui8minutes_value, 6); // 0 - 59
   2242                     tng__write_upto8bits_elements(pMTX_Header,
   2243                                                   aui32ElementPointers,
   2244                                                   ui8hours_value, 5); // 0 - 23
   2245                 } else {
   2246                     tng__write_upto8bits_elements(pMTX_Header,
   2247                                                   aui32ElementPointers,
   2248                                                   ui8seconds_flag, 1);
   2249 
   2250                     if (ui8seconds_flag) {
   2251                         tng__write_upto8bits_elements(pMTX_Header,
   2252                                                       aui32ElementPointers,
   2253                                                       ui8seconds_value, 6); // 0 - 59
   2254                         tng__write_upto8bits_elements(pMTX_Header,
   2255                                                       aui32ElementPointers,
   2256                                                       ui8minutes_flag, 1);
   2257 
   2258                         if (ui8minutes_flag) {
   2259                             tng__write_upto8bits_elements(pMTX_Header,
   2260                                                           aui32ElementPointers,
   2261                                                           ui8minutes_value, 6); // 0 - 59
   2262                             tng__write_upto8bits_elements(pMTX_Header,
   2263                                                           aui32ElementPointers,
   2264                                                           ui8hours_flag, 1);
   2265 
   2266                             if (ui8hours_flag)
   2267                                 tng__write_upto8bits_elements(pMTX_Header,
   2268                                                               aui32ElementPointers,
   2269                                                               ui8hours_value, 5); // 0 - 23
   2270                         }
   2271                     }
   2272                 }
   2273 
   2274                 if (ui8time_offset_length > 0) {
   2275                     // Two's complement storage : If time_offset<0 = ((2 ^ v) + time_offset)
   2276                     if (i32time_offset < 0)
   2277                         tng__write_upto32bits_elements(pMTX_Header,
   2278                                                        aui32ElementPointers,
   2279                                                        (IMG_UINT32)((2 ^ ui8time_offset_length) + i32time_offset),
   2280                                                        ui8time_offset_length);
   2281                     else
   2282                         tng__write_upto32bits_elements(pMTX_Header,
   2283                                                        aui32ElementPointers,
   2284                                                        (IMG_UINT32) i32time_offset,
   2285                                                        ui8time_offset_length);
   2286                 }
   2287             }
   2288         }
   2289     }
   2290 
   2291 #ifdef SEI_NOT_USE_TOKEN_ALIGN
   2292     // Pad to end of byte
   2293     if (!ui8pic_struct_present_flag)
   2294         tng__insert_element_token(pMTX_Header,
   2295                                   aui32ElementPointers,
   2296                                   ELEMENT_STARTCODE_RAWDATA);
   2297     ui8Pad = (ui8PayloadSizeBits + 7) / 8;
   2298     ui8Pad = (ui8Pad * 8) - ui8PayloadSizeBits;
   2299     if (ui8Pad > 0)
   2300         tng__write_upto8bits_elements(pMTX_Header,
   2301                                       aui32ElementPointers,
   2302                                       1 << (ui8Pad - 1),
   2303                                       ui8Pad); // SEI payload type (buffering period)
   2304 #else
   2305     tng__insert_element_token(pMTX_Header,
   2306                               aui32ElementPointers,
   2307                               ELEMENT_INSERTBYTEALIGN_H264); // Tell MTX to insert the byte align field
   2308     tng__insert_element_token(pMTX_Header,
   2309                               aui32ElementPointers,
   2310                               ELEMENT_STARTCODE_RAWDATA);
   2311 #endif
   2312 
   2313     // Write terminator
   2314     tng__write_upto8bits_elements(pMTX_Header,
   2315                                   aui32ElementPointers,
   2316                                   0x80, 8);
   2317     return;
   2318 }
   2319 
   2320 
   2321 
   2322 void tng__H264ES_prepare_AUD_header(unsigned char *virtual_addr)
   2323 {
   2324     // Essential we initialise our header structures before building
   2325     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
   2326     MTX_HEADER_ELEMENT *This_Element;
   2327     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2328     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   2329     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   2330     aui32ElementPointers[0] = This_Element;
   2331 
   2332     tng__H264ES_writebits_AUD_header(pMTX_Header, aui32ElementPointers);
   2333 
   2334     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   2335 }
   2336 
   2337 
   2338 void tng__H264ES_prepare_SEI_buffering_period_header(
   2339     unsigned char *virtual_addr,
   2340     IMG_UINT8 ui8nal_cpb_cnt_minus1,
   2341     IMG_UINT8 ui8nal_initial_cpb_removal_delay_length,
   2342     IMG_UINT8 ui8NalHrdBpPresentFlag,
   2343     IMG_UINT32 ui32nal_initial_cpb_removal_delay,
   2344     IMG_UINT32 ui32nal_initial_cpb_removal_delay_offset,
   2345     IMG_UINT8 ui8VclHrdBpPresentFlag,
   2346     IMG_UINT32 ui32vcl_initial_cpb_removal_delay,
   2347     IMG_UINT32 ui32vcl_initial_cpb_removal_delay_offset)
   2348 {
   2349     // Essential we initialise our header structures before building
   2350     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
   2351     MTX_HEADER_ELEMENT *This_Element;
   2352     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2353     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   2354     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   2355     aui32ElementPointers[0] = This_Element;
   2356 
   2357     tng__H264ES_writebits_SEI_buffering_period_header(
   2358         pMTX_Header, aui32ElementPointers,
   2359         ui8NalHrdBpPresentFlag,
   2360         ui8nal_cpb_cnt_minus1,
   2361         ui8nal_initial_cpb_removal_delay_length,
   2362         ui32nal_initial_cpb_removal_delay,
   2363         ui32nal_initial_cpb_removal_delay_offset,
   2364         ui8VclHrdBpPresentFlag,
   2365         ui8nal_cpb_cnt_minus1,
   2366         ui32vcl_initial_cpb_removal_delay,
   2367         ui32vcl_initial_cpb_removal_delay_offset);
   2368 
   2369     pMTX_Header->ui32Elements++;
   2370     //Has been used as an index, so need to add 1 for a valid element count
   2371     return;
   2372 }
   2373 
   2374 void tng__H264ES_prepare_SEI_picture_timing_header(
   2375     unsigned char *virtual_addr,
   2376     IMG_UINT8 ui8CpbDpbDelaysPresentFlag,
   2377     IMG_UINT32 ui32cpb_removal_delay_length_minus1,
   2378     IMG_UINT32 ui32dpb_output_delay_length_minus1,
   2379     IMG_UINT32 ui32cpb_removal_delay,
   2380     IMG_UINT32 ui32dpb_output_delay,
   2381     IMG_UINT8 ui8pic_struct_present_flag,
   2382     IMG_UINT8 ui8pic_struct,
   2383     IMG_UINT8 ui8NumClockTS,
   2384     IMG_UINT8 *aui8clock_timestamp_flag,
   2385     IMG_UINT8 ui8full_timestamp_flag,
   2386     IMG_UINT8 ui8seconds_flag,
   2387     IMG_UINT8 ui8minutes_flag,
   2388     IMG_UINT8 ui8hours_flag,
   2389     IMG_UINT8 ui8seconds_value,
   2390     IMG_UINT8 ui8minutes_value,
   2391     IMG_UINT8 ui8hours_value,
   2392     IMG_UINT8 ui8ct_type,
   2393     IMG_UINT8 ui8nuit_field_based_flag,
   2394     IMG_UINT8 ui8counting_type,
   2395     IMG_UINT8 ui8discontinuity_flag,
   2396     IMG_UINT8 ui8cnt_dropped_flag,
   2397     IMG_UINT8 ui8n_frames,
   2398     IMG_UINT8 ui8time_offset_length,
   2399     IMG_INT32 i32time_offset)
   2400 {
   2401     // Essential we initialise our header structures before building
   2402     MTX_HEADER_PARAMS * pMTX_Header = (MTX_HEADER_PARAMS *)virtual_addr;
   2403     MTX_HEADER_ELEMENT *This_Element;
   2404     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2405     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   2406     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   2407     aui32ElementPointers[0] = This_Element;
   2408 
   2409     tng__H264ES_writebits_SEI_picture_timing_header(
   2410         pMTX_Header, aui32ElementPointers,
   2411         ui8CpbDpbDelaysPresentFlag,
   2412         ui32cpb_removal_delay_length_minus1,
   2413         ui32dpb_output_delay_length_minus1,
   2414         ui32cpb_removal_delay,
   2415         ui32dpb_output_delay,
   2416         ui8pic_struct_present_flag,
   2417         ui8pic_struct,
   2418         ui8NumClockTS,
   2419         aui8clock_timestamp_flag,
   2420         ui8full_timestamp_flag,
   2421         ui8seconds_flag,
   2422         ui8minutes_flag,
   2423         ui8hours_flag,
   2424         ui8seconds_value,
   2425         ui8minutes_value,
   2426         ui8hours_value,
   2427         ui8ct_type,
   2428         ui8nuit_field_based_flag,
   2429         ui8counting_type,
   2430         ui8discontinuity_flag,
   2431         ui8cnt_dropped_flag,
   2432         ui8n_frames,
   2433         ui8time_offset_length,
   2434         i32time_offset);
   2435 
   2436     pMTX_Header->ui32Elements++;
   2437     //Has been used as an index, so need to add 1 for a valid element count
   2438     return;
   2439 }
   2440 
   2441 static void tng__H264ES_set_sequence_level_profile(
   2442     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
   2443     IMG_UINT8 uiLevel,
   2444     IMG_UINT8 uiProfile)
   2445 {
   2446     switch (uiLevel) {
   2447     case 10:
   2448         pSHParams->ucLevel =  SH_LEVEL_10;
   2449         break;
   2450     case 111:
   2451         pSHParams->ucLevel =  SH_LEVEL_1B;
   2452         break;
   2453     case 11:
   2454         pSHParams->ucLevel =  SH_LEVEL_11;
   2455         break;
   2456     case 12:
   2457         pSHParams->ucLevel =  SH_LEVEL_12;
   2458         break;
   2459     case 20:
   2460         pSHParams->ucLevel =  SH_LEVEL_20;
   2461         break;
   2462     case 30:
   2463         pSHParams->ucLevel =  SH_LEVEL_30;
   2464         break;
   2465     case 31:
   2466         pSHParams->ucLevel =  SH_LEVEL_31;
   2467         break;
   2468     case 32:
   2469         pSHParams->ucLevel =  SH_LEVEL_32;
   2470         break;
   2471     case 40:
   2472         pSHParams->ucLevel =  SH_LEVEL_40;
   2473         break;
   2474     case 41:
   2475         pSHParams->ucLevel =  SH_LEVEL_41;
   2476         break;
   2477     case 42:
   2478         pSHParams->ucLevel =  SH_LEVEL_42;
   2479         break;
   2480     default:
   2481         pSHParams->ucLevel =  SH_LEVEL_30;
   2482         break;
   2483     }
   2484 
   2485     switch (uiProfile) {
   2486     case 5:
   2487         pSHParams->ucProfile  = SH_PROFILE_BP;
   2488         break;
   2489     case 6:
   2490         pSHParams->ucProfile  = SH_PROFILE_MP;
   2491         break;
   2492     default:
   2493         pSHParams->ucProfile  = SH_PROFILE_MP;
   2494         break;
   2495     }
   2496     return ;
   2497 }
   2498 
   2499 void tng__H264ES_prepare_sequence_header(
   2500     void *pHeaderMemory,
   2501     H264_VUI_PARAMS *psVUI_Params,
   2502     H264_CROP_PARAMS *psCropParams,
   2503     IMG_UINT16 ui16PictureWidth,
   2504     IMG_UINT16 ui16PictureHeight,
   2505     IMG_UINT32 ui32CustomQuantMask,
   2506     IMG_UINT8 ui8ProfileIdc,
   2507     IMG_UINT8 ui8LevelIdc,
   2508     IMG_UINT8 ui8FieldCount,
   2509     IMG_UINT8 ui8MaxNumRefFrames,
   2510     IMG_BOOL  bPpsScaling,
   2511     IMG_BOOL  bUseDefaultScalingList,
   2512     IMG_BOOL  bEnableLossless,
   2513     IMG_BOOL  bASO
   2514 )
   2515 {
   2516     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
   2517      * Essential we initialise our header structures before building
   2518      */
   2519     H264_SEQUENCE_HEADER_PARAMS SHParams;
   2520     /* Route output elements to memory provided */
   2521     MTX_HEADER_PARAMS  *mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
   2522     MTX_HEADER_ELEMENT *This_Element;
   2523     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2524     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   2525     This_Element = mtx_hdr->asElementStream;
   2526     aui32ElementPointers[0] = This_Element;
   2527 
   2528     memset(&SHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
   2529 
   2530     SHParams.ucProfile = ui8ProfileIdc - 5;
   2531     SHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
   2532     SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
   2533     SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
   2534     SHParams.gaps_in_frame_num_value = IMG_FALSE;
   2535     SHParams.VUI_Params_Present = psVUI_Params->vui_flag;
   2536     if (SHParams.VUI_Params_Present)
   2537         memcpy(&SHParams.VUI_Params, psVUI_Params, sizeof(H264_VUI_PARAMS));
   2538     SHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
   2539 
   2540     SHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
   2541     SHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
   2542 
   2543 
   2544     SHParams.seq_scaling_matrix_present_flag = (ui32CustomQuantMask != 0 && !bPpsScaling);
   2545     SHParams.bUseDefaultScalingList = (bUseDefaultScalingList && !bPpsScaling);
   2546 
   2547     SHParams.max_num_ref_frames = ui8MaxNumRefFrames;
   2548     SHParams.bIsLossless = bEnableLossless;
   2549     SHParams.log2_max_pic_order_cnt = 6;
   2550 #ifdef _TOPAZHP_PDUMP_
   2551     tng_trace_seq_header_params(&SHParams);
   2552 #endif
   2553     tng__H264ES_writebits_sequence_header(mtx_hdr, aui32ElementPointers, &SHParams, psCropParams, NULL, bASO);
   2554     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
   2555 }
   2556 
   2557 static void tng__H264ES_writebits_mvc_sequence_header(
   2558     MTX_HEADER_PARAMS *pMTX_Header,
   2559     MTX_HEADER_ELEMENT **aui32ElementPointers,
   2560     H264_SEQUENCE_HEADER_PARAMS *pSHParams,
   2561     H264_CROP_PARAMS *psCrop,
   2562     H264_SCALING_MATRIX_PARAMS __maybe_unused * psScalingMatrix)
   2563 {
   2564     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
   2565     tng__H264_writebits_startcode_prefix_element(pMTX_Header, aui32ElementPointers, 4);
   2566 
   2567     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
   2568 
   2569     // 4 Byte StartCodePrefix Pregenerated in: H264_WriteBits_StartCodePrefix_Element()
   2570     // Byte aligned (bit 32)
   2571     tng__write_upto8bits_elements(pMTX_Header,
   2572                                   aui32ElementPointers, (0 << 7) |                                                        // forbidden_zero_bit=0
   2573                                   (0x3 << 5) |                                                                            // nal_ref_idc=01 (may be 11)
   2574                                   (15),                                                                                           // nal_unit_type=15
   2575                                   8);
   2576 
   2577     // Byte aligned (bit 40)
   2578     // profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP)
   2579     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 118, 8);
   2580 
   2581     // Byte aligned (bit 48)
   2582     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, (0 << 7) |     // constrain_set0_flag = 1 for MP + BP constraints
   2583                                   (0 << 6) |                                                  // constrain_set1_flag  = 1 for MP + BP constraints
   2584                                   (0 << 5) |                                                                                              // constrain_set2_flag = always 0 in BP/MP
   2585                                   (0 << 4),                                                           // constrain_set3_flag = 1 for level 1b, 0 for others
   2586                                   // reserved_zero_4bits = 0
   2587                                   8);
   2588 
   2589     // Byte aligned (bit 56)
   2590     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
   2591 
   2592     tng__generate_ue(pMTX_Header, aui32ElementPointers, MVC_SPS_ID);                // seq_parameter_Set_id = 1 FOR subset-SPS
   2593     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // chroma_format_idc = 1
   2594     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_luma_minus8 = 0
   2595     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // bit_depth_chroma_minus8 = 0
   2596     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->bIsLossless ? 1 : 0, 1); // qpprime_y_zero_transform_bypass_flag = 0
   2597 
   2598     if (pSHParams->bUseDefaultScalingList || pSHParams->seq_scaling_matrix_present_flag) {
   2599         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);         // seq_scaling_matrix_present_flag
   2600         if (!pSHParams->bUseDefaultScalingList) {
   2601 #ifdef _FIXME_
   2602             H264_WriteBits_ScalingLists(pMTX_Header, aui32ElementPointers, psScalingMatrix, IMG_TRUE);
   2603 #endif
   2604             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   2605         } else {
   2606             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 8);         // seq_scaling_list_present_flag[i] = 0; 0 < i < 8
   2607         }
   2608     } else {
   2609         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);         // seq_scaling_matrix_present_flag
   2610     }
   2611 
   2612     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);         // log2_max_frame_num_minus4 = 1
   2613     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);         // pic_order_cnt_type = 0
   2614     tng__generate_ue(pMTX_Header, aui32ElementPointers, 2);         // log2_max_pic_order_cnt_Isb_minus4 = 2
   2615 
   2616     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSHParams->max_num_ref_frames); //num_ref_frames ue(2), typically 2
   2617     // Bytes aligned (bit 72)
   2618     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
   2619                                   (pSHParams->gaps_in_frame_num_value), // gaps_in_frame_num_value_allowed_Flag   - (1 bit)
   2620                                   1);
   2621 
   2622     ///**** GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
   2623     ///**** ELEMENT BITCOUNT: xx
   2624     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)
   2625     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)
   2626     // We don't know the alignment at this point, so will have to use bit writing functions
   2627 
   2628     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, pSHParams->ucFrame_mbs_only_flag, 1); // frame_mb_only_flag 1=frame encoding, 0=field encoding
   2629 
   2630     if (!pSHParams->ucFrame_mbs_only_flag) // in the case of interlaced encoding
   2631         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1); // mb_adaptive_frame_field_flag = 0 in Topaz(field encoding at the sequence level)
   2632 
   2633     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // direct_8x8_inference_flag=1 in Topaz
   2634 
   2635     if (psCrop->bClip) {
   2636         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);
   2637         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16LeftCropOffset);
   2638         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16RightCropOffset);
   2639         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16TopCropOffset);
   2640         tng__generate_ue(pMTX_Header, aui32ElementPointers, psCrop->ui16BottomCropOffset);
   2641 
   2642     } else {
   2643         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);
   2644     }
   2645 
   2646     ///**** GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE ****///
   2647     ///**** ELEMENT BITCOUNT: xx
   2648     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
   2649                                   (pSHParams->VUI_Params_Present),                                        // vui_parameters_present_flag (VUI only in 1st sequence of stream)
   2650                                   1);
   2651     if (pSHParams->VUI_Params_Present > 0)
   2652         tng__H264_writebits_VUI_params(pMTX_Header, aui32ElementPointers, &(pSHParams->VUI_Params));
   2653 
   2654 
   2655     {
   2656         int viewIdx = 0;
   2657         int numViews = MAX_MVC_VIEWS;
   2658         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); //bit_equal_to_one
   2659 
   2660         // sequence parameter set MVC extension
   2661         tng__generate_ue(pMTX_Header, aui32ElementPointers, (numViews - 1));     //num_views_minus1
   2662         for (viewIdx = 0; viewIdx < numViews; viewIdx++) {
   2663             tng__generate_ue(pMTX_Header, aui32ElementPointers, viewIdx);
   2664         }
   2665 
   2666         // anchor references
   2667         for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
   2668             //tng__generate_ue( pMTX_Header, aui32ElementPointers, 0);     // num_anchor_refs_l0  = 0
   2669             tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_anchor_refs_l0  = 1; view-1 refers to view-0
   2670             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // anchor_ref_l0 = 0
   2671 
   2672             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_anchor_refs_l1  = 0
   2673         }
   2674 
   2675         // non-anchor references
   2676         for (viewIdx = 1; viewIdx < numViews; viewIdx++) {
   2677             tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);      // num_non_anchor_refs_l0  = 0
   2678             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // non_anchor_refs_l0  = 0
   2679 
   2680             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);      // num_non_anchor_refs_l1  = 0
   2681         }
   2682 
   2683         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_level_values_signaled_minus1  = 0
   2684 
   2685         //for(levelIdx=0; levelIdx<= 0; levelIdx++)
   2686         {
   2687             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
   2688             tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // num_applicable_ops_minus1  = 0
   2689             {
   2690                 tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 3); // applicable_ops_temporal_id  = 0
   2691                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_target_views_minus1  = 0
   2692                 {
   2693                     tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);              // applicable_op_target_view_id  = 0
   2694                 }
   2695                 tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                  // applicable_op_num_views_minus1  = 0
   2696             }
   2697         }
   2698 
   2699         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
   2700                                       0,                    // mvc_vui_parameters_present_flag =0
   2701                                       1);
   2702 
   2703         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,
   2704                                       0,                    // additional_extension2_flag =0
   2705                                       1);
   2706     }
   2707 
   2708 
   2709     // Finally we need to align to the next byte
   2710     // Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point)
   2711     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_INSERTBYTEALIGN_H264);
   2712 }
   2713 
   2714 
   2715 /*
   2716 ******************************************************************************
   2717  @Function              H264_PrepareMvcSequenceHeader
   2718  @details
   2719  Prepare an H264 SPS in a form for the MTX to encode into a bitstream.
   2720  @param    pMTX_Header       : pointer to header structure to populate
   2721  @param    uiPicWidthInMbs   : picture width in MBs
   2722  @param    uiPicHeightInMbs  : picture height in MBs
   2723  @param    bVuiParamsPresent : IMG_TRUE if VUI paramters present
   2724  @param    psParams          : VUI parameters
   2725  @param    psCrop                         : Pointer to crop parameter structure
   2726  @param   psSHParams              : Pointer to sequence header params structure
   2727  @return   None
   2728 ******************************************************************************/
   2729 void tng__H264ES_prepare_mvc_sequence_header(
   2730     void *pHeaderMemory,
   2731     H264_CROP_PARAMS *psCropParams,
   2732     IMG_UINT16 ui16PictureWidth,
   2733     IMG_UINT16 ui16PictureHeight,
   2734     IMG_UINT32 ui32CustomQuantMask,
   2735     IMG_UINT8 ui8ProfileIdc,
   2736     IMG_UINT8 ui8LevelIdc,
   2737     IMG_UINT8 ui8FieldCount,
   2738     IMG_UINT8 ui8MaxNumRefFrames,
   2739     IMG_BOOL  bPpsScaling,
   2740     IMG_BOOL  bUseDefaultScalingList,
   2741     IMG_BOOL  bEnableLossless,
   2742     IMG_BOOL  __maybe_unused bASO)
   2743 {
   2744     H264_SEQUENCE_HEADER_PARAMS sSHParams;
   2745     MTX_HEADER_PARAMS * pMTX_Header;
   2746     MTX_HEADER_ELEMENT *This_Element;
   2747     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2748     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
   2749 
   2750 #if HEADERS_VERBOSE_OUTPUT
   2751     drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n");
   2752     drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n");
   2753     drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n");
   2754 #endif
   2755 
   2756     // Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
   2757     // Essential we initialise our header structures before building
   2758     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   2759     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   2760     aui32ElementPointers[0] = This_Element;
   2761 
   2762     memset(&sSHParams, 0, sizeof(H264_SEQUENCE_HEADER_PARAMS));
   2763 
   2764     sSHParams.ucProfile = ui8ProfileIdc - 5;
   2765     sSHParams.ucLevel = (ui8LevelIdc != 111) ? ui8LevelIdc : SH_LEVEL_1B;
   2766     sSHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)((ui16PictureWidth >> 4)- 1);
   2767     sSHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)((ui16PictureHeight >> 4) - 1);
   2768     sSHParams.gaps_in_frame_num_value = IMG_FALSE;
   2769     sSHParams.VUI_Params_Present = IMG_FALSE;
   2770     sSHParams.ucFrame_mbs_only_flag = (ui8FieldCount > 1) ? IMG_FALSE : IMG_TRUE;
   2771     sSHParams.seq_scaling_matrix_present_flag = (bPpsScaling) ? IMG_FALSE : (IMG_UINT8)(ui32CustomQuantMask);
   2772     sSHParams.bUseDefaultScalingList = (bPpsScaling) ? IMG_FALSE : bUseDefaultScalingList;
   2773     sSHParams.max_num_ref_frames = ui8MaxNumRefFrames;
   2774     sSHParams.bIsLossless = bEnableLossless;
   2775     sSHParams.log2_max_pic_order_cnt = 6;
   2776 #ifdef _TOPAZHP_PDUMP_
   2777     tng_trace_seq_header_params(&sSHParams);
   2778 #endif
   2779     tng__H264ES_writebits_mvc_sequence_header(pMTX_Header, aui32ElementPointers, &sSHParams, psCropParams, NULL);
   2780     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   2781     return ;
   2782 }
   2783 
   2784 void tng__H264ES_prepare_picture_header(
   2785     void *pHeaderMemory,
   2786     IMG_BOOL    bCabacEnabled,
   2787     IMG_BOOL    b_8x8transform,
   2788     IMG_BOOL    bIntraConstrained,
   2789     IMG_INT8    i8CQPOffset,
   2790     IMG_BOOL    bWeightedPrediction,
   2791     IMG_UINT8   ui8WeightedBiPred,
   2792     IMG_BOOL    bMvcPPS,
   2793     IMG_BOOL    bScalingMatrix,
   2794     IMG_BOOL    bScalingLists)
   2795 {
   2796     MTX_HEADER_PARAMS *pMTX_Header;
   2797     H264_PICTURE_HEADER_PARAMS sPHParams;
   2798 
   2799     /* Route output elements to memory provided */
   2800     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
   2801     /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame)
   2802      * Essential we initialise our header structures before building
   2803      */
   2804     MTX_HEADER_ELEMENT *This_Element;
   2805     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2806     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   2807     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   2808     aui32ElementPointers[0] = This_Element;
   2809 
   2810     memset(&sPHParams, 0, sizeof(H264_PICTURE_HEADER_PARAMS));
   2811 
   2812     sPHParams.pic_parameter_set_id = bMvcPPS ? MVC_PPS_ID : 0;
   2813     sPHParams.seq_parameter_set_id = bMvcPPS ? MVC_SPS_ID : 0;
   2814     sPHParams.entropy_coding_mode_flag = bCabacEnabled ? 1 : 0;
   2815     sPHParams.weighted_pred_flag = bWeightedPrediction;
   2816     sPHParams.weighted_bipred_idc = ui8WeightedBiPred;
   2817     sPHParams.chroma_qp_index_offset = i8CQPOffset;
   2818     sPHParams.constrained_intra_pred_flag = bIntraConstrained ? 1 : 0;
   2819     sPHParams.transform_8x8_mode_flag = b_8x8transform ? 1 : 0;
   2820     sPHParams.pic_scaling_matrix_present_flag = bScalingMatrix ? 1 : 0;
   2821     sPHParams.bUseDefaultScalingList = !bScalingLists;
   2822     sPHParams.second_chroma_qp_index_offset = i8CQPOffset;
   2823 #ifdef _TOPAZHP_PDUMP_
   2824     tng_trace_pic_header_params(&sPHParams);
   2825 #endif
   2826     tng__H264ES_writebits_picture_header(pMTX_Header, aui32ElementPointers, &sPHParams, NULL);
   2827     /* Has been used as an index, so need to add 1 for a valid element count */
   2828     pMTX_Header->ui32Elements++;
   2829     return ;
   2830 }
   2831 
   2832 void tng__H264_prepare_slice_header(
   2833     IMG_UINT32 *pHeaderMemory,
   2834     IMG_BOOL        bIntraSlice,
   2835     IMG_BOOL        bInterBSlice,
   2836     IMG_BOOL        bMultiRef,
   2837     IMG_UINT8       ui8DisableDeblockingFilterIDC,
   2838     IMG_UINT32      ui32DisplayFrameNumber,
   2839     IMG_UINT32      ui32FrameNumId,
   2840     IMG_UINT32      uiFirst_MB_Address,
   2841     IMG_UINT32      __maybe_unused uiMBSkipRun,
   2842     IMG_BOOL        bCabacEnabled,
   2843     IMG_BOOL        bIsInterlaced,
   2844     IMG_UINT8       ui8FieldNum,
   2845     WEIGHTED_PREDICTION_VALUES *pWeightedSetup,
   2846     IMG_BOOL        bIsLongTermRef
   2847 )
   2848 {
   2849     H264_SLICE_HEADER_PARAMS SlHParams;
   2850     MTX_HEADER_PARAMS *pMTX_Header;
   2851     /* Route output elements to memory provided */
   2852     pMTX_Header = (MTX_HEADER_PARAMS *) pHeaderMemory;
   2853 
   2854     memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
   2855 
   2856 
   2857     SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
   2858     /* pcb -        I think that this is more correct now*/
   2859     SlHParams.SliceFrame_Type = bIntraSlice ? (((ui32FrameNumId % (1 << 5)) == 0) ?
   2860                                 SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
   2861     /*
   2862     if (bIntraSlice) {
   2863         if ((ui32FrameNumId%(1<<5))==0)
   2864             SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE;
   2865         else
   2866             SlHParams.SliceFrame_Type = SLHP_I_SLICEFRAME_TYPE;
   2867     } else {
   2868         if (bInterBSlice)
   2869             SlHParams.SliceFrame_Type = SLHP_B_SLICEFRAME_TYPE;
   2870         else
   2871             SlHParams.SliceFrame_Type = SLHP_P_SLICEFRAME_TYPE;
   2872     }
   2873     */
   2874     SlHParams.Frame_Num_DO   = (IMG_UINT8) ui32FrameNumId % (1 << 5);
   2875     SlHParams.Idr_Pic_Id     = (IMG_UINT8)(ui32DisplayFrameNumber & 1);
   2876     SlHParams.Picture_Num_DO = (IMG_UINT8)((ui32DisplayFrameNumber % (1 << 5)) * 2);
   2877 
   2878     SlHParams.First_MB_Address =  uiFirst_MB_Address;
   2879     SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
   2880     SlHParams.bPiCInterlace = bIsInterlaced;
   2881     SlHParams.bFieldType    = ui8FieldNum;
   2882     SlHParams.iDebAlphaOffsetDiv2   = 0;
   2883     SlHParams.iDebBetaOffsetDiv2    = 0;
   2884 
   2885     if (bMultiRef)
   2886         SlHParams.num_ref_idx_l0_active_minus1 = 1;
   2887     else
   2888         SlHParams.num_ref_idx_l0_active_minus1 = 0;
   2889 
   2890     SlHParams.weighted_pred_flag            = pWeightedSetup ? pWeightedSetup->weighted_pred_flag             : 0;
   2891     SlHParams.weighted_bipred_idc   = pWeightedSetup ? pWeightedSetup->weighted_bipred_idc            : 0;
   2892     SlHParams.luma_log2_weight_denom        = pWeightedSetup ? pWeightedSetup->luma_log2_weight_denom         : 0;
   2893     SlHParams.chroma_log2_weight_denom      = pWeightedSetup ? pWeightedSetup->chroma_log2_weight_denom : 0;
   2894     SlHParams.luma_weight_l0_flag[0]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][0]                      : 0;
   2895     SlHParams.luma_weight_l0[0]             = pWeightedSetup ? pWeightedSetup->weight[0][0]                   : 0;
   2896     SlHParams.luma_offset_l0[0]             = pWeightedSetup ? pWeightedSetup->offset[0][0]                   : 0;
   2897     SlHParams.chroma_weight_l0_flag[0]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][0]                      : 0;
   2898     SlHParams.chromaB_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[1][0]                   : 0;
   2899     SlHParams.chromaB_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[1][0]                   : 0;
   2900     SlHParams.chromaR_weight_l0[0]          = pWeightedSetup ? pWeightedSetup->weight[2][0]                   : 0;
   2901     SlHParams.chromaR_offset_l0[0]          = pWeightedSetup ? pWeightedSetup->offset[2][0]                   : 0;
   2902     SlHParams.luma_weight_l0_flag[1]        = pWeightedSetup ? pWeightedSetup->weight_flag[0][1]                      : 0;
   2903     SlHParams.luma_weight_l0[1]             = pWeightedSetup ? pWeightedSetup->weight[0][1]                   : 0;
   2904     SlHParams.luma_offset_l0[1]             = pWeightedSetup ? pWeightedSetup->offset[0][1]                   : 0;
   2905     SlHParams.chroma_weight_l0_flag[1]      = pWeightedSetup ? pWeightedSetup->weight_flag[1][1]                      : 0;
   2906     SlHParams.chromaB_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[1][1]                   : 0;
   2907     SlHParams.chromaB_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[1][1]                   : 0;
   2908     SlHParams.chromaR_weight_l0[1]          = pWeightedSetup ? pWeightedSetup->weight[2][1]                   : 0;
   2909     SlHParams.chromaR_offset_l0[1]          = pWeightedSetup ? pWeightedSetup->offset[2][1]                   : 0;
   2910 
   2911     SlHParams.bIsLongTermRef = bIsLongTermRef;
   2912     tng__H264_getelements_slice_header(pMTX_Header, &SlHParams, bCabacEnabled);
   2913 
   2914     /*
   2915         {
   2916             IMG_UINT32      *pMTX_Header_Mem = (IMG_UINT32 *)mtx_hdr;
   2917             // rhk: first insert normal header.
   2918             tng__H264_getelements_slice_header(mtx_hdr, &SlHParams, bCabacEnabled, uiIdrPicId);
   2919 
   2920             // put a marker to indicate that this is a complex header
   2921             // note that first "int" in the buffer is used for number of elements
   2922             // which is not going to be more than 255
   2923             *pMTX_Header_Mem |= 0x100;
   2924 
   2925             // rhk: insert skipped frame header at an offset of 128 bytes
   2926             pMTX_Header_Mem += (HEADER_SIZE >> 3);  // get a pointer to the second half of memory
   2927             mtx_hdr = (MTX_HEADER_PARAMS *)pMTX_Header_Mem;
   2928             tng__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun, bCabacEnabled);
   2929         }
   2930     */
   2931 }
   2932 
   2933 void tng__MPEG4_prepare_sequence_header(
   2934     void *pHeaderMemory,
   2935     IMG_BOOL bBFrame,
   2936     MPEG4_PROFILE_TYPE sProfile,
   2937     IMG_UINT8 Profile_and_level_indication,
   2938     FIXED_VOP_TIME_TYPE sFixed_vop_time_increment,
   2939     IMG_UINT32 Picture_Width_Pixels,
   2940     IMG_UINT32 Picture_Height_Pixels,
   2941     VBVPARAMS * psVBVParams,
   2942     IMG_UINT32 VopTimeResolution)
   2943 {
   2944     MTX_HEADER_PARAMS *mtx_hdr;
   2945 
   2946     /* Route output elements to memory provided */
   2947     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory;
   2948     /* Builds a single MPEG4 video sequence header from the given parameters */
   2949 
   2950     /* Essential we initialise our header structures before building */
   2951     MTX_HEADER_ELEMENT *This_Element;
   2952     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   2953     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2954     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
   2955     aui32ElementPointers[0] = This_Element;
   2956 
   2957     tng__MPEG4_writebits_sequence_header(mtx_hdr,
   2958         				 aui32ElementPointers,
   2959         				 bBFrame,
   2960 					 sProfile,
   2961        				 	 Profile_and_level_indication,
   2962        				 	 sFixed_vop_time_increment,
   2963         				 Picture_Width_Pixels,
   2964         				 Picture_Height_Pixels,
   2965         				 psVBVParams,
   2966 					 VopTimeResolution);
   2967 
   2968     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
   2969 
   2970 }
   2971 
   2972 void tng__MPEG4_prepare_vop_header(
   2973     IMG_UINT32 *pHeaderMem,
   2974     IMG_BOOL bIsVOP_coded,
   2975     IMG_UINT32 VOP_time_increment,
   2976     IMG_UINT8 sSearch_range,
   2977     IMG_UINT8 eVop_Coding_Type,
   2978     IMG_UINT32 VopTimeResolution)
   2979 {
   2980     MTX_HEADER_PARAMS *mtx_hdr;
   2981 
   2982     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
   2983 
   2984     /* Builds a single MPEG4 VOP (picture) header from the given parameters */
   2985     /* Essential we initialise our header structures before building */
   2986     MTX_HEADER_ELEMENT *This_Element;
   2987     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   2988     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   2989     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
   2990     aui32ElementPointers[0] = This_Element;
   2991 
   2992     /* Frame QScale no longer written here as it is inserted by MTX later
   2993      * (add as parameter to MTX_Send_Elements_To_VLC)
   2994      */
   2995     tng__MPEG4_writebits_VOP_header(
   2996         mtx_hdr, aui32ElementPointers, bIsVOP_coded,
   2997         VOP_time_increment,
   2998         sSearch_range,
   2999         eVop_Coding_Type,
   3000         VopTimeResolution);
   3001 
   3002     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
   3003 
   3004 }
   3005 
   3006 void tng__H263_prepare_sequence_header(
   3007     IMG_UINT32 *pHeaderMem,
   3008     IMG_UINT8 Profile_and_level_indication)
   3009 {
   3010     MTX_HEADER_PARAMS *mtx_hdr;
   3011 
   3012     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
   3013 
   3014     /* Builds a single H263 video sequence header from the given parameters */
   3015 
   3016     /* Essential we initialise our header structures before building */
   3017     MTX_HEADER_ELEMENT *This_Element;
   3018     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3019     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   3020     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
   3021     aui32ElementPointers[0] = This_Element;
   3022 
   3023     H263_writebits_VideoSequenceHeader(mtx_hdr, aui32ElementPointers, Profile_and_level_indication);
   3024 
   3025     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
   3026 
   3027 }
   3028 
   3029 void tng__H263_prepare_picture_header(
   3030     IMG_UINT32 *pHeaderMem,
   3031     IMG_UINT8 Temporal_Ref,
   3032     H263_PICTURE_CODING_TYPE PictureCodingType,
   3033     H263_SOURCE_FORMAT_TYPE SourceFormatType,
   3034     IMG_UINT8 FrameRate,
   3035     IMG_UINT16 PictureWidth,
   3036     IMG_UINT16 PictureHeigth)
   3037 {
   3038     MTX_HEADER_PARAMS *mtx_hdr;
   3039 
   3040     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
   3041 
   3042     /* Essential we initialise our header structures before building */
   3043     MTX_HEADER_ELEMENT *This_Element;
   3044     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3045     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   3046     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
   3047     aui32ElementPointers[0] = This_Element;
   3048 
   3049     H263_writebits_VideoPictureHeader(
   3050         mtx_hdr, aui32ElementPointers,
   3051         Temporal_Ref,
   3052         PictureCodingType,
   3053         SourceFormatType,
   3054         FrameRate,
   3055         PictureWidth,
   3056         PictureHeigth);
   3057 
   3058     mtx_hdr->ui32Elements++; /* Has been used as an index, so need to add 1 for a valid element count */
   3059 }
   3060 
   3061 void tng__H263_prepare_GOBslice_header(
   3062     IMG_UINT32 *pHeaderMem,
   3063     IMG_UINT8 GOBNumber,
   3064     IMG_UINT8 GOBFrameId)
   3065 {
   3066     MTX_HEADER_PARAMS *mtx_hdr;
   3067 
   3068     mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem;
   3069 
   3070     /* Essential we initialise our header structures before building */
   3071     MTX_HEADER_ELEMENT *This_Element;
   3072     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3073     mtx_hdr->ui32Elements = ELEMENTS_EMPTY;
   3074     This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream;
   3075     aui32ElementPointers[0] = This_Element;
   3076 
   3077     H263_writebits_GOBSliceHeader(mtx_hdr, aui32ElementPointers, GOBNumber, GOBFrameId);
   3078 
   3079     mtx_hdr->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   3080 
   3081     /* silent the warning message */
   3082     (void)Show_Bits;
   3083     (void)Show_Elements;
   3084     /*
   3085     (void)tng__H264_writebits_SEI_rbspheader;
   3086     (void)tng__H264_getelements_skip_B_slice;
   3087     (void)tng__H264_getelements_backward_zero_B_slice;
   3088     (void)tng__H264_getelements_rbsp_ATE_only;
   3089     (void)tng_MPEG4_getelements_video_packet_header;
   3090     */
   3091 }
   3092 
   3093 void tng__H264ES_notforsims_writebits_extension_sliceheader(
   3094     MTX_HEADER_PARAMS *pMTX_Header,
   3095     MTX_HEADER_ELEMENT **aui32ElementPointers,
   3096     H264_SLICE_HEADER_PARAMS *pSlHParams,
   3097     IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
   3098 {
   3099     bStartNextRawDataElement = IMG_FALSE;
   3100 
   3101     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
   3102 
   3103     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
   3104 
   3105     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3106     ///**** ELEMENT BITCOUNT: 8
   3107 
   3108     // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
   3109     //(3 bytes when slice is first in a picture without sequence/picture_header before picture
   3110     // Byte aligned (bit 32 or 24)
   3111     // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
   3112     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
   3113 
   3114     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE); //MTX fills this value in
   3115     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3116 
   3117     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 20, 5);    // nal_unit_type for coded_slice_extension
   3118 
   3119 
   3120     //if(nal_unit_type == 14 || nal_unit_type == 20)
   3121     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // SVC extension flag
   3122 
   3123     // nal_unit_header_mvc_extension()
   3124     {
   3125         if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) {
   3126             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
   3127         } else if ((pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) && bIsIDR) {
   3128             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // non_idr_flag flag
   3129         } else {
   3130             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // non_idr_flag flag
   3131         }
   3132 
   3133         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 6);   // priority_id flag
   3134         tng__write_upto32bits_elements(pMTX_Header, aui32ElementPointers,    1, 10);   // view_id = hardcoded to 1 for dependent view
   3135 
   3136         //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 3);   // temporal_id flag
   3137         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_TEMPORAL_ID); // temporal_id flag
   3138         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ANCHOR_PIC_FLAG); // anchor_pic_flag
   3139 
   3140         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3141 
   3142         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    0, 1);   // interview flag is always FALSE for dependent frames
   3143 
   3144         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers,    1, 1);   // reserved one bit
   3145     }
   3146 
   3147     // slice header
   3148     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
   3149 
   3150     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3151 
   3152     ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3153     /* The following is slice parameter set in BP/MP */
   3154     //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)
   3155     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
   3156     // kab: //not clean change from IDR to intra, IDR should have separate flag
   3157 
   3158     tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);  // pic_parameter_set_id = 1 for dependent view
   3159 
   3160     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
   3161     bStartNextRawDataElement = IMG_TRUE;
   3162 
   3163     if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
   3164         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3165 
   3166         // interlaced encoding
   3167         if (pSlHParams->bPiCInterlace) {
   3168             CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3169             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
   3170             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
   3171             //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3172             bStartNextRawDataElement = IMG_TRUE;
   3173         }
   3174     }
   3175 
   3176     if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
   3177         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3178         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // idr_pic_id ue(v) = 0 (1b) in Topaz
   3179     }
   3180 
   3181     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
   3182     bStartNextRawDataElement = IMG_TRUE;
   3183 
   3184     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
   3185         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
   3186 
   3187     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
   3188         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_NUM_REF_IDX_ACTIVE);
   3189         bStartNextRawDataElement = IMG_TRUE;
   3190     } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
   3191         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3192         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);             // num_ref_idx_active_override_flag (1 bit) = 0 in Topaz
   3193     }
   3194 
   3195     // reference picture list modification
   3196     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
   3197         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
   3198         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3199         bStartNextRawDataElement = IMG_TRUE;
   3200     }
   3201 
   3202     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)        {
   3203         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3204         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // ref_pic_list_ordering_flag_l1 (1 bit) = 0, no reference picture ordering in Topaz
   3205     }
   3206 
   3207     // WEIGHTED PREDICTION
   3208     /*      tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
   3209         bStartNextRawDataElement = IMG_TRUE;*/
   3210 
   3211     if ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) || (bIsIDR)) {
   3212         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3213         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // no_output_of_prior_pics_flag (1 bit) = 0
   3214         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // long_term_reference_flag (1 bit) = 0
   3215     } else {
   3216         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
   3217         //tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3218         bStartNextRawDataElement = IMG_TRUE;
   3219     }
   3220 
   3221     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
   3222                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
   3223         CheckStartRawDataElement(pMTX_Header, aui32ElementPointers);
   3224         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
   3225     }
   3226     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
   3227     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3228 
   3229     ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3230     ///**** ELEMENT BITCOUNT: 11
   3231     // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
   3232     //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
   3233     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
   3234     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
   3235         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
   3236         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
   3237     }
   3238     //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
   3239     // no byte alignment at end of slice headers
   3240 }
   3241 
   3242 
   3243 /*****************************************************************************
   3244 ******************************************************************************/
   3245 static void tng__H264ES_notforsims_writebits_slice_header(
   3246     MTX_HEADER_PARAMS *pMTX_Header,
   3247     MTX_HEADER_ELEMENT **aui32ElementPointers,
   3248     H264_SLICE_HEADER_PARAMS *pSlHParams,
   3249     IMG_BOOL bCabacEnabled, IMG_BOOL bIsIDR)
   3250 {
   3251     bStartNextRawDataElement = IMG_FALSE;
   3252     unsigned char* pdg = (unsigned char*)pMTX_Header;
   3253 
   3254     if (pSlHParams->ui16MvcViewIdx == (IMG_UINT16)(NON_MVC_VIEW)) {
   3255         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_RAWDATA);
   3256     } else if (pSlHParams->ui16MvcViewIdx == MVC_BASE_VIEW_IDX) {
   3257         tng__insert_prefix_nal_header(pMTX_Header, aui32ElementPointers,
   3258                                       pSlHParams, bCabacEnabled);
   3259         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_STARTCODE_MIDHDR);
   3260     } else {
   3261         //Insert
   3262         tng__H264ES_notforsims_writebits_extension_sliceheader(pMTX_Header, aui32ElementPointers,
   3263                 pSlHParams, bCabacEnabled, bIsIDR);
   3264         return;
   3265     }
   3266 
   3267     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
   3268 
   3269     ///**** GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3270     ///**** ELEMENT BITCOUNT: 8
   3271 
   3272     // StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes)
   3273     //(3 bytes when slice is first in a picture without sequence/picture_header before picture
   3274     // Byte aligned (bit 32 or 24)
   3275     // NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type
   3276 
   3277     tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);   // forbidden_zero_bit
   3278 
   3279     // nal_ref_idc, 0x03 for IDR slice, for non-IDR slice, fw chose a value
   3280     //tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 3 : ELEMENT_REFERENCE)), 2);
   3281     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REFERENCE);
   3282     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3283 
   3284     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
   3285                                   5);
   3286 
   3287     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_CURRMBNR); //MTX fills this value in
   3288     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3289 
   3290 
   3291     ///**** GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3292     /* The following is slice parameter set in BP/MP */
   3293     //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)
   3294     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
   3295     // kab: //not clean change from IDR to intra, IDR should have separate flag
   3296     if (pSlHParams->ui16MvcViewIdx != (IMG_UINT16)(NON_MVC_VIEW))
   3297         tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->ui16MvcViewIdx);  // pic_parameter_set_id = 0
   3298     else
   3299         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);  // pic_parameter_set_id = 0
   3300 
   3301     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_FRAME_NUM); // Insert token to tell MTX to insert frame_num
   3302 
   3303     if ((pSlHParams->bPiCInterlace) || (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)) {
   3304         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3305         // interlaced encoding
   3306         if (pSlHParams->bPiCInterlace) {
   3307             tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1);                                          // field_pic_flag = 1
   3308             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_BOTTOM_FIELD); // Insert token to tell MTX to insert BOTTOM_FIELD flag if required
   3309             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3310         }
   3311 
   3312         if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE)
   3313             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_IDR_PIC_ID);       // idr_pic_id ue(v)
   3314     }
   3315 
   3316     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_PIC_ORDER_CNT); // Insert token to tell MTX to insert pic_order_cnt_lsb
   3317 
   3318     if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
   3319         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_DIRECT_SPATIAL_MV_FLAG); // Insert token to tell MTX to insert direct_spatial_mv_pred_flag
   3320 
   3321     if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE) {
   3322         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
   3323     } else if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) {
   3324         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3325         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 0, 1);                                                                 // num_ref_idx_active_override_flag (1 bit) = 0
   3326     }
   3327 
   3328     if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE &&
   3329         pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) {
   3330         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L0); // Insert token to tell MTX to insert reference list 0 reordering
   3331         if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE)
   3332             tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_REORDER_L1); // Insert token to tell MTX to insert reference list 1 reordering
   3333     }
   3334 
   3335 
   3336     // WEIGHTED PREDICTION
   3337     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SLICEWEIGHTEDPREDICTIONSTRUCT);
   3338     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3339 
   3340     if (pSlHParams->bReferencePicture && pSlHParams->bIsLongTermRef) {
   3341         tng__write_upto8bits_elements(pMTX_Header, aui32ElementPointers, 1, 1); // adaptive_ref_pic_marking_mode_flag (1 bit) = 0
   3342 
   3343         // Clear any existing long-term reference
   3344         tng__generate_ue(pMTX_Header, aui32ElementPointers, 5);                                 // memory_management_control_operation
   3345 
   3346         // Allow a single long-term reference
   3347         tng__generate_ue(pMTX_Header, aui32ElementPointers, 4);                                 // memory_management_control_operation
   3348         tng__generate_ue(pMTX_Header, aui32ElementPointers, 1);                                 // max_long_term_frame_idx_plus1
   3349 
   3350         // Set current picture as the long-term reference
   3351         tng__generate_ue(pMTX_Header, aui32ElementPointers, 6);                                 // memory_management_control_operation
   3352         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // long_term_frame_idx
   3353 
   3354         // End
   3355         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0);                                 // memory_management_control_operation
   3356     } else {
   3357         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_ADAPTIVE); //MTX fills this value in
   3358         tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3359     }
   3360 
   3361     if (bCabacEnabled && ((SLHP_P_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type) ||
   3362                           (SLHP_B_SLICEFRAME_TYPE == pSlHParams->SliceFrame_Type))) {
   3363         tng__generate_ue(pMTX_Header, aui32ElementPointers, 0); // hard code cabac_init_idc value of 0
   3364     }
   3365     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_SQP); //MTX fills this value in
   3366     tng__insert_element_token(pMTX_Header, aui32ElementPointers, ELEMENT_RAWDATA);
   3367 
   3368     ///**** GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE ****///
   3369     ///**** ELEMENT BITCOUNT: 11
   3370     // Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here
   3371     //pucHS=tng__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); //slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26)
   3372     tng__generate_ue(pMTX_Header, aui32ElementPointers, pSlHParams->Disable_Deblocking_Filter_Idc); //disable_deblocking_filter_idc ue(v) = 2?
   3373 
   3374     if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) {
   3375         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebAlphaOffsetDiv2); //slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz
   3376         tng__generate_se(pMTX_Header, aui32ElementPointers, pSlHParams->iDebBetaOffsetDiv2); //slice_beta_offset_div2 se(v) = 0 (1b) in Topaz
   3377     }
   3378     //num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here
   3379     // no byte alignment at end of slice headers
   3380 }
   3381 
   3382 /******************************************************************************
   3383  @Function              H264_NOTFORSIMS_PrepareSliceHeader
   3384  @details
   3385  Sim guys, DO NOT EVER USE THIS FUNCTION!
   3386  Prepare an H264 slice header in a form for the MTX to encode into a
   3387  bitstream.
   3388  @param    pMTX_Header        : pointer to header structure to populate
   3389  @param    bIntraSlice        : IMG_TRUE if this is an IDR or I slice
   3390  @param    bInterBSlice        : IMG_TRUE if this is a B Frame slice
   3391  @param    ui8DisableDeblockingFilterIDC : syntax element
   3392  @param    ui32FrameNumId      : syntax element (used for references)
   3393  @param    uiFirst_MB_Address : first_mb_in_slice syntax element
   3394  @param    uiMBSkipRun        : number of MBs to skip
   3395  @param    bCabacEnabled      : IMG_TRUE to use CABAC
   3396  @param    bIsInterlaced      : IMG_TRUE for interlaced slices
   3397  @param    bIsIDR             : IMG_TRUE if this is an IDR slice
   3398  @param    bIsLongTermRef     : IMG_TRUE if the frame is to be used as a long-term reference
   3399  @return   None
   3400 ******************************************************************************/
   3401 
   3402 void tng__H264ES_notforsims_prepare_sliceheader(
   3403     IMG_UINT8      *slice_mem_p,
   3404     IMG_UINT32      ui32SliceType,
   3405     IMG_UINT8       ui8DisableDeblockingFilterIDC,
   3406     IMG_UINT32      uiFirst_MB_Address,
   3407     IMG_UINT32      __maybe_unused uiMBSkipRun,
   3408     IMG_BOOL        bCabacEnabled,
   3409     IMG_BOOL        bIsInterlaced,
   3410     IMG_UINT16      ui16MvcViewIdx,
   3411     IMG_BOOL        bIsLongTermRef
   3412 )
   3413 {
   3414     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
   3415     MTX_HEADER_PARAMS *pMTX_Header = (MTX_HEADER_PARAMS *) &(slice_temp_p->sSliceHdrTmpl);
   3416     H264_SLICE_HEADER_PARAMS SlHParams;
   3417     MTX_HEADER_ELEMENT *This_Element;
   3418     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3419     IMG_FRAME_TEMPLATE_TYPE eSliceType = (IMG_FRAME_TEMPLATE_TYPE)ui32SliceType;
   3420     IMG_BOOL bIntraSlice = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTRA));
   3421     IMG_BOOL bInterBSlice = (eSliceType == IMG_FRAME_INTER_B);
   3422     IMG_BOOL bIsIDR = ((eSliceType == IMG_FRAME_IDR) || (eSliceType == IMG_FRAME_INTER_P_IDR));
   3423 
   3424     memset(&SlHParams, 0, sizeof(H264_SLICE_HEADER_PARAMS));
   3425 
   3426     SlHParams.ui8Start_Code_Prefix_Size_Bytes = 4;
   3427     /* 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 */
   3428     SlHParams.SliceFrame_Type = bIntraSlice ? (bIsIDR ? SLHP_IDR_SLICEFRAME_TYPE : SLHP_I_SLICEFRAME_TYPE) : (bInterBSlice ? SLHP_B_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE);
   3429 
   3430     SlHParams.First_MB_Address = uiFirst_MB_Address;
   3431     SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) ui8DisableDeblockingFilterIDC;
   3432     SlHParams.bPiCInterlace = bIsInterlaced;
   3433     SlHParams.iDebAlphaOffsetDiv2 = 0;
   3434     SlHParams.iDebBetaOffsetDiv2  = 0;
   3435     // setup the new flags used for B frame as reference
   3436     SlHParams.bReferencePicture = bInterBSlice ? 0 : 1;
   3437     SlHParams.ui16MvcViewIdx = ui16MvcViewIdx;
   3438     SlHParams.bIsLongTermRef = bIsLongTermRef;
   3439     SlHParams.log2_max_pic_order_cnt = 2;
   3440     SlHParams.uLongTermRefNum = 0;
   3441     SlHParams.bRefIsLongTermRef[0] = 0;
   3442     SlHParams.uRefLongTermRefNum[0] = 0;
   3443     SlHParams.bRefIsLongTermRef[1] = 0;
   3444     SlHParams.uRefLongTermRefNum[1] = 0;
   3445     // Builds a single slice header from the given parameters (mid frame)
   3446     // Essential we initialise our header structures before building
   3447 //    memset(pMTX_Header, 0, 128);
   3448     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   3449     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   3450     aui32ElementPointers[0] = This_Element;
   3451 #ifdef _TOPAZHP_PDUMP_
   3452     tng_trace_slice_header_params(&SlHParams);
   3453 #endif
   3454     tng__H264ES_notforsims_writebits_slice_header(pMTX_Header, aui32ElementPointers, &SlHParams, bCabacEnabled, bIsIDR);
   3455     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   3456 }
   3457 
   3458 /**************************************************************************************************
   3459 * Function:             H263_NOTFORSIMS_PrepareGOBSliceHeader
   3460 * Description:  Generates the slice params template
   3461 *
   3462 ***************************************************************************************************/
   3463 
   3464 void tng__H263ES_notforsims_prepare_gobsliceheader(
   3465     IMG_UINT8       *slice_mem_p)
   3466 {
   3467     // Essential we initialise our header structures before building
   3468     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
   3469     MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
   3470     MTX_HEADER_ELEMENT *This_Element;
   3471     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3472     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   3473     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   3474     aui32ElementPointers[0] = This_Element;
   3475     H263_NOTFORSIMS_WriteBits_GOBSliceHeader(pMTX_Header, aui32ElementPointers);
   3476     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   3477 }
   3478 
   3479 /**************************************************************************************************
   3480 * Function:             MPEG2_PrepareSliceHeader
   3481 * Description:  Generates the slice params template
   3482 *
   3483 ***************************************************************************************************/
   3484 void tng__MPEG2_prepare_sliceheader(
   3485     IMG_UINT8               *slice_mem_p)
   3486 {
   3487     // Essential we initialise our header structures before building
   3488     SLICE_PARAMS *slice_temp_p = (SLICE_PARAMS*)slice_mem_p;
   3489     MTX_HEADER_PARAMS *     pMTX_Header = (MTX_HEADER_PARAMS *) & (slice_temp_p->sSliceHdrTmpl);
   3490     MTX_HEADER_ELEMENT *This_Element;
   3491     MTX_HEADER_ELEMENT *aui32ElementPointers[MAXNUMBERELEMENTS];
   3492     pMTX_Header->ui32Elements = ELEMENTS_EMPTY;
   3493     This_Element = (MTX_HEADER_ELEMENT *) pMTX_Header->asElementStream;
   3494     aui32ElementPointers[0] = This_Element;
   3495 //      MPEG2_WriteBits_SliceHeader(pMTX_Header, aui32ElementPointers);
   3496     pMTX_Header->ui32Elements++; //Has been used as an index, so need to add 1 for a valid element count
   3497 }
   3498 
   3499 
   3500