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