1/*-------------------------------------------------------------------------- 2Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. 3 4Redistribution and use in source and binary forms, with or without 5modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of The Linux Foundation nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27--------------------------------------------------------------------------*/ 28 29#include "extra_data_handler.h" 30 31int debug_level = PRIO_ERROR; 32 33extra_data_handler::extra_data_handler() 34{ 35 rbsp_buf = (OMX_U8 *) calloc(1,100); 36 memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement)); 37 frame_packing_arrangement.cancel_flag = 1; 38 pack_sei = false; 39 sei_payload_type = -1; 40} 41 42extra_data_handler::~extra_data_handler() 43{ 44 if (rbsp_buf) { 45 free(rbsp_buf); 46 rbsp_buf = NULL; 47 } 48} 49 50OMX_U32 extra_data_handler::d_u(OMX_U32 num_bits) 51{ 52 OMX_U32 rem_bits = num_bits, bins = 0, shift = 0; 53 54 while (rem_bits >= bit_ptr) { 55 DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr, 56 (unsigned int)byte_ptr, rbsp_buf[byte_ptr]); 57 bins <<= shift; 58 shift = (8-bit_ptr); 59 bins |= ((rbsp_buf[byte_ptr] << shift) & 0xFF) >> shift; 60 rem_bits -= bit_ptr; 61 bit_ptr = 8; 62 byte_ptr ++; 63 } 64 65 DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr, 66 (unsigned int)byte_ptr, rbsp_buf[byte_ptr]); 67 68 if (rem_bits) { 69 bins <<= rem_bits; 70 bins |= ((rbsp_buf[byte_ptr] << (8-bit_ptr)) & 0xFF) >> (8-rem_bits); 71 bit_ptr -= rem_bits; 72 73 if (bit_ptr == 0) { 74 bit_ptr = 8; 75 byte_ptr++; 76 } 77 } 78 79 DEBUG_PRINT_LOW("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr, 80 (unsigned int)byte_ptr, rbsp_buf[byte_ptr]); 81 82 DEBUG_PRINT_LOW("In %s() bin/num_bits : %x/%u", __func__, (unsigned)bins, (unsigned int)num_bits); 83 return bins; 84} 85 86OMX_U32 extra_data_handler::d_ue() 87{ 88 OMX_S32 lead_zeros = -1; 89 OMX_U32 symbol, bit; 90 91 do { 92 bit = d_u(1); 93 lead_zeros++; 94 } while (!bit); 95 96 symbol = ((1 << lead_zeros) - 1) + d_u(lead_zeros); 97 98 DEBUG_PRINT_LOW("In %s() symbol : %u", __func__, (unsigned int)symbol); 99 return symbol; 100} 101 102OMX_U32 extra_data_handler::parse_frame_pack(void) 103{ 104 frame_packing_arrangement.id = d_ue(); 105 frame_packing_arrangement.cancel_flag = d_u(1); 106 107 if (!frame_packing_arrangement.cancel_flag) { 108 frame_packing_arrangement.type = d_u(7); 109 frame_packing_arrangement.quincunx_sampling_flag = d_u(1); 110 frame_packing_arrangement.content_interpretation_type = d_u(6); 111 frame_packing_arrangement.spatial_flipping_flag = d_u(1); 112 frame_packing_arrangement.frame0_flipped_flag = d_u(1); 113 frame_packing_arrangement.field_views_flag = d_u(1); 114 frame_packing_arrangement.current_frame_is_frame0_flag = d_u(1); 115 frame_packing_arrangement.frame0_self_contained_flag = d_u(1); 116 frame_packing_arrangement.frame1_self_contained_flag = d_u(1); 117 118 if (!frame_packing_arrangement.quincunx_sampling_flag && 119 frame_packing_arrangement.type != 5) { 120 frame_packing_arrangement.frame0_grid_position_x = d_u(4); 121 frame_packing_arrangement.frame0_grid_position_y = d_u(4); 122 frame_packing_arrangement.frame1_grid_position_x = d_u(4); 123 frame_packing_arrangement.frame1_grid_position_y = d_u(4); 124 } 125 126 frame_packing_arrangement.reserved_byte = d_u(8); 127 frame_packing_arrangement.repetition_period = d_ue(); 128 } 129 130 frame_packing_arrangement.extension_flag = d_u(1); 131 132 return 1; 133} 134 135OMX_S32 extra_data_handler::parse_rbsp(OMX_U8 *buf, OMX_U32 len) 136{ 137 OMX_U32 i = 3, j=0, startcode; 138 OMX_U32 nal_unit_type, nal_ref_idc, forbidden_zero_bit; 139 140 bit_ptr = 8; 141 byte_ptr = 0; 142 143 startcode = buf[0] << 16 | buf[1] <<8 | buf[2]; 144 145 if (!startcode) { 146 startcode |= buf[i++]; 147 } 148 149 if (startcode != H264_START_CODE) { 150 DEBUG_PRINT_ERROR("ERROR: In %s() Start code not found", __func__); 151 return -1; 152 } 153 154 forbidden_zero_bit = (buf[i] & 0x80) >>7; 155 156 if (forbidden_zero_bit) { 157 DEBUG_PRINT_ERROR("ERROR: In %s() Non-zero forbidden bit", __func__); 158 return -1; 159 } 160 161 nal_ref_idc = (buf[i] & 0x60) >>5; 162 DEBUG_PRINT_LOW("In %s() nal_ref_idc ; %u", __func__, (unsigned int)nal_ref_idc); 163 164 nal_unit_type = (buf[i++] & 0x1F); 165 166 while (i<len) { 167 if (!(buf[i] + buf[i+1]) && (buf[i+2] == H264_EMULATION_BYTE) && 168 (i+2 < len)) { 169 rbsp_buf[j++] = buf[i++]; 170 rbsp_buf[j++] = buf[i++]; 171 i++; 172 } else 173 rbsp_buf[j++] = buf[i++]; 174 } 175 176 return nal_unit_type; 177} 178OMX_S32 extra_data_handler::parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length) 179{ 180 OMX_U32 nal_unit_type, payload_type = 0, payload_size = 0; 181 OMX_U32 marker = 0, pad = 0xFF; 182 183 nal_unit_type = parse_rbsp(buffer, buffer_length); 184 185 if (nal_unit_type != NAL_TYPE_SEI) { 186 DEBUG_PRINT_ERROR("ERROR: In %s() - Non SEI NAL ", __func__); 187 return -1; 188 } else { 189 190 while (rbsp_buf[byte_ptr] == 0xFF) 191 payload_type += rbsp_buf[byte_ptr++]; 192 193 payload_type += rbsp_buf[byte_ptr++]; 194 195 DEBUG_PRINT_LOW("In %s() payload_type : %u", __func__, (unsigned int)payload_type); 196 197 while (rbsp_buf[byte_ptr] == 0xFF) 198 payload_size += rbsp_buf[byte_ptr++]; 199 200 payload_size += rbsp_buf[byte_ptr++]; 201 202 DEBUG_PRINT_LOW("In %s() payload_size : %u", __func__, (unsigned int)payload_size); 203 204 switch (payload_type) { 205 case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT: 206 DEBUG_PRINT_LOW("In %s() Frame Packing SEI ", __func__); 207 parse_frame_pack(); 208 break; 209 default: 210 DEBUG_PRINT_LOW("INFO: In %s() Not Supported SEI NAL ", __func__); 211 break; 212 } 213 } 214 215 if (bit_ptr != 8) { 216 marker = d_u(1); 217 218 if (marker) { 219 if (bit_ptr != 8) { 220 pad = d_u(bit_ptr); 221 222 if (pad) { 223 DEBUG_PRINT_ERROR("ERROR: In %s() padding Bits Error in SEI", 224 __func__); 225 return -1; 226 } 227 } 228 } else { 229 DEBUG_PRINT_ERROR("ERROR: In %s() Marker Bit Error in SEI", 230 __func__); 231 return -1; 232 } 233 } 234 235 DEBUG_PRINT_LOW("In %s() payload_size : %u/%u", __func__, 236 (unsigned int)payload_size, (unsigned int)byte_ptr); 237 return 1; 238} 239 240OMX_S32 extra_data_handler::parse_ltrinfo(OMX_OTHER_EXTRADATATYPE *pExtra) 241{ 242 OMX_U32 *pLTR; 243 pExtra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo; 244 pLTR = (OMX_U32* )pExtra + 5; 245 DEBUG_PRINT_HIGH("ExtraData LTR ID %u", (unsigned int)*pLTR); 246 return 0; 247} 248/*====================================================================== 249 Slice Information will be available as below (each line is of 4 bytes) 250 | number of slices | 251 | 1st slice offset | 252 | 1st slice size | 253 | .. | 254 | Nth slice offset | 255 | Nth slice size | 256 ======================================================================*/ 257OMX_S32 extra_data_handler::parse_sliceinfo( 258 OMX_BUFFERHEADERTYPE *pBufHdr, OMX_OTHER_EXTRADATATYPE *pExtra) 259{ 260 OMX_U32 slice_offset = 0, slice_size = 0, total_size = 0; 261 OMX_U8 *pBuffer = (OMX_U8 *)pBufHdr->pBuffer; 262 OMX_U32 *data = (OMX_U32 *)(void *)pExtra->data; 263 OMX_U32 num_slices = *data; 264 DEBUG_PRINT_LOW("number of slices = %u", (unsigned int)num_slices); 265 266 if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) { 267 DEBUG_PRINT_ERROR("unknown error in slice info extradata"); 268 return -1; 269 } 270 271 for (unsigned i = 0; i < num_slices; i++) { 272 slice_offset = (OMX_U32)(*(data + (i*2 + 1))); 273 274 if ((*(pBuffer + slice_offset + 0) != 0x00) || 275 (*(pBuffer + slice_offset + 1) != 0x00) || 276 (*(pBuffer + slice_offset + 2) != 0x00) || 277 (*(pBuffer + slice_offset + 3) != H264_START_CODE)) { 278 DEBUG_PRINT_ERROR("found 0x%x instead of start code at offset[%u] " 279 "for slice[%u]", (unsigned)(*(OMX_U32 *)(pBuffer + slice_offset)), 280 (unsigned int)slice_offset, i); 281 return -1; 282 } 283 284 if (slice_offset != total_size) { 285 DEBUG_PRINT_ERROR("offset of slice number %d is not correct " 286 "or previous slice size is not correct", i); 287 return -1; 288 } 289 290 slice_size = (OMX_U32)(*(data + (i*2 + 2))); 291 total_size += slice_size; 292 DEBUG_PRINT_LOW("slice number %d offset/size = %u/%u", 293 i, (unsigned int)slice_offset, (unsigned int)slice_size); 294 } 295 296 if (pBufHdr->nFilledLen != total_size) { 297 DEBUG_PRINT_ERROR("frame_size[%u] is not equal to " 298 "total slices size[%u]", (unsigned int)pBufHdr->nFilledLen, (unsigned int)total_size); 299 return -1; 300 } 301 302 return 0; 303} 304 305OMX_U32 extra_data_handler::parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) 306{ 307 DEBUG_PRINT_LOW("In %s() flags: 0x%x", __func__, (unsigned)buf_hdr->nFlags); 308 309 if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) { 310 311 OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *) 312 ((unsigned long)(buf_hdr->pBuffer + buf_hdr->nOffset + 313 buf_hdr->nFilledLen + 3)&(~3)); 314 315 while (extra_data && 316 ((unsigned long)extra_data > (unsigned long)buf_hdr->pBuffer) && 317 ((unsigned long)extra_data < (unsigned long)buf_hdr->pBuffer + buf_hdr->nAllocLen)) { 318 319 DEBUG_PRINT_LOW("extradata(%p): nSize = 0x%x, eType = 0x%x," 320 " nDataSize = 0x%x", extra_data, (unsigned int)extra_data->nSize, 321 extra_data->eType, (unsigned int)extra_data->nDataSize); 322 323 if ((extra_data->eType == VDEC_EXTRADATA_NONE) || 324 (extra_data->eType == VEN_EXTRADATA_NONE)) { 325 DEBUG_PRINT_LOW("No more extradata available"); 326 extra_data->eType = OMX_ExtraDataNone; 327 break; 328 } else if (extra_data->eType == VDEC_EXTRADATA_SEI) { 329 DEBUG_PRINT_LOW("Extradata SEI of size %u found, " 330 "parsing it", (unsigned int)extra_data->nDataSize); 331 parse_sei(extra_data->data, extra_data->nDataSize); 332 } else if (extra_data->eType == VEN_EXTRADATA_QCOMFILLER) { 333 DEBUG_PRINT_LOW("Extradata Qcom Filler found, skip %u bytes", 334 (unsigned int)extra_data->nSize); 335 } else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) { 336 DEBUG_PRINT_LOW("Extradata SliceInfo of size %u found, " 337 "parsing it", (unsigned int)extra_data->nDataSize); 338 parse_sliceinfo(buf_hdr, extra_data); 339 } 340 341#ifndef _MSM8974_ 342 else if (extra_data->eType == VEN_EXTRADATA_LTRINFO) { 343 DEBUG_PRINT_LOW("Extradata LTRInfo of size %d found, " 344 "parsing it", extra_data->nDataSize); 345 parse_ltrinfo(extra_data); 346 } 347 348#endif 349 else { 350 DEBUG_PRINT_ERROR("Unknown extradata(%p) found, nSize = 0x%x, " 351 "eType = 0x%x, nDataSize = 0x%x", extra_data, 352 (unsigned int)extra_data->nSize, extra_data->eType, (unsigned int)extra_data->nDataSize); 353 buf_hdr->nFlags &= ~(OMX_BUFFERFLAG_EXTRADATA); 354 break; 355 } 356 357 extra_data = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) extra_data) + 358 extra_data->nSize); 359 } 360 } 361 362 return 1; 363} 364 365OMX_U32 extra_data_handler::get_frame_pack_data( 366 OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack) 367{ 368 DEBUG_PRINT_LOW("%s:%d get frame data", __func__, __LINE__); 369 memcpy(&frame_pack->id,&frame_packing_arrangement.id, 370 FRAME_PACK_SIZE*sizeof(OMX_U32)); 371 return 1; 372} 373 374OMX_U32 extra_data_handler::set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT 375 *frame_pack) 376{ 377 DEBUG_PRINT_LOW("%s:%d set frame data", __func__, __LINE__); 378 memcpy(&frame_packing_arrangement.id, &frame_pack->id, 379 FRAME_PACK_SIZE*sizeof(OMX_U32)); 380 pack_sei = true; 381 sei_payload_type = SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT; 382 return 1; 383} 384 385OMX_U32 extra_data_handler::e_u(OMX_U32 symbol, OMX_U32 num_bits) 386{ 387 OMX_U32 rem_bits = num_bits, shift; 388 389 DEBUG_PRINT_LOW("%s bin : %x/%u", __func__, (unsigned)symbol, (unsigned int)num_bits); 390 391 while (rem_bits >= bit_ptr) { 392 shift = rem_bits - bit_ptr; 393 rbsp_buf[byte_ptr] |= (symbol >> shift); 394 symbol = (symbol << (32 - shift)) >> (32 - shift); 395 rem_bits -= bit_ptr; 396 DEBUG_PRINT_LOW("%sstream byte/rem_bits %x/%u", __func__, 397 (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits); 398 byte_ptr ++; 399 bit_ptr = 8; 400 } 401 402 if (rem_bits) { 403 shift = bit_ptr - rem_bits; 404 rbsp_buf[byte_ptr] |= (symbol << shift); 405 bit_ptr -= rem_bits; 406 DEBUG_PRINT_LOW("%s 2 stream byte/rem_bits %x/%u", __func__, 407 (unsigned)rbsp_buf[byte_ptr], (unsigned int)rem_bits); 408 409 if (bit_ptr == 0) { 410 bit_ptr = 8; 411 byte_ptr++; 412 } 413 } 414 415 return 1; 416} 417 418OMX_U32 extra_data_handler::e_ue(OMX_U32 symbol) 419{ 420 OMX_U32 i, sym_len, sufix_len, info; 421 OMX_U32 nn =(symbol + 1) >> 1; 422 423 DEBUG_PRINT_LOW("%s bin : %x", __func__, (unsigned)symbol); 424 425 for (i=0; i < 33 && nn != 0; i++) 426 nn >>= 1; 427 428 sym_len = ((i << 1) + 1); 429 info = symbol + 1 - (1 << i); 430 sufix_len = (1 << (sym_len >>1)); 431 info = sufix_len | (info & (sufix_len - 1)); 432 e_u(info, sym_len); 433 return 1; 434} 435 436OMX_U32 extra_data_handler::create_frame_pack() 437{ 438 e_ue(frame_packing_arrangement.id); 439 e_u(frame_packing_arrangement.cancel_flag, 1); 440 441 if (!frame_packing_arrangement.cancel_flag) { 442 e_u(frame_packing_arrangement.type, 7); 443 e_u(frame_packing_arrangement.quincunx_sampling_flag, 1); 444 e_u(frame_packing_arrangement.content_interpretation_type, 6); 445 e_u(frame_packing_arrangement.spatial_flipping_flag, 1); 446 e_u(frame_packing_arrangement.frame0_flipped_flag, 1); 447 e_u(frame_packing_arrangement.field_views_flag, 1); 448 e_u(frame_packing_arrangement.current_frame_is_frame0_flag, 1); 449 e_u(frame_packing_arrangement.frame0_self_contained_flag, 1); 450 e_u(frame_packing_arrangement.frame1_self_contained_flag, 1); 451 452 if (!frame_packing_arrangement.quincunx_sampling_flag && 453 frame_packing_arrangement.type != 5) { 454 e_u(frame_packing_arrangement.frame0_grid_position_x, 4); 455 e_u(frame_packing_arrangement.frame0_grid_position_y, 4); 456 e_u(frame_packing_arrangement.frame1_grid_position_x, 4); 457 e_u(frame_packing_arrangement.frame1_grid_position_y, 4); 458 } 459 460 e_u(frame_packing_arrangement.reserved_byte, 8); 461 e_ue(frame_packing_arrangement.repetition_period); 462 } 463 464 e_u(frame_packing_arrangement.extension_flag, 1); 465 return 1; 466} 467 468OMX_S32 extra_data_handler::create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type) 469{ 470 OMX_U32 i, j = 7; 471 472 for (i = 0; i < 3; i++) 473 *buf++ = 0x00; 474 475 *buf++ = H264_START_CODE; 476 *buf++ = nalu_type; 477 *buf++ = (sei_payload_type & 0x000000FF); 478 *buf++ = byte_ptr - 1; //payload will contain 1 byte of rbsp_trailing_bits 479 //that shouldn't be taken into account 480 481 for (i = 0; i < byte_ptr ; i += 2) { 482 *buf++ = rbsp_buf[i]; 483 j++; 484 485 if (i+1 < byte_ptr) { 486 *buf++ = rbsp_buf[i+1]; 487 j++; 488 489 if (!(rbsp_buf[i] + rbsp_buf[i+1])) { 490 *buf++ = H264_EMULATION_BYTE; 491 j++; 492 } 493 } 494 } 495 496 DEBUG_PRINT_LOW("%s rbsp length %u", __func__, (unsigned int)j); 497 return j; 498} 499 500OMX_U32 extra_data_handler::create_sei(OMX_U8 *buffer) 501{ 502 OMX_U32 i, ret_val = 0; 503 504 byte_ptr = 0; 505 bit_ptr = 8; 506 507 if (sei_payload_type == SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT) { 508 create_frame_pack(); 509 510 if (bit_ptr != 8) { 511 e_u(1,1); 512 513 if (bit_ptr != 8) 514 e_u(0,bit_ptr); 515 } 516 517 //Payload will have been byte aligned by now, 518 //insert the rbsp trailing bits 519 e_u(1, 1); 520 e_u(0, 7); 521 522 ret_val = create_rbsp(buffer, NAL_TYPE_SEI); 523 } 524 525 pack_sei = false; 526 sei_payload_type = -1; 527 528 return ret_val; 529} 530 531OMX_U32 extra_data_handler::create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) 532{ 533 OMX_U8 *buffer = (OMX_U8 *) (buf_hdr->pBuffer + 534 buf_hdr->nOffset + buf_hdr->nFilledLen); 535 OMX_U32 msg_size; 536 537 if (buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 538 DEBUG_PRINT_LOW("%s:%d create extra data with config", __func__, 539 __LINE__); 540 541 if (pack_sei) { 542 msg_size = create_sei(buffer); 543 544 if ( msg_size > 0) 545 buf_hdr->nFilledLen += msg_size; 546 } 547 } 548 549 return 1; 550} 551 552