OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 return; | 212 return; |
213 } | 213 } |
214 | 214 |
215 DVLOG(4) << "POC " << poc << " no longer using VA surface " | 215 DVLOG(4) << "POC " << poc << " no longer using VA surface " |
216 << it->second->va_surface()->id(); | 216 << it->second->va_surface()->id(); |
217 | 217 |
218 decode_surfaces_in_use_.erase(it); | 218 decode_surfaces_in_use_.erase(it); |
219 } | 219 } |
220 | 220 |
221 bool VaapiH264Decoder::SendPPS() { | 221 bool VaapiH264Decoder::SendPPS() { |
222 const H264PPS* pps = parser_.GetPPS(curr_pps_id_); | 222 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); |
223 DCHECK(pps); | 223 DCHECK(pps); |
224 | 224 |
225 const H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); | 225 const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); |
226 DCHECK(sps); | 226 DCHECK(sps); |
227 | 227 |
228 DCHECK(curr_pic_.get()); | 228 DCHECK(curr_pic_.get()); |
229 | 229 |
230 VAPictureParameterBufferH264 pic_param; | 230 VAPictureParameterBufferH264 pic_param; |
231 memset(&pic_param, 0, sizeof(VAPictureParameterBufferH264)); | 231 memset(&pic_param, 0, sizeof(VAPictureParameterBufferH264)); |
232 | 232 |
233 #define FROM_SPS_TO_PP(a) pic_param.a = sps->a; | 233 #define FROM_SPS_TO_PP(a) pic_param.a = sps->a; |
234 #define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a; | 234 #define FROM_SPS_TO_PP2(a, b) pic_param.b = sps->a; |
235 FROM_SPS_TO_PP2(pic_width_in_mbs_minus1, picture_width_in_mbs_minus1); | 235 FROM_SPS_TO_PP2(pic_width_in_mbs_minus1, picture_width_in_mbs_minus1); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 arraysize(pic_param.ReferenceFrames)); | 299 arraysize(pic_param.ReferenceFrames)); |
300 | 300 |
301 pic_param.num_ref_frames = sps->max_num_ref_frames; | 301 pic_param.num_ref_frames = sps->max_num_ref_frames; |
302 | 302 |
303 return vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, | 303 return vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, |
304 sizeof(VAPictureParameterBufferH264), | 304 sizeof(VAPictureParameterBufferH264), |
305 &pic_param); | 305 &pic_param); |
306 } | 306 } |
307 | 307 |
308 bool VaapiH264Decoder::SendIQMatrix() { | 308 bool VaapiH264Decoder::SendIQMatrix() { |
309 const H264PPS* pps = parser_.GetPPS(curr_pps_id_); | 309 const media::H264PPS* pps = parser_.GetPPS(curr_pps_id_); |
310 DCHECK(pps); | 310 DCHECK(pps); |
311 | 311 |
312 VAIQMatrixBufferH264 iq_matrix_buf; | 312 VAIQMatrixBufferH264 iq_matrix_buf; |
313 memset(&iq_matrix_buf, 0, sizeof(VAIQMatrixBufferH264)); | 313 memset(&iq_matrix_buf, 0, sizeof(VAIQMatrixBufferH264)); |
314 | 314 |
315 if (pps->pic_scaling_matrix_present_flag) { | 315 if (pps->pic_scaling_matrix_present_flag) { |
316 for (int i = 0; i < 6; ++i) { | 316 for (int i = 0; i < 6; ++i) { |
317 for (int j = 0; j < 16; ++j) | 317 for (int j = 0; j < 16; ++j) |
318 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j]; | 318 iq_matrix_buf.ScalingList4x4[i][j] = pps->scaling_list4x4[i][j]; |
319 } | 319 } |
320 | 320 |
321 for (int i = 0; i < 2; ++i) { | 321 for (int i = 0; i < 2; ++i) { |
322 for (int j = 0; j < 64; ++j) | 322 for (int j = 0; j < 64; ++j) |
323 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j]; | 323 iq_matrix_buf.ScalingList8x8[i][j] = pps->scaling_list8x8[i][j]; |
324 } | 324 } |
325 } else { | 325 } else { |
326 const H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); | 326 const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); |
327 DCHECK(sps); | 327 DCHECK(sps); |
328 for (int i = 0; i < 6; ++i) { | 328 for (int i = 0; i < 6; ++i) { |
329 for (int j = 0; j < 16; ++j) | 329 for (int j = 0; j < 16; ++j) |
330 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j]; | 330 iq_matrix_buf.ScalingList4x4[i][j] = sps->scaling_list4x4[i][j]; |
331 } | 331 } |
332 | 332 |
333 for (int i = 0; i < 2; ++i) { | 333 for (int i = 0; i < 2; ++i) { |
334 for (int j = 0; j < 64; ++j) | 334 for (int j = 0; j < 64; ++j) |
335 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j]; | 335 iq_matrix_buf.ScalingList8x8[i][j] = sps->scaling_list8x8[i][j]; |
336 } | 336 } |
337 } | 337 } |
338 | 338 |
339 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, | 339 return vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, |
340 sizeof(VAIQMatrixBufferH264), | 340 sizeof(VAIQMatrixBufferH264), |
341 &iq_matrix_buf); | 341 &iq_matrix_buf); |
342 } | 342 } |
343 | 343 |
344 bool VaapiH264Decoder::SendVASliceParam(H264SliceHeader* slice_hdr) { | 344 bool VaapiH264Decoder::SendVASliceParam(media::H264SliceHeader* slice_hdr) { |
345 const H264PPS* pps = parser_.GetPPS(slice_hdr->pic_parameter_set_id); | 345 const media::H264PPS* pps = parser_.GetPPS(slice_hdr->pic_parameter_set_id); |
346 DCHECK(pps); | 346 DCHECK(pps); |
347 | 347 |
348 const H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); | 348 const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); |
349 DCHECK(sps); | 349 DCHECK(sps); |
350 | 350 |
351 VASliceParameterBufferH264 slice_param; | 351 VASliceParameterBufferH264 slice_param; |
352 memset(&slice_param, 0, sizeof(VASliceParameterBufferH264)); | 352 memset(&slice_param, 0, sizeof(VASliceParameterBufferH264)); |
353 | 353 |
354 slice_param.slice_data_size = slice_hdr->nalu_size; | 354 slice_param.slice_data_size = slice_hdr->nalu_size; |
355 slice_param.slice_data_offset = 0; | 355 slice_param.slice_data_offset = 0; |
356 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; | 356 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; |
357 slice_param.slice_data_bit_offset = slice_hdr->header_bit_size; | 357 slice_param.slice_data_bit_offset = slice_hdr->header_bit_size; |
358 | 358 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 &slice_param); | 433 &slice_param); |
434 } | 434 } |
435 | 435 |
436 bool VaapiH264Decoder::SendSliceData(const uint8* ptr, size_t size) { | 436 bool VaapiH264Decoder::SendSliceData(const uint8* ptr, size_t size) { |
437 // Can't help it, blame libva... | 437 // Can't help it, blame libva... |
438 void* non_const_ptr = const_cast<uint8*>(ptr); | 438 void* non_const_ptr = const_cast<uint8*>(ptr); |
439 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size, | 439 return vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, size, |
440 non_const_ptr); | 440 non_const_ptr); |
441 } | 441 } |
442 | 442 |
443 bool VaapiH264Decoder::PrepareRefPicLists(H264SliceHeader* slice_hdr) { | 443 bool VaapiH264Decoder::PrepareRefPicLists(media::H264SliceHeader* slice_hdr) { |
444 ref_pic_list0_.clear(); | 444 ref_pic_list0_.clear(); |
445 ref_pic_list1_.clear(); | 445 ref_pic_list1_.clear(); |
446 | 446 |
447 // Fill reference picture lists for B and S/SP slices. | 447 // Fill reference picture lists for B and S/SP slices. |
448 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { | 448 if (slice_hdr->IsPSlice() || slice_hdr->IsSPSlice()) { |
449 ConstructReferencePicListsP(slice_hdr); | 449 ConstructReferencePicListsP(slice_hdr); |
450 return ModifyReferencePicList(slice_hdr, 0); | 450 return ModifyReferencePicList(slice_hdr, 0); |
451 } | 451 } |
452 | 452 |
453 if (slice_hdr->IsBSlice()) { | 453 if (slice_hdr->IsBSlice()) { |
454 ConstructReferencePicListsB(slice_hdr); | 454 ConstructReferencePicListsB(slice_hdr); |
455 return ModifyReferencePicList(slice_hdr, 0) && | 455 return ModifyReferencePicList(slice_hdr, 0) && |
456 ModifyReferencePicList(slice_hdr, 1); | 456 ModifyReferencePicList(slice_hdr, 1); |
457 } | 457 } |
458 | 458 |
459 return true; | 459 return true; |
460 } | 460 } |
461 | 461 |
462 bool VaapiH264Decoder::QueueSlice(H264SliceHeader* slice_hdr) { | 462 bool VaapiH264Decoder::QueueSlice(media::H264SliceHeader* slice_hdr) { |
463 DCHECK(curr_pic_.get()); | 463 DCHECK(curr_pic_.get()); |
464 | 464 |
465 if (!PrepareRefPicLists(slice_hdr)) | 465 if (!PrepareRefPicLists(slice_hdr)) |
466 return false; | 466 return false; |
467 | 467 |
468 if (!SendVASliceParam(slice_hdr)) | 468 if (!SendVASliceParam(slice_hdr)) |
469 return false; | 469 return false; |
470 | 470 |
471 if (!SendSliceData(slice_hdr->nalu_data, slice_hdr->nalu_size)) | 471 if (!SendSliceData(slice_hdr->nalu_data, slice_hdr->nalu_size)) |
472 return false; | 472 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
488 | 488 |
489 if (!vaapi_wrapper_->DecodeAndDestroyPendingBuffers( | 489 if (!vaapi_wrapper_->DecodeAndDestroyPendingBuffers( |
490 dec_surface->va_surface()->id())) { | 490 dec_surface->va_surface()->id())) { |
491 DVLOG(1) << "Failed decoding picture"; | 491 DVLOG(1) << "Failed decoding picture"; |
492 return false; | 492 return false; |
493 } | 493 } |
494 | 494 |
495 return true; | 495 return true; |
496 } | 496 } |
497 | 497 |
498 | 498 bool VaapiH264Decoder::InitCurrPicture(media::H264SliceHeader* slice_hdr) { |
499 bool VaapiH264Decoder::InitCurrPicture(H264SliceHeader* slice_hdr) { | |
500 DCHECK(curr_pic_.get()); | 499 DCHECK(curr_pic_.get()); |
501 | 500 |
502 memset(curr_pic_.get(), 0, sizeof(H264Picture)); | 501 memset(curr_pic_.get(), 0, sizeof(H264Picture)); |
503 | 502 |
504 curr_pic_->idr = slice_hdr->idr_pic_flag; | 503 curr_pic_->idr = slice_hdr->idr_pic_flag; |
505 | 504 |
506 if (slice_hdr->field_pic_flag) { | 505 if (slice_hdr->field_pic_flag) { |
507 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM | 506 curr_pic_->field = slice_hdr->bottom_field_flag ? H264Picture::FIELD_BOTTOM |
508 : H264Picture::FIELD_TOP; | 507 : H264Picture::FIELD_TOP; |
509 } else { | 508 } else { |
(...skipping 24 matching lines...) Expand all Loading... |
534 COMPILE_ASSERT(sizeof(curr_pic_->ref_pic_marking) == | 533 COMPILE_ASSERT(sizeof(curr_pic_->ref_pic_marking) == |
535 sizeof(slice_hdr->ref_pic_marking), | 534 sizeof(slice_hdr->ref_pic_marking), |
536 ref_pic_marking_array_sizes_do_not_match); | 535 ref_pic_marking_array_sizes_do_not_match); |
537 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, | 536 memcpy(curr_pic_->ref_pic_marking, slice_hdr->ref_pic_marking, |
538 sizeof(curr_pic_->ref_pic_marking)); | 537 sizeof(curr_pic_->ref_pic_marking)); |
539 } | 538 } |
540 | 539 |
541 return true; | 540 return true; |
542 } | 541 } |
543 | 542 |
544 bool VaapiH264Decoder::CalculatePicOrderCounts(H264SliceHeader* slice_hdr) { | 543 bool VaapiH264Decoder::CalculatePicOrderCounts( |
| 544 media::H264SliceHeader* slice_hdr) { |
545 DCHECK_NE(curr_sps_id_, -1); | 545 DCHECK_NE(curr_sps_id_, -1); |
546 const H264SPS* sps = parser_.GetSPS(curr_sps_id_); | 546 const media::H264SPS* sps = parser_.GetSPS(curr_sps_id_); |
547 | 547 |
548 int pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; | 548 int pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb; |
549 curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb; | 549 curr_pic_->pic_order_cnt_lsb = pic_order_cnt_lsb; |
550 | 550 |
551 switch (sps->pic_order_cnt_type) { | 551 switch (sps->pic_order_cnt_type) { |
552 case 0: | 552 case 0: |
553 // See spec 8.2.1.1. | 553 // See spec 8.2.1.1. |
554 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; | 554 int prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb; |
555 if (slice_hdr->idr_pic_flag) { | 555 if (slice_hdr->idr_pic_flag) { |
556 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; | 556 prev_pic_order_cnt_msb = prev_pic_order_cnt_lsb = 0; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 return a->pic_num > b->pic_num; | 743 return a->pic_num > b->pic_num; |
744 } | 744 } |
745 }; | 745 }; |
746 | 746 |
747 struct LongTermPicNumAscCompare { | 747 struct LongTermPicNumAscCompare { |
748 bool operator()(const H264Picture* a, const H264Picture* b) const { | 748 bool operator()(const H264Picture* a, const H264Picture* b) const { |
749 return a->long_term_pic_num < b->long_term_pic_num; | 749 return a->long_term_pic_num < b->long_term_pic_num; |
750 } | 750 } |
751 }; | 751 }; |
752 | 752 |
753 void VaapiH264Decoder::ConstructReferencePicListsP(H264SliceHeader* slice_hdr) { | 753 void VaapiH264Decoder::ConstructReferencePicListsP( |
| 754 media::H264SliceHeader* slice_hdr) { |
754 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: | 755 // RefPicList0 (8.2.4.2.1) [[1] [2]], where: |
755 // [1] shortterm ref pics sorted by descending pic_num, | 756 // [1] shortterm ref pics sorted by descending pic_num, |
756 // [2] longterm ref pics by ascending long_term_pic_num. | 757 // [2] longterm ref pics by ascending long_term_pic_num. |
757 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); | 758 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); |
758 // First get the short ref pics... | 759 // First get the short ref pics... |
759 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); | 760 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); |
760 size_t num_short_refs = ref_pic_list0_.size(); | 761 size_t num_short_refs = ref_pic_list0_.size(); |
761 | 762 |
762 // and sort them to get [1]. | 763 // and sort them to get [1]. |
763 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), PicNumDescCompare()); | 764 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), PicNumDescCompare()); |
(...skipping 12 matching lines...) Expand all Loading... |
776 return a->pic_order_cnt < b->pic_order_cnt; | 777 return a->pic_order_cnt < b->pic_order_cnt; |
777 } | 778 } |
778 }; | 779 }; |
779 | 780 |
780 struct POCDescCompare { | 781 struct POCDescCompare { |
781 bool operator()(const H264Picture* a, const H264Picture* b) const { | 782 bool operator()(const H264Picture* a, const H264Picture* b) const { |
782 return a->pic_order_cnt > b->pic_order_cnt; | 783 return a->pic_order_cnt > b->pic_order_cnt; |
783 } | 784 } |
784 }; | 785 }; |
785 | 786 |
786 void VaapiH264Decoder::ConstructReferencePicListsB(H264SliceHeader* slice_hdr) { | 787 void VaapiH264Decoder::ConstructReferencePicListsB( |
| 788 media::H264SliceHeader* slice_hdr) { |
787 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: | 789 // RefPicList0 (8.2.4.2.3) [[1] [2] [3]], where: |
788 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, | 790 // [1] shortterm ref pics with POC < curr_pic's POC sorted by descending POC, |
789 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, | 791 // [2] shortterm ref pics with POC > curr_pic's POC by ascending POC, |
790 // [3] longterm ref pics by ascending long_term_pic_num. | 792 // [3] longterm ref pics by ascending long_term_pic_num. |
791 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); | 793 DCHECK(ref_pic_list0_.empty() && ref_pic_list1_.empty()); |
792 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); | 794 dpb_.GetShortTermRefPicsAppending(ref_pic_list0_); |
793 size_t num_short_refs = ref_pic_list0_.size(); | 795 size_t num_short_refs = ref_pic_list0_.size(); |
794 | 796 |
795 // First sort ascending, this will put [1] in right place and finish [2]. | 797 // First sort ascending, this will put [1] in right place and finish [2]. |
796 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), POCAscCompare()); | 798 std::sort(ref_pic_list0_.begin(), ref_pic_list0_.end(), POCAscCompare()); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 (to + 2 == static_cast<int>(v->size()))); | 881 (to + 2 == static_cast<int>(v->size()))); |
880 | 882 |
881 v->resize(to + 2); | 883 v->resize(to + 2); |
882 | 884 |
883 for (int i = to + 1; i > from; --i) | 885 for (int i = to + 1; i > from; --i) |
884 (*v)[i] = (*v)[i - 1]; | 886 (*v)[i] = (*v)[i - 1]; |
885 | 887 |
886 (*v)[from] = pic; | 888 (*v)[from] = pic; |
887 } | 889 } |
888 | 890 |
889 bool VaapiH264Decoder::ModifyReferencePicList(H264SliceHeader *slice_hdr, | 891 bool VaapiH264Decoder::ModifyReferencePicList(media::H264SliceHeader* slice_hdr, |
890 int list) { | 892 int list) { |
891 int num_ref_idx_lX_active_minus1; | 893 int num_ref_idx_lX_active_minus1; |
892 H264Picture::PtrVector* ref_pic_listx; | 894 H264Picture::PtrVector* ref_pic_listx; |
893 H264ModificationOfPicNum* list_mod; | 895 media::H264ModificationOfPicNum* list_mod; |
894 | 896 |
895 // This can process either ref_pic_list0 or ref_pic_list1, depending on | 897 // This can process either ref_pic_list0 or ref_pic_list1, depending on |
896 // the list argument. Set up pointers to proper list to be processed here. | 898 // the list argument. Set up pointers to proper list to be processed here. |
897 if (list == 0) { | 899 if (list == 0) { |
898 if (!slice_hdr->ref_pic_list_modification_flag_l0) | 900 if (!slice_hdr->ref_pic_list_modification_flag_l0) |
899 return true; | 901 return true; |
900 | 902 |
901 list_mod = slice_hdr->ref_list_l0_modifications; | 903 list_mod = slice_hdr->ref_list_l0_modifications; |
902 num_ref_idx_lX_active_minus1 = ref_pic_list0_.size() - 1; | 904 num_ref_idx_lX_active_minus1 = ref_pic_list0_.size() - 1; |
903 | 905 |
(...skipping 11 matching lines...) Expand all Loading... |
915 DCHECK_GE(num_ref_idx_lX_active_minus1, 0); | 917 DCHECK_GE(num_ref_idx_lX_active_minus1, 0); |
916 | 918 |
917 // Spec 8.2.4.3: | 919 // Spec 8.2.4.3: |
918 // Reorder pictures on the list in a way specified in the stream. | 920 // Reorder pictures on the list in a way specified in the stream. |
919 int pic_num_lx_pred = curr_pic_->pic_num; | 921 int pic_num_lx_pred = curr_pic_->pic_num; |
920 int ref_idx_lx = 0; | 922 int ref_idx_lx = 0; |
921 int pic_num_lx_no_wrap; | 923 int pic_num_lx_no_wrap; |
922 int pic_num_lx; | 924 int pic_num_lx; |
923 bool done = false; | 925 bool done = false; |
924 H264Picture* pic; | 926 H264Picture* pic; |
925 for (int i = 0; i < H264SliceHeader::kRefListModSize && !done; ++i) { | 927 for (int i = 0; i < media::H264SliceHeader::kRefListModSize && !done; ++i) { |
926 switch (list_mod->modification_of_pic_nums_idc) { | 928 switch (list_mod->modification_of_pic_nums_idc) { |
927 case 0: | 929 case 0: |
928 case 1: | 930 case 1: |
929 // Modify short reference picture position. | 931 // Modify short reference picture position. |
930 if (list_mod->modification_of_pic_nums_idc == 0) { | 932 if (list_mod->modification_of_pic_nums_idc == 0) { |
931 // Subtract given value from predicted PicNum. | 933 // Subtract given value from predicted PicNum. |
932 pic_num_lx_no_wrap = pic_num_lx_pred - | 934 pic_num_lx_no_wrap = pic_num_lx_pred - |
933 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); | 935 (static_cast<int>(list_mod->abs_diff_pic_num_minus1) + 1); |
934 // Wrap around max_pic_num_ if it becomes < 0 as result | 936 // Wrap around max_pic_num_ if it becomes < 0 as result |
935 // of subtraction. | 937 // of subtraction. |
(...skipping 11 matching lines...) Expand all Loading... |
947 | 949 |
948 // For use in next iteration. | 950 // For use in next iteration. |
949 pic_num_lx_pred = pic_num_lx_no_wrap; | 951 pic_num_lx_pred = pic_num_lx_no_wrap; |
950 | 952 |
951 if (pic_num_lx_no_wrap > curr_pic_->pic_num) | 953 if (pic_num_lx_no_wrap > curr_pic_->pic_num) |
952 pic_num_lx = pic_num_lx_no_wrap - max_pic_num_; | 954 pic_num_lx = pic_num_lx_no_wrap - max_pic_num_; |
953 else | 955 else |
954 pic_num_lx = pic_num_lx_no_wrap; | 956 pic_num_lx = pic_num_lx_no_wrap; |
955 | 957 |
956 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, | 958 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, |
957 H264SliceHeader::kRefListModSize); | 959 media::H264SliceHeader::kRefListModSize); |
958 pic = dpb_.GetShortRefPicByPicNum(pic_num_lx); | 960 pic = dpb_.GetShortRefPicByPicNum(pic_num_lx); |
959 if (!pic) { | 961 if (!pic) { |
960 DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; | 962 DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; |
961 return false; | 963 return false; |
962 } | 964 } |
963 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, | 965 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, |
964 num_ref_idx_lX_active_minus1, pic); | 966 num_ref_idx_lX_active_minus1, pic); |
965 ref_idx_lx++; | 967 ref_idx_lx++; |
966 | 968 |
967 for (int src = ref_idx_lx, dst = ref_idx_lx; | 969 for (int src = ref_idx_lx, dst = ref_idx_lx; |
968 src <= num_ref_idx_lX_active_minus1 + 1; ++src) { | 970 src <= num_ref_idx_lX_active_minus1 + 1; ++src) { |
969 if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx) | 971 if (PicNumF((*ref_pic_listx)[src]) != pic_num_lx) |
970 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; | 972 (*ref_pic_listx)[dst++] = (*ref_pic_listx)[src]; |
971 } | 973 } |
972 break; | 974 break; |
973 | 975 |
974 case 2: | 976 case 2: |
975 // Modify long term reference picture position. | 977 // Modify long term reference picture position. |
976 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, | 978 DCHECK_LT(num_ref_idx_lX_active_minus1 + 1, |
977 H264SliceHeader::kRefListModSize); | 979 media::H264SliceHeader::kRefListModSize); |
978 pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num); | 980 pic = dpb_.GetLongRefPicByLongTermPicNum(list_mod->long_term_pic_num); |
979 if (!pic) { | 981 if (!pic) { |
980 DVLOG(1) << "Malformed stream, no pic num " | 982 DVLOG(1) << "Malformed stream, no pic num " |
981 << list_mod->long_term_pic_num; | 983 << list_mod->long_term_pic_num; |
982 return false; | 984 return false; |
983 } | 985 } |
984 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, | 986 ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, |
985 num_ref_idx_lX_active_minus1, pic); | 987 num_ref_idx_lX_active_minus1, pic); |
986 ref_idx_lx++; | 988 ref_idx_lx++; |
987 | 989 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 | 1069 |
1068 if (!OutputAllRemainingPics()) | 1070 if (!OutputAllRemainingPics()) |
1069 return false; | 1071 return false; |
1070 | 1072 |
1071 ClearDPB(); | 1073 ClearDPB(); |
1072 | 1074 |
1073 DCHECK(decode_surfaces_in_use_.empty()); | 1075 DCHECK(decode_surfaces_in_use_.empty()); |
1074 return true; | 1076 return true; |
1075 } | 1077 } |
1076 | 1078 |
1077 bool VaapiH264Decoder::StartNewFrame(H264SliceHeader* slice_hdr) { | 1079 bool VaapiH264Decoder::StartNewFrame(media::H264SliceHeader* slice_hdr) { |
1078 // TODO posciak: add handling of max_num_ref_frames per spec. | 1080 // TODO posciak: add handling of max_num_ref_frames per spec. |
1079 | 1081 |
1080 // If the new frame is an IDR, output what's left to output and clear DPB | 1082 // If the new frame is an IDR, output what's left to output and clear DPB |
1081 if (slice_hdr->idr_pic_flag) { | 1083 if (slice_hdr->idr_pic_flag) { |
1082 // (unless we are explicitly instructed not to do so). | 1084 // (unless we are explicitly instructed not to do so). |
1083 if (!slice_hdr->no_output_of_prior_pics_flag) { | 1085 if (!slice_hdr->no_output_of_prior_pics_flag) { |
1084 // Output DPB contents. | 1086 // Output DPB contents. |
1085 if (!Flush()) | 1087 if (!Flush()) |
1086 return false; | 1088 return false; |
1087 } | 1089 } |
(...skipping 25 matching lines...) Expand all Loading... |
1113 if (!QueueSlice(slice_hdr)) | 1115 if (!QueueSlice(slice_hdr)) |
1114 return false; | 1116 return false; |
1115 | 1117 |
1116 return true; | 1118 return true; |
1117 } | 1119 } |
1118 | 1120 |
1119 bool VaapiH264Decoder::HandleMemoryManagementOps() { | 1121 bool VaapiH264Decoder::HandleMemoryManagementOps() { |
1120 // 8.2.5.4 | 1122 // 8.2.5.4 |
1121 for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) { | 1123 for (unsigned int i = 0; i < arraysize(curr_pic_->ref_pic_marking); ++i) { |
1122 // Code below does not support interlaced stream (per-field pictures). | 1124 // Code below does not support interlaced stream (per-field pictures). |
1123 H264DecRefPicMarking* ref_pic_marking = &curr_pic_->ref_pic_marking[i]; | 1125 media::H264DecRefPicMarking* ref_pic_marking = |
| 1126 &curr_pic_->ref_pic_marking[i]; |
1124 H264Picture* to_mark; | 1127 H264Picture* to_mark; |
1125 int pic_num_x; | 1128 int pic_num_x; |
1126 | 1129 |
1127 switch (ref_pic_marking->memory_mgmnt_control_operation) { | 1130 switch (ref_pic_marking->memory_mgmnt_control_operation) { |
1128 case 0: | 1131 case 0: |
1129 // Normal end of operations' specification. | 1132 // Normal end of operations' specification. |
1130 return true; | 1133 return true; |
1131 | 1134 |
1132 case 1: | 1135 case 1: |
1133 // Mark a short term reference picture as unused so it can be removed | 1136 // Mark a short term reference picture as unused so it can be removed |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 case 50: return 110400; | 1393 case 50: return 110400; |
1391 case 51: // fallthrough | 1394 case 51: // fallthrough |
1392 case 52: return 184320; | 1395 case 52: return 184320; |
1393 default: | 1396 default: |
1394 DVLOG(1) << "Invalid codec level (" << level << ")"; | 1397 DVLOG(1) << "Invalid codec level (" << level << ")"; |
1395 return 0; | 1398 return 0; |
1396 } | 1399 } |
1397 } | 1400 } |
1398 | 1401 |
1399 bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { | 1402 bool VaapiH264Decoder::ProcessSPS(int sps_id, bool* need_new_buffers) { |
1400 const H264SPS* sps = parser_.GetSPS(sps_id); | 1403 const media::H264SPS* sps = parser_.GetSPS(sps_id); |
1401 DCHECK(sps); | 1404 DCHECK(sps); |
1402 DVLOG(4) << "Processing SPS"; | 1405 DVLOG(4) << "Processing SPS"; |
1403 | 1406 |
1404 *need_new_buffers = false; | 1407 *need_new_buffers = false; |
1405 | 1408 |
1406 if (sps->frame_mbs_only_flag == 0) { | 1409 if (sps->frame_mbs_only_flag == 0) { |
1407 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; | 1410 DVLOG(1) << "frame_mbs_only_flag != 1 not supported"; |
1408 report_error_to_uma_cb_.Run(FRAME_MBS_ONLY_FLAG_NOT_ONE); | 1411 report_error_to_uma_cb_.Run(FRAME_MBS_ONLY_FLAG_NOT_ONE); |
1409 return false; | 1412 return false; |
1410 } | 1413 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1454 return false; | 1457 return false; |
1455 } | 1458 } |
1456 | 1459 |
1457 dpb_.set_max_num_pics(max_dpb_size); | 1460 dpb_.set_max_num_pics(max_dpb_size); |
1458 | 1461 |
1459 *need_new_buffers = true; | 1462 *need_new_buffers = true; |
1460 return true; | 1463 return true; |
1461 } | 1464 } |
1462 | 1465 |
1463 bool VaapiH264Decoder::ProcessPPS(int pps_id) { | 1466 bool VaapiH264Decoder::ProcessPPS(int pps_id) { |
1464 const H264PPS* pps = parser_.GetPPS(pps_id); | 1467 const media::H264PPS* pps = parser_.GetPPS(pps_id); |
1465 DCHECK(pps); | 1468 DCHECK(pps); |
1466 | 1469 |
1467 curr_pps_id_ = pps->pic_parameter_set_id; | 1470 curr_pps_id_ = pps->pic_parameter_set_id; |
1468 | 1471 |
1469 return true; | 1472 return true; |
1470 } | 1473 } |
1471 | 1474 |
1472 bool VaapiH264Decoder::FinishPrevFrameIfPresent() { | 1475 bool VaapiH264Decoder::FinishPrevFrameIfPresent() { |
1473 // If we already have a frame waiting to be decoded, decode it and finish. | 1476 // If we already have a frame waiting to be decoded, decode it and finish. |
1474 if (curr_pic_ != NULL) { | 1477 if (curr_pic_ != NULL) { |
1475 if (!DecodePicture()) | 1478 if (!DecodePicture()) |
1476 return false; | 1479 return false; |
1477 return FinishPicture(); | 1480 return FinishPicture(); |
1478 } | 1481 } |
1479 | 1482 |
1480 return true; | 1483 return true; |
1481 } | 1484 } |
1482 | 1485 |
1483 bool VaapiH264Decoder::ProcessSlice(H264SliceHeader* slice_hdr) { | 1486 bool VaapiH264Decoder::ProcessSlice(media::H264SliceHeader* slice_hdr) { |
1484 prev_frame_num_ = frame_num_; | 1487 prev_frame_num_ = frame_num_; |
1485 frame_num_ = slice_hdr->frame_num; | 1488 frame_num_ = slice_hdr->frame_num; |
1486 | 1489 |
1487 if (prev_frame_num_ > 0 && prev_frame_num_ < frame_num_ - 1) { | 1490 if (prev_frame_num_ > 0 && prev_frame_num_ < frame_num_ - 1) { |
1488 DVLOG(1) << "Gap in frame_num!"; | 1491 DVLOG(1) << "Gap in frame_num!"; |
1489 report_error_to_uma_cb_.Run(GAPS_IN_FRAME_NUM); | 1492 report_error_to_uma_cb_.Run(GAPS_IN_FRAME_NUM); |
1490 return false; | 1493 return false; |
1491 } | 1494 } |
1492 | 1495 |
1493 if (slice_hdr->field_pic_flag == 0) | 1496 if (slice_hdr->field_pic_flag == 0) |
(...skipping 29 matching lines...) Expand all Loading... |
1523 DCHECK(size); | 1526 DCHECK(size); |
1524 | 1527 |
1525 // Got new input stream data from the client. | 1528 // Got new input stream data from the client. |
1526 DVLOG(4) << "New input stream id: " << input_id << " at: " << (void*) ptr | 1529 DVLOG(4) << "New input stream id: " << input_id << " at: " << (void*) ptr |
1527 << " size: " << size; | 1530 << " size: " << size; |
1528 parser_.SetStream(ptr, size); | 1531 parser_.SetStream(ptr, size); |
1529 curr_input_id_ = input_id; | 1532 curr_input_id_ = input_id; |
1530 } | 1533 } |
1531 | 1534 |
1532 VaapiH264Decoder::DecResult VaapiH264Decoder::Decode() { | 1535 VaapiH264Decoder::DecResult VaapiH264Decoder::Decode() { |
1533 H264Parser::Result par_res; | 1536 media::H264Parser::Result par_res; |
1534 H264NALU nalu; | 1537 media::H264NALU nalu; |
1535 DCHECK_NE(state_, kError); | 1538 DCHECK_NE(state_, kError); |
1536 | 1539 |
1537 while (1) { | 1540 while (1) { |
1538 // If we've already decoded some of the stream (after reset, i.e. we are | 1541 // If we've already decoded some of the stream (after reset, i.e. we are |
1539 // not in kNeedStreamMetadata state), we may be able to go back into | 1542 // not in kNeedStreamMetadata state), we may be able to go back into |
1540 // decoding state not only starting at/resuming from an SPS, but also from | 1543 // decoding state not only starting at/resuming from an SPS, but also from |
1541 // other resume points, such as IDRs. In the latter case we need an output | 1544 // other resume points, such as IDRs. In the latter case we need an output |
1542 // surface, because we will end up decoding that IDR in the process. | 1545 // surface, because we will end up decoding that IDR in the process. |
1543 // Otherwise we just look for an SPS and don't produce any output frames. | 1546 // Otherwise we just look for an SPS and don't produce any output frames. |
1544 if (state_ != kNeedStreamMetadata && available_va_surfaces_.empty()) { | 1547 if (state_ != kNeedStreamMetadata && available_va_surfaces_.empty()) { |
1545 DVLOG(4) << "No output surfaces available"; | 1548 DVLOG(4) << "No output surfaces available"; |
1546 return kRanOutOfSurfaces; | 1549 return kRanOutOfSurfaces; |
1547 } | 1550 } |
1548 | 1551 |
1549 par_res = parser_.AdvanceToNextNALU(&nalu); | 1552 par_res = parser_.AdvanceToNextNALU(&nalu); |
1550 if (par_res == H264Parser::kEOStream) | 1553 if (par_res == media::H264Parser::kEOStream) |
1551 return kRanOutOfStreamData; | 1554 return kRanOutOfStreamData; |
1552 else if (par_res != H264Parser::kOk) | 1555 else if (par_res != media::H264Parser::kOk) |
1553 SET_ERROR_AND_RETURN(); | 1556 SET_ERROR_AND_RETURN(); |
1554 | 1557 |
1555 DVLOG(4) << "NALU found: " << static_cast<int>(nalu.nal_unit_type); | 1558 DVLOG(4) << "NALU found: " << static_cast<int>(nalu.nal_unit_type); |
1556 | 1559 |
1557 switch (nalu.nal_unit_type) { | 1560 switch (nalu.nal_unit_type) { |
1558 case H264NALU::kNonIDRSlice: | 1561 case media::H264NALU::kNonIDRSlice: |
1559 // We can't resume from a non-IDR slice. | 1562 // We can't resume from a non-IDR slice. |
1560 if (state_ != kDecoding) | 1563 if (state_ != kDecoding) |
1561 break; | 1564 break; |
1562 // else fallthrough | 1565 // else fallthrough |
1563 case H264NALU::kIDRSlice: { | 1566 case media::H264NALU::kIDRSlice: { |
1564 // TODO(posciak): the IDR may require an SPS that we don't have | 1567 // TODO(posciak): the IDR may require an SPS that we don't have |
1565 // available. For now we'd fail if that happens, but ideally we'd like | 1568 // available. For now we'd fail if that happens, but ideally we'd like |
1566 // to keep going until the next SPS in the stream. | 1569 // to keep going until the next SPS in the stream. |
1567 if (state_ == kNeedStreamMetadata) { | 1570 if (state_ == kNeedStreamMetadata) { |
1568 // We need an SPS, skip this IDR and keep looking. | 1571 // We need an SPS, skip this IDR and keep looking. |
1569 break; | 1572 break; |
1570 } | 1573 } |
1571 | 1574 |
1572 // If after reset, we should be able to recover from an IDR. | 1575 // If after reset, we should be able to recover from an IDR. |
1573 H264SliceHeader slice_hdr; | 1576 media::H264SliceHeader slice_hdr; |
1574 | 1577 |
1575 par_res = parser_.ParseSliceHeader(nalu, &slice_hdr); | 1578 par_res = parser_.ParseSliceHeader(nalu, &slice_hdr); |
1576 if (par_res != H264Parser::kOk) | 1579 if (par_res != media::H264Parser::kOk) |
1577 SET_ERROR_AND_RETURN(); | 1580 SET_ERROR_AND_RETURN(); |
1578 | 1581 |
1579 if (!ProcessSlice(&slice_hdr)) | 1582 if (!ProcessSlice(&slice_hdr)) |
1580 SET_ERROR_AND_RETURN(); | 1583 SET_ERROR_AND_RETURN(); |
1581 | 1584 |
1582 state_ = kDecoding; | 1585 state_ = kDecoding; |
1583 break; | 1586 break; |
1584 } | 1587 } |
1585 | 1588 |
1586 case H264NALU::kSPS: { | 1589 case media::H264NALU::kSPS: { |
1587 int sps_id; | 1590 int sps_id; |
1588 | 1591 |
1589 if (!FinishPrevFrameIfPresent()) | 1592 if (!FinishPrevFrameIfPresent()) |
1590 SET_ERROR_AND_RETURN(); | 1593 SET_ERROR_AND_RETURN(); |
1591 | 1594 |
1592 par_res = parser_.ParseSPS(&sps_id); | 1595 par_res = parser_.ParseSPS(&sps_id); |
1593 if (par_res != H264Parser::kOk) | 1596 if (par_res != media::H264Parser::kOk) |
1594 SET_ERROR_AND_RETURN(); | 1597 SET_ERROR_AND_RETURN(); |
1595 | 1598 |
1596 bool need_new_buffers = false; | 1599 bool need_new_buffers = false; |
1597 if (!ProcessSPS(sps_id, &need_new_buffers)) | 1600 if (!ProcessSPS(sps_id, &need_new_buffers)) |
1598 SET_ERROR_AND_RETURN(); | 1601 SET_ERROR_AND_RETURN(); |
1599 | 1602 |
1600 state_ = kDecoding; | 1603 state_ = kDecoding; |
1601 | 1604 |
1602 if (need_new_buffers) { | 1605 if (need_new_buffers) { |
1603 if (!Flush()) | 1606 if (!Flush()) |
1604 return kDecodeError; | 1607 return kDecodeError; |
1605 | 1608 |
1606 available_va_surfaces_.clear(); | 1609 available_va_surfaces_.clear(); |
1607 return kAllocateNewSurfaces; | 1610 return kAllocateNewSurfaces; |
1608 } | 1611 } |
1609 break; | 1612 break; |
1610 } | 1613 } |
1611 | 1614 |
1612 case H264NALU::kPPS: { | 1615 case media::H264NALU::kPPS: { |
1613 if (state_ != kDecoding) | 1616 if (state_ != kDecoding) |
1614 break; | 1617 break; |
1615 | 1618 |
1616 int pps_id; | 1619 int pps_id; |
1617 | 1620 |
1618 if (!FinishPrevFrameIfPresent()) | 1621 if (!FinishPrevFrameIfPresent()) |
1619 SET_ERROR_AND_RETURN(); | 1622 SET_ERROR_AND_RETURN(); |
1620 | 1623 |
1621 par_res = parser_.ParsePPS(&pps_id); | 1624 par_res = parser_.ParsePPS(&pps_id); |
1622 if (par_res != H264Parser::kOk) | 1625 if (par_res != media::H264Parser::kOk) |
1623 SET_ERROR_AND_RETURN(); | 1626 SET_ERROR_AND_RETURN(); |
1624 | 1627 |
1625 if (!ProcessPPS(pps_id)) | 1628 if (!ProcessPPS(pps_id)) |
1626 SET_ERROR_AND_RETURN(); | 1629 SET_ERROR_AND_RETURN(); |
1627 break; | 1630 break; |
1628 } | 1631 } |
1629 | 1632 |
1630 default: | 1633 default: |
1631 DVLOG(4) << "Skipping NALU type: " << nalu.nal_unit_type;; | 1634 DVLOG(4) << "Skipping NALU type: " << nalu.nal_unit_type;; |
1632 break; | 1635 break; |
1633 } | 1636 } |
1634 } | 1637 } |
1635 } | 1638 } |
1636 | 1639 |
1637 size_t VaapiH264Decoder::GetRequiredNumOfPictures() { | 1640 size_t VaapiH264Decoder::GetRequiredNumOfPictures() { |
1638 return dpb_.max_num_pics() + kPicsInPipeline; | 1641 return dpb_.max_num_pics() + kPicsInPipeline; |
1639 } | 1642 } |
1640 | 1643 |
1641 } // namespace content | 1644 } // namespace content |
OLD | NEW |