BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / media / base / android / video_decoder_job.cc
blob2a29d015cc567787aa21b28c3fdc044f2f5de0de
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
3 // found in the LICENSE file.
5 #include "media/base/android/video_decoder_job.h"
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/threading/thread.h"
10 #include "media/base/android/media_codec_bridge.h"
11 #include "media/base/android/media_drm_bridge.h"
13 namespace media {
15 class VideoDecoderThread : public base::Thread {
16 public:
17 VideoDecoderThread() : base::Thread("MediaSource_VideoDecoderThread") {
18 Start();
22 // TODO(qinmin): Check if it is tolerable to use worker pool to handle all the
23 // decoding tasks so that we don't need a global thread here.
24 // http://crbug.com/245750
25 base::LazyInstance<VideoDecoderThread>::Leaky
26 g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER;
28 VideoDecoderJob::VideoDecoderJob(
29 const base::Closure& request_data_cb,
30 const base::Closure& request_resources_cb,
31 const base::Closure& on_demuxer_config_changed_cb)
32 : MediaDecoderJob(g_video_decoder_thread.Pointer()->task_runner(),
33 request_data_cb,
34 on_demuxer_config_changed_cb),
35 video_codec_(kUnknownVideoCodec),
36 config_width_(0),
37 config_height_(0),
38 output_width_(0),
39 output_height_(0),
40 request_resources_cb_(request_resources_cb) {
43 VideoDecoderJob::~VideoDecoderJob() {}
45 bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) {
46 // For an empty surface, always pass it to the |media_codec_bridge_| job so
47 // that it can detach from the current one. Otherwise, don't pass an
48 // unprotected surface if the video content requires a protected one.
49 if (!surface.IsEmpty() && IsProtectedSurfaceRequired() &&
50 !surface.is_protected()) {
51 return false;
54 surface_ = surface.Pass();
55 need_to_reconfig_decoder_job_ = true;
56 return true;
59 bool VideoDecoderJob::HasStream() const {
60 return video_codec_ != kUnknownVideoCodec;
63 void VideoDecoderJob::ReleaseDecoderResources() {
64 MediaDecoderJob::ReleaseDecoderResources();
65 surface_ = gfx::ScopedJavaSurface();
68 void VideoDecoderJob::SetDemuxerConfigs(const DemuxerConfigs& configs) {
69 video_codec_ = configs.video_codec;
70 config_width_ = configs.video_size.width();
71 config_height_ = configs.video_size.height();
72 set_is_content_encrypted(configs.is_video_encrypted);
73 if (!media_codec_bridge_) {
74 output_width_ = config_width_;
75 output_height_ = config_height_;
79 void VideoDecoderJob::ReleaseOutputBuffer(
80 int output_buffer_index,
81 size_t offset,
82 size_t size,
83 bool render_output,
84 base::TimeDelta current_presentation_timestamp,
85 const ReleaseOutputCompletionCallback& callback) {
86 media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output);
87 callback.Run(current_presentation_timestamp, current_presentation_timestamp);
90 bool VideoDecoderJob::ComputeTimeToRender() const {
91 return true;
94 bool VideoDecoderJob::IsCodecReconfigureNeeded(
95 const DemuxerConfigs& configs) const {
96 if (!media_codec_bridge_)
97 return true;
99 if (!AreDemuxerConfigsChanged(configs))
100 return false;
102 bool only_size_changed = false;
103 if (video_codec_ == configs.video_codec &&
104 is_content_encrypted() == configs.is_video_encrypted) {
105 only_size_changed = true;
108 return !only_size_changed ||
109 !static_cast<VideoCodecBridge*>(media_codec_bridge_.get())->
110 IsAdaptivePlaybackSupported(configs.video_size.width(),
111 configs.video_size.height());
114 bool VideoDecoderJob::AreDemuxerConfigsChanged(
115 const DemuxerConfigs& configs) const {
116 return video_codec_ != configs.video_codec ||
117 is_content_encrypted() != configs.is_video_encrypted ||
118 config_width_ != configs.video_size.width() ||
119 config_height_ != configs.video_size.height();
122 MediaDecoderJob::MediaDecoderJobStatus
123 VideoDecoderJob::CreateMediaCodecBridgeInternal() {
124 if (surface_.IsEmpty()) {
125 ReleaseMediaCodecBridge();
126 return STATUS_FAILURE;
129 // If we cannot find a key frame in cache, browser seek is needed.
130 bool next_video_data_is_iframe = SetCurrentFrameToPreviouslyCachedKeyFrame();
131 if (!next_video_data_is_iframe)
132 return STATUS_KEY_FRAME_REQUIRED;
134 bool is_secure = is_content_encrypted() && drm_bridge() &&
135 drm_bridge()->IsProtectedSurfaceRequired();
137 media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
138 video_codec_, is_secure, gfx::Size(config_width_, config_height_),
139 surface_.j_surface().obj(), GetMediaCrypto().obj()));
141 if (!media_codec_bridge_)
142 return STATUS_FAILURE;
144 request_resources_cb_.Run();
145 return STATUS_SUCCESS;
148 bool VideoDecoderJob::UpdateOutputFormat() {
149 if (!media_codec_bridge_)
150 return false;
151 int prev_output_width = output_width_;
152 int prev_output_height = output_height_;
153 // See b/18224769. The values reported from MediaCodecBridge::GetOutputFormat
154 // correspond to the actual video frame size, but this is not necessarily the
155 // size that should be output.
156 output_width_ = config_width_;
157 output_height_ = config_height_;
158 return (output_width_ != prev_output_width) ||
159 (output_height_ != prev_output_height);
162 bool VideoDecoderJob::IsProtectedSurfaceRequired() {
163 return is_content_encrypted() && drm_bridge() &&
164 drm_bridge()->IsProtectedSurfaceRequired();
167 } // namespace media