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