Chromium Code Reviews| Index: remoting/client/rectangle_update_decoder.cc |
| diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc |
| index af123e85b84941ef09de9a68831e403caa13d0e0..42621790dfc11788bd9be366a698695ba5cbb4f4 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 { |
| +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); |
| + |
| + // Byte-swap the pixels for compatibility with the android.graphics.Bitmap |
| + // class. |
|
Sergey Ulanov
2013/09/28 00:33:32
nit: Don't need this comment here. it might be bet
Lambros
2013/09/28 00:51:11
Done.
|
| + // TODO(lambroslambrou): Refactor so that the VideoDecoder produces data |
|
Sergey Ulanov
2013/09/28 00:33:32
Move this TODO above the class definition - we won
Lambros
2013/09/28 00:51:11
Done.
|
| + // in the right byte-order, instead of swapping it here. |
| + 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, |