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