OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "media/gpu/vt_video_decode_accelerator_mac.h" | 5 #include "media/gpu/vt_video_decode_accelerator_mac.h" |
6 | 6 |
7 #include <CoreVideo/CoreVideo.h> | 7 #include <CoreVideo/CoreVideo.h> |
8 #include <OpenGL/CGLIOSurface.h> | 8 #include <OpenGL/CGLIOSurface.h> |
9 #include <OpenGL/gl.h> | 9 #include <OpenGL/gl.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 25 matching lines...) Expand all Loading... |
36 | 36 |
37 #define NOTIFY_STATUS(name, status, session_failure) \ | 37 #define NOTIFY_STATUS(name, status, session_failure) \ |
38 do { \ | 38 do { \ |
39 OSSTATUS_DLOG(ERROR, status) << name; \ | 39 OSSTATUS_DLOG(ERROR, status) << name; \ |
40 NotifyError(PLATFORM_FAILURE, session_failure); \ | 40 NotifyError(PLATFORM_FAILURE, session_failure); \ |
41 } while (0) | 41 } while (0) |
42 | 42 |
43 namespace media { | 43 namespace media { |
44 | 44 |
45 // Only H.264 with 4:2:0 chroma sampling is supported. | 45 // Only H.264 with 4:2:0 chroma sampling is supported. |
46 static const media::VideoCodecProfile kSupportedProfiles[] = { | 46 static const VideoCodecProfile kSupportedProfiles[] = { |
47 media::H264PROFILE_BASELINE, media::H264PROFILE_MAIN, | 47 H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_EXTENDED, |
48 media::H264PROFILE_EXTENDED, media::H264PROFILE_HIGH, | 48 H264PROFILE_HIGH, |
49 // TODO(hubbe): Try to re-enable this again somehow. Currently it seems | 49 // TODO(hubbe): Try to re-enable this again somehow. Currently it seems |
50 // that some codecs fail to check the profile during initialization and | 50 // that some codecs fail to check the profile during initialization and |
51 // then fail on the first frame decode, which currently results in a | 51 // then fail on the first frame decode, which currently results in a |
52 // pipeline failure. | 52 // pipeline failure. |
53 // media::H264PROFILE_HIGH10PROFILE, | 53 // H264PROFILE_HIGH10PROFILE, |
54 media::H264PROFILE_SCALABLEBASELINE, media::H264PROFILE_SCALABLEHIGH, | 54 H264PROFILE_SCALABLEBASELINE, H264PROFILE_SCALABLEHIGH, |
55 media::H264PROFILE_STEREOHIGH, media::H264PROFILE_MULTIVIEWHIGH, | 55 H264PROFILE_STEREOHIGH, H264PROFILE_MULTIVIEWHIGH, |
56 }; | 56 }; |
57 | 57 |
58 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). | 58 // Size to use for NALU length headers in AVC format (can be 1, 2, or 4). |
59 static const int kNALUHeaderLength = 4; | 59 static const int kNALUHeaderLength = 4; |
60 | 60 |
61 // We request 5 picture buffers from the client, each of which has a texture ID | 61 // We request 5 picture buffers from the client, each of which has a texture ID |
62 // that we can bind decoded frames to. We need enough to satisfy preroll, and | 62 // that we can bind decoded frames to. We need enough to satisfy preroll, and |
63 // enough to avoid unnecessary stalling, but no more than that. The resource | 63 // enough to avoid unnecessary stalling, but no more than that. The resource |
64 // requirements are low, as we don't need the textures to be backed by storage. | 64 // requirements are low, as we don't need the textures to be backed by storage. |
65 static const int kNumPictureBuffers = media::limits::kMaxVideoFrames + 1; | 65 static const int kNumPictureBuffers = limits::kMaxVideoFrames + 1; |
66 | 66 |
67 // Maximum number of frames to queue for reordering before we stop asking for | 67 // Maximum number of frames to queue for reordering before we stop asking for |
68 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the | 68 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the |
69 // reorder queue.) | 69 // reorder queue.) |
70 static const int kMaxReorderQueueSize = 16; | 70 static const int kMaxReorderQueueSize = 16; |
71 | 71 |
72 // Build an |image_config| dictionary for VideoToolbox initialization. | 72 // Build an |image_config| dictionary for VideoToolbox initialization. |
73 static base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig( | 73 static base::ScopedCFTypeRef<CFMutableDictionaryRef> BuildImageConfig( |
74 CMVideoDimensions coded_dimensions) { | 74 CMVideoDimensions coded_dimensions) { |
75 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; | 75 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // kVTDecompressionPropertyKey_UsingHardwareAcceleratedVideoDecoder | 454 // kVTDecompressionPropertyKey_UsingHardwareAcceleratedVideoDecoder |
455 CFSTR("UsingHardwareAcceleratedVideoDecoder"), kCFAllocatorDefault, | 455 CFSTR("UsingHardwareAcceleratedVideoDecoder"), kCFAllocatorDefault, |
456 cf_using_hardware.InitializeInto()) == 0) { | 456 cf_using_hardware.InitializeInto()) == 0) { |
457 using_hardware = CFBooleanGetValue(cf_using_hardware); | 457 using_hardware = CFBooleanGetValue(cf_using_hardware); |
458 } | 458 } |
459 UMA_HISTOGRAM_BOOLEAN("Media.VTVDA.HardwareAccelerated", using_hardware); | 459 UMA_HISTOGRAM_BOOLEAN("Media.VTVDA.HardwareAccelerated", using_hardware); |
460 | 460 |
461 return true; | 461 return true; |
462 } | 462 } |
463 | 463 |
464 void VTVideoDecodeAccelerator::DecodeTask( | 464 void VTVideoDecodeAccelerator::DecodeTask(const BitstreamBuffer& bitstream, |
465 const media::BitstreamBuffer& bitstream, | 465 Frame* frame) { |
466 Frame* frame) { | |
467 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); | 466 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread()); |
468 | 467 |
469 // Map the bitstream buffer. | 468 // Map the bitstream buffer. |
470 SharedMemoryRegion memory(bitstream, true); | 469 SharedMemoryRegion memory(bitstream, true); |
471 if (!memory.Map()) { | 470 if (!memory.Map()) { |
472 DLOG(ERROR) << "Failed to map bitstream buffer"; | 471 DLOG(ERROR) << "Failed to map bitstream buffer"; |
473 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); | 472 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); |
474 return; | 473 return; |
475 } | 474 } |
476 const uint8_t* buf = static_cast<uint8_t*>(memory.memory()); | 475 const uint8_t* buf = static_cast<uint8_t*>(memory.memory()); |
477 | 476 |
478 // NALUs are stored with Annex B format in the bitstream buffer (start codes), | 477 // NALUs are stored with Annex B format in the bitstream buffer (start codes), |
479 // but VideoToolbox expects AVC format (length headers), so we must rewrite | 478 // but VideoToolbox expects AVC format (length headers), so we must rewrite |
480 // the data. | 479 // the data. |
481 // | 480 // |
482 // Locate relevant NALUs and compute the size of the rewritten data. Also | 481 // Locate relevant NALUs and compute the size of the rewritten data. Also |
483 // record any parameter sets for VideoToolbox initialization. | 482 // record any parameter sets for VideoToolbox initialization. |
484 std::vector<uint8_t> sps; | 483 std::vector<uint8_t> sps; |
485 std::vector<uint8_t> spsext; | 484 std::vector<uint8_t> spsext; |
486 std::vector<uint8_t> pps; | 485 std::vector<uint8_t> pps; |
487 bool has_slice = false; | 486 bool has_slice = false; |
488 size_t data_size = 0; | 487 size_t data_size = 0; |
489 std::vector<media::H264NALU> nalus; | 488 std::vector<H264NALU> nalus; |
490 parser_.SetStream(buf, memory.size()); | 489 parser_.SetStream(buf, memory.size()); |
491 media::H264NALU nalu; | 490 H264NALU nalu; |
492 while (true) { | 491 while (true) { |
493 media::H264Parser::Result result = parser_.AdvanceToNextNALU(&nalu); | 492 H264Parser::Result result = parser_.AdvanceToNextNALU(&nalu); |
494 if (result == media::H264Parser::kEOStream) | 493 if (result == H264Parser::kEOStream) |
495 break; | 494 break; |
496 if (result == media::H264Parser::kUnsupportedStream) { | 495 if (result == H264Parser::kUnsupportedStream) { |
497 DLOG(ERROR) << "Unsupported H.264 stream"; | 496 DLOG(ERROR) << "Unsupported H.264 stream"; |
498 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); | 497 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); |
499 return; | 498 return; |
500 } | 499 } |
501 if (result != media::H264Parser::kOk) { | 500 if (result != H264Parser::kOk) { |
502 DLOG(ERROR) << "Failed to parse H.264 stream"; | 501 DLOG(ERROR) << "Failed to parse H.264 stream"; |
503 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 502 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
504 return; | 503 return; |
505 } | 504 } |
506 switch (nalu.nal_unit_type) { | 505 switch (nalu.nal_unit_type) { |
507 case media::H264NALU::kSPS: | 506 case H264NALU::kSPS: |
508 result = parser_.ParseSPS(&last_sps_id_); | 507 result = parser_.ParseSPS(&last_sps_id_); |
509 if (result == media::H264Parser::kUnsupportedStream) { | 508 if (result == H264Parser::kUnsupportedStream) { |
510 DLOG(ERROR) << "Unsupported SPS"; | 509 DLOG(ERROR) << "Unsupported SPS"; |
511 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); | 510 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); |
512 return; | 511 return; |
513 } | 512 } |
514 if (result != media::H264Parser::kOk) { | 513 if (result != H264Parser::kOk) { |
515 DLOG(ERROR) << "Could not parse SPS"; | 514 DLOG(ERROR) << "Could not parse SPS"; |
516 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 515 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
517 return; | 516 return; |
518 } | 517 } |
519 sps.assign(nalu.data, nalu.data + nalu.size); | 518 sps.assign(nalu.data, nalu.data + nalu.size); |
520 spsext.clear(); | 519 spsext.clear(); |
521 break; | 520 break; |
522 | 521 |
523 case media::H264NALU::kSPSExt: | 522 case H264NALU::kSPSExt: |
524 // TODO(sandersd): Check that the previous NALU was an SPS. | 523 // TODO(sandersd): Check that the previous NALU was an SPS. |
525 spsext.assign(nalu.data, nalu.data + nalu.size); | 524 spsext.assign(nalu.data, nalu.data + nalu.size); |
526 break; | 525 break; |
527 | 526 |
528 case media::H264NALU::kPPS: | 527 case H264NALU::kPPS: |
529 result = parser_.ParsePPS(&last_pps_id_); | 528 result = parser_.ParsePPS(&last_pps_id_); |
530 if (result == media::H264Parser::kUnsupportedStream) { | 529 if (result == H264Parser::kUnsupportedStream) { |
531 DLOG(ERROR) << "Unsupported PPS"; | 530 DLOG(ERROR) << "Unsupported PPS"; |
532 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); | 531 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); |
533 return; | 532 return; |
534 } | 533 } |
535 if (result != media::H264Parser::kOk) { | 534 if (result != H264Parser::kOk) { |
536 DLOG(ERROR) << "Could not parse PPS"; | 535 DLOG(ERROR) << "Could not parse PPS"; |
537 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 536 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
538 return; | 537 return; |
539 } | 538 } |
540 pps.assign(nalu.data, nalu.data + nalu.size); | 539 pps.assign(nalu.data, nalu.data + nalu.size); |
541 break; | 540 break; |
542 | 541 |
543 case media::H264NALU::kSliceDataA: | 542 case H264NALU::kSliceDataA: |
544 case media::H264NALU::kSliceDataB: | 543 case H264NALU::kSliceDataB: |
545 case media::H264NALU::kSliceDataC: | 544 case H264NALU::kSliceDataC: |
546 case media::H264NALU::kNonIDRSlice: | 545 case H264NALU::kNonIDRSlice: |
547 case media::H264NALU::kIDRSlice: | 546 case H264NALU::kIDRSlice: |
548 // Compute the |pic_order_cnt| for the picture from the first slice. | 547 // Compute the |pic_order_cnt| for the picture from the first slice. |
549 if (!has_slice) { | 548 if (!has_slice) { |
550 // Verify that we are not trying to decode a slice without an IDR. | 549 // Verify that we are not trying to decode a slice without an IDR. |
551 if (waiting_for_idr_) { | 550 if (waiting_for_idr_) { |
552 if (nalu.nal_unit_type == media::H264NALU::kIDRSlice) { | 551 if (nalu.nal_unit_type == H264NALU::kIDRSlice) { |
553 waiting_for_idr_ = false; | 552 waiting_for_idr_ = false; |
554 } else { | 553 } else { |
555 // We can't compute anything yet, bail on this frame. | 554 // We can't compute anything yet, bail on this frame. |
556 has_slice = true; | 555 has_slice = true; |
557 break; | 556 break; |
558 } | 557 } |
559 } | 558 } |
560 | 559 |
561 media::H264SliceHeader slice_hdr; | 560 H264SliceHeader slice_hdr; |
562 result = parser_.ParseSliceHeader(nalu, &slice_hdr); | 561 result = parser_.ParseSliceHeader(nalu, &slice_hdr); |
563 if (result == media::H264Parser::kUnsupportedStream) { | 562 if (result == H264Parser::kUnsupportedStream) { |
564 DLOG(ERROR) << "Unsupported slice header"; | 563 DLOG(ERROR) << "Unsupported slice header"; |
565 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); | 564 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); |
566 return; | 565 return; |
567 } | 566 } |
568 if (result != media::H264Parser::kOk) { | 567 if (result != H264Parser::kOk) { |
569 DLOG(ERROR) << "Could not parse slice header"; | 568 DLOG(ERROR) << "Could not parse slice header"; |
570 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 569 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
571 return; | 570 return; |
572 } | 571 } |
573 | 572 |
574 // TODO(sandersd): Maintain a cache of configurations and reconfigure | 573 // TODO(sandersd): Maintain a cache of configurations and reconfigure |
575 // when a slice references a new config. | 574 // when a slice references a new config. |
576 DCHECK_EQ(slice_hdr.pic_parameter_set_id, last_pps_id_); | 575 DCHECK_EQ(slice_hdr.pic_parameter_set_id, last_pps_id_); |
577 const media::H264PPS* pps = | 576 const H264PPS* pps = parser_.GetPPS(slice_hdr.pic_parameter_set_id); |
578 parser_.GetPPS(slice_hdr.pic_parameter_set_id); | |
579 if (!pps) { | 577 if (!pps) { |
580 DLOG(ERROR) << "Mising PPS referenced by slice"; | 578 DLOG(ERROR) << "Mising PPS referenced by slice"; |
581 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 579 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
582 return; | 580 return; |
583 } | 581 } |
584 | 582 |
585 DCHECK_EQ(pps->seq_parameter_set_id, last_sps_id_); | 583 DCHECK_EQ(pps->seq_parameter_set_id, last_sps_id_); |
586 const media::H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); | 584 const H264SPS* sps = parser_.GetSPS(pps->seq_parameter_set_id); |
587 if (!sps) { | 585 if (!sps) { |
588 DLOG(ERROR) << "Mising SPS referenced by PPS"; | 586 DLOG(ERROR) << "Mising SPS referenced by PPS"; |
589 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 587 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
590 return; | 588 return; |
591 } | 589 } |
592 | 590 |
593 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &frame->pic_order_cnt)) { | 591 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &frame->pic_order_cnt)) { |
594 DLOG(ERROR) << "Unable to compute POC"; | 592 DLOG(ERROR) << "Unable to compute POC"; |
595 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); | 593 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); |
596 return; | 594 return; |
597 } | 595 } |
598 | 596 |
599 if (nalu.nal_unit_type == media::H264NALU::kIDRSlice) | 597 if (nalu.nal_unit_type == H264NALU::kIDRSlice) |
600 frame->is_idr = true; | 598 frame->is_idr = true; |
601 | 599 |
602 if (sps->vui_parameters_present_flag && | 600 if (sps->vui_parameters_present_flag && |
603 sps->bitstream_restriction_flag) { | 601 sps->bitstream_restriction_flag) { |
604 frame->reorder_window = | 602 frame->reorder_window = |
605 std::min(sps->max_num_reorder_frames, kMaxReorderQueueSize - 1); | 603 std::min(sps->max_num_reorder_frames, kMaxReorderQueueSize - 1); |
606 } | 604 } |
607 } | 605 } |
608 has_slice = true; | 606 has_slice = true; |
609 default: | 607 default: |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 status = CMBlockBufferAssureBlockMemory(data); | 700 status = CMBlockBufferAssureBlockMemory(data); |
703 if (status) { | 701 if (status) { |
704 NOTIFY_STATUS("CMBlockBufferAssureBlockMemory()", status, | 702 NOTIFY_STATUS("CMBlockBufferAssureBlockMemory()", status, |
705 SFT_PLATFORM_ERROR); | 703 SFT_PLATFORM_ERROR); |
706 return; | 704 return; |
707 } | 705 } |
708 | 706 |
709 // Copy NALU data into the CMBlockBuffer, inserting length headers. | 707 // Copy NALU data into the CMBlockBuffer, inserting length headers. |
710 size_t offset = 0; | 708 size_t offset = 0; |
711 for (size_t i = 0; i < nalus.size(); i++) { | 709 for (size_t i = 0; i < nalus.size(); i++) { |
712 media::H264NALU& nalu = nalus[i]; | 710 H264NALU& nalu = nalus[i]; |
713 uint32_t header = base::HostToNet32(static_cast<uint32_t>(nalu.size)); | 711 uint32_t header = base::HostToNet32(static_cast<uint32_t>(nalu.size)); |
714 status = | 712 status = |
715 CMBlockBufferReplaceDataBytes(&header, data, offset, kNALUHeaderLength); | 713 CMBlockBufferReplaceDataBytes(&header, data, offset, kNALUHeaderLength); |
716 if (status) { | 714 if (status) { |
717 NOTIFY_STATUS("CMBlockBufferReplaceDataBytes()", status, | 715 NOTIFY_STATUS("CMBlockBufferReplaceDataBytes()", status, |
718 SFT_PLATFORM_ERROR); | 716 SFT_PLATFORM_ERROR); |
719 return; | 717 return; |
720 } | 718 } |
721 offset += kNALUHeaderLength; | 719 offset += kNALUHeaderLength; |
722 status = CMBlockBufferReplaceDataBytes(nalu.data, data, offset, nalu.size); | 720 status = CMBlockBufferReplaceDataBytes(nalu.data, data, offset, nalu.size); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 FROM_HERE, | 815 FROM_HERE, |
818 base::Bind(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type)); | 816 base::Bind(&VTVideoDecodeAccelerator::FlushDone, weak_this_, type)); |
819 } | 817 } |
820 | 818 |
821 void VTVideoDecodeAccelerator::FlushDone(TaskType type) { | 819 void VTVideoDecodeAccelerator::FlushDone(TaskType type) { |
822 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 820 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
823 task_queue_.push(Task(type)); | 821 task_queue_.push(Task(type)); |
824 ProcessWorkQueues(); | 822 ProcessWorkQueues(); |
825 } | 823 } |
826 | 824 |
827 void VTVideoDecodeAccelerator::Decode(const media::BitstreamBuffer& bitstream) { | 825 void VTVideoDecodeAccelerator::Decode(const BitstreamBuffer& bitstream) { |
828 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 826 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
829 if (bitstream.id() < 0) { | 827 if (bitstream.id() < 0) { |
830 DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id(); | 828 DLOG(ERROR) << "Invalid bitstream, id: " << bitstream.id(); |
831 if (base::SharedMemory::IsHandleValid(bitstream.handle())) | 829 if (base::SharedMemory::IsHandleValid(bitstream.handle())) |
832 base::SharedMemory::CloseHandle(bitstream.handle()); | 830 base::SharedMemory::CloseHandle(bitstream.handle()); |
833 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); | 831 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); |
834 return; | 832 return; |
835 } | 833 } |
836 DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id())); | 834 DCHECK_EQ(0u, assigned_bitstream_ids_.count(bitstream.id())); |
837 assigned_bitstream_ids_.insert(bitstream.id()); | 835 assigned_bitstream_ids_.insert(bitstream.id()); |
838 Frame* frame = new Frame(bitstream.id()); | 836 Frame* frame = new Frame(bitstream.id()); |
839 pending_frames_[frame->bitstream_id] = make_linked_ptr(frame); | 837 pending_frames_[frame->bitstream_id] = make_linked_ptr(frame); |
840 decoder_thread_.task_runner()->PostTask( | 838 decoder_thread_.task_runner()->PostTask( |
841 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::DecodeTask, | 839 FROM_HERE, base::Bind(&VTVideoDecodeAccelerator::DecodeTask, |
842 base::Unretained(this), bitstream, frame)); | 840 base::Unretained(this), bitstream, frame)); |
843 } | 841 } |
844 | 842 |
845 void VTVideoDecodeAccelerator::AssignPictureBuffers( | 843 void VTVideoDecodeAccelerator::AssignPictureBuffers( |
846 const std::vector<media::PictureBuffer>& pictures) { | 844 const std::vector<PictureBuffer>& pictures) { |
847 DCHECK(gpu_thread_checker_.CalledOnValidThread()); | 845 DCHECK(gpu_thread_checker_.CalledOnValidThread()); |
848 | 846 |
849 for (const media::PictureBuffer& picture : pictures) { | 847 for (const PictureBuffer& picture : pictures) { |
850 DCHECK(!picture_info_map_.count(picture.id())); | 848 DCHECK(!picture_info_map_.count(picture.id())); |
851 assigned_picture_ids_.insert(picture.id()); | 849 assigned_picture_ids_.insert(picture.id()); |
852 available_picture_ids_.push_back(picture.id()); | 850 available_picture_ids_.push_back(picture.id()); |
853 DCHECK_LE(1u, picture.internal_texture_ids().size()); | 851 DCHECK_LE(1u, picture.internal_texture_ids().size()); |
854 DCHECK_LE(1u, picture.texture_ids().size()); | 852 DCHECK_LE(1u, picture.texture_ids().size()); |
855 picture_info_map_.insert(std::make_pair( | 853 picture_info_map_.insert(std::make_pair( |
856 picture.id(), | 854 picture.id(), |
857 base::WrapUnique(new PictureInfo(picture.internal_texture_ids()[0], | 855 base::WrapUnique(new PictureInfo(picture.internal_texture_ids()[0], |
858 picture.texture_ids()[0])))); | 856 picture.texture_ids()[0])))); |
859 } | 857 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 // Assign the new image(s) to the the picture info. | 1054 // Assign the new image(s) to the the picture info. |
1057 picture_info->gl_image = gl_image; | 1055 picture_info->gl_image = gl_image; |
1058 picture_info->cv_image = frame.image; | 1056 picture_info->cv_image = frame.image; |
1059 available_picture_ids_.pop_back(); | 1057 available_picture_ids_.pop_back(); |
1060 | 1058 |
1061 // TODO(sandersd): Currently, the size got from | 1059 // TODO(sandersd): Currently, the size got from |
1062 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to | 1060 // CMVideoFormatDescriptionGetDimensions is visible size. We pass it to |
1063 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in | 1061 // GpuVideoDecoder so that GpuVideoDecoder can use correct visible size in |
1064 // resolution changed. We should find the correct API to get the real | 1062 // resolution changed. We should find the correct API to get the real |
1065 // coded size and fix it. | 1063 // coded size and fix it. |
1066 client_->PictureReady(media::Picture(picture_id, frame.bitstream_id, | 1064 client_->PictureReady(Picture(picture_id, frame.bitstream_id, |
1067 gfx::Rect(frame.coded_size), true)); | 1065 gfx::Rect(frame.coded_size), true)); |
1068 return true; | 1066 return true; |
1069 } | 1067 } |
1070 | 1068 |
1071 void VTVideoDecodeAccelerator::NotifyError( | 1069 void VTVideoDecodeAccelerator::NotifyError( |
1072 Error vda_error_type, | 1070 Error vda_error_type, |
1073 VTVDASessionFailureType session_failure_type) { | 1071 VTVDASessionFailureType session_failure_type) { |
1074 DCHECK_LT(session_failure_type, SFT_MAX + 1); | 1072 DCHECK_LT(session_failure_type, SFT_MAX + 1); |
1075 if (!gpu_thread_checker_.CalledOnValidThread()) { | 1073 if (!gpu_thread_checker_.CalledOnValidThread()) { |
1076 gpu_task_runner_->PostTask( | 1074 gpu_task_runner_->PostTask( |
1077 FROM_HERE, | 1075 FROM_HERE, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 QueueFlush(TASK_DESTROY); | 1125 QueueFlush(TASK_DESTROY); |
1128 } | 1126 } |
1129 | 1127 |
1130 bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1128 bool VTVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
1131 const base::WeakPtr<Client>& decode_client, | 1129 const base::WeakPtr<Client>& decode_client, |
1132 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1130 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
1133 return false; | 1131 return false; |
1134 } | 1132 } |
1135 | 1133 |
1136 // static | 1134 // static |
1137 media::VideoDecodeAccelerator::SupportedProfiles | 1135 VideoDecodeAccelerator::SupportedProfiles |
1138 VTVideoDecodeAccelerator::GetSupportedProfiles() { | 1136 VTVideoDecodeAccelerator::GetSupportedProfiles() { |
1139 SupportedProfiles profiles; | 1137 SupportedProfiles profiles; |
1140 for (const auto& supported_profile : kSupportedProfiles) { | 1138 for (const auto& supported_profile : kSupportedProfiles) { |
1141 SupportedProfile profile; | 1139 SupportedProfile profile; |
1142 profile.profile = supported_profile; | 1140 profile.profile = supported_profile; |
1143 profile.min_resolution.SetSize(16, 16); | 1141 profile.min_resolution.SetSize(16, 16); |
1144 profile.max_resolution.SetSize(4096, 2160); | 1142 profile.max_resolution.SetSize(4096, 2160); |
1145 profiles.push_back(profile); | 1143 profiles.push_back(profile); |
1146 } | 1144 } |
1147 return profiles; | 1145 return profiles; |
1148 } | 1146 } |
1149 | 1147 |
1150 } // namespace media | 1148 } // namespace media |
OLD | NEW |