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

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

Issue 1481633002: Never reuse a VideoToolbox decompression session. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2564
Patch Set: Created 5 years 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
« no previous file with comments | « content/common/gpu/media/vt_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 5 #include <algorithm>
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 10
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 // that we can bind decoded frames to. We need enough to satisfy preroll, and 58 // that we can bind decoded frames to. We need enough to satisfy preroll, and
59 // enough to avoid unnecessary stalling, but no more than that. The resource 59 // enough to avoid unnecessary stalling, but no more than that. The resource
60 // requirements are low, as we don't need the textures to be backed by storage. 60 // requirements are low, as we don't need the textures to be backed by storage.
61 static const int kNumPictureBuffers = media::limits::kMaxVideoFrames + 1; 61 static const int kNumPictureBuffers = media::limits::kMaxVideoFrames + 1;
62 62
63 // Maximum number of frames to queue for reordering before we stop asking for 63 // Maximum number of frames to queue for reordering before we stop asking for
64 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the 64 // more. (NotifyEndOfBitstreamBuffer() is called when frames are moved into the
65 // reorder queue.) 65 // reorder queue.)
66 static const int kMaxReorderQueueSize = 16; 66 static const int kMaxReorderQueueSize = 16;
67 67
68 // When set to false, always create a new decoder instead of reusing the
69 // existing configuration when the configuration changes. This works around a
70 // bug in VideoToolbox that results in corruption before Mac OS X 10.10.3. The
71 // value is set in InitializeVideoToolbox().
72 static bool g_enable_compatible_configuration_reuse = true;
73
74 // Build an |image_config| dictionary for VideoToolbox initialization. 68 // Build an |image_config| dictionary for VideoToolbox initialization.
75 static base::ScopedCFTypeRef<CFMutableDictionaryRef> 69 static base::ScopedCFTypeRef<CFMutableDictionaryRef>
76 BuildImageConfig(CMVideoDimensions coded_dimensions) { 70 BuildImageConfig(CMVideoDimensions coded_dimensions) {
77 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config; 71 base::ScopedCFTypeRef<CFMutableDictionaryRef> image_config;
78 72
79 // 4:2:2 is used over the native 4:2:0 because only 4:2:2 can be directly 73 // 4:2:2 is used over the native 4:2:0 because only 4:2:2 can be directly
80 // bound to a texture by CGLTexImageIOSurface2D(). 74 // bound to a texture by CGLTexImageIOSurface2D().
81 int32_t pixel_format = kCVPixelFormatType_422YpCbCr8; 75 int32_t pixel_format = kCVPixelFormatType_422YpCbCr8;
82 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i) 76 #define CFINT(i) CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &i)
83 base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format)); 77 base::ScopedCFTypeRef<CFNumberRef> cf_pixel_format(CFINT(pixel_format));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 static bool InitializeVideoToolboxInternal() { 175 static bool InitializeVideoToolboxInternal() {
182 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 176 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
183 switches::kDisableAcceleratedVideoDecode)) { 177 switches::kDisableAcceleratedVideoDecode)) {
184 return false; 178 return false;
185 } 179 }
186 180
187 if (!IsVtInitialized()) { 181 if (!IsVtInitialized()) {
188 // CoreVideo is also required, but the loader stops after the first path is 182 // CoreVideo is also required, but the loader stops after the first path is
189 // loaded. Instead we rely on the transitive dependency from VideoToolbox to 183 // loaded. Instead we rely on the transitive dependency from VideoToolbox to
190 // CoreVideo. 184 // CoreVideo.
191 // TODO(sandersd): Fallback to PrivateFrameworks to support OS X < 10.8.
192 StubPathMap paths; 185 StubPathMap paths;
193 paths[kModuleVt].push_back(FILE_PATH_LITERAL( 186 paths[kModuleVt].push_back(FILE_PATH_LITERAL(
194 "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox")); 187 "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox"));
195 if (!InitializeStubs(paths)) { 188 if (!InitializeStubs(paths)) {
196 LOG(WARNING) << "Failed to initialize VideoToolbox framework. " 189 LOG(WARNING) << "Failed to initialize VideoToolbox framework. "
197 << "Hardware accelerated video decoding will be disabled."; 190 << "Hardware accelerated video decoding will be disabled.";
198 return false; 191 return false;
199 } 192 }
200 } 193 }
201 194
(...skipping 16 matching lines...) Expand all
218 0x22, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x0e, 211 0x22, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x0e,
219 0xa6, 0x08, 0xf1, 0x22, 0x59, 0xa0}; 212 0xa6, 0x08, 0xf1, 0x22, 0x59, 0xa0};
220 const uint8_t pps_small[] = {0x68, 0xe9, 0x79, 0x72, 0xc0}; 213 const uint8_t pps_small[] = {0x68, 0xe9, 0x79, 0x72, 0xc0};
221 if (!CreateVideoToolboxSession(sps_small, arraysize(sps_small), pps_small, 214 if (!CreateVideoToolboxSession(sps_small, arraysize(sps_small), pps_small,
222 arraysize(pps_small), false)) { 215 arraysize(pps_small), false)) {
223 LOG(WARNING) << "Failed to create software VideoToolbox session. " 216 LOG(WARNING) << "Failed to create software VideoToolbox session. "
224 << "Hardware accelerated video decoding will be disabled."; 217 << "Hardware accelerated video decoding will be disabled.";
225 return false; 218 return false;
226 } 219 }
227 220
228 // Set |g_enable_compatible_configuration_reuse| to false on
229 // Mac OS X < 10.10.3.
230 base::Version os_x_version(base::SysInfo::OperatingSystemVersion());
231 if (os_x_version.IsOlderThan("10.10.3"))
232 g_enable_compatible_configuration_reuse = false;
233
234 return true; 221 return true;
235 } 222 }
236 223
237 bool InitializeVideoToolbox() { 224 bool InitializeVideoToolbox() {
238 // InitializeVideoToolbox() is called only from the GPU process main thread; 225 // InitializeVideoToolbox() is called only from the GPU process main thread;
239 // once for sandbox warmup, and then once each time a VTVideoDecodeAccelerator 226 // once for sandbox warmup, and then once each time a VTVideoDecodeAccelerator
240 // is initialized. 227 // is initialized.
241 static bool attempted = false; 228 static bool attempted = false;
242 static bool succeeded = false; 229 static bool succeeded = false;
243 230
(...skipping 19 matching lines...) Expand all
263 vda->Output(source_frame_refcon, status, image_buffer); 250 vda->Output(source_frame_refcon, status, image_buffer);
264 } 251 }
265 252
266 VTVideoDecodeAccelerator::Task::Task(TaskType type) : type(type) { 253 VTVideoDecodeAccelerator::Task::Task(TaskType type) : type(type) {
267 } 254 }
268 255
269 VTVideoDecodeAccelerator::Task::~Task() { 256 VTVideoDecodeAccelerator::Task::~Task() {
270 } 257 }
271 258
272 VTVideoDecodeAccelerator::Frame::Frame(int32_t bitstream_id) 259 VTVideoDecodeAccelerator::Frame::Frame(int32_t bitstream_id)
273 : bitstream_id(bitstream_id), pic_order_cnt(0), reorder_window(0) { 260 : bitstream_id(bitstream_id),
261 pic_order_cnt(0),
262 is_idr(false),
263 reorder_window(0) {
274 } 264 }
275 265
276 VTVideoDecodeAccelerator::Frame::~Frame() { 266 VTVideoDecodeAccelerator::Frame::~Frame() {
277 } 267 }
278 268
279 VTVideoDecodeAccelerator::PictureInfo::PictureInfo(uint32_t client_texture_id, 269 VTVideoDecodeAccelerator::PictureInfo::PictureInfo(uint32_t client_texture_id,
280 uint32_t service_texture_id) 270 uint32_t service_texture_id)
281 : client_texture_id(client_texture_id), 271 : client_texture_id(client_texture_id),
282 service_texture_id(service_texture_id) {} 272 service_texture_id(service_texture_id) {}
283 273
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 nalu_data_ptrs.push_back(&last_sps_.front()); 369 nalu_data_ptrs.push_back(&last_sps_.front());
380 nalu_data_sizes.push_back(last_sps_.size()); 370 nalu_data_sizes.push_back(last_sps_.size());
381 if (!last_spsext_.empty()) { 371 if (!last_spsext_.empty()) {
382 nalu_data_ptrs.push_back(&last_spsext_.front()); 372 nalu_data_ptrs.push_back(&last_spsext_.front());
383 nalu_data_sizes.push_back(last_spsext_.size()); 373 nalu_data_sizes.push_back(last_spsext_.size());
384 } 374 }
385 nalu_data_ptrs.push_back(&last_pps_.front()); 375 nalu_data_ptrs.push_back(&last_pps_.front());
386 nalu_data_sizes.push_back(last_pps_.size()); 376 nalu_data_sizes.push_back(last_pps_.size());
387 377
388 // Construct a new format description from the parameter sets. 378 // Construct a new format description from the parameter sets.
389 // TODO(sandersd): Replace this with custom code to support OS X < 10.9.
390 format_.reset(); 379 format_.reset();
391 OSStatus status = CMVideoFormatDescriptionCreateFromH264ParameterSets( 380 OSStatus status = CMVideoFormatDescriptionCreateFromH264ParameterSets(
392 kCFAllocatorDefault, 381 kCFAllocatorDefault,
393 nalu_data_ptrs.size(), // parameter_set_count 382 nalu_data_ptrs.size(), // parameter_set_count
394 &nalu_data_ptrs.front(), // &parameter_set_pointers 383 &nalu_data_ptrs.front(), // &parameter_set_pointers
395 &nalu_data_sizes.front(), // &parameter_set_sizes 384 &nalu_data_sizes.front(), // &parameter_set_sizes
396 kNALUHeaderLength, // nal_unit_header_length 385 kNALUHeaderLength, // nal_unit_header_length
397 format_.InitializeInto()); 386 format_.InitializeInto());
398 if (status) { 387 if (status) {
399 NOTIFY_STATUS("CMVideoFormatDescriptionCreateFromH264ParameterSets()", 388 NOTIFY_STATUS("CMVideoFormatDescriptionCreateFromH264ParameterSets()",
400 status, SFT_PLATFORM_ERROR); 389 status, SFT_PLATFORM_ERROR);
401 return false; 390 return false;
402 } 391 }
403 392
404 // Store the new configuration data. 393 // Store the new configuration data.
394 // TODO(sandersd): Despite the documentation, this seems to return the visible
395 // size. However, the output always appears to be top-left aligned, so it
396 // makes no difference. Re-verify this and update the variable name.
405 CMVideoDimensions coded_dimensions = 397 CMVideoDimensions coded_dimensions =
406 CMVideoFormatDescriptionGetDimensions(format_); 398 CMVideoFormatDescriptionGetDimensions(format_);
407 coded_size_.SetSize(coded_dimensions.width, coded_dimensions.height); 399 coded_size_.SetSize(coded_dimensions.width, coded_dimensions.height);
408 400
409 // If the session is compatible, there's nothing else to do.
410 if (g_enable_compatible_configuration_reuse && session_ &&
411 VTDecompressionSessionCanAcceptFormatDescription(session_, format_)) {
412 return true;
413 }
414
415 // Prepare VideoToolbox configuration dictionaries. 401 // Prepare VideoToolbox configuration dictionaries.
416 base::ScopedCFTypeRef<CFMutableDictionaryRef> decoder_config( 402 base::ScopedCFTypeRef<CFMutableDictionaryRef> decoder_config(
417 CFDictionaryCreateMutable( 403 CFDictionaryCreateMutable(
418 kCFAllocatorDefault, 404 kCFAllocatorDefault,
419 1, // capacity 405 1, // capacity
420 &kCFTypeDictionaryKeyCallBacks, 406 &kCFTypeDictionaryKeyCallBacks,
421 &kCFTypeDictionaryValueCallBacks)); 407 &kCFTypeDictionaryValueCallBacks));
422 if (!decoder_config.get()) { 408 if (!decoder_config.get()) {
423 DLOG(ERROR) << "Failed to create CFMutableDictionary."; 409 DLOG(ERROR) << "Failed to create CFMutableDictionary.";
424 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR); 410 NotifyError(PLATFORM_FAILURE, SFT_PLATFORM_ERROR);
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); 537 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM);
552 return; 538 return;
553 } 539 }
554 pps.assign(nalu.data, nalu.data + nalu.size); 540 pps.assign(nalu.data, nalu.data + nalu.size);
555 break; 541 break;
556 542
557 case media::H264NALU::kSliceDataA: 543 case media::H264NALU::kSliceDataA:
558 case media::H264NALU::kSliceDataB: 544 case media::H264NALU::kSliceDataB:
559 case media::H264NALU::kSliceDataC: 545 case media::H264NALU::kSliceDataC:
560 case media::H264NALU::kNonIDRSlice: 546 case media::H264NALU::kNonIDRSlice:
561 // TODO(sandersd): Check that there has been an IDR slice since the
562 // last reset.
563 case media::H264NALU::kIDRSlice: 547 case media::H264NALU::kIDRSlice:
564 // Compute the |pic_order_cnt| for the picture from the first slice. 548 // Compute the |pic_order_cnt| for the picture from the first slice.
565 // TODO(sandersd): Make sure that any further slices are part of the
566 // same picture or a redundant coded picture.
567 if (!has_slice) { 549 if (!has_slice) {
568 media::H264SliceHeader slice_hdr; 550 media::H264SliceHeader slice_hdr;
569 result = parser_.ParseSliceHeader(nalu, &slice_hdr); 551 result = parser_.ParseSliceHeader(nalu, &slice_hdr);
570 if (result == media::H264Parser::kUnsupportedStream) { 552 if (result == media::H264Parser::kUnsupportedStream) {
571 DLOG(ERROR) << "Unsupported slice header"; 553 DLOG(ERROR) << "Unsupported slice header";
572 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM); 554 NotifyError(PLATFORM_FAILURE, SFT_UNSUPPORTED_STREAM);
573 return; 555 return;
574 } 556 }
575 if (result != media::H264Parser::kOk) { 557 if (result != media::H264Parser::kOk) {
576 DLOG(ERROR) << "Could not parse slice header"; 558 DLOG(ERROR) << "Could not parse slice header";
(...skipping 19 matching lines...) Expand all
596 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); 578 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM);
597 return; 579 return;
598 } 580 }
599 581
600 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &frame->pic_order_cnt)) { 582 if (!poc_.ComputePicOrderCnt(sps, slice_hdr, &frame->pic_order_cnt)) {
601 DLOG(ERROR) << "Unable to compute POC"; 583 DLOG(ERROR) << "Unable to compute POC";
602 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM); 584 NotifyError(UNREADABLE_INPUT, SFT_INVALID_STREAM);
603 return; 585 return;
604 } 586 }
605 587
588 if (nalu.nal_unit_type == media::H264NALU::kIDRSlice)
589 frame->is_idr = true;
590
606 if (sps->vui_parameters_present_flag && 591 if (sps->vui_parameters_present_flag &&
607 sps->bitstream_restriction_flag) { 592 sps->bitstream_restriction_flag) {
608 frame->reorder_window = std::min(sps->max_num_reorder_frames, 593 frame->reorder_window = std::min(sps->max_num_reorder_frames,
609 kMaxReorderQueueSize - 1); 594 kMaxReorderQueueSize - 1);
610 } 595 }
611 } 596 }
612 has_slice = true; 597 has_slice = true;
613 default: 598 default:
614 nalus.push_back(nalu); 599 nalus.push_back(nalu);
615 data_size += kNALUHeaderLength + nalu.size; 600 data_size += kNALUHeaderLength + nalu.size;
(...skipping 16 matching lines...) Expand all
632 if (last_sps_.empty()) { 617 if (last_sps_.empty()) {
633 DLOG(ERROR) << "Invalid configuration; no SPS"; 618 DLOG(ERROR) << "Invalid configuration; no SPS";
634 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); 619 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
635 return; 620 return;
636 } 621 }
637 if (last_pps_.empty()) { 622 if (last_pps_.empty()) {
638 DLOG(ERROR) << "Invalid configuration; no PPS"; 623 DLOG(ERROR) << "Invalid configuration; no PPS";
639 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM); 624 NotifyError(INVALID_ARGUMENT, SFT_INVALID_STREAM);
640 return; 625 return;
641 } 626 }
642 if (!ConfigureDecoder()) 627
628 // If it's not an IDR frame, we can't reconfigure the decoder anyway. We
629 // assume that any config change not on an IDR must be compatible.
630 if (frame->is_idr && !ConfigureDecoder())
643 return; 631 return;
644 } 632 }
645 633
646 // If there are no image slices, drop the bitstream buffer by returning an 634 // If there are no image slices, drop the bitstream buffer by returning an
647 // empty frame. 635 // empty frame.
648 if (!has_slice) { 636 if (!has_slice) {
649 if (!FinishDelayedFrames()) 637 if (!FinishDelayedFrames())
650 return; 638 return;
651 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( 639 gpu_task_runner_->PostTask(FROM_HERE, base::Bind(
652 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); 640 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame));
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 bool VTVideoDecodeAccelerator::ProcessTaskQueue() { 877 bool VTVideoDecodeAccelerator::ProcessTaskQueue() {
890 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 878 DCHECK(gpu_thread_checker_.CalledOnValidThread());
891 DCHECK_EQ(state_, STATE_DECODING); 879 DCHECK_EQ(state_, STATE_DECODING);
892 880
893 if (task_queue_.empty()) 881 if (task_queue_.empty())
894 return false; 882 return false;
895 883
896 const Task& task = task_queue_.front(); 884 const Task& task = task_queue_.front();
897 switch (task.type) { 885 switch (task.type) {
898 case TASK_FRAME: 886 case TASK_FRAME:
899 // TODO(sandersd): Signal IDR explicitly (not using pic_order_cnt == 0).
900 if (reorder_queue_.size() < kMaxReorderQueueSize && 887 if (reorder_queue_.size() < kMaxReorderQueueSize &&
901 (task.frame->pic_order_cnt != 0 || reorder_queue_.empty())) { 888 (!task.frame->is_idr || reorder_queue_.empty())) {
902 assigned_bitstream_ids_.erase(task.frame->bitstream_id); 889 assigned_bitstream_ids_.erase(task.frame->bitstream_id);
903 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id); 890 client_->NotifyEndOfBitstreamBuffer(task.frame->bitstream_id);
904 reorder_queue_.push(task.frame); 891 reorder_queue_.push(task.frame);
905 task_queue_.pop(); 892 task_queue_.pop();
906 return true; 893 return true;
907 } 894 }
908 return false; 895 return false;
909 896
910 case TASK_FLUSH: 897 case TASK_FLUSH:
911 DCHECK_EQ(task.type, pending_flush_tasks_.front()); 898 DCHECK_EQ(task.type, pending_flush_tasks_.front());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 DCHECK_EQ(state_, STATE_DECODING); 932 DCHECK_EQ(state_, STATE_DECODING);
946 933
947 if (reorder_queue_.empty()) 934 if (reorder_queue_.empty())
948 return false; 935 return false;
949 936
950 // If the next task is a flush (because there is a pending flush or becuase 937 // If the next task is a flush (because there is a pending flush or becuase
951 // the next frame is an IDR), then we don't need a full reorder buffer to send 938 // the next frame is an IDR), then we don't need a full reorder buffer to send
952 // the next frame. 939 // the next frame.
953 bool flushing = !task_queue_.empty() && 940 bool flushing = !task_queue_.empty() &&
954 (task_queue_.front().type != TASK_FRAME || 941 (task_queue_.front().type != TASK_FRAME ||
955 task_queue_.front().frame->pic_order_cnt == 0); 942 task_queue_.front().frame->is_idr);
956 943
957 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window); 944 size_t reorder_window = std::max(0, reorder_queue_.top()->reorder_window);
958 if (flushing || reorder_queue_.size() > reorder_window) { 945 if (flushing || reorder_queue_.size() > reorder_window) {
959 if (ProcessFrame(*reorder_queue_.top())) { 946 if (ProcessFrame(*reorder_queue_.top())) {
960 reorder_queue_.pop(); 947 reorder_queue_.pop();
961 return true; 948 return true;
962 } 949 }
963 } 950 }
964 951
965 return false; 952 return false;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 DCHECK(gpu_thread_checker_.CalledOnValidThread()); 1101 DCHECK(gpu_thread_checker_.CalledOnValidThread());
1115 1102
1116 // In a forceful shutdown, the decoder thread may be dead already. 1103 // In a forceful shutdown, the decoder thread may be dead already.
1117 if (!decoder_thread_.IsRunning()) { 1104 if (!decoder_thread_.IsRunning()) {
1118 delete this; 1105 delete this;
1119 return; 1106 return;
1120 } 1107 }
1121 1108
1122 // For a graceful shutdown, return assigned buffers and flush before 1109 // For a graceful shutdown, return assigned buffers and flush before
1123 // destructing |this|. 1110 // destructing |this|.
1124 // TODO(sandersd): Make sure the decoder won't try to read the buffers again 1111 // TODO(sandersd): Prevent the decoder from reading buffers before discarding
1125 // before discarding them. 1112 // them.
1126 for (int32_t bitstream_id : assigned_bitstream_ids_) 1113 for (int32_t bitstream_id : assigned_bitstream_ids_)
1127 client_->NotifyEndOfBitstreamBuffer(bitstream_id); 1114 client_->NotifyEndOfBitstreamBuffer(bitstream_id);
1128 assigned_bitstream_ids_.clear(); 1115 assigned_bitstream_ids_.clear();
1129 state_ = STATE_DESTROYING; 1116 state_ = STATE_DESTROYING;
1130 QueueFlush(TASK_DESTROY); 1117 QueueFlush(TASK_DESTROY);
1131 } 1118 }
1132 1119
1133 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { 1120 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() {
1134 return false; 1121 return false;
1135 } 1122 }
1136 1123
1137 // static 1124 // static
1138 media::VideoDecodeAccelerator::SupportedProfiles 1125 media::VideoDecodeAccelerator::SupportedProfiles
1139 VTVideoDecodeAccelerator::GetSupportedProfiles() { 1126 VTVideoDecodeAccelerator::GetSupportedProfiles() {
1140 SupportedProfiles profiles; 1127 SupportedProfiles profiles;
1141 for (const auto& supported_profile : kSupportedProfiles) { 1128 for (const auto& supported_profile : kSupportedProfiles) {
1142 SupportedProfile profile; 1129 SupportedProfile profile;
1143 profile.profile = supported_profile; 1130 profile.profile = supported_profile;
1144 profile.min_resolution.SetSize(16, 16); 1131 profile.min_resolution.SetSize(16, 16);
1145 profile.max_resolution.SetSize(4096, 2160); 1132 profile.max_resolution.SetSize(4096, 2160);
1146 profiles.push_back(profile); 1133 profiles.push_back(profile);
1147 } 1134 }
1148 return profiles; 1135 return profiles;
1149 } 1136 }
1150 1137
1151 } // namespace content 1138 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/vt_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698