diff options
author | lambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-02 06:53:58 +0000 |
---|---|---|
committer | lambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-02 06:53:58 +0000 |
commit | 596c78f82f1092e486f38eeb8e27a3118f90e807 (patch) | |
tree | 55c2d399a75f58d6b8e66ac297bcd9963f49673e /remoting/client/rectangle_update_decoder.cc | |
parent | 77787cf1a890f6318c0f4dfb1ee5deb4ee068e85 (diff) | |
download | chromium_src-596c78f82f1092e486f38eeb8e27a3118f90e807.zip chromium_src-596c78f82f1092e486f38eeb8e27a3118f90e807.tar.gz chromium_src-596c78f82f1092e486f38eeb8e27a3118f90e807.tar.bz2 |
Byte-swap the video frame pixels before passing them to Java.
When a complete video frame is decoded, this CL converts the pixels from
BGRA to a format suitable for loading into a Java Bitmap directly. This
removes the need to create a temporary int[] array in Java.
Review URL: https://codereview.chromium.org/23677011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226405 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client/rectangle_update_decoder.cc')
-rw-r--r-- | remoting/client/rectangle_update_decoder.cc | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc index af123e8..3ff2be1 100644 --- a/remoting/client/rectangle_update_decoder.cc +++ b/remoting/client/rectangle_update_decoder.cc @@ -16,6 +16,7 @@ #include "remoting/codec/video_decoder_vp8.h" #include "remoting/client/frame_consumer.h" #include "remoting/protocol/session_config.h" +#include "third_party/libyuv/include/libyuv/convert_argb.h" #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" using base::Passed; @@ -24,6 +25,55 @@ using remoting::protocol::SessionConfig; namespace remoting { +// This class wraps a VideoDecoder and byte-swaps the pixels for compatibility +// with the android.graphics.Bitmap class. +// TODO(lambroslambrou): Refactor so that the VideoDecoder produces data +// in the right byte-order, instead of swapping it here. +class RgbToBgrVideoDecoderFilter : public VideoDecoder { + public: + RgbToBgrVideoDecoderFilter(scoped_ptr<VideoDecoder> parent) + : parent_(parent.Pass()) { + } + + virtual void Initialize(const webrtc::DesktopSize& screen_size) OVERRIDE { + parent_->Initialize(screen_size); + } + + virtual bool DecodePacket(const VideoPacket& packet) OVERRIDE { + return parent_->DecodePacket(packet); + } + + virtual void Invalidate(const webrtc::DesktopSize& view_size, + const webrtc::DesktopRegion& region) OVERRIDE { + return parent_->Invalidate(view_size, region); + } + + virtual void RenderFrame(const webrtc::DesktopSize& view_size, + const webrtc::DesktopRect& clip_area, + uint8* image_buffer, + int image_stride, + webrtc::DesktopRegion* output_region) OVERRIDE { + parent_->RenderFrame(view_size, clip_area, image_buffer, image_stride, + output_region); + + for (webrtc::DesktopRegion::Iterator i(*output_region); !i.IsAtEnd(); + i.Advance()) { + webrtc::DesktopRect rect = i.rect(); + uint8* pixels = image_buffer + (rect.top() * image_stride) + + (rect.left() * kBytesPerPixel); + libyuv::ABGRToARGB(pixels, image_stride, pixels, image_stride, + rect.width(), rect.height()); + } + } + + virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE { + return parent_->GetImageShape(); + } + + private: + scoped_ptr<VideoDecoder> parent_; +}; + RectangleUpdateDecoder::RectangleUpdateDecoder( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, @@ -39,6 +89,13 @@ RectangleUpdateDecoder::~RectangleUpdateDecoder() { } void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { + if (!decode_task_runner_->BelongsToCurrentThread()) { + decode_task_runner_->PostTask( + FROM_HERE, base::Bind(&RectangleUpdateDecoder::Initialize, this, + config)); + return; + } + // Initialize decoder based on the selected codec. ChannelConfig::Codec codec = config.video_config().codec; if (codec == ChannelConfig::CODEC_VERBATIM) { @@ -48,6 +105,12 @@ void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { } else { NOTREACHED() << "Invalid Encoding found: " << codec; } + + if (consumer_->GetPixelFormat() == FrameConsumer::FORMAT_RGBA) { + scoped_ptr<VideoDecoder> wrapper( + new RgbToBgrVideoDecoderFilter(decoder_.Pass())); + decoder_ = wrapper.Pass(); + } } void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, |