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

Unified 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: addressing comments 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 side-by-side diff with in-line comments
Download patch
Index: media/base/android/video_decoder_job.cc
diff --git a/media/base/android/video_decoder_job.cc b/media/base/android/video_decoder_job.cc
index 884bc6d3d0ba6247073c9adb355783cf90576a0e..e69187dba6d566c9b77bee3f06d57bcfb8fbf390 100644
--- a/media/base/android/video_decoder_job.cc
+++ b/media/base/android/video_decoder_job.cc
@@ -8,6 +8,7 @@
#include "base/lazy_instance.h"
#include "base/threading/thread.h"
#include "media/base/android/media_codec_bridge.h"
+#include "media/base/android/media_drm_bridge.h"
namespace media {
@@ -24,39 +25,50 @@ class VideoDecoderThread : public base::Thread {
base::LazyInstance<VideoDecoderThread>::Leaky
g_video_decoder_thread = LAZY_INSTANCE_INITIALIZER;
-VideoDecoderJob* VideoDecoderJob::Create(
- const VideoCodec video_codec,
- bool is_secure,
- const gfx::Size& size,
- jobject surface,
- jobject media_crypto,
- const base::Closure& request_data_cb,
- const base::Closure& request_resources_cb,
- const base::Closure& release_resources_cb) {
- scoped_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder(
- video_codec, is_secure, size, surface, media_crypto));
- if (codec)
- return new VideoDecoderJob(codec.Pass(), request_data_cb,
- request_resources_cb, release_resources_cb);
-
- LOG(ERROR) << "Failed to create VideoDecoderJob.";
- return NULL;
-}
-
VideoDecoderJob::VideoDecoderJob(
- scoped_ptr<VideoCodecBridge> video_codec_bridge,
const base::Closure& request_data_cb,
const base::Closure& request_resources_cb,
- const base::Closure& release_resources_cb)
+ const base::Closure& release_resources_cb,
+ const base::Closure& on_demuxer_config_changed_cb)
: MediaDecoderJob(g_video_decoder_thread.Pointer()->message_loop_proxy(),
- video_codec_bridge.get(), request_data_cb),
- video_codec_bridge_(video_codec_bridge.Pass()),
- release_resources_cb_(release_resources_cb) {
- request_resources_cb.Run();
+ request_data_cb,
+ on_demuxer_config_changed_cb),
+ video_codec_(kUnknownVideoCodec),
+ width_(0),
+ height_(0),
+ request_resources_cb_(request_resources_cb),
+ release_resources_cb_(release_resources_cb),
+ next_video_data_is_iframe_(true) {
}
-VideoDecoderJob::~VideoDecoderJob() {
- release_resources_cb_.Run();
+VideoDecoderJob::~VideoDecoderJob() {}
+
+bool VideoDecoderJob::SetVideoSurface(gfx::ScopedJavaSurface surface) {
+ // For an empty surface, always pass it to the |media_codec_bridge_| job so
+ // that it can detach from the current one. Otherwise, don't pass an
+ // unprotected surface if the video content requires a protected one.
+ if (!surface.IsEmpty() && IsProtectedSurfaceRequired() &&
+ !surface.is_protected()) {
+ return false;
+ }
+
+ surface_ = surface.Pass();
+ need_to_reconfig_decoder_job_ = true;
+ return true;
+}
+
+bool VideoDecoderJob::HasStream() const {
+ return video_codec_ != kUnknownVideoCodec;
+}
+
+void VideoDecoderJob::Flush() {
+ MediaDecoderJob::Flush();
+ next_video_data_is_iframe_ = true;
+}
+
+void VideoDecoderJob::ReleaseDecoderResources() {
+ MediaDecoderJob::ReleaseDecoderResources();
+ surface_ = gfx::ScopedJavaSurface();
}
void VideoDecoderJob::ReleaseOutputBuffer(
@@ -65,7 +77,7 @@ void VideoDecoderJob::ReleaseOutputBuffer(
bool render_output,
base::TimeDelta current_presentation_timestamp,
const ReleaseOutputCompletionCallback& callback) {
- video_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output);
+ media_codec_bridge_->ReleaseOutputBuffer(output_buffer_index, render_output);
callback.Run(current_presentation_timestamp, current_presentation_timestamp);
}
@@ -73,4 +85,57 @@ bool VideoDecoderJob::ComputeTimeToRender() const {
return true;
}
+void VideoDecoderJob::UpdateDemuxerConfigs(const DemuxerConfigs& configs) {
+ video_codec_ = configs.video_codec;
+ width_ = configs.video_size.width();
+ height_ = configs.video_size.height();
+ set_is_content_encrypted(configs.is_video_encrypted);
+}
+
+bool VideoDecoderJob::IsDemuxerConfigChanged(
+ const DemuxerConfigs& configs) const {
+ return video_codec_ != configs.video_codec ||
+ is_content_encrypted() != configs.is_video_encrypted ||
+ width_ != configs.video_size.width() ||
+ height_ != configs.video_size.height();
+}
+
+bool VideoDecoderJob::CreateMediaCodecBridgeInternal() {
+ if (surface_.IsEmpty()) {
+ ReleaseMediaCodecBridge();
+ return false;
+ }
+
+ // If the next data is not iframe, return false so that the player need to
+ // perform a browser seek.
+ if (!next_video_data_is_iframe_)
+ return false;
+
+ bool is_secure = is_content_encrypted() && drm_bridge() &&
+ drm_bridge()->IsProtectedSurfaceRequired();
+
+ media_codec_bridge_.reset(VideoCodecBridge::CreateDecoder(
+ video_codec_, is_secure, gfx::Size(width_, height_),
+ surface_.j_surface().obj(), GetMediaCrypto().obj()));
+
+ if (!media_codec_bridge_)
+ return false;
+
+ request_resources_cb_.Run();
+ return true;
+}
+
+void VideoDecoderJob::CurrentDataConsumed(bool is_config_change) {
+ next_video_data_is_iframe_ = is_config_change;
+}
+
+void VideoDecoderJob::OnMediaCodecBridgeReleased() {
+ release_resources_cb_.Run();
+}
+
+bool VideoDecoderJob::IsProtectedSurfaceRequired() {
+ return is_content_encrypted() && drm_bridge() &&
+ drm_bridge()->IsProtectedSurfaceRequired();
+}
+
} // namespace media
« 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