Ticket #9410: fix9410-bbc-hd2.patch
File fix9410-bbc-hd2.patch, 16.5 KB (added by , 10 years ago) |
---|
-
mythtv/libs/libmythtv/mpeg/H264Parser.cpp
diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.cpp b/mythtv/libs/libmythtv/mpeg/H264Parser.cpp old mode 100644 new mode 100755 index ac805e7..96422e2
a b static const float eps = 1E-5; 92 92 93 93 H264Parser::H264Parser(void) 94 94 { 95 rbsp_buffer = NULL; 96 rbsp_buffer_size = 0; 95 97 Reset(); 96 98 I_is_keyframe = true; 97 memset(&gb, 0, sizeof(gb));98 99 } 99 100 100 101 void H264Parser::Reset(void) … … void H264Parser::Reset(void) 144 145 145 146 AU_offset = frame_start_offset = keyframe_start_offset = 0; 146 147 on_frame = on_key_frame = false; 148 149 resetRBSP(); 147 150 } 148 151 149 152 … … bool H264Parser::new_AU(void) 183 186 one or more of the following ways. 184 187 185 188 - frame_num differs in value. The value of frame_num used to 186 test this condition is the value of frame_num that appears in187 the syntax of the slice header, regardless of whether that value188 is inferred to have been equal to 0 for subsequent use in the189 decoding process due to the presence of190 memory_management_control_operation equal to 5.189 test this condition is the value of frame_num that appears in 190 the syntax of the slice header, regardless of whether that value 191 is inferred to have been equal to 0 for subsequent use in the 192 decoding process due to the presence of 193 memory_management_control_operation equal to 5. 191 194 Note: If the current picture is an IDR picture FrameNum and 192 195 PrevRefFrameNum are set equal to 0. 193 196 - pic_parameter_set_id differs in value. 194 197 - field_pic_flag differs in value. 195 198 - bottom_field_flag is present in both and differs in value. 196 - nal_ref_idc differs in value with one of the nal_ref_idc values197 being equal to 0.199 - nal_ref_idc differs in value with one of the nal_ref_idc 200 values being equal to 0. 198 201 - pic_order_cnt_type is equal to 0 for both and either 199 pic_order_cnt_lsb differs in value, or delta_pic_order_cnt_bottom200 differs in value.202 pic_order_cnt_lsb differs in value, or delta_pic_order_cnt_bottom 203 differs in value. 201 204 - pic_order_cnt_type is equal to 1 for both and either 202 delta_pic_order_cnt[0] differs in value, or203 delta_pic_order_cnt[1] differs in value.205 delta_pic_order_cnt[0] differs in value, or 206 delta_pic_order_cnt[1] differs in value. 204 207 - nal_unit_type differs in value with one of the nal_unit_type values 205 being equal to 5.208 being equal to 5. 206 209 - nal_unit_type is equal to 5 for both and idr_pic_id differs in 207 value.210 value. 208 211 209 212 NOTE â Some of the VCL NAL units in redundant coded pictures or some 210 213 non-VCL NAL units (e.g. an access unit delimiter NAL unit) may also … … bool H264Parser::new_AU(void) 230 233 else if ((bottom_field_flag != -1 && prev_bottom_field_flag != -1) && 231 234 bottom_field_flag != prev_bottom_field_flag) 232 235 result = true; 236 else if ((nal_ref_idc == 0 || prev_nal_ref_idc == 0) && 237 nal_ref_idc != prev_nal_ref_idc) 238 result = true; 233 239 else if ((pic_order_cnt_type == 0 && prev_pic_order_cnt_type == 0) && 234 240 (pic_order_cnt_lsb != prev_pic_order_cnt_lsb || 235 241 delta_pic_order_cnt_bottom != … … bool H264Parser::new_AU(void) 253 259 prev_pic_parameter_set_id = pic_parameter_set_id; 254 260 prev_field_pic_flag = field_pic_flag; 255 261 prev_bottom_field_flag = bottom_field_flag; 262 prev_nal_ref_idc = nal_ref_idc; 256 263 prev_pic_order_cnt_lsb = pic_order_cnt_lsb; 257 264 prev_delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom; 258 265 prev_delta_pic_order_cnt[0] = delta_pic_order_cnt[0]; … … bool H264Parser::new_AU(void) 263 270 return result; 264 271 } 265 272 273 void H264Parser::resetRBSP(void) 274 { 275 rbsp_index = 0; 276 consecutive_zeros = 0; 277 have_unfinished_NAL = false; 278 } 279 280 void H264Parser::fillRBSP(const uint8_t *byteP, uint32_t byte_count) 281 { 282 /* 283 bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE 284 bytes larger then the actual read bits 285 */ 286 uint32_t required_size = rbsp_index + byte_count + FF_INPUT_BUFFER_PADDING_SIZE; 287 if(rbsp_buffer_size < required_size) 288 { 289 /* Need a bigger buffer */ 290 uint8_t *new_buffer = new uint8_t[required_size]; 291 292 if(new_buffer == NULL) 293 { 294 /* Discard the new bytes and allow parsing of 295 * the current NAL to fail VERBOSE */ 296 return; 297 } 298 299 /* Copy across bytes from old buffer */ 300 memcpy(new_buffer, rbsp_buffer, rbsp_index); 301 302 delete [] rbsp_buffer; 303 rbsp_buffer = new_buffer; 304 rbsp_buffer_size = required_size; 305 } 306 307 /* From rbsp while we have data and we don't run into a 308 * new start code */ 309 while(byte_count && (consecutive_zeros < 2 || *byteP != 0x01)) 310 { 311 /* Copy the byte into the rbsp, unless it 312 * is the 0x03 in a 0x000003 */ 313 if(consecutive_zeros < 2 || *byteP != 0x03) 314 rbsp_buffer[rbsp_index++] = *byteP; 315 316 if(*byteP == 0) 317 consecutive_zeros += 1; 318 else 319 consecutive_zeros = 0; 320 321 byteP += 1; 322 byte_count -= 1; 323 } 324 325 /* Stick some zeros on the end to run into */ 326 for(uint32_t i = 0; i < FF_INPUT_BUFFER_PADDING_SIZE; i++) 327 rbsp_buffer[rbsp_index + i] = 0; 328 } 329 266 330 uint32_t H264Parser::addBytes(const uint8_t *bytes, 267 331 const uint32_t byte_count, 268 332 const uint64_t stream_offset) 269 333 { 270 const uint8_t *byteP = bytes; 271 const uint8_t *endP = bytes + byte_count; 272 uint8_t first_byte; 334 const uint8_t *startP = bytes; 273 335 274 state_changed = is_keyframe = false; 336 state_changed = false; 337 on_frame = false; 338 on_key_frame = false; 275 339 276 while ( byteP < endP)340 while (startP < bytes + byte_count && !on_frame) 277 341 { 278 byteP = ff_find_start_code(byteP, endP, &sync_accumulator); 342 const uint8_t *endP; 343 bool found_start_code; 344 345 endP = ff_find_start_code(startP, bytes + byte_count, &sync_accumulator); 346 347 found_start_code = ((sync_accumulator & 0xffffff00) == 0x00000100); 348 349 /* Between bytes and byteP we potentially have some more 350 * bytes of a NAL we've had insufficient of to parse so far 351 * (plus some bytes of start code) */ 352 if(have_unfinished_NAL) 353 { 354 fillRBSP(startP, endP - startP); 355 processRBSP(found_start_code); 356 } 279 357 280 if ((sync_accumulator & 0xffffff00) == 0x00000100) 358 startP = endP; 359 360 if (found_start_code) 281 361 { 362 if(have_unfinished_NAL) 363 { 364 /* We've found a new start code, without complete 365 * parsing of the previous NAL. Either there's a 366 * problem with the stream or with this parser. 367 * VERBOSE */ 368 } 369 370 /* Prepare for accepting the new NAL */ 371 resetRBSP(); 372 373 /* If we find the start of an AU somewhere from here 374 * to the next start code, the offset to associate with 375 * it is the one passed in to this call, not any of the 376 * subsequent calls. */ 377 pkt_offset = stream_offset; 282 378 /* 283 379 nal_unit_type specifies the type of RBSP data structure contained in 284 380 the NAL unit as specified in Table 7-1. VCL NAL units … … uint32_t H264Parser::addBytes(const uint8_t *bytes, 299 395 10 End of sequence end_of_seq_rbsp( ) 300 396 11 End of stream end_of_stream_rbsp( ) 301 397 */ 302 first_byte = *(byteP - 1); 303 nal_unit_type = first_byte & 0x1f; 304 nal_ref_idc = (first_byte >> 5) & 0x3; 398 nal_unit_type = sync_accumulator & 0x1f; 399 nal_ref_idc = (sync_accumulator >> 5) & 0x3; 305 400 306 401 if (nal_unit_type == SPS || nal_unit_type == PPS || 307 402 nal_unit_type == SEI || NALisSlice(nal_unit_type)) 308 403 { 309 /* 310 bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE 311 bytes larger then the actual read bits 312 */ 313 if (byteP + 1 + FF_INPUT_BUFFER_PADDING_SIZE < endP) 314 { 315 init_get_bits(&gb, byteP, 8 * (endP - byteP)); 316 317 if (nal_unit_type == SEI) 318 { 319 decode_SEI(&gb); 320 set_AU_pending(stream_offset); 321 } 322 else if (nal_unit_type == SPS) 323 { 324 decode_SPS(&gb); 325 set_AU_pending(stream_offset); 326 } 327 else if (nal_unit_type == PPS) 328 { 329 decode_PPS(&gb); 330 set_AU_pending(stream_offset); 331 } 332 else 333 { 334 decode_Header(&gb); 335 if (new_AU()) 336 set_AU_pending(stream_offset); 337 } 338 339 byteP += (get_bits_count(&gb) / 8); 340 } 404 /* This is a NAL we need to parse. We may have the body 405 * of it in the part of the stream past to us this call, 406 * or we may get the rest in subsequent calls to addBytes. 407 * Either way, we have yet to fill the rbsp buffer. */ 408 have_unfinished_NAL = true; 341 409 } 342 else if (!AU_pending) 343 { 344 if (nal_unit_type == AU_DELIMITER || 410 else if (nal_unit_type == AU_DELIMITER || 345 411 (nal_unit_type > SPS_EXT && 346 412 nal_unit_type < AUXILIARY_SLICE)) 347 { 348 AU_pending = true; 349 AU_offset = stream_offset; 350 } 351 else if ((nal_ref_idc == 0 || prev_nal_ref_idc == 0) && 352 nal_ref_idc != prev_nal_ref_idc) 353 { 354 AU_pending = true; 355 AU_offset = stream_offset; 356 } 413 { 414 set_AU_pending(); 357 415 } 416 } 417 } 358 418 359 if (AU_pending && NALisSlice(nal_unit_type)) 360 { 361 /* Once we know the slice type of a new AU, we can 362 * determine if it is a keyframe or just a frame */ 419 return startP - bytes; 420 } 363 421 364 AU_pending = false;365 state_changed = true;366 422 367 on_frame = true; 368 frame_start_offset = AU_offset; 423 void H264Parser::processRBSP(bool rbsp_complete) 424 { 425 GetBitContext gb; 369 426 370 if (is_keyframe) 371 { 372 on_key_frame = true; 373 keyframe_start_offset = AU_offset; 374 } 375 else 376 on_key_frame = false; 377 } 378 else 379 on_frame = on_key_frame = false; 427 init_get_bits(&gb, rbsp_buffer, 8 * rbsp_index); 428 429 if (nal_unit_type == SEI) 430 { 431 /* SEI cannot be parsed without knowing its size. If 432 * we haven't got the whole rbsp, return and wait for 433 * the rest */ 434 if(!rbsp_complete) 435 return; 380 436 381 prev_nal_ref_idc = nal_ref_idc;437 set_AU_pending(); 382 438 383 return byteP - bytes; 384 } 439 decode_SEI(&gb); 440 } 441 else if (nal_unit_type == SPS) 442 { 443 /* Best wait until we have the whole thing */ 444 if(!rbsp_complete) 445 return; 446 447 set_AU_pending(); 448 449 decode_SPS(&gb); 450 } 451 else if (nal_unit_type == PPS) 452 { 453 /* Best wait until we have the whole thing */ 454 if(!rbsp_complete) 455 return; 456 457 set_AU_pending(); 458 459 decode_PPS(&gb); 460 } 461 else 462 { 463 /* Need only parse the header. So return only 464 * if we have insufficient bytes */ 465 if(!rbsp_complete && rbsp_index < MAX_SLICE_HEADER_SIZE) 466 return; 467 468 decode_Header(&gb); 469 470 if (new_AU()) 471 set_AU_pending(); 385 472 } 386 473 387 return byteP - bytes; 474 /* If we got this far, we managed to parse a sufficient 475 * prefix of the current NAL. We can go onto the next. */ 476 have_unfinished_NAL = false; 477 478 if (AU_pending && NALisSlice(nal_unit_type)) 479 { 480 /* Once we know the slice type of a new AU, we can 481 * determine if it is a keyframe or just a frame */ 482 483 AU_pending = false; 484 state_changed = true; 485 486 on_frame = true; 487 frame_start_offset = AU_offset; 488 489 if (is_keyframe || au_contains_keyframe_message) 490 { 491 on_key_frame = true; 492 keyframe_start_offset = AU_offset; 493 } 494 } 388 495 } 389 496 390 497 /* … … bool H264Parser::decode_Header(GetBitContext *gb) 394 501 { 395 502 uint first_mb_in_slice; 396 503 504 is_keyframe = false; 505 397 506 if (log2_max_frame_num == 0 || pic_order_present_flag == -1) 398 507 { 399 508 // SPS or PPS has not been parsed yet … … void H264Parser::decode_SPS(GetBitContext * gb) 600 709 { 601 710 for (int idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); ++idx) 602 711 { 603 get_bits1(gb); // scaling_list 712 if(get_bits1(gb)) // Scaling list presnent 713 { 714 int sl_n = ((idx < 6) ? 16 : 64); 715 for(int sl_i = 0; sl_i < sl_n; sl_i++) 716 { 717 get_se_golomb(gb); 718 } 719 } 604 720 } 605 721 } 606 722 } … … void H264Parser::decode_SEI(GetBitContext *gb) 853 969 exact_match_flag = get_bits1(gb); 854 970 broken_link_flag = get_bits1(gb); 855 971 changing_group_slice_idc = get_bits(gb, 2); 856 is_keyframe |= (recovery_frame_cnt >= 0);972 au_contains_keyframe_message = (recovery_frame_cnt >= 0); 857 973 return; 858 974 859 975 default: … … void H264Parser::vui_parameters(GetBitContext * gb) 1015 1131 1016 1132 uint H264Parser::frameRate(void) const 1017 1133 { 1018 uint64_t 1134 uint64_t num; 1019 1135 uint64_t fps; 1020 1136 1021 1137 num = 500 * (uint64_t)timeScale; /* 1000 * 0.5 */ -
mythtv/libs/libmythtv/mpeg/H264Parser.h
diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.h b/mythtv/libs/libmythtv/mpeg/H264Parser.h old mode 100644 new mode 100755 index 2117a96..a1e6db8
a b extern "C" { 48 48 class H264Parser { 49 49 public: 50 50 51 enum { 52 MAX_SLICE_HEADER_SIZE = 256 53 }; 54 51 55 // ITU-T Rec. H.264 table 7-1 52 56 enum NAL_unit_type { 53 57 UNKNOWN = 0, … … class H264Parser { 101 105 }; 102 106 103 107 H264Parser(void); 104 ~H264Parser(void) { ;}108 ~H264Parser(void) {delete [] rbsp_buffer;} 105 109 106 110 uint32_t addBytes(const uint8_t *bytes, 107 111 const uint32_t byte_count, … … class H264Parser { 158 162 private: 159 163 enum constants {EXTENDED_SAR = 255}; 160 164 161 inline void set_AU_pending( const uint64_t & stream_offset)165 inline void set_AU_pending(void) 162 166 { 163 167 if (!AU_pending) 164 168 { 165 169 AU_pending = true; 166 AU_offset = stream_offset; 170 AU_offset = pkt_offset; 171 au_contains_keyframe_message = false; 167 172 } 168 173 } 169 174 170 175 bool new_AU(void); 176 void resetRBSP(void); 177 void fillRBSP(const uint8_t *byteP, uint32_t byte_count); 178 void processRBSP(bool rbsp_complete); 171 179 bool decode_Header(GetBitContext *gb); 172 180 void decode_SPS(GetBitContext *gb); 173 181 void decode_PPS(GetBitContext * gb); … … class H264Parser { 177 185 bool AU_pending; 178 186 bool state_changed; 179 187 bool seen_sps; 188 bool au_contains_keyframe_message; 180 189 bool is_keyframe; 181 190 bool I_is_keyframe; 182 191 183 192 uint32_t sync_accumulator; 184 GetBitContext gb; 193 uint8_t *rbsp_buffer; 194 uint32_t rbsp_buffer_size; 195 uint32_t rbsp_index; 196 uint32_t consecutive_zeros; 197 bool have_unfinished_NAL; 185 198 186 199 int prev_frame_num, frame_num; 187 200 uint slice_type; … … class H264Parser { 218 231 uint32_t unitsInTick, timeScale; 219 232 bool fixedRate; 220 233 221 uint64_t AU_offset, frame_start_offset, keyframe_start_offset;234 uint64_t pkt_offset, AU_offset, frame_start_offset, keyframe_start_offset; 222 235 bool on_frame, on_key_frame; 223 236 }; 224 237