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