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

Side by Side Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2365103002: Send the h264 SPS and PPS configuration parameters to AVDA (Closed)
Patch Set: Make it a non-member function Created 4 years, 2 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <array>
9 #include <memory> 10 #include <memory>
10 11
11 #include "base/android/build_info.h" 12 #include "base/android/build_info.h"
12 #include "base/auto_reset.h" 13 #include "base/auto_reset.h"
13 #include "base/bind.h" 14 #include "base/bind.h"
14 #include "base/bind_helpers.h" 15 #include "base/bind_helpers.h"
15 #include "base/callback_helpers.h" 16 #include "base/callback_helpers.h"
16 #include "base/command_line.h" 17 #include "base/command_line.h"
17 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/message_loop/message_loop.h" 20 #include "base/message_loop/message_loop.h"
20 #include "base/metrics/histogram.h" 21 #include "base/metrics/histogram.h"
21 #include "base/sys_info.h" 22 #include "base/sys_info.h"
22 #include "base/task_runner_util.h" 23 #include "base/task_runner_util.h"
23 #include "base/threading/thread.h" 24 #include "base/threading/thread.h"
24 #include "base/threading/thread_checker.h" 25 #include "base/threading/thread_checker.h"
25 #include "base/threading/thread_task_runner_handle.h" 26 #include "base/threading/thread_task_runner_handle.h"
26 #include "base/trace_event/trace_event.h" 27 #include "base/trace_event/trace_event.h"
27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 28 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
28 #include "gpu/command_buffer/service/mailbox_manager.h" 29 #include "gpu/command_buffer/service/mailbox_manager.h"
29 #include "gpu/ipc/service/gpu_channel.h" 30 #include "gpu/ipc/service/gpu_channel.h"
30 #include "media/base/android/media_codec_bridge.h" 31 #include "media/base/android/media_codec_bridge.h"
31 #include "media/base/android/media_codec_util.h" 32 #include "media/base/android/media_codec_util.h"
32 #include "media/base/bind_to_current_loop.h" 33 #include "media/base/bind_to_current_loop.h"
33 #include "media/base/bitstream_buffer.h" 34 #include "media/base/bitstream_buffer.h"
34 #include "media/base/limits.h" 35 #include "media/base/limits.h"
35 #include "media/base/media.h" 36 #include "media/base/media.h"
36 #include "media/base/timestamp_constants.h" 37 #include "media/base/timestamp_constants.h"
37 #include "media/base/video_decoder_config.h" 38 #include "media/base/video_decoder_config.h"
39 #include "media/formats/mp4/box_definitions.h"
38 #include "media/gpu/avda_picture_buffer_manager.h" 40 #include "media/gpu/avda_picture_buffer_manager.h"
39 #include "media/gpu/shared_memory_region.h" 41 #include "media/gpu/shared_memory_region.h"
40 #include "media/video/picture.h" 42 #include "media/video/picture.h"
41 #include "ui/gl/android/scoped_java_surface.h" 43 #include "ui/gl/android/scoped_java_surface.h"
42 #include "ui/gl/android/surface_texture.h" 44 #include "ui/gl/android/surface_texture.h"
43 #include "ui/gl/gl_bindings.h" 45 #include "ui/gl/gl_bindings.h"
44 46
45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 47 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
46 #include "media/mojo/services/mojo_cdm_service.h" 48 #include "media/mojo/services/mojo_cdm_service.h"
47 #endif 49 #endif
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // For RecordFormatChangedMetric. 124 // For RecordFormatChangedMetric.
123 enum FormatChangedValue { 125 enum FormatChangedValue {
124 CodecInitialized = false, 126 CodecInitialized = false,
125 MissingFormatChanged = true 127 MissingFormatChanged = true
126 }; 128 };
127 129
128 inline void RecordFormatChangedMetric(FormatChangedValue value) { 130 inline void RecordFormatChangedMetric(FormatChangedValue value) {
129 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); 131 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value);
130 } 132 }
131 133
134 // Extract the SPS and PPS from |extra_data| (which should be an AVCC) and write
135 // them to |csd0| and |csd1|, respectively, in the format MediaCodec expects.
136 // Returns true on success. The out parameters are not modified on failure.
137 bool ExtractSpsAndPps(const std::vector<uint8_t>& extra_data,
138 std::vector<uint8_t>* csd0,
139 std::vector<uint8_t>* csd1) {
140 mp4::AVCDecoderConfigurationRecord record;
141 if (!record.Parse(extra_data.data(), extra_data.size()))
142 return false;
143
144 const std::array<uint8_t, 4> prefix = {0, 0, 0, 1};
dcheng 2016/09/27 22:41:15 constexpr
watk 2016/09/27 22:56:02 Done.
145 for (const std::vector<uint8_t>& sps : record.sps_list) {
146 csd0->insert(csd0->end(), prefix.begin(), prefix.end());
147 csd0->insert(csd0->end(), sps.begin(), sps.end());
148 }
149
150 for (const std::vector<uint8_t>& pps : record.pps_list) {
151 csd1->insert(csd1->end(), prefix.begin(), prefix.end());
152 csd1->insert(csd1->end(), pps.begin(), pps.end());
153 }
154
155 return true;
156 }
157
132 } // namespace 158 } // namespace
133 159
134 // AVDAManager manages shared resources for a number of AVDA instances. 160 // AVDAManager manages shared resources for a number of AVDA instances.
135 // Its responsibilities include: 161 // Its responsibilities include:
136 // - Starting and stopping a shared "construction" thread for instantiating and 162 // - Starting and stopping a shared "construction" thread for instantiating and
137 // releasing MediaCodecs. 163 // releasing MediaCodecs.
138 // - Detecting when a task has hung on the construction thread so AVDAs can 164 // - Detecting when a task has hung on the construction thread so AVDAs can
139 // stop using it. 165 // stop using it.
140 // - Running a RepeatingTimer so that AVDAs can get a regular callback to 166 // - Running a RepeatingTimer so that AVDAs can get a regular callback to
141 // DoIOTask(). 167 // DoIOTask().
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); 509 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile);
484 codec_config_->initial_expected_coded_size_ = 510 codec_config_->initial_expected_coded_size_ =
485 config.initial_expected_coded_size; 511 config.initial_expected_coded_size;
486 512
487 if (codec_config_->codec_ != kCodecVP8 && 513 if (codec_config_->codec_ != kCodecVP8 &&
488 codec_config_->codec_ != kCodecVP9 && 514 codec_config_->codec_ != kCodecVP9 &&
489 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 515 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
490 codec_config_->codec_ != kCodecHEVC && 516 codec_config_->codec_ != kCodecHEVC &&
491 #endif 517 #endif
492 codec_config_->codec_ != kCodecH264) { 518 codec_config_->codec_ != kCodecH264) {
493 LOG(ERROR) << "Unsupported profile: " << config.profile; 519 DLOG(ERROR) << "Unsupported profile: " << config.profile;
494 return false; 520 return false;
495 } 521 }
496 522
497 // Only use MediaCodec for VP8/9 if it's likely backed by hardware 523 // Only use MediaCodec for VP8/9 if it's likely backed by hardware
498 // or if the stream is encrypted. 524 // or if the stream is encrypted.
499 if (IsMediaCodecSoftwareDecodingForbidden() && 525 if (IsMediaCodecSoftwareDecodingForbidden() &&
500 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, 526 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_,
501 MEDIA_CODEC_DECODER)) { 527 MEDIA_CODEC_DECODER)) {
502 DVLOG(1) << "Initialization failed: " 528 DVLOG(1) << "Initialization failed: "
503 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") 529 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9")
504 << " is not hardware accelerated"; 530 << " is not hardware accelerated";
505 return false; 531 return false;
506 } 532 }
507 533
534 if (codec_config_->codec_ == kCodecH264 && !config.extra_data.empty()) {
535 if (!ExtractSpsAndPps(config.extra_data, &codec_config_->csd0_,
536 &codec_config_->csd1_)) {
537 DLOG(ERROR) << "Failed to parse extra_data as an AVCC.";
538 return false;
539 }
540 }
541
508 auto gles_decoder = get_gles2_decoder_cb_.Run(); 542 auto gles_decoder = get_gles2_decoder_cb_.Run();
509 if (!gles_decoder) { 543 if (!gles_decoder) {
510 LOG(ERROR) << "Failed to get gles2 decoder instance."; 544 DLOG(ERROR) << "Failed to get gles2 decoder instance.";
511 return false; 545 return false;
512 } 546 }
513 547
514 // If we're low on resources, we may decide to defer creation of the surface 548 // If we're low on resources, we may decide to defer creation of the surface
515 // until the codec is actually used. 549 // until the codec is actually used.
516 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, 550 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id,
517 codec_config_->codec_)) { 551 codec_config_->codec_)) {
518 DCHECK(!deferred_initialization_pending_); 552 DCHECK(!deferred_initialization_pending_);
519 553
520 // We should never be here if a SurfaceView is required. 554 // We should never be here if a SurfaceView is required.
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 : nullptr; 1175 : nullptr;
1142 1176
1143 // |needs_protected_surface_| implies encrypted stream. 1177 // |needs_protected_surface_| implies encrypted stream.
1144 DCHECK(!codec_config->needs_protected_surface_ || media_crypto); 1178 DCHECK(!codec_config->needs_protected_surface_ || media_crypto);
1145 1179
1146 const bool require_software_codec = !codec_config->allow_autodetection_; 1180 const bool require_software_codec = !codec_config->allow_autodetection_;
1147 1181
1148 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( 1182 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder(
1149 codec_config->codec_, codec_config->needs_protected_surface_, 1183 codec_config->codec_, codec_config->needs_protected_surface_,
1150 codec_config->initial_expected_coded_size_, 1184 codec_config->initial_expected_coded_size_,
1151 codec_config->surface_.j_surface().obj(), media_crypto, true, 1185 codec_config->surface_.j_surface().obj(), media_crypto,
1152 require_software_codec)); 1186 codec_config->csd0_, codec_config->csd1_, true, require_software_codec));
1153 1187
1154 return codec; 1188 return codec;
1155 } 1189 }
1156 1190
1157 void AndroidVideoDecodeAccelerator::OnCodecConfigured( 1191 void AndroidVideoDecodeAccelerator::OnCodecConfigured(
1158 std::unique_ptr<VideoCodecBridge> media_codec) { 1192 std::unique_ptr<VideoCodecBridge> media_codec) {
1159 DCHECK(thread_checker_.CalledOnValidThread()); 1193 DCHECK(thread_checker_.CalledOnValidThread());
1160 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); 1194 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED);
1161 1195
1162 // Record one instance of the codec being initialized. 1196 // Record one instance of the codec being initialized.
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 1735
1702 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1736 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1703 const { 1737 const {
1704 // Prevent MediaCodec from using its internal software decoders when we have 1738 // Prevent MediaCodec from using its internal software decoders when we have
1705 // more secure and up to date versions in the renderer process. 1739 // more secure and up to date versions in the renderer process.
1706 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || 1740 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 ||
1707 codec_config_->codec_ == kCodecVP9); 1741 codec_config_->codec_ == kCodecVP9);
1708 } 1742 }
1709 1743
1710 } // namespace media 1744 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698