summaryrefslogtreecommitdiffstats
path: root/remoting/client/rectangle_update_decoder.cc
diff options
context:
space:
mode:
authorlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-02 06:53:58 +0000
committerlambroslambrou@chromium.org <lambroslambrou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-02 06:53:58 +0000
commit596c78f82f1092e486f38eeb8e27a3118f90e807 (patch)
tree55c2d399a75f58d6b8e66ac297bcd9963f49673e /remoting/client/rectangle_update_decoder.cc
parent77787cf1a890f6318c0f4dfb1ee5deb4ee068e85 (diff)
downloadchromium_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.cc63
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,