OLD | NEW |
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" |
(...skipping 15 matching lines...) Expand all Loading... |
26 g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER; | 26 g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER; |
27 | 27 |
28 VideoDecoderJob::VideoDecoderJob( | 28 VideoDecoderJob::VideoDecoderJob( |
29 const base::Closure& request_data_cb, | 29 const base::Closure& request_data_cb, |
30 const base::Closure& request_resources_cb, | 30 const base::Closure& request_resources_cb, |
31 const base::Closure& on_demuxer_config_changed_cb) | 31 const base::Closure& on_demuxer_config_changed_cb) |
32 : MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(), | 32 : MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(), |
33 request_data_cb, | 33 request_data_cb, |
34 on_demuxer_config_changed_cb), | 34 on_demuxer_config_changed_cb), |
35 video_codec_(kUnknownVideoCodec), | 35 video_codec_(kUnknownVideoCodec), |
36 width_(0), | 36 config_width_(0), |
37 height_(0), | 37 config_height_(0), |
| 38 output_width_(0), |
| 39 output_height_(0), |
38 request_resources_cb_(request_resources_cb), | 40 request_resources_cb_(request_resources_cb), |
39 next_video_data_is_iframe_(true) { | 41 next_video_data_is_iframe_(true) { |
40 } | 42 } |
41 | 43 |
42 VideoDecoderJob::~VideoDecoderJob() {} | 44 VideoDecoderJob::~VideoDecoderJob() {} |
43 | 45 |
44 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 46 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
45 // For an empty surface, always pass it to the |media_codec_bridge_| job so | 47 // For an empty surface, always pass it to the |media_codec_bridge_| job so |
46 // that it can detach from the current one. Otherwise, don't pass an | 48 // that it can detach from the current one. Otherwise, don't pass an |
47 // unprotected surface if the video content requires a protected one. | 49 // unprotected surface if the video content requires a protected one. |
(...skipping 14 matching lines...) Expand all Loading... |
62 void VideoDecoderJob::Flush() { | 64 void VideoDecoderJob::Flush() { |
63 MediaDecoderJob::Flush(); | 65 MediaDecoderJob::Flush(); |
64 next_video_data_is_iframe_ = true; | 66 next_video_data_is_iframe_ = true; |
65 } | 67 } |
66 | 68 |
67 void VideoDecoderJob::ReleaseDecoderResources() { | 69 void VideoDecoderJob::ReleaseDecoderResources() { |
68 MediaDecoderJob::ReleaseDecoderResources(); | 70 MediaDecoderJob::ReleaseDecoderResources(); |
69 surface_ = gfx::ScopedJavaSurface(); | 71 surface_ = gfx::ScopedJavaSurface(); |
70 } | 72 } |
71 | 73 |
| 74 void VideoDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { |
| 75 video_codec_ = configs.video_codec; |
| 76 config_width_ = configs.video_size.width(); |
| 77 config_height_ = configs.video_size.height(); |
| 78 set_is_content_encrypted(configs.is_video_encrypted); |
| 79 if (!media_codec_bridge_) { |
| 80 output_width_ = config_width_; |
| 81 output_height_ = config_height_; |
| 82 } |
| 83 } |
| 84 |
72 void VideoDecoderJob::ReleaseOutputBuffer( | 85 void VideoDecoderJob::ReleaseOutputBuffer( |
73 int output_buffer_index, | 86 int output_buffer_index, |
74 size_t size, | 87 size_t size, |
75 bool render_output, | 88 bool render_output, |
76 base::TimeDelta current_presentation_timestamp, | 89 base::TimeDelta current_presentation_timestamp, |
77 const ReleaseOutputCompletionCallback& callback) { | 90 const ReleaseOutputCompletionCallback& callback) { |
78 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output); | 91 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output); |
79 callback.Run(current_presentation_timestamp, current_presentation_timestamp); | 92 callback.Run(current_presentation_timestamp, current_presentation_timestamp); |
80 } | 93 } |
81 | 94 |
82 bool VideoDecoderJob::ComputeTimeToRender() const { | 95 bool VideoDecoderJob::ComputeTimeToRender() const { |
83 return true; | 96 return true; |
84 } | 97 } |
85 | 98 |
86 void VideoDecoderJob::UpdateDemuxerConfigs(const DemuxerConfigs& configs) { | |
87 video_codec_ = configs.video_codec; | |
88 width_ = configs.video_size.width(); | |
89 height_ = configs.video_size.height(); | |
90 set_is_content_encrypted(configs.is_video_encrypted); | |
91 } | |
92 | |
93 bool VideoDecoderJob::IsCodecReconfigureNeeded( | 99 bool VideoDecoderJob::IsCodecReconfigureNeeded( |
94 const DemuxerConfigs& configs) const { | 100 const DemuxerConfigs& configs) const { |
95 if (!media_codec_bridge_) | 101 if (!media_codec_bridge_) |
96 return true; | 102 return true; |
97 | 103 |
98 if (!AreDemuxerConfigsChanged(configs)) | 104 if (!AreDemuxerConfigsChanged(configs)) |
99 return false; | 105 return false; |
100 | 106 |
101 bool only_size_changed = false; | 107 bool only_size_changed = false; |
102 if (video_codec_ == configs.video_codec && | 108 if (video_codec_ == configs.video_codec && |
103 is_content_encrypted() == configs.is_video_encrypted) { | 109 is_content_encrypted() == configs.is_video_encrypted) { |
104 only_size_changed = true; | 110 only_size_changed = true; |
105 } | 111 } |
106 | 112 |
107 return !only_size_changed || | 113 return !only_size_changed || |
108 !static_cast<VideoCodecBridge*>(media_codec_bridge_.get())-> | 114 !static_cast<VideoCodecBridge*>(media_codec_bridge_.get())-> |
109 IsAdaptivePlaybackSupported(configs.video_size.width(), | 115 IsAdaptivePlaybackSupported(configs.video_size.width(), |
110 configs.video_size.height()); | 116 configs.video_size.height()); |
111 } | 117 } |
112 | 118 |
113 bool VideoDecoderJob::AreDemuxerConfigsChanged( | 119 bool VideoDecoderJob::AreDemuxerConfigsChanged( |
114 const DemuxerConfigs& configs) const { | 120 const DemuxerConfigs& configs) const { |
115 return video_codec_ != configs.video_codec || | 121 return video_codec_ != configs.video_codec || |
116 is_content_encrypted() != configs.is_video_encrypted || | 122 is_content_encrypted() != configs.is_video_encrypted || |
117 width_ != configs.video_size.width() || | 123 config_width_ != configs.video_size.width() || |
118 height_ != configs.video_size.height(); | 124 config_height_ != configs.video_size.height(); |
119 } | 125 } |
120 | 126 |
121 bool VideoDecoderJob::CreateMediaCodecBridgeInternal() { | 127 bool VideoDecoderJob::CreateMediaCodecBridgeInternal() { |
122 if (surface_.IsEmpty()) { | 128 if (surface_.IsEmpty()) { |
123 ReleaseMediaCodecBridge(); | 129 ReleaseMediaCodecBridge(); |
124 return false; | 130 return false; |
125 } | 131 } |
126 | 132 |
127 // If the next data is not iframe, return false so that the player need to | 133 // If the next data is not iframe, return false so that the player need to |
128 // perform a browser seek. | 134 // perform a browser seek. |
129 if (!next_video_data_is_iframe_) | 135 if (!next_video_data_is_iframe_) |
130 return false; | 136 return false; |
131 | 137 |
132 bool is_secure = is_content_encrypted() && drm_bridge() && | 138 bool is_secure = is_content_encrypted() && drm_bridge() && |
133 drm_bridge()->IsProtectedSurfaceRequired(); | 139 drm_bridge()->IsProtectedSurfaceRequired(); |
134 | 140 |
135 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( | 141 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( |
136 video_codec_, is_secure, gfx::Size(width_, height_), | 142 video_codec_, is_secure, gfx::Size(config_width_, config_height_), |
137 surface_.j_surface().obj(), GetMediaCrypto().obj())); | 143 surface_.j_surface().obj(), GetMediaCrypto().obj())); |
138 | 144 |
139 if (!media_codec_bridge_) | 145 if (!media_codec_bridge_) |
140 return false; | 146 return false; |
141 | 147 |
142 request_resources_cb_.Run(); | 148 request_resources_cb_.Run(); |
143 return true; | 149 return true; |
144 } | 150 } |
145 | 151 |
146 void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) { | 152 void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) { |
147 next_video_data_is_iframe_ = is_config_change; | 153 next_video_data_is_iframe_ = is_config_change; |
148 } | 154 } |
149 | 155 |
| 156 bool VideoDecoderJob::UpdateOutputFormat() { |
| 157 if (!media_codec_bridge_) |
| 158 return false; |
| 159 int prev_output_width = output_width_; |
| 160 int prev_output_height = output_height_; |
| 161 media_codec_bridge_->GetOutputFormat(&output_width_, &output_height_); |
| 162 return (output_width_ != prev_output_width) || |
| 163 (output_height_ != prev_output_height); |
| 164 } |
| 165 |
150 bool VideoDecoderJob::IsProtectedSurfaceRequired() { | 166 bool VideoDecoderJob::IsProtectedSurfaceRequired() { |
151 return is_content_encrypted() && drm_bridge() && | 167 return is_content_encrypted() && drm_bridge() && |
152 drm_bridge()->IsProtectedSurfaceRequired(); | 168 drm_bridge()->IsProtectedSurfaceRequired(); |
153 } | 169 } |
154 | 170 |
155 } // namespace media | 171 } // namespace media |
OLD | NEW |