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 * Zeng Li <zeng.li (at) intel.com> 27 * Shengquan Yuan <shengquan.yuan (at) intel.com> 28 * Binglin Chen <binglin.chen (at) intel.com> 29 * 30 */ 31 32 33 #include <stdio.h> 34 #include <string.h> 35 #include "img_types.h" 36 #include "psb_def.h" 37 #include "lnc_hostheader.h" 38 #include "psb_drv_debug.h" 39 40 41 /* Global stores the latest QP information for the DoHeader() 42 * routine, should be filled in by the rate control algorithm. 43 */ 44 #define HEADERS_VERBOSE_OUTPUT 0 45 46 /* #define USESTATICWHEREPOSSIBLE 1 */ 47 48 #define MAXNUMBERELEMENTS 16 49 50 51 /* SOME USEFUL TEST FUNCTIONS */ 52 #ifndef TOPAZ_MTX_HW 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 #ifndef TOPAZ_MTX_HW 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 *) pMTX_Header->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 lnc__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) { 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 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, InputVal.UI8Input[0], (IMG_UINT16) - Shift); 244 } 245 } 246 247 static void lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[EndByte-1], (IMG_UINT8)((bit_cnt) % 8)); 266 else 267 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Bytes[BitLp-1], 8); 272 } 273 } 274 275 static void lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 294 295 /* Write zeros and 1 bit set */ 296 lnc__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 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiChunk, 8); 303 uiVal = uiVal - (uiChunk << ucZeros); 304 } 305 306 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) uiVal, ucZeros); 307 } 308 309 310 static void lnc__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 lnc__generate_ue(mtx_hdr, elt_p, uiCodeNum); 323 } 324 325 326 static void lnc__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 if (elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_STARTCODE_RAWDATA 336 || elt_p[mtx_hdr->Elements]->Element_Type == ELEMENT_RAWDATA) { 337 /*Add a new element aligned to word boundary 338 *Find RAWBit size in bytes (rounded to word boundary)) 339 */ 340 341 /* NumberofRawbits (excluding size of bit count field)+ size of the bitcount field */ 342 Offset = elt_p[mtx_hdr->Elements]->Size + 8 + 31; 343 Offset /= 32;/* Now contains rawbits size in words */ 344 Offset += 1;/* Now contains rawbits+element_type size in words */ 345 Offset *= 4;/* Convert to number of bytes (total size of structure in bytes, aligned to word boundary) */ 346 } else { 347 Offset = 4; 348 } 349 350 mtx_hdr->Elements++; 351 P = (IMG_UINT8 *) elt_p[mtx_hdr->Elements-1]; 352 P += Offset; 353 elt_p[mtx_hdr->Elements] = (MTX_HEADER_ELEMENT *) P; 354 } else 355 mtx_hdr->Elements = 0; 356 357 elt_p[mtx_hdr->Elements]->Element_Type = Token; 358 elt_p[mtx_hdr->Elements]->Size = 0; 359 } 360 361 /* 362 * Intermediary functions to build H264 headers 363 */ 364 static void lnc__H264_writebits_startcode_prefix_element( 365 MTX_HEADER_PARAMS *mtx_hdr, 366 MTX_HEADER_ELEMENT **elt_p, 367 IMG_UINT32 ByteSize) 368 { 369 /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */ 370 IMG_UINT32 Lp; 371 372 /* 373 * Byte aligned (bit 0) 374 * (3 bytes in slice header when slice is first in a picture 375 * without sequence/picture_header before picture 376 */ 377 378 for (Lp = 0; Lp < ByteSize - 1; Lp++) 379 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 380 381 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 382 383 /* Byte aligned (bit 32 or 24) */ 384 return; 385 } 386 387 static void lnc__H264_writebits_sequence_header0( 388 MTX_HEADER_PARAMS *mtx_hdr, 389 MTX_HEADER_ELEMENT **elt_p, 390 H264_SEQUENCE_HEADER_PARAMS *pSHParams) 391 { 392 /* GENERATES THE FIRST ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE */ 393 394 /* 4 Byte StartCodePrefix Pregenerated in: lnc__H264_writebits_startcode_prefix_element() 395 * Byte aligned (bit 32) 396 */ 397 lnc__write_upto8bits_elements( 398 mtx_hdr, 399 elt_p, (0 << 7) |/* forbidden_zero_bit=0 */ 400 (0x3 << 5) |/* nal_ref_idc=01 (may be 11) */ 401 (7), /* nal_unit_type=00111 */ 402 8); 403 404 405 /* Byte aligned (bit 40) 406 * profile_idc = 8 bits = 66 for BP (PROFILE_IDC_BP), 77 for MP (PROFILE_IDC_MP) 407 */ 408 lnc__write_upto8bits_elements( 409 mtx_hdr, 410 elt_p, 411 (pSHParams->ucProfile == SH_PROFILE_BP ? 66 : 77), 412 8); 413 414 /* Byte aligned (bit 48) */ 415 lnc__write_upto8bits_elements( 416 mtx_hdr, 417 elt_p, 418 (1 << 7) |/* constrain_set0_flag = 0 for MP, 1 for BP */ 419 (1 << 6) |/* constrain_set1_flag = 0 for BP, 1 for MP */ 420 (0 << 5) | /* constrain_set2_flag = always 0 in BP/MP */ 421 ((pSHParams->ucLevel == SH_LEVEL_1B ? 1 : 0) << 4), /* constrain_set3_flag = 1 for level 1b, 0 for others */ 422 /* reserved_zero_4bits = 0 */ 423 8); 424 425 /* Byte aligned (bit 56) */ 426 lnc__write_upto8bits_elements( 427 mtx_hdr, 428 elt_p, 429 (IMG_UINT8)((pSHParams->ucLevel > 100) ? (pSHParams->ucLevel - 100) : pSHParams->ucLevel) , 430 8);/* level_idc (8 bits) = 11 for 1b, 10xlevel for others */ 431 432 /* Byte aligned (bit 64) */ 433 lnc__write_upto8bits_elements( 434 mtx_hdr, elt_p, (1 << 7) | /* seq_parameter_Set_id = 0 in Topaz -> ue(0)= 1b */ 435 (2 << 4) | /* log2_max_frame_num_minus4 = 1 in Topaz -> ue(1)= 010b */ 436 (1 << 3) | /* pic_order_cnt_type = 0 in Topaz -> ue(0)= 1b */ 437 (3), /* log2_max_pic_order_cnt_Isb_minus4 = 2 in Topaz -> ue(2)= 011b */ 438 8); 439 } 440 441 static void lnc__H264_writebits_sequence_header1( 442 MTX_HEADER_PARAMS *mtx_hdr, 443 MTX_HEADER_ELEMENT **elt_p, 444 H264_SEQUENCE_HEADER_PARAMS *pSHParams, 445 H264_CROP_PARAMS *psCropParams) 446 { 447 /* GENERATES THE SECOND, VARIABLE LENGTH, ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE 448 * ELEMENT BITCOUNT: xx 449 * pic_width_in_mbs_minus1: ue(v) from 10 to 44 (176 to 720 pixel per row) 450 */ 451 /* max_num_ref_frames = 1 ue(1) = 010b */ 452 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucMax_num_ref_frames); 453 /* gaps_in_frame_num_value_allowed_Flag - (1 bit) - Not supported 454 * in Topaz (0) */ 455 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 456 457 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucWidth_in_mbs_minus1); 458 459 /* pic_height_in_maps_units_minus1: ue(v) Value from 8 to 35 (144 to 576 pixels per column) */ 460 lnc__generate_ue(mtx_hdr, elt_p, pSHParams->ucHeight_in_maps_units_minus1); 461 462 /* We don't know the alignment at this point, so will have to use bit writing functions */ 463 lnc__write_upto8bits_elements( 464 mtx_hdr, elt_p, 465 (1 << 2) | /* frame_mb_only_flag (always 1) */ 466 (1 << 1), /* direct_8x8_inference_flag=1 in Topaz */ 467 2); 468 469 if (psCropParams && psCropParams->bClip) { 470 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 471 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->LeftCropOffset); 472 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->RightCropOffset); 473 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->TopCropOffset); 474 lnc__generate_ue(mtx_hdr, elt_p, psCropParams->BottomCropOffset); 475 476 } else { 477 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 478 } 479 } 480 481 482 static void lnc__H264_writebits_VUI_params( 483 MTX_HEADER_PARAMS *mtx_hdr, 484 MTX_HEADER_ELEMENT **elt_p, 485 H264_VUI_PARAMS *VUIParams) 486 { 487 /* Builds VUI Params for the Sequence Header (only present in the 1st sequence of stream) */ 488 lnc__write_upto8bits_elements( 489 mtx_hdr, elt_p, 490 (0 << 4) | /* aspect_ratio_info_present_flag = 0 in Topaz */ 491 (0 << 3) | /* overscan_info_present_flag (1 bit) = 0 in Topaz */ 492 (0 << 2) | /* video_signal_type_present_flag (1 bit) = 0 in Topaz */ 493 (0 << 1) | /* chroma_loc_info_present_flag (1 bit) = 0 in Topaz */ 494 (1),/* timing_info_present_flag (1 bit) = 1 in Topaz */ 495 5); 496 497 /* num_units_in_tick (32 bits) = 1 in Topaz */ 498 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 499 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 500 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 501 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 502 503 /* time_scale (32 bits) = frame rate */ 504 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 505 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 506 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 507 lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8) VUIParams->Time_Scale, 8); 508 509 /* fixed_frame_rate_flag (1 bit) = 1 in Topaz */ 510 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 511 /* nal_hrd_parameters_present_flag (1 bit) = 1 in Topaz */ 512 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 513 514 /** Definitions for nal_hrd_parameters() contained in VUI structure for Topaz 515 * cpb_cnt_minus1 ue(v) = 0 in Topaz = 1b 516 */ 517 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 518 /* bit_rate_scale (4 bits) = 0 in Topaz, cpb_size_scale (4 bits) = 0 in Topaz */ 519 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 2, 8); 520 521 /* bit_rate_value_minus1[0] ue(v) = (Bitrate/64)-1 [RANGE:0 to (2^32)-2] */ 522 lnc__generate_ue(mtx_hdr, elt_p, VUIParams->bit_rate_value_minus1); 523 /* cpb_size_value_minus1[0] ue(v) = (CPB_Bits_Size/16)-1 524 * where CPB_Bits_Size = 1.5 * Bitrate [RANGE:0 to (2^32)-2] 525 */ 526 lnc__generate_ue(mtx_hdr, elt_p, VUIParams->cbp_size_value_minus1); 527 528 /* cbr_flag[0] (1 bit) = 0 for VBR, 1 for CBR */ 529 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VUIParams->CBR, 1); 530 531 lnc__write_upto8bits_elements( 532 mtx_hdr, elt_p, 533 VUIParams->initial_cpb_removal_delay_length_minus1, 534 5); /* initial_cpb_removal_delay_length_minus1 (5 bits) = ??? */ 535 536 lnc__write_upto8bits_elements( 537 mtx_hdr, 538 elt_p, 539 VUIParams->cpb_removal_delay_length_minus1, 540 5); /* cpb_removal_delay_length_minus1 (5 bits) = ??? */ 541 542 lnc__write_upto8bits_elements( 543 mtx_hdr, elt_p, 544 VUIParams->dpb_output_delay_length_minus1, 545 5); /* dpb_output_delay_length_minus1 (5 bits) = ??? */ 546 547 lnc__write_upto8bits_elements( 548 mtx_hdr, 549 elt_p, 550 VUIParams->time_offset_length, 551 5); /* time_offst_length (5 bits) = ??? */ 552 553 /* End of nal_hrd_parameters() */ 554 555 lnc__write_upto8bits_elements( 556 mtx_hdr, 557 elt_p, 558 0, 1);/* vcl_hrd_parameters_present_flag (1 bit) = 0 in Topaz */ 559 560 /* if( nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag ) 561 * FIX for BRN23039 562 * low_delay_hrd_flag 563 */ 564 lnc__write_upto8bits_elements( 565 mtx_hdr, elt_p, 566 0, 1);/* low_delay_hrd_flag */ 567 568 569 lnc__write_upto8bits_elements( 570 mtx_hdr, elt_p, 571 0, 1);/* pic_struct_present_flag (1 bit) = 0 in Topaz */ 572 573 lnc__write_upto8bits_elements( 574 mtx_hdr, elt_p, 575 0, 1);/* bitstream_restriction_flag (1 bit) = 0 in Topaz */ 576 } 577 578 static void lnc__H264_writebits_sequence_header2( 579 MTX_HEADER_PARAMS *mtx_hdr, 580 MTX_HEADER_ELEMENT **elt_p, 581 H264_SEQUENCE_HEADER_PARAMS *pSHParams) 582 { 583 /* GENERATES THE THIRD ELEMENT OF THE H264_SEQUENCE_HEADER() STRUCTURE 584 * ELEMENT BITCOUNT: xx 585 */ 586 IMG_UINT8 SBP; 587 lnc__write_upto8bits_elements( 588 mtx_hdr, elt_p, 589 (pSHParams->VUI_Params_Present),/* vui_parameters_present_flag (VUI only in 1st sequence of stream) */ 590 1); 591 592 if (pSHParams->VUI_Params_Present > 0) 593 lnc__H264_writebits_VUI_params(mtx_hdr, elt_p, &(pSHParams->VUI_Params)); 594 595 /* Finally we need to align to the next byte 596 * We know the size of the data in the sequence header (no MTX variables) 597 * and start is byte aligned, so it's possible to add this field here rather than 598 * MTX ELEMENT_INSERTBYTEALIGN_H264 command. 599 */ 600 601 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 602 SBP = (elt_p[mtx_hdr->Elements]->Size) & 7; 603 604 if (SBP > 0) lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8 - (SBP)); 605 } 606 607 static void lnc__H264_writebits_picture_header0( 608 MTX_HEADER_PARAMS *mtx_hdr, 609 MTX_HEADER_ELEMENT **elt_p) 610 { 611 /* GENERATES THE FIRST (STATIC) ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE 612 * ELEMENT BITCOUNT: 18 613 */ 614 615 /* 4 Byte StartCodePrefix Pregenerated in: lnc__H264_writebits_startcode_prefix_element() 616 * Byte aligned (bit 32) 617 */ 618 lnc__write_upto8bits_elements( 619 mtx_hdr, 620 elt_p, (0 << 7) | /* forbidden_zero_bit */ 621 (1 << 5) | /* nal_ref_idc (2 bits) = 1 */ 622 (8),/* nal_unit_tpye (5 bits) = 8 */ 623 8); 624 625 /* Byte aligned (bit 40) */ 626 lnc__write_upto8bits_elements( 627 mtx_hdr, 628 elt_p, 629 (1 << 7) | /* pic_parameter_set_id ue(v) = 0 in Topaz */ 630 (1 << 6) | /* seq_parameter_set_id ue(v) = 0 in Topaz */ 631 (0 << 5) | /* entropy_coding_mode_flag (1 bit) 0 for CAVLC */ 632 (0 << 4) | /* pic_order_present_flag (1 bit) = 0 */ 633 (1 << 3) | /* num_slice_group_minus1 ue(v) = 0 in Topaz */ 634 (1 << 2) | /* num_ref_idx_l0_active_minus1 ue(v) = 0 in Topaz */ 635 (1 << 1) | /* num_ref_idx_l1_active_minus1 ue(v) = 0 in Topaz */ 636 (0), /* weighted_pred_flag (1 bit) = 0 in Topaz */ 637 8); 638 639 /* Byte aligned (bit 48) */ 640 lnc__write_upto8bits_elements( 641 mtx_hdr, 642 elt_p, 0, 643 2);/* weighted_bipred_flag (2 bits) = 0 in Topaz */ 644 } 645 646 static void lnc__H264_writebits_picture_header1( 647 MTX_HEADER_PARAMS *mtx_hdr, 648 MTX_HEADER_ELEMENT **elt_p) 649 { 650 /* GENERATES THE SECOND ELEMENT OF THE H264_PICTURE_HEADER() STRUCTURE 651 * ELEMENT BITCOUNT: 5 652 */ 653 654 /* The following field will be generated as a special case by MTX - so not here 655 * lnc__generate_se(mtx_hdr, pPHParams->pic_init_qp_minus26); // pic_int_qp_minus26 se(v) = -26 to 25 in Topaz 656 */ 657 lnc__generate_se(mtx_hdr, elt_p, 0); /* pic_int_qs_minus26 se(v) = 0 in Topaz */ 658 lnc__generate_se(mtx_hdr, elt_p, 0); /* chroma_qp_index_offset se(v) = 0 in Topaz */ 659 660 lnc__write_upto8bits_elements( 661 mtx_hdr, 662 elt_p, 663 (1 << 2) | /* deblocking_filter_control_present_flag (1 bit) = 1 in Topaz */ 664 (0 << 1) | /* constrained_intra_pred_Flag (1 bit) = 0 in Topaz */ 665 (0), /* redundant_pic_cnt_present_flag (1 bit) = 0 in Topaz */ 666 3); 667 668 /* Byte align is done using an element command (MTX elements in this structure, we don't know it's size) */ 669 } 670 671 672 static void lnc__H264_writebits_slice_header0( 673 MTX_HEADER_PARAMS *mtx_hdr, 674 MTX_HEADER_ELEMENT **elt_p, 675 H264_SLICE_HEADER_PARAMS *pSlHParams) 676 { 677 /* GENERATES THE FIRST ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE 678 * ELEMENT BITCOUNT: 8 679 * 680 * StartCodePrefix Pregenerated in: Build_H264_4Byte_StartCodePrefix_Element() (4 or 3 bytes) 681 * (3 bytes when slice is first in a picture without sequence/picture_header before picture 682 * Byte aligned (bit 32 or 24) 683 * NOTE: Slice_Type and Frame_Type are always the same, hence SliceFrame_Type 684 */ 685 lnc__write_upto8bits_elements( 686 mtx_hdr, elt_p, 687 (0 << 7) |/* forbidden_zero_bit */ 688 ((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 */ 689 ((pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE ? 5 : 1)),/* nal_unit_tpye (5 bits) = I-frame IDR, and 1 for rest */ 690 8); 691 } 692 693 694 static void lnc__H264_writebits_slice_header1( 695 MTX_HEADER_PARAMS *mtx_hdr, 696 MTX_HEADER_ELEMENT **elt_p, 697 H264_SLICE_HEADER_PARAMS *pSlHParams, 698 IMG_UINT16 uiIdrPicId) 699 { 700 /* GENERATES THE SECOND ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE 701 * The following is slice parameter set in BP/MP 702 */ 703 704 /* first_mb_in_slice = First MB address in slice: ue(Range 0 - 1619) */ 705 lnc__generate_ue(mtx_hdr, elt_p, (IMG_UINT32) pSlHParams->First_MB_Address); 706 707 lnc__generate_ue( 708 mtx_hdr, elt_p, 709 (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 */ 710 711 /* kab: not clean change from IDR to intra, IDR should have separate flag */ 712 713 lnc__write_upto8bits_elements( 714 mtx_hdr, elt_p, 715 (1 << 5) | /* pic_parameter_set_id, ue(v) = 0 (=1b) in Topaz */ 716 pSlHParams->Frame_Num_DO,/* frame_num (5 bits) = frame nuo. in decoding order */ 717 6); 718 719 /* frame_mb_only_flag is always 1, so no need for field_pic_flag or bottom_field_flag */ 720 if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) 721 lnc__generate_ue(mtx_hdr, elt_p, uiIdrPicId); 722 723 /* kab: Idr_pic_id only for IDR, not nessesarely for all I pictures */ 724 725 /* if (pic_order_cnt_type == 0) //Note: (pic_order_cnt_type always 0 in Topaz) */ 726 lnc__write_upto8bits_elements( 727 mtx_hdr, elt_p, 728 pSlHParams->Picture_Num_DO, 729 6); /* pic_order_cnt_lsb (6 bits) - picture no in display order */ 730 731 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) 732 lnc__write_upto8bits_elements( 733 mtx_hdr, 734 elt_p, 735 0, 736 1);/* direct_spatial_mv_pred_flag (1 bit) = 0, spatial direct mode not supported in Topaz */ 737 738 if (pSlHParams->SliceFrame_Type == SLHP_P_SLICEFRAME_TYPE || pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) 739 lnc__write_upto8bits_elements( 740 mtx_hdr, 741 elt_p, 742 0, 743 1);/* num_ref_idx_active_override_flag (1 bit) = 0 in Topaz */ 744 745 if (pSlHParams->SliceFrame_Type != SLHP_I_SLICEFRAME_TYPE && 746 pSlHParams->SliceFrame_Type != SLHP_IDR_SLICEFRAME_TYPE) { 747 if (pSlHParams->bUsesLongTermRef) { 748 /* ref_pic_list_ordering_flag_IO (1 bit) = 1, L0 749 * reference picture ordering */ 750 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 751 752 /* modification_of_pic_nums_idc = 2 */ 753 lnc__generate_ue(mtx_hdr, elt_p, 2); 754 /* long_term_pic_num = 0 */ 755 lnc__generate_ue(mtx_hdr, elt_p, 0); 756 /* modification_of_pic_nums_idc = 3 */ 757 lnc__generate_ue(mtx_hdr, elt_p, 3); 758 } else { 759 /* ref_pic_list_ordering_flag_IO (1 bit) = 0, no 760 * L0 reference picture ordering */ 761 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 762 } 763 } 764 765 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) 766 lnc__write_upto8bits_elements( 767 mtx_hdr, 768 elt_p, 769 0, 770 1); /* ref_pic_list_ordering_flag_I1 (1 bit) = 0, no L1 reference picture ordering in Topaz */ 771 772 if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) { 773 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);/* no_output_of_prior_pics_flag (1 bit) = 0 */ 774 lnc__write_upto8bits_elements(mtx_hdr, elt_p, pSlHParams->bIsLongTermRef ? 1 : 0, 1);/* long_term_reference_flag (1 bit) */ 775 } else if (pSlHParams->bIsLongTermRef) { 776 /* adaptive_ref_pic_marking_mode_flag (1 bit) = 1 */ 777 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 778 /* allow a single long-term reference */ 779 /* memory_management_control_operation */ 780 lnc__generate_ue(mtx_hdr, elt_p, 4); 781 /* max_long_term_frame_idx_plus1 */ 782 lnc__generate_ue(mtx_hdr, elt_p, 1); 783 /* set current picture as the long-term reference */ 784 /* memory_management_control_operation */ 785 lnc__generate_ue(mtx_hdr, elt_p, 6); 786 /* long_term_frame_idx */ 787 lnc__generate_ue(mtx_hdr, elt_p, 0); 788 /* END */ 789 lnc__generate_ue(mtx_hdr, elt_p, 0); 790 } else { 791 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1);/* adaptive_ref_pic_marking_mode_flag (1 bit) = 0 */ 792 } 793 } 794 795 796 static void lnc__H264_writebits_slice_header2( 797 MTX_HEADER_PARAMS *mtx_hdr, 798 MTX_HEADER_ELEMENT **elt_p, 799 H264_SLICE_HEADER_PARAMS *pSlHParams) 800 { 801 /* GENERATES ELEMENT OF THE H264_SLICE_HEADER() STRUCTURE 802 * ELEMENT BITCOUNT: 11 803 */ 804 805 #if 0 806 /* Next field is generated on MTX with a special commnad (not ELEMENT_RAW) - so not defined here */ 807 808 /* slice_qp_delta se(v) = SliceQPy - (pic_init_qp_minus26+26) */ 809 /* pucHS=lnc__generate_se(pucHS, puiBitPos, pSlHParams->Slice_QP_Delta); */ 810 #endif 811 812 lnc__generate_ue( 813 mtx_hdr, 814 elt_p, 815 pSlHParams->Disable_Deblocking_Filter_Idc); /* disable_deblocking_filter_idc ue(v) = 2? */ 816 817 if (pSlHParams->Disable_Deblocking_Filter_Idc != 1) { 818 lnc__generate_se(mtx_hdr, elt_p, 0); /* slice_alpha_c0_offset_div2 se(v) = 0 (1b) in Topaz */ 819 lnc__generate_se(mtx_hdr, elt_p, 0); /* slice_beta_offset_div2 se(v) = 0 (1b) in Topaz */ 820 } 821 822 /* num_slice_groups_minus1 ==0 in Topaz, so no slice_group_change_cycle field here 823 * no byte alignment at end of slice headers 824 */ 825 } 826 827 828 829 static void lnc__H264_writebits_sequence_header( 830 MTX_HEADER_PARAMS *mtx_hdr, 831 MTX_HEADER_ELEMENT **elt_p, 832 H264_SEQUENCE_HEADER_PARAMS *pSHParams, 833 H264_CROP_PARAMS *psCropParams) 834 { 835 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 836 837 lnc__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4); 838 lnc__H264_writebits_sequence_header0(mtx_hdr, elt_p, pSHParams); 839 lnc__H264_writebits_sequence_header1(mtx_hdr, elt_p, pSHParams, psCropParams); 840 lnc__H264_writebits_sequence_header2(mtx_hdr, elt_p, pSHParams); 841 } 842 843 844 static void lnc__H264_writebits_picture_header( 845 MTX_HEADER_PARAMS *mtx_hdr, 846 MTX_HEADER_ELEMENT **elt_p) 847 { 848 /* Begin building the picture header element */ 849 #ifdef USESTATICWHEREPOSSIBLE 850 IMG_UINT32 *p; 851 p = (IMG_UINT32 *) mtx_hdr; 852 p[0] = 3; 853 p[1] = 0; 854 p[2] = 50; 855 p[3] = 13510657; 856 p[4] = 2; 857 p[5] = 1; 858 p[6] = 57349; 859 p[7] = 6; 860 #else 861 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 862 863 lnc__H264_writebits_startcode_prefix_element(mtx_hdr, elt_p, 4); 864 lnc__H264_writebits_picture_header0(mtx_hdr, elt_p); 865 866 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_QP); /* MTX fills this value in */ 867 868 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 869 lnc__H264_writebits_picture_header1(mtx_hdr, elt_p); 870 871 /* Tell MTX to insert the byte align field */ 872 /* (we don't know final stream size for alignment at this point) */ 873 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264); 874 #endif 875 876 } 877 878 879 static void lnc__H264_writebits_slice_header( 880 MTX_HEADER_PARAMS *mtx_hdr, 881 MTX_HEADER_ELEMENT **elt_p, 882 H264_SLICE_HEADER_PARAMS *pSlHParams, 883 IMG_UINT16 uiIdrPicId) 884 { 885 #ifdef USESTATICWHEREPOSSIBLE 886 IMG_UINT32 *p; 887 p = (IMG_UINT32 *) mtx_hdr; 888 889 p[0] = p[1] = 0; 890 p[2] = 40; 891 if (pSlHParams->SliceFrame_Type == SLHP_B_SLICEFRAME_TYPE) p[3] = 257; 892 else if (pSlHParams->SliceFrame_Type == SLHP_IDR_SLICEFRAME_TYPE) p[3] = 9473; 893 else p[3] = 8449; 894 #else 895 /* -- Begin building the picture header element */ 896 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 897 898 lnc__H264_writebits_startcode_prefix_element( 899 mtx_hdr, 900 elt_p, 901 pSlHParams->Start_Code_Prefix_Size_Bytes); /* Can be 3 or 4 bytes - always 4 bytes in our implementations */ 902 lnc__H264_writebits_slice_header0(mtx_hdr, elt_p, pSlHParams); 903 #endif 904 905 lnc__H264_writebits_slice_header1(mtx_hdr, elt_p, pSlHParams, uiIdrPicId); 906 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_SQP); //MTX fills this value in 907 908 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 909 lnc__H264_writebits_slice_header2(mtx_hdr, elt_p, pSlHParams); 910 911 /* no byte alignment at end of slice headers */ 912 } 913 914 915 static void lnc__H264_writebits_endofsequence_header( 916 MTX_HEADER_PARAMS *mtx_hdr, 917 MTX_HEADER_ELEMENT **elt_p) 918 { 919 /* GENERATES THE FIRST ELEMENT OF THE H264_ENDOFSEQUENCE_HEADER() STRUCTURE */ 920 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 921 922 /* Byte aligned (bit 32) */ 923 lnc__write_upto8bits_elements( 924 mtx_hdr, 925 elt_p, 926 (0 << 7) |/* forbidden_zero_bit=0 */ 927 (0 << 5) |/* nal_ref_idc=0 for nal_unit_type=10 */ 928 (10),/* nal_unit_type=10 */ 929 8); 930 } 931 932 933 static void lnc__H264_writebits_SEI_rbspheader( 934 MTX_HEADER_PARAMS *mtx_hdr, 935 MTX_HEADER_ELEMENT **elt_p, 936 IMG_UINT32 Initial_cpb_removal_delay) 937 { 938 /* Byte aligned (bit 32) */ 939 lnc__H264_writebits_startcode_prefix_element( 940 mtx_hdr, elt_p, 4);/* 32 bit start code prefix */ 941 942 lnc__write_upto8bits_elements( 943 mtx_hdr, 944 elt_p, 945 (0 << 7) |/* forbidden_zero_bit */ 946 (1 << 5) |/* nal_ref_idc (2 bits) = 1 */ 947 (6),/* nal_unit_tpye (5 bits) = 6 (SEI packet) */ 948 8); 949 950 /* last_payload_type_byte (8 bits) = 0 for buffering period */ 951 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 952 953 /* last_payload_size_byte (8 bits) = 41 as SEI_message length is 41-bit */ 954 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 41, 8); 955 956 /* sequence_parameter_set_id ue(0) = 1b sequence_parameter_set_id=0 in Topaz */ 957 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 958 959 /* Initial_cpb_removal_delay (20 bits) x is initial cpb delay of each sequence */ 960 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Initial_cpb_removal_delay, 20); 961 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 962 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 963 964 /* Initial_cpb_removal_delay_offset (20 bits) 0x10101 (It won't be used in Topaz) */ 965 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4); 966 967 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */ 968 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264); 969 } 970 971 972 static void lnc__H264_writebits_endofstream_header( 973 MTX_HEADER_PARAMS *mtx_hdr, 974 MTX_HEADER_ELEMENT **elt_p) 975 { 976 /* GENERATES THE FIRST ELEMENT OF THE H264_ENDOFSTREAM_HEADER() STRUCTURE */ 977 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 978 /* Byte aligned (bit 32) */ 979 lnc__write_upto8bits_elements( 980 mtx_hdr, 981 elt_p, 982 (0 << 7) |/* forbidden_zero_bit=0 */ 983 (0 << 5) |/* nal_ref_idc=0 for nal_unit_type=11 */ 984 (11),/* nal_unit_type=11 */ 985 8); 986 } 987 988 /* 989 * High level functions to call when a H264 header is required 990 */ 991 static void lnc__H264_getelements_skip_B_slice( 992 MTX_HEADER_PARAMS *mtx_hdr, 993 H264_SLICE_HEADER_PARAMS *pSlHParams, 994 IMG_UINT8 MB_No_In_Slice) 995 { 996 /* Skipped P-Slice 997 * Ensure pSlHParams is filled with appropriate parameters for a P-slice 998 * Essential we initialise our header structures before building 999 */ 1000 MTX_HEADER_ELEMENT *This_Element; 1001 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1002 mtx_hdr->Elements = ELEMENTS_EMPTY; 1003 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1004 elt_p[0] = This_Element; 1005 1006 /* Not sure if this will be required in the final spec 1007 * lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); 1008 */ 1009 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, 0); 1010 1011 /* mb_skip_run = mb_no_in_slice */ 1012 lnc__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice); 1013 1014 /* Tell MTX to insert the byte align field 1015 * (we don't know final stream size for alignment at this point) 1016 */ 1017 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264); 1018 1019 /* Has been used as an index, so need to add 1 for a valid element count */ 1020 mtx_hdr->Elements++; 1021 } 1022 1023 static void lnc__H264_getelements_backward_zero_B_slice( 1024 MTX_HEADER_PARAMS *mtx_hdr, 1025 IMG_UINT8 MB_No_In_Slice) 1026 { 1027 /* Skipped P-Slice 1028 * Ensure pSlHParams is filled with appropriate parameters for a P-slice 1029 * Essential we initialise our header structures before building 1030 */ 1031 IMG_UINT8 Lp; 1032 MTX_HEADER_ELEMENT *This_Element; 1033 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1034 mtx_hdr->Elements = ELEMENTS_EMPTY; 1035 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1036 elt_p[0] = This_Element; 1037 1038 for (Lp = 0; Lp < MB_No_In_Slice; Lp++) { 1039 /* mb_skip_run = ue(0) = 1b */ 1040 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1041 /* backward_zero_B_mb() - all static */ 1042 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 15, 5); 1043 } 1044 1045 /* Tell MTX to insert the byte align field 1046 * (we don't know final stream size for alignment at this point) 1047 */ 1048 lnc__insert_element_token( 1049 mtx_hdr, 1050 elt_p, 1051 ELEMENT_INSERTBYTEALIGN_H264); 1052 1053 /* Has been used as an index, so need to add 1 for a valid element count */ 1054 mtx_hdr->Elements++; 1055 } 1056 1057 1058 static void lnc__H264_getelements_rbsp_ATE_only(MTX_HEADER_PARAMS *mtx_hdr) 1059 { 1060 /* Skipped P-Slice 1061 * Ensure pSlHParams is filled with appropriate parameters for a P-slice 1062 * Essential we initialise our header structures before building 1063 */ 1064 MTX_HEADER_ELEMENT *This_Element; 1065 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1066 mtx_hdr->Elements = ELEMENTS_EMPTY; 1067 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1068 elt_p[0] = This_Element; 1069 1070 /* Tell MTX to insert the byte align field 1071 * (we don't know final stream size for alignment at this point) 1072 */ 1073 lnc__insert_element_token( 1074 mtx_hdr, 1075 elt_p, 1076 ELEMENT_INSERTBYTEALIGN_H264); 1077 1078 /* Has been used as an index, so need to add 1 for a valid element count */ 1079 mtx_hdr->Elements++; 1080 } 1081 1082 1083 static void lnc__H264_getelements_skip_P_slice( 1084 MTX_HEADER_PARAMS *mtx_hdr, 1085 H264_SLICE_HEADER_PARAMS *pSlHParams, 1086 IMG_UINT32 MB_No_In_Slice) 1087 { 1088 /* Skipped P-Slice 1089 * Ensure pSlHParams is filled with appropriate parameters for a B-slice 1090 * Essential we initialise our header structures before building 1091 */ 1092 MTX_HEADER_ELEMENT *This_Element; 1093 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1094 mtx_hdr->Elements = ELEMENTS_EMPTY; 1095 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1096 elt_p[0] = This_Element; 1097 1098 /* lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER); */ 1099 /* Not sure if this will be required in the final spec */ 1100 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, 0); 1101 lnc__generate_ue(mtx_hdr, elt_p, MB_No_In_Slice); /* mb_skip_run = mb_no_in_slice */ 1102 1103 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) */ 1104 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_H264); 1105 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1106 } 1107 1108 1109 1110 static void lnc__H264_getelements_sequence_header( 1111 MTX_HEADER_PARAMS *mtx_hdr, 1112 H264_SEQUENCE_HEADER_PARAMS *pSHParams, 1113 H264_CROP_PARAMS *psCropParams) 1114 { 1115 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame) 1116 * Essential we initialise our header structures before building 1117 */ 1118 MTX_HEADER_ELEMENT *This_Element; 1119 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1120 mtx_hdr->Elements = ELEMENTS_EMPTY; 1121 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1122 elt_p[0] = This_Element; 1123 1124 lnc__H264_writebits_sequence_header(mtx_hdr, elt_p, pSHParams, psCropParams); 1125 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1126 } 1127 1128 1129 static void lnc__H264_getelements_picture_header(MTX_HEADER_PARAMS *mtx_hdr) 1130 { 1131 /* Builds a sequence, picture and slice header with from the given inputs parameters (start of new frame) 1132 * Essential we initialise our header structures before building 1133 */ 1134 MTX_HEADER_ELEMENT *This_Element; 1135 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1136 mtx_hdr->Elements = ELEMENTS_EMPTY; 1137 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1138 elt_p[0] = This_Element; 1139 1140 lnc__H264_writebits_picture_header(mtx_hdr, elt_p); 1141 mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count 1142 } 1143 1144 1145 static void lnc__H264_getelements_slice_header( 1146 MTX_HEADER_PARAMS *mtx_hdr, 1147 H264_SLICE_HEADER_PARAMS *pSlHParams, 1148 IMG_UINT16 uiIdrPicId) 1149 { 1150 /* Builds a single slice header from the given parameters (mid frame) 1151 * Essential we initialise our header structures before building 1152 */ 1153 MTX_HEADER_ELEMENT *This_Element; 1154 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1155 mtx_hdr->Elements = ELEMENTS_EMPTY; 1156 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1157 elt_p[0] = This_Element; 1158 1159 /* Not sure if this will be required in the final spec */ 1160 /* lnc__insert_element_token(mtx_hdr, ELEMENT_STARTCOUNTER);*/ 1161 lnc__H264_writebits_slice_header(mtx_hdr, elt_p, pSlHParams, uiIdrPicId); 1162 1163 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1164 } 1165 1166 1167 static void lnc__H264_getelements_endofsequence_header( 1168 MTX_HEADER_PARAMS *mtx_hdr) 1169 { 1170 /* Builds a single endofsequence header from the given parameters (mid frame) */ 1171 1172 /* Essential we initialise our header structures before building */ 1173 MTX_HEADER_ELEMENT *This_Element; 1174 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1175 mtx_hdr->Elements = ELEMENTS_EMPTY; 1176 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1177 elt_p[0] = This_Element; 1178 1179 lnc__H264_writebits_endofsequence_header(mtx_hdr, elt_p); 1180 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1181 } 1182 1183 1184 1185 static void lnc__H264_getelements_endofstream_header(MTX_HEADER_PARAMS *mtx_hdr) 1186 { 1187 /* Builds a single endofstream header from the given parameters (mid frame) */ 1188 1189 /* Essential we initialise our header structures before building */ 1190 MTX_HEADER_ELEMENT *This_Element; 1191 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1192 mtx_hdr->Elements = ELEMENTS_EMPTY; 1193 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1194 elt_p[0] = This_Element; 1195 1196 lnc__H264_writebits_endofstream_header(mtx_hdr, elt_p); 1197 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1198 } 1199 1200 static IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal) 1201 { 1202 IMG_UINT8 Bits = 32; 1203 if (CodeVal == 0) 1204 return 1; 1205 while (!(CodeVal & 0x80000000)) { 1206 CodeVal <<= 1; 1207 Bits--; 1208 } 1209 return Bits; 1210 } 1211 1212 /* 1213 * Intermediary functions to build MPEG4 headers 1214 */ 1215 #define MATCH_TO_ENC 1216 1217 1218 static void lnc__MPEG4_writebits_sequence_header( 1219 MTX_HEADER_PARAMS *mtx_hdr, 1220 MTX_HEADER_ELEMENT **elt_p, 1221 IMG_BOOL bBFrame, 1222 MPEG4_PROFILE_TYPE bProfile, 1223 IMG_UINT8 Profile_and_level_indication, 1224 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment, 1225 IMG_UINT32 Picture_Width_Pixels, 1226 IMG_UINT32 Picture_Height_Pixels, 1227 VBVPARAMS *sVBVParams, IMG_UINT32 VopTimeResolution) /* Send NULL pointer if there are no VBVParams */ 1228 { 1229 /* Essential we insert the element before we try to fill it! */ 1230 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 1231 1232 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */ 1233 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32); 1234 1235 /* profile_and_level_indication = 8 Bits = SP L0-L3 and SP L4-L5 are supported */ 1236 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8); 1237 1238 /* visual_object_start_code = 32 Bits = 0x1B5 */ 1239 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1240 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1241 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 1242 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 181, 8); 1243 1244 /* is_visual_object_identifier = 1 Bit = 0 */ 1245 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1246 1247 /* visual_object_type = 4 Bits = Video ID = 1 */ 1248 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4); 1249 1250 /* video_signal_type = 1 Bit = 1 */ 1251 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1252 1253 /* byte_aligned_bits = 2 Bits = 01b (byte_aligned_bits is 2-bit stuffing bit field 01) */ 1254 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2); 1255 1256 /* video_object_start_code = 32 Bits = 0x100 One VO only in a Topaz video stream */ 1257 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1258 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1259 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 1260 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1261 1262 /* video_object_layer_start_code = 32 Bits = 0x120 One VOL only in a Topaz stream */ 1263 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1264 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 8); 1265 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 1266 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 32, 8); 1267 1268 /* random_accessible_vol = 1 Bit = 0 (P-Frame in GOP) */ 1269 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1270 1271 if (bProfile == SP) { 1272 /* video_object_type_indication = 8 Bits = 0x01 for SP */ 1273 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 8); 1274 #ifndef MATCH_TO_ENC 1275 /* is_object_layer_identifier = 1 Bit = 0 for SP */ 1276 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1277 #else 1278 /* to match the encoder */ 1279 1280 /* is_object_layer_identifier = 1 Bit */ 1281 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1282 1283 /* video_object_layer_verid = 4 Bits */ 1284 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4); 1285 1286 /* video_object_layer_priority = 3 Bits */ 1287 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3); // 0 is reserved... 1288 #endif 1289 } else { 1290 /* video_object_type_indication = 8 Bits = 0x11 for ASP */ 1291 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 3, 8); 1292 1293 /* is_object_layer_identifier = 1 Bit = 1 for ASP */ 1294 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1295 1296 /* video_object_layer_verid = 4 Bits = 5 is for ASP */ 1297 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 5, 4); 1298 1299 /* video_object_layer_priority = 3 Bits = 1 (Highest priority) */ 1300 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 3); 1301 } 1302 1303 /* aspect_ratio_info = 4 Bits =0x1 (Square pixel) */ 1304 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4); 1305 #ifndef MATCH_TO_ENC 1306 /* vol_control_parameters = 1 Bit = 1 (Always send VOL control parameters) */ 1307 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1308 #else 1309 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1310 1311 #endif 1312 1313 #ifndef MATCH_TO_ENC 1314 /* chroma_format = 2 Bits = 01b (4:2:0) */ 1315 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2); 1316 1317 /* low_delay = 1 Bit = 0 with B-frame and 1 without B-frame */ 1318 if (bBFrame) 1319 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1320 else 1321 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1322 1323 /* vbv_parameters = 1 Bit =0/1 */ 1324 if (sVBVParams) { 1325 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1326 1327 /* For recording, only send vbv parameters in 1st sequence header. 1328 * For video phone, it should be sent more often, such as once per sequence 1329 */ 1330 lnc__write_upto32bits_elements( 1331 mtx_hdr, 1332 elt_p, 1333 sVBVParams->First_half_bit_rate, 1334 15); /* first_half_bit_rate */ 1335 1336 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */ 1337 lnc__write_upto32bits_elements( 1338 mtx_hdr, 1339 elt_p, 1340 sVBVParams->Latter_half_bit_rate, 1341 15); /* latter_half_bit_rate */ 1342 1343 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */ 1344 lnc__write_upto32bits_elements( 1345 mtx_hdr, 1346 elt_p, 1347 sVBVParams->First_half_vbv_buffer_size, 1348 15);/* first_half_vbv_buffer_size */ 1349 1350 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1351 lnc__write_upto32bits_elements( 1352 mtx_hdr, elt_p, 1353 sVBVParams->Latter_half_vbv_buffer_size, 1354 15); /* latter_half_vbv_buffer_size */ 1355 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */ 1356 lnc__write_upto32bits_elements( 1357 mtx_hdr, 1358 elt_p, 1359 sVBVParams->First_half_vbv_occupancy, 1360 15); /* first_half_vbv_occupancy */ 1361 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */ 1362 lnc__write_upto32bits_elements( 1363 mtx_hdr, 1364 elt_p, 1365 sVBVParams->Latter_half_vbv_occupancy, 1366 15); /* latter_half_vbv_occupancy */ 1367 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1);/* Marker Bit = 1 */ 1368 } else 1369 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); /* No vbv parameters present */ 1370 #endif 1371 /* video_object_layer_shape = 2 Bits = 00b Rectangular shape */ 1372 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2); 1373 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1374 1375 /* vop_time_increment_solution = 16 Bits */ 1376 lnc__write_upto32bits_elements(mtx_hdr, elt_p, VopTimeResolution, 16); 1377 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1378 1379 #ifndef MATCH_TO_ENC 1380 /* fixed_vop_rate = 1 Bits = 1 Always fixed frame rate */ 1381 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1382 1383 /* fixed_vop_time_increment = Variable number of bits based on the time increment resolution. */ 1384 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, Bits2Code(VopTimeResolution - 1)); 1385 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1386 #else 1387 /* fixed_vop_rate = 1 Bits = 0 */ 1388 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1389 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1390 1391 #endif 1392 /* video_object_layer_width = 13 Bits Picture width in pixel units */ 1393 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Width_Pixels, 13); 1394 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1395 1396 /* video_object_layer_height = 13 Bits Picture height in pixel units */ 1397 lnc__write_upto32bits_elements(mtx_hdr, elt_p, Picture_Height_Pixels, 13); 1398 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); /* Marker Bit = 1 */ 1399 1400 /* interlaced = 1 Bit = 0 Topaz only encodes progressive frames */ 1401 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1402 1403 /* obmc_disable = 1 Bit = 1 No overlapped MC in Topaz */ 1404 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1405 1406 /* sprite_enable = 1 Bit = 0 Not use sprite in Topaz */ 1407 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1408 1409 /* not_8_bit = 1 Bit = 0 8-bit video in Topaz */ 1410 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1411 1412 /* quant_type = 1 Bit = 0 2nd quantization method in Topaz */ 1413 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1414 1415 if (bProfile == ASP) { 1416 /* quarter_sample = 1 Bit = 0 No -pel MC in Topaz */ 1417 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1418 } 1419 1420 /* complexity_estimation_disable = 1 Bit = 1 No complexity estimation in Topaz */ 1421 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1422 #ifndef MATCH_TO_ENC 1423 1424 /* resync_marker_disable = 1 Bit = 0 Always enable resync marker in Topaz */ 1425 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1426 #else 1427 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1428 #endif 1429 /* data_partitioned = 1 Bit = 0 No data partitioning in Topaz */ 1430 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1431 1432 if (bProfile == ASP) { 1433 /* newpred_enable = 1 Bit = 0 No newpred mode in SP/ASP */ 1434 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1435 /* reduced_vop_resolution_enable=1 Bit = 0 No reduced resolution frame in SP/ASP */ 1436 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1437 } 1438 1439 /* scalability = 1 Bit = 0 No scalability in SP/ASP */ 1440 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1441 1442 /* byte_aligned_bits */ 1443 1444 /* Tell MTX to insert the byte align field 1445 * (we don't know final stream size for alignment at this point) 1446 */ 1447 lnc__insert_element_token( 1448 mtx_hdr, 1449 elt_p, 1450 ELEMENT_INSERTBYTEALIGN_MPG4); 1451 1452 return; 1453 } 1454 1455 1456 /* Utility function */ 1457 /* 1458 IMG_UINT8 Bits2Code(IMG_UINT32 CodeVal) 1459 { 1460 IMG_UINT8 Bits=32; 1461 if(CodeVal==0) 1462 return 1; 1463 while(!(CodeVal & 0x80000000)) 1464 { 1465 CodeVal<<=1; 1466 Bits--; 1467 } 1468 return Bits; 1469 } 1470 */ 1471 1472 /* MPEG 4 VOP (Picture) Header */ 1473 static void lnc__MPEG4_writebits_VOP_header( 1474 MTX_HEADER_PARAMS *mtx_hdr, 1475 MTX_HEADER_ELEMENT **elt_p, 1476 IMG_BOOL bIsVOP_coded, 1477 IMG_UINT8 VOP_time_increment, 1478 SEARCH_RANGE_TYPE sSearch_range, 1479 VOP_CODING_TYPE sVopCodingType, 1480 IMG_UINT32 VopTimeResolution) 1481 { 1482 IMG_BOOL bIsSyncPoint; 1483 /* Essential we insert the element before we try to fill it! */ 1484 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 1485 1486 /* visual_object_sequence_start_code = 32 Bits = 0x1B6 */ 1487 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 438, 32); 1488 1489 /* vop_coding_type = 2 Bits = 0 for I-frame and 1 for P-frame */ 1490 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sVopCodingType, 2); 1491 bIsSyncPoint = (VOP_time_increment > 1) && ((VOP_time_increment) % VopTimeResolution == 0); 1492 1493 #ifndef MATCH_TO_ENC 1494 /* modulo_time_base = 1 Bit = 0 As at least 1 synchronization point (I-frame) per second in Topaz */ 1495 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1496 #else 1497 1498 lnc__write_upto8bits_elements(mtx_hdr, elt_p, bIsSyncPoint ? 2 : 0 , bIsSyncPoint ? 2 : 1); 1499 1500 #endif 1501 1502 /* marker_bit = 1 Bits = 1 */ 1503 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1504 1505 #ifndef MATCH_TO_ENC 1506 /* vop_time_increment = Variable bits based on resolution 1507 * = x Reset to 0 at I-frame and plus fixed_vop_time_increment each frame 1508 */ 1509 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VOP_time_increment, 5); 1510 #else 1511 /* will chrash here... */ 1512 lnc__write_upto8bits_elements( 1513 mtx_hdr, elt_p, 1514 (VOP_time_increment) % VopTimeResolution, 1515 Bits2Code(VopTimeResolution - 1)); 1516 1517 #endif 1518 /* marker_bit = 1 Bit = 1 */ 1519 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1520 1521 if (!bIsVOP_coded) { 1522 /* vop_coded = 1 Bit = 0 for skipped frame */ 1523 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1524 1525 /* byte_aligned_bits (skipped pictures are byte aligned) */ 1526 /* Tell MTX to insert the byte align field (we don't know final stream size for alignment at this point) 1527 * End of VOP - skipped picture 1528 */ 1529 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_INSERTBYTEALIGN_MPG4); 1530 } else { 1531 /* vop_coded = 1 Bit = 1 for normal coded frame */ 1532 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1533 1534 if (sVopCodingType == P_FRAME) { 1535 /* vop_rounding_type = 1 Bit = 0 vop_rounding_type is 0 in Topaz */ 1536 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1537 } 1538 1539 /* intra_dc_vlc_thr = 3 Bits = 0 Use intra DC VLC in Topaz */ 1540 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3); 1541 1542 /* vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX */ 1543 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, Frame_Q_scale, 5); */ 1544 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE); 1545 1546 if (sVopCodingType == P_FRAME) { 1547 /* vop_fcode_forward = 3 bits = 2 for +/-32 and 3 for +/-64 search range */ 1548 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 1549 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3); 1550 } 1551 1552 /* 1553 **** THE FINAL PART OF VOP STRUCTURE CAN'T BE GENERATED HERE 1554 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 1555 video_packet_data ( ) = 1st VP that doesnt have the VP header 1556 1557 while (nextbits_bytealigned ( ) == resync_marker) 1558 { 1559 video_packet _header( ) 1560 video_packet _data( ) All MB in the slice 1561 } 1562 */ 1563 } 1564 } 1565 1566 1567 /* MPEG 4 Video Packet (Slice) Header */ 1568 static void lnc__MPEG4_writebits_videopacket_header( 1569 MTX_HEADER_PARAMS *mtx_hdr, 1570 MTX_HEADER_ELEMENT **elt_p, 1571 VOP_CODING_TYPE eVop_Coding_Type, 1572 IMG_UINT8 Fcode, 1573 IMG_UINT32 MBNumber, 1574 IMG_UINT32 MBNumberlength, 1575 IMG_BOOL bHeader_Extension_Code, 1576 IMG_UINT8 VOP_Time_Increment, 1577 SEARCH_RANGE_TYPE sSearch_range) 1578 { 1579 /* Essential we insert the element before we try to fill it! */ 1580 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 1581 1582 if (eVop_Coding_Type == I_FRAME) { 1583 /* resync_marker = 17 bit =0x1 17-bit for I-frame */ 1584 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17); 1585 } else { 1586 /* resync_marker = 17 bit =0x1 (16+fcode) bits for P-frame */ 1587 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 16 + Fcode); 1588 } 1589 1590 /* macroblock_number = 1-14 bits = ?????? */ 1591 lnc__write_upto32bits_elements(mtx_hdr, elt_p, MBNumber, MBNumberlength); 1592 1593 /* quant_scale = 5 bits =1-32 VP (Slice) Q_scale 1594 * lnc__write_upto8bits_elements(mtx_hdr, elt_p, VP_Slice_Q_Scale, 5); 1595 */ 1596 lnc__insert_element_token( 1597 mtx_hdr, elt_p, 1598 ELEMENT_SLICEQSCALE); /* Insert token to tell MTX to insert rate-control value */ 1599 1600 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); /* Begin writing rawdata again */ 1601 1602 if (bHeader_Extension_Code) { 1603 /* header_extension_code = 1bit = 1 picture header parameters are repeated */ 1604 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1605 1606 /* modulo_time_base = 1 bit = 0 The same as it is in the current picture header */ 1607 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1608 1609 /* marker_bit = 1 bit = 1 */ 1610 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1611 1612 /* vop_time_increment = 5 bits = 0-30 The same as it is in the current picture header */ 1613 lnc__write_upto8bits_elements(mtx_hdr, elt_p, VOP_Time_Increment, 5); 1614 1615 /* marker_bit = 1 bit = 1 */ 1616 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1617 1618 /* vop_coding_type= 2 bits = 0/1 The same as it is in the current picture header */ 1619 lnc__write_upto8bits_elements(mtx_hdr, elt_p, eVop_Coding_Type, 2); 1620 1621 /* intra_dc_vlc_thr = 3 bits = 0 The same as it is in the current picture header */ 1622 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 3); 1623 1624 if (eVop_Coding_Type == P_FRAME) { 1625 /* vop_fcode_forward = 3 bits = 2/3 The same as it is in the current picture header */ 1626 lnc__write_upto8bits_elements(mtx_hdr, elt_p, sSearch_range, 3); 1627 } 1628 } else { 1629 /* header_extension_code = 1 bits =0 picture header parameters are NOT repeated */ 1630 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1631 } 1632 } 1633 1634 /* 1635 * High level functions to call when a MPEG4 header is required - HOST ROUTINES 1636 */ 1637 static void lnc__MPEG4_getelements_sequence_header( 1638 MTX_HEADER_PARAMS *mtx_hdr, 1639 IMG_BOOL bBFrame, 1640 MPEG4_PROFILE_TYPE sProfile, 1641 IMG_UINT8 Profile_and_level_indication, 1642 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment, 1643 IMG_UINT32 Picture_Width_Pixels, 1644 IMG_UINT32 Picture_Height_Pixels, 1645 VBVPARAMS *sVBVParams, 1646 IMG_UINT32 VopTimeResolution) /* NULL pointer if there are no VBVParams */ 1647 { 1648 /* Builds a single MPEG4 video sequence header from the given parameters */ 1649 1650 /* Essential we initialise our header structures before building */ 1651 MTX_HEADER_ELEMENT *This_Element; 1652 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1653 mtx_hdr->Elements = ELEMENTS_EMPTY; 1654 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1655 elt_p[0] = This_Element; 1656 1657 lnc__MPEG4_writebits_sequence_header( 1658 mtx_hdr, 1659 elt_p, 1660 bBFrame, sProfile, 1661 Profile_and_level_indication, 1662 sFixed_vop_time_increment, 1663 Picture_Width_Pixels, 1664 Picture_Height_Pixels, 1665 sVBVParams, VopTimeResolution); 1666 1667 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1668 } 1669 1670 1671 /* MPEG 4 VOP (Picture) Header */ 1672 static void lnc__MPEG4_getelements_VOP_header( 1673 MTX_HEADER_PARAMS *mtx_hdr, 1674 IMG_BOOL bIsVOP_coded, 1675 IMG_UINT8 VOP_time_increment, 1676 SEARCH_RANGE_TYPE sSearch_range, 1677 VOP_CODING_TYPE sVopCodingType, 1678 IMG_UINT32 VopTimeResolution) 1679 { 1680 /* Builds a single MPEG4 VOP (picture) header from the given parameters */ 1681 1682 /* Essential we initialise our header structures before building */ 1683 MTX_HEADER_ELEMENT *This_Element; 1684 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1685 mtx_hdr->Elements = ELEMENTS_EMPTY; 1686 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1687 elt_p[0] = This_Element; 1688 1689 /* Frame QScale no longer written here as it is inserted by MTX later 1690 * (add as parameter to MTX_Send_Elements_To_VLC) 1691 */ 1692 lnc__MPEG4_writebits_VOP_header( 1693 mtx_hdr, elt_p, bIsVOP_coded, 1694 VOP_time_increment, 1695 sSearch_range, 1696 sVopCodingType, VopTimeResolution); 1697 1698 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1699 } 1700 1701 1702 static void lnc_MPEG4_getelements_video_packet_header( 1703 MTX_HEADER_PARAMS *mtx_hdr, 1704 VOP_CODING_TYPE eVop_Coding_Type, 1705 IMG_UINT8 Fcode, 1706 IMG_UINT32 MBNumber, 1707 IMG_UINT32 MBNumberlength, 1708 IMG_BOOL bHeader_Extension_Code, 1709 IMG_UINT8 VOP_Time_Increment, 1710 SEARCH_RANGE_TYPE sSearch_range) 1711 { 1712 /* Builds a single MPEG4 video packet (slice) header from the given parameters */ 1713 1714 /* Essential we initialise our header structures before building */ 1715 MTX_HEADER_ELEMENT *This_Element; 1716 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 1717 mtx_hdr->Elements = ELEMENTS_EMPTY; 1718 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 1719 elt_p[0] = This_Element; 1720 1721 /* Slice QScale no longer written here as it is inserted by MTX later 1722 * (add as parameter when sending to VLC) 1723 */ 1724 lnc__MPEG4_writebits_videopacket_header( 1725 mtx_hdr, elt_p, eVop_Coding_Type, 1726 Fcode, MBNumber, MBNumberlength, 1727 bHeader_Extension_Code, VOP_Time_Increment, sSearch_range); 1728 1729 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 1730 } 1731 1732 /* 1733 * Intermediary functions to build H263 headers 1734 */ 1735 static void H263_writebits_VideoSequenceHeader( 1736 MTX_HEADER_PARAMS *mtx_hdr, 1737 MTX_HEADER_ELEMENT **elt_p, 1738 IMG_UINT8 Profile_and_level_indication) 1739 { 1740 /* Essential we insert the element before we try to fill it! */ 1741 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 1742 1743 /* visual_object_sequence_start_code = 32 Bits = 0x1B0 */ 1744 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 432, 32); 1745 1746 /* profile_and_level_indication = 8 Bits = x SP L0-L3 and SP L4-L5 are supported */ 1747 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Profile_and_level_indication, 8); 1748 1749 /* visual_object_start_code = 32 Bits = 0x1B5 */ 1750 1751 /* 437 too large for the lnc__write_upto32bits_elements function */ 1752 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 437, 32); 1753 1754 /* is_visual_object_identifier = 1 Bit = 0 */ 1755 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1756 1757 /* is_visual_object_type = 4 Bits = 1 Video ID */ 1758 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4); 1759 1760 /* video_signal_type = 1 Bit = 0 */ 1761 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1762 1763 /* byte_aligned_bits = 2 Bits = 01b byte_aligned_bits is 2-bit stuffing bit field 01 */ 1764 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 2); 1765 1766 /* video_object_start_code =32 Bits = 0x100 One VO only in a Topaz video stream */ 1767 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 256, 32); 1768 1769 return; 1770 } 1771 1772 1773 static void H263_writebits_VideoPictureHeader( 1774 MTX_HEADER_PARAMS *mtx_hdr, 1775 MTX_HEADER_ELEMENT **elt_p, 1776 IMG_UINT8 Temporal_Ref, 1777 H263_PICTURE_CODING_TYPE PictureCodingType, 1778 //IMG_UINT8 Q_Scale, 1779 H263_SOURCE_FORMAT_TYPE SourceFormatType, 1780 IMG_UINT8 FrameRate, 1781 IMG_UINT16 PictureWidth, 1782 IMG_UINT16 PictureHeight, 1783 IMG_UINT8 *OptionalCustomPCF) 1784 { 1785 IMG_UINT8 UFEP; 1786 1787 #ifdef USESTATICWHEREPOSSIBLE 1788 IMG_UINT16 *p; 1789 1790 p = (IMG_UINT16 *) mtx_hdr; 1791 p[0] = p[1] = p[2] = p[3] = 0; 1792 p[4] = 38; 1793 p[5] = 32768 | ((Temporal_Ref >> 6) << 8); 1794 p[6] = ((Temporal_Ref & 63) << 2) | 2 | (SourceFormatType << 10); 1795 #else 1796 1797 /* Essential we insert the element before we try to fill it! */ 1798 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 1799 1800 /* short_video_start_marker = 22 Bits = 0x20 Picture start code */ 1801 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 32, 22); 1802 1803 /* temporal_reference = 8 Bits = 0-255 Each picture increased by 1 */ 1804 lnc__write_upto8bits_elements(mtx_hdr, elt_p, Temporal_Ref, 8); 1805 1806 /* marker_bit = 1 Bit = 1 */ 1807 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1808 1809 /* zero_bit = 1 Bits = 0 */ 1810 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1811 1812 /* split_screen_indicator = 1 Bits = 0 No direct effect on encoding of picture */ 1813 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1814 1815 /* document_camera_indicator= 1 Bits = 0 No direct effect on encoding of picture */ 1816 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1817 1818 /* full_picture_freeze_release=1 Bits = 0 No direct effect on encoding of picture */ 1819 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1820 1821 /* source_format = 3 Bits = 1-4 See note */ 1822 lnc__write_upto8bits_elements(mtx_hdr, elt_p, SourceFormatType, 3); 1823 #endif 1824 1825 1826 /*Write optional Custom Picture Clock Frequency(OCPCF)*/ 1827 if (FrameRate == 30 || FrameRate == 0/* unspecified */) { 1828 *OptionalCustomPCF = 0; // 0 for CIF PCF 1829 } else { 1830 *OptionalCustomPCF = 1; //1 for Custom PCF 1831 } 1832 1833 1834 if (SourceFormatType != 7) { 1835 /* picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame */ 1836 lnc__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 1); 1837 1838 /* four_reserved_zero_bits = 4 Bits = 0 */ 1839 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 4); 1840 } else { 1841 static IMG_UINT8 RTYPE = 0; 1842 1843 // if I- Frame set Update Full Extended PTYPE to true 1844 if ((PictureCodingType == I_FRAME) || (SourceFormatType == 7) || *OptionalCustomPCF) { 1845 UFEP = 1; 1846 } else { 1847 UFEP = 0; 1848 1849 // RTYPE can be set to 1 only in case of P or PB picture. 1850 //RTYPE ^= 1; 1851 } 1852 1853 // write UFEP of 3 bits. 1854 lnc__write_upto8bits_elements(mtx_hdr, elt_p, UFEP, 3); 1855 1856 // if UFEP was present( if it was 1). 1857 // Optional part of PPTYPE. 1858 if (UFEP == 1) { 1859 // write souce_format_optional. value = 110 (custom source format). 1860 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 6, 3); 1861 /* souce_format_optional */ 1862 1863 lnc__write_upto8bits_elements(mtx_hdr, elt_p, *OptionalCustomPCF , 1); 1864 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 0, 10); 1865 /* 10 reserve bits */ 1866 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 8, 4); 1867 /* 4 reserve bits */ 1868 } 1869 /* picture_coding_type = 1 Bit = 0/1 0 for I-frame and 1 for P-frame */ 1870 lnc__write_upto8bits_elements(mtx_hdr, elt_p, PictureCodingType, 3); 1871 1872 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2); 1873 /* two_reserve_bits, rounding_type, two_reserve_bits marker_bit CPM */ 1874 1875 // Rounding Type (RTYPE) (1 for P Picture, 0 for all other Picture frames. 1876 lnc__write_upto8bits_elements(mtx_hdr, elt_p, RTYPE, 1); 1877 //2 reserve bits 1878 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 2); 1879 // - 1 (ON) to prevent start code emulation. 1880 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1 , 1); 1881 // CPM immediately follows the PPTYPE part of the header. 1882 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0 , 1); 1883 1884 if (UFEP == 1) { 1885 IMG_UINT16 ui16PWI, ui16PHI; 1886 1887 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 4); 1888 /* aspect ratio */ 1889 //PictureWidth --; 1890 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth >> 8), 1); 1891 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureWidth & 0xFF), 8); 1892 1893 ui16PWI = (PictureWidth >> 2) - 1; 1894 lnc__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PWI, 9); 1895 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1896 /* marker_bit = 1 Bit = 1 */ 1897 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeigth >> 8), 1); 1898 //lnc__write_upto8bits_elements(mtx_hdr, elt_p, (IMG_UINT8)(PictureHeigth & 0xFF), 8); 1899 /* good up to that point */ 1900 ui16PHI = PictureHeight >> 2; 1901 lnc__write_upto32bits_elements(mtx_hdr, elt_p, (IMG_UINT8)ui16PHI, 9); 1902 1903 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); */ 1904 /* marker_bit = 1 Bit = 1 */ 1905 /* just checking */ 1906 if (*OptionalCustomPCF == 1) { 1907 //IMG_UINT8 CPCFC; 1908 //CPCFC = (IMG_UINT8)(1800/(IMG_UINT16)FrameRate); 1909 /* you can use the table for division */ 1910 //CPCFC <<= 1; /* for Clock Conversion Code */ 1911 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1, 1); 1912 // Clock Divisor : 7 bits The natural binary representation of the value of the clock divisor. 1913 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 1800000 / (FrameRate * 1000), 7); 1914 } 1915 } 1916 if (*OptionalCustomPCF == 1) { 1917 IMG_UINT8 ui8ETR; // extended Temporal reference 1918 // Two MSBs of 10 bit temporal_reference : value 0 1919 ui8ETR = Temporal_Ref >> 8; 1920 1921 lnc__write_upto8bits_elements(mtx_hdr, elt_p, ui8ETR, 2); 1922 /* Two MSBs of temporal_reference */ 1923 } 1924 } 1925 /* vop_quant = 5 Bits = x 5-bit frame Q_scale from rate control - GENERATED BY MTX */ 1926 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, Q_Scale, 5); */ 1927 1928 /* Insert token to tell MTX to insert rate-control value 1929 * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, FrameQScale)) 1930 */ 1931 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_FRAMEQSCALE); 1932 1933 1934 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_RAWDATA); 1935 1936 /* zero_bit = 1 Bit = 0 1937 * pei = 1 Bit = 0 No direct effect on encoding of picture 1938 */ 1939 if (SourceFormatType != 7) { 1940 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1941 } 1942 1943 /* 1944 FOLLOWING SECTION CAN'T BE GENERATED HERE 1945 gob_data( ) 1946 for(i=1; i<num_gob_in_picture; i++) { 1947 gob_header( ) 1948 gob_data( ) 1949 } 1950 */ 1951 lnc__write_upto8bits_elements(mtx_hdr, elt_p, 0, 1); 1952 return; 1953 } 1954 1955 1956 static void H263_writebits_GOBSliceHeader( 1957 MTX_HEADER_PARAMS *mtx_hdr, 1958 MTX_HEADER_ELEMENT **elt_p, 1959 IMG_UINT8 GOBNumber, 1960 IMG_UINT8 GOBFrameId) 1961 { 1962 #ifdef USESTATICWHEREPOSSIBLE 1963 IMG_UINT16 *p; 1964 p = (IMG_UINT16 *) mtx_hdr; 1965 /* 1966 p[0]=1; 1967 p[1]=p[2]=p[3]=0; 1968 */ 1969 *(int *)mtx_hdr = 1; 1970 p[4] = 24; 1971 p[5] = (128 | ((GOBNumber & 31) << 2) | (GOBFrameId & 3)) << 8; 1972 p[6] = 5; 1973 #else 1974 /* Essential we insert the element before we try to fill it! */ 1975 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_STARTCODE_RAWDATA); 1976 1977 /* gob_resync_marker = 17 = 0x1 */ 1978 lnc__write_upto32bits_elements(mtx_hdr, elt_p, 1, 17); 1979 1980 /* gob_number = 5 = 0-17 It is gob number in a picture */ 1981 lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOBNumber, 5); 1982 1983 /* gob_frame_id = 2 = 0-3 See note */ 1984 lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOBFrameId, 2); 1985 1986 /* quant_scale = 5 = 1-32 gob (Slice) Q_scale */ 1987 /* lnc__write_upto8bits_elements(mtx_hdr, elt_p, GOB_Q_Scale, 5); */ 1988 1989 /* Insert token to tell MTX to insert rate-control value 1990 * (QScale is sent as an argument in MTX_Send_Elements_To_VLC(&MTX_Header, SliceQScale)) 1991 */ 1992 lnc__insert_element_token(mtx_hdr, elt_p, ELEMENT_SLICEQSCALE); 1993 #endif 1994 } 1995 1996 /* 1997 * High level functions to call when a H263 header is required - HOST ROUTINES 1998 */ 1999 static void lnc__H263_getelements_videosequence_header( 2000 MTX_HEADER_PARAMS *mtx_hdr, 2001 IMG_UINT8 Profile_and_level_indication) 2002 { 2003 /* Builds a single H263 video sequence header from the given parameters */ 2004 2005 /* Essential we initialise our header structures before building */ 2006 MTX_HEADER_ELEMENT *This_Element; 2007 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 2008 mtx_hdr->Elements = ELEMENTS_EMPTY; 2009 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 2010 elt_p[0] = This_Element; 2011 2012 H263_writebits_VideoSequenceHeader(mtx_hdr, elt_p, Profile_and_level_indication); 2013 2014 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 2015 } 2016 2017 static void lnc__H263_getelements_videopicture_header( 2018 MTX_HEADER_PARAMS *mtx_hdr, 2019 IMG_UINT8 Temporal_Ref, 2020 H263_PICTURE_CODING_TYPE PictureCodingType, 2021 H263_SOURCE_FORMAT_TYPE SourceFormatType, 2022 IMG_UINT8 FrameRate, 2023 IMG_UINT16 PictureWidth, 2024 IMG_UINT16 PictureHeight, 2025 IMG_UINT8 *OptionalCustomPCF) 2026 { 2027 /* Essential we initialise our header structures before building */ 2028 MTX_HEADER_ELEMENT *This_Element; 2029 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 2030 mtx_hdr->Elements = ELEMENTS_EMPTY; 2031 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 2032 elt_p[0] = This_Element; 2033 2034 H263_writebits_VideoPictureHeader( 2035 mtx_hdr, elt_p, 2036 Temporal_Ref, 2037 PictureCodingType, 2038 SourceFormatType, 2039 FrameRate, 2040 PictureWidth, 2041 PictureHeight, 2042 OptionalCustomPCF); 2043 mtx_hdr->Elements++; /* Has been used as an index, so need to add 1 for a valid element count */ 2044 } 2045 2046 static void lnc__H263_getelements_GOBslice_header( 2047 MTX_HEADER_PARAMS *mtx_hdr, 2048 IMG_UINT8 GOBNumber, 2049 IMG_UINT8 GOBFrameId) 2050 { 2051 /* Essential we initialise our header structures before building */ 2052 MTX_HEADER_ELEMENT *This_Element; 2053 MTX_HEADER_ELEMENT *elt_p[MAXNUMBERELEMENTS]; 2054 mtx_hdr->Elements = ELEMENTS_EMPTY; 2055 This_Element = (MTX_HEADER_ELEMENT *) mtx_hdr->asElementStream; 2056 elt_p[0] = This_Element; 2057 2058 H263_writebits_GOBSliceHeader(mtx_hdr, elt_p, GOBNumber, GOBFrameId); 2059 2060 mtx_hdr->Elements++; //Has been used as an index, so need to add 1 for a valid element count 2061 } 2062 2063 2064 2065 void lnc__H264_prepare_sequence_header( 2066 IMG_UINT32 *pHeaderMemory, 2067 IMG_UINT32 uiMaxNumRefFrames, 2068 IMG_UINT32 uiPicWidthInMbs, 2069 IMG_UINT32 uiPicHeightInMbs, 2070 IMG_BOOL VUI_present, H264_VUI_PARAMS *VUI_params, 2071 H264_CROP_PARAMS *psCropParams, 2072 IMG_UINT8 uiLevel, 2073 IMG_UINT8 uiProfile) 2074 { 2075 H264_SEQUENCE_HEADER_PARAMS SHParams; 2076 MTX_HEADER_PARAMS *mtx_hdr; 2077 2078 memset(&SHParams, 0, sizeof(SHParams)); 2079 2080 /* Route output elements to memory provided */ 2081 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2082 2083 /* Setup Sequence Header information */ 2084 switch (uiProfile) { 2085 case 5: 2086 SHParams.ucProfile = SH_PROFILE_BP; 2087 break; 2088 case 6: 2089 SHParams.ucProfile = SH_PROFILE_MP; 2090 break; 2091 default: 2092 SHParams.ucProfile = SH_PROFILE_MP; 2093 break; 2094 } 2095 2096 switch (uiLevel) { 2097 case 10: 2098 SHParams.ucLevel = SH_LEVEL_1; 2099 break; 2100 case 111: 2101 SHParams.ucLevel = SH_LEVEL_1B; 2102 break; 2103 case 11: 2104 SHParams.ucLevel = SH_LEVEL_11; 2105 break; 2106 case 12: 2107 SHParams.ucLevel = SH_LEVEL_12; 2108 break; 2109 case 20: 2110 SHParams.ucLevel = SH_LEVEL_2; 2111 break; 2112 case 30: 2113 SHParams.ucLevel = SH_LEVEL_3; 2114 break; 2115 case 31: 2116 SHParams.ucLevel = SH_LEVEL_31; 2117 break; 2118 default: 2119 SHParams.ucLevel = SH_LEVEL_3; 2120 break; 2121 } 2122 2123 SHParams.ucMax_num_ref_frames = uiMaxNumRefFrames; 2124 SHParams.ucWidth_in_mbs_minus1 = (IMG_UINT8)(uiPicWidthInMbs - 1); 2125 SHParams.ucHeight_in_maps_units_minus1 = (IMG_UINT8)(uiPicHeightInMbs - 1); 2126 SHParams.VUI_Params_Present = VUI_present; 2127 if (VUI_present) 2128 SHParams.VUI_Params = *VUI_params; 2129 2130 /* All picture header information is static 2131 * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway) 2132 */ 2133 2134 /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug 2135 * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0; 2136 */ 2137 2138 #if HEADERS_VERBOSE_OUTPUT 2139 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n"); 2140 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n"); 2141 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n"); 2142 #endif 2143 2144 /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */ 2145 lnc__H264_getelements_sequence_header(mtx_hdr, &SHParams, psCropParams); 2146 } 2147 2148 void lnc__H264_prepare_picture_header(IMG_UINT32 *pHeaderMemory) 2149 { 2150 MTX_HEADER_PARAMS *mtx_hdr; 2151 2152 2153 /* Route output elements to memory provided */ 2154 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2155 2156 /* All picture header information is static 2157 * (apart from 'pic_init_qp_minus26' and 'rsbp_byte_align' fields, which are set in MTX anyway) 2158 */ 2159 2160 /* Clears ensures elementstream memory is zeroed.. not necessary, but makes it easier to debug 2161 * for (Lp=0;Lp<MAX_HEADERSIZEWORDS-1;Lp++) MTX_Header.asElementStream[Lp]=0; 2162 */ 2163 2164 #if HEADERS_VERBOSE_OUTPUT 2165 drv_debug_msg(VIDEO_DEBUG_GENERAL, "\n\n**********************************************************************\n"); 2166 drv_debug_msg(VIDEO_DEBUG_GENERAL, "******** HOST FIRMWARE ROUTINES TO PASS HEADERS AND TOKENS TO MTX******\n"); 2167 drv_debug_msg(VIDEO_DEBUG_GENERAL, "**********************************************************************\n\n"); 2168 #endif 2169 2170 /* Functions that actually pack Elements (MTX_HEADER_PARAMS structure) with header information */ 2171 lnc__H264_getelements_picture_header(mtx_hdr); 2172 } 2173 2174 void lnc__H264_prepare_slice_header( 2175 IMG_UINT32 *pHeaderMemory, 2176 IMG_BOOL bIntraSlice, 2177 IMG_UINT32 uiDisableDeblockingFilterIDC, 2178 IMG_UINT32 uiFrameNumber, 2179 IMG_UINT32 uiFirst_MB_Address, 2180 IMG_UINT32 uiMBSkipRun, 2181 IMG_UINT32 force_idr, 2182 IMG_BOOL bUsesLongTermRef, 2183 IMG_BOOL bIsLongTermRef, 2184 IMG_UINT16 uiIdrPicId) 2185 { 2186 H264_SLICE_HEADER_PARAMS SlHParams; 2187 MTX_HEADER_PARAMS *mtx_hdr; 2188 2189 /* Route output elements to memory provided */ 2190 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2191 2192 SlHParams.Start_Code_Prefix_Size_Bytes = 4; 2193 2194 /* pcb - I think that this is more correct now*/ 2195 if (force_idr) 2196 SlHParams.SliceFrame_Type = SLHP_IDR_SLICEFRAME_TYPE; 2197 else 2198 SlHParams.SliceFrame_Type = bIntraSlice ? SLHP_I_SLICEFRAME_TYPE : SLHP_P_SLICEFRAME_TYPE; 2199 2200 SlHParams.Frame_Num_DO = (IMG_UINT8) uiFrameNumber % (1 << 5); 2201 SlHParams.Picture_Num_DO = (IMG_UINT8)(SlHParams.Frame_Num_DO * 2); 2202 2203 SlHParams.bUsesLongTermRef = bUsesLongTermRef; 2204 SlHParams.bIsLongTermRef = bIsLongTermRef; 2205 2206 SlHParams.First_MB_Address = uiFirst_MB_Address; 2207 SlHParams.Disable_Deblocking_Filter_Idc = (IMG_UINT8) uiDisableDeblockingFilterIDC; 2208 2209 if (uiMBSkipRun) 2210 lnc__H264_getelements_skip_P_slice(mtx_hdr, &SlHParams, uiMBSkipRun); 2211 else 2212 lnc__H264_getelements_slice_header(mtx_hdr, &SlHParams, uiIdrPicId); 2213 } 2214 2215 void lnc__H264_prepare_eodofstream_header(IMG_UINT32 *pHeaderMemory) 2216 { 2217 MTX_HEADER_PARAMS *mtx_hdr; 2218 2219 /* Route output elements to memory provided */ 2220 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2221 2222 lnc__H264_getelements_endofstream_header(mtx_hdr); 2223 } 2224 2225 void lnc__H264_prepare_endofpicture_header(IMG_UINT32 *pHeaderMemory) 2226 { 2227 MTX_HEADER_PARAMS *mtx_hdr; 2228 2229 /* Route output elements to memory provided */ 2230 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2231 2232 /* H264_GetElements_EndOfPicture_Header(MTX_Header); */ 2233 } 2234 2235 void lnc__H264_prepare_endofsequence_header(IMG_UINT32 *pHeaderMemory) 2236 { 2237 MTX_HEADER_PARAMS *mtx_hdr; 2238 2239 /* Route output elements to memory provided */ 2240 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2241 2242 lnc__H264_getelements_endofsequence_header(mtx_hdr); 2243 } 2244 2245 void lnc__MPEG4_prepare_sequence_header( 2246 IMG_UINT32 *pHeaderMemory, 2247 IMG_BOOL bBFrame, 2248 MPEG4_PROFILE_TYPE sProfile, 2249 IMG_UINT8 Profile_and_level_indication, 2250 FIXED_VOP_TIME_TYPE sFixed_vop_time_increment, 2251 IMG_UINT32 Picture_Width_Pixels, 2252 IMG_UINT32 Picture_Height_Pixels, 2253 IMG_BOOL bVBVPresent, 2254 IMG_UINT32 First_half_bit_rate, 2255 IMG_UINT32 Latter_half_bit_rate, 2256 IMG_UINT32 First_half_vbv_buffer_size, 2257 IMG_UINT32 Latter_half_vbv_buffer_size, 2258 IMG_UINT32 First_half_vbv_occupancy, 2259 IMG_UINT32 Latter_half_vbv_occupancy, 2260 IMG_UINT32 VopTimeResolution) 2261 { 2262 MTX_HEADER_PARAMS *mtx_hdr; 2263 VBVPARAMS sVBVParams; 2264 2265 sVBVParams.First_half_bit_rate = First_half_bit_rate; 2266 sVBVParams.Latter_half_bit_rate = Latter_half_bit_rate; 2267 sVBVParams.First_half_vbv_buffer_size = First_half_vbv_buffer_size; 2268 sVBVParams.Latter_half_vbv_buffer_size = Latter_half_vbv_buffer_size; 2269 sVBVParams.First_half_vbv_occupancy = First_half_vbv_occupancy; 2270 sVBVParams.Latter_half_vbv_occupancy = Latter_half_vbv_occupancy; 2271 2272 /* Route output elements to memory provided */ 2273 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMemory; 2274 2275 if (bVBVPresent) 2276 lnc__MPEG4_getelements_sequence_header( 2277 mtx_hdr, bBFrame, sProfile, 2278 Profile_and_level_indication, 2279 sFixed_vop_time_increment, 2280 Picture_Width_Pixels, Picture_Height_Pixels, 2281 &sVBVParams, VopTimeResolution); 2282 else 2283 lnc__MPEG4_getelements_sequence_header( 2284 mtx_hdr, bBFrame, sProfile, 2285 Profile_and_level_indication, 2286 sFixed_vop_time_increment, 2287 Picture_Width_Pixels, Picture_Height_Pixels, 2288 NULL, VopTimeResolution);/* NULL pointer if there are no VBVParams */ 2289 } 2290 2291 void lnc__MPEG4_prepare_vop_header( 2292 IMG_UINT32 *pHeaderMem, 2293 IMG_BOOL bIsVOP_coded, 2294 IMG_UINT32 VOP_time_increment, 2295 IMG_UINT8 sSearch_range, 2296 IMG_UINT8 eVop_Coding_Type, 2297 IMG_UINT32 VopTimeResolution) 2298 { 2299 MTX_HEADER_PARAMS *mtx_hdr; 2300 2301 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem; 2302 2303 /* Frame QScale (and Slice QScale in the slice case) 2304 * no longer written here as it is inserted by MTX later 2305 * (add as parameter to MTX_Send_Elements_To_VLC) 2306 */ 2307 lnc__MPEG4_getelements_VOP_header( 2308 mtx_hdr, 2309 bIsVOP_coded, 2310 VOP_time_increment, 2311 sSearch_range, 2312 eVop_Coding_Type, VopTimeResolution); 2313 } 2314 2315 void lnc__H263_prepare_sequence_header( 2316 IMG_UINT32 *pHeaderMem, 2317 IMG_UINT8 Profile_and_level_indication) 2318 { 2319 MTX_HEADER_PARAMS *mtx_hdr; 2320 2321 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem; 2322 2323 lnc__H263_getelements_videosequence_header(mtx_hdr, Profile_and_level_indication); 2324 } 2325 2326 void lnc__H263_prepare_picture_header( 2327 IMG_UINT32 *pHeaderMem, 2328 IMG_UINT8 Temporal_Ref, 2329 H263_PICTURE_CODING_TYPE PictureCodingType, 2330 H263_SOURCE_FORMAT_TYPE SourceFormatType, 2331 IMG_UINT8 FrameRate, 2332 IMG_UINT16 PictureWidth, 2333 IMG_UINT16 PictureHeight, 2334 IMG_UINT8 *OptionalCustomPCF) 2335 { 2336 MTX_HEADER_PARAMS *mtx_hdr; 2337 2338 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem; 2339 lnc__H263_getelements_videopicture_header( 2340 mtx_hdr, 2341 Temporal_Ref, 2342 PictureCodingType, 2343 SourceFormatType, 2344 FrameRate, 2345 PictureWidth, 2346 PictureHeight, 2347 OptionalCustomPCF); 2348 } 2349 2350 void lnc__H263_prepare_GOBslice_header( 2351 IMG_UINT32 *pHeaderMem, 2352 IMG_UINT8 GOBNumber, 2353 IMG_UINT8 GOBFrameId) 2354 { 2355 MTX_HEADER_PARAMS *mtx_hdr; 2356 2357 mtx_hdr = (MTX_HEADER_PARAMS *) pHeaderMem; 2358 2359 lnc__H263_getelements_GOBslice_header( 2360 mtx_hdr, 2361 GOBNumber, 2362 GOBFrameId); 2363 2364 /* silent the warning message */ 2365 (void)Show_Bits; 2366 (void)Show_Elements; 2367 (void)lnc__H264_writebits_SEI_rbspheader; 2368 (void)lnc__H264_getelements_skip_B_slice; 2369 (void)lnc__H264_getelements_backward_zero_B_slice; 2370 (void)lnc__H264_getelements_rbsp_ATE_only; 2371 (void)lnc_MPEG4_getelements_video_packet_header; 2372 } 2373 2374