| 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 |