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 19 matching lines...) Expand all Loading... |
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 config_width_(0), | 36 config_width_(0), |
37 config_height_(0), | 37 config_height_(0), |
38 output_width_(0), | 38 output_width_(0), |
39 output_height_(0), | 39 output_height_(0), |
40 request_resources_cb_(request_resources_cb), | 40 request_resources_cb_(request_resources_cb) { |
41 next_video_data_is_iframe_(true) { | |
42 } | 41 } |
43 | 42 |
44 VideoDecoderJob::~VideoDecoderJob() {} | 43 VideoDecoderJob::~VideoDecoderJob() {} |
45 | 44 |
46 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) { | 45 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) { |
47 // For an empty surface, always pass it to the |media_codec_bridge_| job so | 46 // For an empty surface, always pass it to the |media_codec_bridge_| job so |
48 // that it can detach from the current one. Otherwise, don't pass an | 47 // that it can detach from the current one. Otherwise, don't pass an |
49 // unprotected surface if the video content requires a protected one. | 48 // unprotected surface if the video content requires a protected one. |
50 if (!surface.IsEmpty() && IsProtectedSurfaceRequired() && | 49 if (!surface.IsEmpty() && IsProtectedSurfaceRequired() && |
51 !surface.is_protected()) { | 50 !surface.is_protected()) { |
52 return false; | 51 return false; |
53 } | 52 } |
54 | 53 |
55 surface_ = surface.Pass(); | 54 surface_ = surface.Pass(); |
56 need_to_reconfig_decoder_job_ = true; | 55 need_to_reconfig_decoder_job_ = true; |
57 return true; | 56 return true; |
58 } | 57 } |
59 | 58 |
60 bool VideoDecoderJob::HasStream() const { | 59 bool VideoDecoderJob::HasStream() const { |
61 return video_codec_ != kUnknownVideoCodec; | 60 return video_codec_ != kUnknownVideoCodec; |
62 } | 61 } |
63 | 62 |
64 void VideoDecoderJob::Flush() { | |
65 MediaDecoderJob::Flush(); | |
66 next_video_data_is_iframe_ = true; | |
67 } | |
68 | |
69 void VideoDecoderJob::ReleaseDecoderResources() { | 63 void VideoDecoderJob::ReleaseDecoderResources() { |
70 MediaDecoderJob::ReleaseDecoderResources(); | 64 MediaDecoderJob::ReleaseDecoderResources(); |
71 surface_ = gfx::ScopedJavaSurface(); | 65 surface_ = gfx::ScopedJavaSurface(); |
72 } | 66 } |
73 | 67 |
74 void VideoDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { | 68 void VideoDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) { |
75 video_codec_ = configs.video_codec; | 69 video_codec_ = configs.video_codec; |
76 config_width_ = configs.video_size.width(); | 70 config_width_ = configs.video_size.width(); |
77 config_height_ = configs.video_size.height(); | 71 config_height_ = configs.video_size.height(); |
78 set_is_content_encrypted(configs.is_video_encrypted); | 72 set_is_content_encrypted(configs.is_video_encrypted); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 } | 111 } |
118 | 112 |
119 bool VideoDecoderJob::AreDemuxerConfigsChanged( | 113 bool VideoDecoderJob::AreDemuxerConfigsChanged( |
120 const DemuxerConfigs& configs) const { | 114 const DemuxerConfigs& configs) const { |
121 return video_codec_ != configs.video_codec || | 115 return video_codec_ != configs.video_codec || |
122 is_content_encrypted() != configs.is_video_encrypted || | 116 is_content_encrypted() != configs.is_video_encrypted || |
123 config_width_ != configs.video_size.width() || | 117 config_width_ != configs.video_size.width() || |
124 config_height_ != configs.video_size.height(); | 118 config_height_ != configs.video_size.height(); |
125 } | 119 } |
126 | 120 |
127 bool VideoDecoderJob::CreateMediaCodecBridgeInternal() { | 121 MediaDecoderJob::MediaDecoderJobStatus |
| 122 VideoDecoderJob::CreateMediaCodecBridgeInternal() { |
128 if (surface_.IsEmpty()) { | 123 if (surface_.IsEmpty()) { |
129 ReleaseMediaCodecBridge(); | 124 ReleaseMediaCodecBridge(); |
130 return false; | 125 return STATUS_FAILURE; |
131 } | 126 } |
132 | 127 |
133 // If the next data is not iframe, return false so that the player need to | 128 // If we cannot find a key frame in cache, browser seek is needed. |
134 // perform a browser seek. | 129 bool next_video_data_is_iframe = SetCurrentFrameToPreviouslyCachedKeyFrame(); |
135 if (!next_video_data_is_iframe_) | 130 if (!next_video_data_is_iframe) |
136 return false; | 131 return STATUS_KEY_FRAME_REQUIRED; |
137 | 132 |
138 bool is_secure = is_content_encrypted() && drm_bridge() && | 133 bool is_secure = is_content_encrypted() && drm_bridge() && |
139 drm_bridge()->IsProtectedSurfaceRequired(); | 134 drm_bridge()->IsProtectedSurfaceRequired(); |
140 | 135 |
141 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( | 136 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder( |
142 video_codec_, is_secure, gfx::Size(config_width_, config_height_), | 137 video_codec_, is_secure, gfx::Size(config_width_, config_height_), |
143 surface_.j_surface().obj(), GetMediaCrypto().obj())); | 138 surface_.j_surface().obj(), GetMediaCrypto().obj())); |
144 | 139 |
145 if (!media_codec_bridge_) | 140 if (!media_codec_bridge_) |
146 return false; | 141 return STATUS_FAILURE; |
147 | 142 |
148 request_resources_cb_.Run(); | 143 request_resources_cb_.Run(); |
149 return true; | 144 return STATUS_SUCCESS; |
150 } | |
151 | |
152 void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) { | |
153 next_video_data_is_iframe_ = is_config_change; | |
154 } | 145 } |
155 | 146 |
156 bool VideoDecoderJob::UpdateOutputFormat() { | 147 bool VideoDecoderJob::UpdateOutputFormat() { |
157 if (!media_codec_bridge_) | 148 if (!media_codec_bridge_) |
158 return false; | 149 return false; |
159 int prev_output_width = output_width_; | 150 int prev_output_width = output_width_; |
160 int prev_output_height = output_height_; | 151 int prev_output_height = output_height_; |
161 // See b/18224769. The values reported from MediaCodecBridge::GetOutputFormat | 152 // See b/18224769. The values reported from MediaCodecBridge::GetOutputFormat |
162 // correspond to the actual video frame size, but this is not necessarily the | 153 // correspond to the actual video frame size, but this is not necessarily the |
163 // size that should be output. | 154 // size that should be output. |
164 output_width_ = config_width_; | 155 output_width_ = config_width_; |
165 output_height_ = config_height_; | 156 output_height_ = config_height_; |
166 return (output_width_ != prev_output_width) || | 157 return (output_width_ != prev_output_width) || |
167 (output_height_ != prev_output_height); | 158 (output_height_ != prev_output_height); |
168 } | 159 } |
169 | 160 |
170 bool VideoDecoderJob::IsProtectedSurfaceRequired() { | 161 bool VideoDecoderJob::IsProtectedSurfaceRequired() { |
171 return is_content_encrypted() && drm_bridge() && | 162 return is_content_encrypted() && drm_bridge() && |
172 drm_bridge()->IsProtectedSurfaceRequired(); | 163 drm_bridge()->IsProtectedSurfaceRequired(); |
173 } | 164 } |
174 | 165 |
175 } // namespace media | 166 } // namespace media |
OLD | NEW |