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