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