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

Side by Side Diff: media/base/android/video_decoder_job.cc

Issue 254473010: Refactor MSE implementation on Android to simplify the logic and improve the performance (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase after recent config IPC change Created 6 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/base/android/video_decoder_job.h" 5 #include "media/base/android/video_decoder_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/threading/thread.h" 9 #include "base/threading/thread.h"
10 #include "media/base/android/media_codec_bridge.h" 10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_drm_bridge.h"
11 12
12 namespace media { 13 namespace media {
13 14
14 class VideoDecoderThread : public base::Thread { 15 class VideoDecoderThread : public base::Thread {
15 public: 16 public:
16 VideoDecoderThread() : base::Thread("MediaSource_VideoDecoderThread") { 17 VideoDecoderThread() : base::Thread("MediaSource_VideoDecoderThread") {
17 Start(); 18 Start();
18 } 19 }
19 }; 20 };
20 21
21 // TODO(qinmin): Check if it is tolerable to use worker pool to handle all the 22 // TODO(qinmin): Check if it is tolerable to use worker pool to handle all the
22 // decoding tasks so that we don't need a global thread here. 23 // decoding tasks so that we don't need a global thread here.
23 // http://crbug.com/245750 24 // http://crbug.com/245750
24 base::LazyInstance<VideoDecoderThread>::Leaky 25 base::LazyInstance<VideoDecoderThread>::Leaky
25 g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER; 26 g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER;
26 27
27 VideoDecoderJob* VideoDecoderJob::Create( 28 VideoDecoderJob::VideoDecoderJob(
28 const VideoCodec video_codec,
29 bool is_secure,
30 const gfx::Size& size,
31 jobject surface,
32 jobject media_crypto,
33 const base::Closure& request_data_cb, 29 const base::Closure& request_data_cb,
34 const base::Closure& request_resources_cb, 30 const base::Closure& request_resources_cb,
35 const base::Closure& release_resources_cb) { 31 const base::Closure& release_resources_cb,
36 scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( 32 const base::Closure& on_demuxer_config_changed_cb)
37 video_codec, is_secure, size, surface, media_crypto)); 33 : MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(),
38 if (codec) 34 request_data_cb,
39 return new VideoDecoderJob(codec.Pass(), request_data_cb, 35 on_demuxer_config_changed_cb),
40 request_resources_cb, release_resources_cb); 36 video_codec_(kUnknownVideoCodec),
41 37 width_(0),
42 LOG(ERROR) << "Failed to create VideoDecoderJob."; 38 height_(0),
43 return NULL; 39 request_resources_cb_(request_resources_cb),
40 release_resources_cb_(release_resources_cb),
41 next_video_data_is_iframe_(true) {
44 } 42 }
45 43
46 VideoDecoderJob::VideoDecoderJob( 44 VideoDecoderJob::~VideoDecoderJob() {}
47 scoped_ptr<VideoCodecBridge> video_codec_bridge, 45
48 const base::Closure& request_data_cb, 46 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) {
49 const base::Closure& request_resources_cb, 47 // For an empty surface, always pass it to the decoder job so that it
wolenetz 2014/05/21 00:48:04 nit: pass to decoder job? we are the decoder job.
qinmin 2014/05/22 00:35:55 Fixed, should be |media_codec_bridge_|. On 2014/05
50 const base::Closure& release_resources_cb) 48 // can detach from the current one. Otherwise, don't pass an unprotected
51 : MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(), 49 // surface if the video content requires a protected one.
52 video_codec_bridge.get(), request_data_cb), 50 if (!surface.IsEmpty() && IsProtectedSurfaceRequired() &&
53 video_codec_bridge_(video_codec_bridge.Pass()), 51 !surface.is_protected()) {
54 release_resources_cb_(release_resources_cb) { 52 return false;
55 request_resources_cb.Run(); 53 }
54
55 surface_ = surface.Pass();
56 need_to_reconfig_decoder_job_ = true;
57 return true;
56 } 58 }
57 59
58 VideoDecoderJob::~VideoDecoderJob() { 60 bool VideoDecoderJob::HasStream() const {
59 release_resources_cb_.Run(); 61 return video_codec_ != kUnknownVideoCodec;
62 }
63
64 void VideoDecoderJob::Flush() {
65 MediaDecoderJob::Flush();
66 next_video_data_is_iframe_ = true;
67 }
68
69 void VideoDecoderJob::ReleaseDecoderResources() {
70 MediaDecoderJob::ReleaseDecoderResources();
71 surface_ = gfx::ScopedJavaSurface();
60 } 72 }
61 73
62 void VideoDecoderJob::ReleaseOutputBuffer( 74 void VideoDecoderJob::ReleaseOutputBuffer(
63 int output_buffer_index, 75 int output_buffer_index,
64 size_t size, 76 size_t size,
65 bool render_output, 77 bool render_output,
66 base::TimeDelta current_presentation_timestamp, 78 base::TimeDelta current_presentation_timestamp,
67 const ReleaseOutputCompletionCallback& callback) { 79 const ReleaseOutputCompletionCallback& callback) {
68 video_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output); 80 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output);
69 callback.Run(current_presentation_timestamp, current_presentation_timestamp); 81 callback.Run(current_presentation_timestamp, current_presentation_timestamp);
70 } 82 }
71 83
72 bool VideoDecoderJob::ComputeTimeToRender() const { 84 bool VideoDecoderJob::ComputeTimeToRender() const {
73 return true; 85 return true;
74 } 86 }
75 87
88 void VideoDecoderJob::UpdateDemuxerConfigs(const DemuxerConfigs& configs) {
89 video_codec_ = configs.video_codec;
90 width_ = configs.video_size.width();
91 height_ = configs.video_size.height();
92 set_is_content_encrypted(configs.is_video_encrypted);
93 }
94
95 bool VideoDecoderJob::IsDemuxerConfigChanged(
96 const DemuxerConfigs& configs) const {
97 return video_codec_ != configs.video_codec ||
98 is_content_encrypted() != configs.is_video_encrypted ||
99 width_ != configs.video_size.width() ||
100 height_ != configs.video_size.height();
101 }
102
103 bool VideoDecoderJob::CreateMediaCodecBridgeInternal() {
104 if (surface_.IsEmpty()) {
105 ReleaseMediaCodecBridge();
106 return false;
107 }
108
109 // If the next data is not iframe, return false so that the player need to
110 // perform a browser seek.
111 if (!next_video_data_is_iframe_)
112 return false;
113
114 bool is_secure = is_content_encrypted() && drm_bridge() &&
115 drm_bridge()->IsProtectedSurfaceRequired();
116
117 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
118 video_codec_, is_secure, gfx::Size(width_, height_),
119 surface_.j_surface().obj(), GetMediaCrypto().obj()));
120
121 if (!media_codec_bridge_)
122 return false;
123
124 request_resources_cb_.Run();
125 return true;
126 }
127
128 void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) {
129 next_video_data_is_iframe_ = is_config_change;
130 }
131
132 void VideoDecoderJob::OnMediaCodecBridgeReleased() {
133 release_resources_cb_.Run();
134 }
135
136 bool VideoDecoderJob::IsProtectedSurfaceRequired() {
137 return is_content_encrypted() && drm_bridge() &&
138 drm_bridge()->IsProtectedSurfaceRequired();
139 }
140
76 } // namespace media 141 } // namespace media
OLDNEW
« media/base/android/video_decoder_job.h ('K') | « media/base/android/video_decoder_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698