Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: content/common/gpu/media/vaapi_h264_decoder.cc

Issue 119153002: Move H264Parser and H264BitReader to media/filters. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add test-25fps.h264 to isolate Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698