| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "remoting/client/rectangle_update_decoder.h" |    5 #include "remoting/client/rectangle_update_decoder.h" | 
|    6  |    6  | 
|    7 #include "base/bind.h" |    7 #include "base/bind.h" | 
|    8 #include "base/callback.h" |    8 #include "base/callback.h" | 
|    9 #include "base/callback_helpers.h" |    9 #include "base/callback_helpers.h" | 
|   10 #include "base/location.h" |   10 #include "base/location.h" | 
|   11 #include "base/logging.h" |   11 #include "base/logging.h" | 
|   12 #include "base/single_thread_task_runner.h" |   12 #include "base/single_thread_task_runner.h" | 
|   13 #include "remoting/base/util.h" |   13 #include "remoting/base/util.h" | 
|   14 #include "remoting/codec/video_decoder.h" |   14 #include "remoting/codec/video_decoder.h" | 
|   15 #include "remoting/codec/video_decoder_verbatim.h" |   15 #include "remoting/codec/video_decoder_verbatim.h" | 
|   16 #include "remoting/codec/video_decoder_vp8.h" |   16 #include "remoting/codec/video_decoder_vp8.h" | 
|   17 #include "remoting/client/frame_consumer.h" |   17 #include "remoting/client/frame_consumer.h" | 
|   18 #include "remoting/protocol/session_config.h" |   18 #include "remoting/protocol/session_config.h" | 
 |   19 #include "third_party/libyuv/include/libyuv/convert_argb.h" | 
|   19 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |   20 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 
|   20  |   21  | 
|   21 using base::Passed; |   22 using base::Passed; | 
|   22 using remoting::protocol::ChannelConfig; |   23 using remoting::protocol::ChannelConfig; | 
|   23 using remoting::protocol::SessionConfig; |   24 using remoting::protocol::SessionConfig; | 
|   24  |   25  | 
|   25 namespace remoting { |   26 namespace remoting { | 
|   26  |   27  | 
 |   28 // This class wraps a VideoDecoder and byte-swaps the pixels for compatibility | 
 |   29 // with the android.graphics.Bitmap class. | 
 |   30 // TODO(lambroslambrou): Refactor so that the VideoDecoder produces data | 
 |   31 // in the right byte-order, instead of swapping it here. | 
 |   32 class RgbToBgrVideoDecoderFilter : public VideoDecoder { | 
 |   33  public: | 
 |   34   RgbToBgrVideoDecoderFilter(scoped_ptr<VideoDecoder> parent) | 
 |   35       : parent_(parent.Pass()) { | 
 |   36   } | 
 |   37  | 
 |   38   virtual void Initialize(const webrtc::DesktopSize& screen_size) OVERRIDE { | 
 |   39     parent_->Initialize(screen_size); | 
 |   40   } | 
 |   41  | 
 |   42   virtual bool DecodePacket(const VideoPacket& packet) OVERRIDE { | 
 |   43     return parent_->DecodePacket(packet); | 
 |   44   } | 
 |   45  | 
 |   46   virtual void Invalidate(const webrtc::DesktopSize& view_size, | 
 |   47                           const webrtc::DesktopRegion& region) OVERRIDE { | 
 |   48     return parent_->Invalidate(view_size, region); | 
 |   49   } | 
 |   50  | 
 |   51   virtual void RenderFrame(const webrtc::DesktopSize& view_size, | 
 |   52                            const webrtc::DesktopRect& clip_area, | 
 |   53                            uint8* image_buffer, | 
 |   54                            int image_stride, | 
 |   55                            webrtc::DesktopRegion* output_region) OVERRIDE { | 
 |   56     parent_->RenderFrame(view_size, clip_area, image_buffer, image_stride, | 
 |   57                          output_region); | 
 |   58  | 
 |   59     for (webrtc::DesktopRegion::Iterator i(*output_region); !i.IsAtEnd(); | 
 |   60          i.Advance()) { | 
 |   61       webrtc::DesktopRect rect = i.rect(); | 
 |   62       uint8* pixels = image_buffer + (rect.top() * image_stride) + | 
 |   63         (rect.left() * kBytesPerPixel); | 
 |   64       libyuv::ABGRToARGB(pixels, image_stride, pixels, image_stride, | 
 |   65                          rect.width(), rect.height()); | 
 |   66     } | 
 |   67   } | 
 |   68  | 
 |   69   virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE { | 
 |   70     return parent_->GetImageShape(); | 
 |   71   } | 
 |   72  | 
 |   73  private: | 
 |   74   scoped_ptr<VideoDecoder> parent_; | 
 |   75 }; | 
 |   76  | 
|   27 RectangleUpdateDecoder::RectangleUpdateDecoder( |   77 RectangleUpdateDecoder::RectangleUpdateDecoder( | 
|   28     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, |   78     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | 
|   29     scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, |   79     scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, | 
|   30     scoped_refptr<FrameConsumerProxy> consumer) |   80     scoped_refptr<FrameConsumerProxy> consumer) | 
|   31     : main_task_runner_(main_task_runner), |   81     : main_task_runner_(main_task_runner), | 
|   32       decode_task_runner_(decode_task_runner), |   82       decode_task_runner_(decode_task_runner), | 
|   33       consumer_(consumer), |   83       consumer_(consumer), | 
|   34       paint_scheduled_(false), |   84       paint_scheduled_(false), | 
|   35       latest_sequence_number_(0) { |   85       latest_sequence_number_(0) { | 
|   36 } |   86 } | 
|   37  |   87  | 
|   38 RectangleUpdateDecoder::~RectangleUpdateDecoder() { |   88 RectangleUpdateDecoder::~RectangleUpdateDecoder() { | 
|   39 } |   89 } | 
|   40  |   90  | 
|   41 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { |   91 void RectangleUpdateDecoder::Initialize(const SessionConfig& config) { | 
 |   92   if (!decode_task_runner_->BelongsToCurrentThread()) { | 
 |   93     decode_task_runner_->PostTask( | 
 |   94         FROM_HERE, base::Bind(&RectangleUpdateDecoder::Initialize, this, | 
 |   95                               config)); | 
 |   96     return; | 
 |   97   } | 
 |   98  | 
|   42   // Initialize decoder based on the selected codec. |   99   // Initialize decoder based on the selected codec. | 
|   43   ChannelConfig::Codec codec = config.video_config().codec; |  100   ChannelConfig::Codec codec = config.video_config().codec; | 
|   44   if (codec == ChannelConfig::CODEC_VERBATIM) { |  101   if (codec == ChannelConfig::CODEC_VERBATIM) { | 
|   45     decoder_.reset(new VideoDecoderVerbatim()); |  102     decoder_.reset(new VideoDecoderVerbatim()); | 
|   46   } else if (codec == ChannelConfig::CODEC_VP8) { |  103   } else if (codec == ChannelConfig::CODEC_VP8) { | 
|   47     decoder_.reset(new VideoDecoderVp8()); |  104     decoder_.reset(new VideoDecoderVp8()); | 
|   48   } else { |  105   } else { | 
|   49     NOTREACHED() << "Invalid Encoding found: " << codec; |  106     NOTREACHED() << "Invalid Encoding found: " << codec; | 
|   50   } |  107   } | 
 |  108  | 
 |  109   if (consumer_->GetPixelFormat() == FrameConsumer::FORMAT_RGBA) { | 
 |  110     scoped_ptr<VideoDecoder> wrapper( | 
 |  111         new RgbToBgrVideoDecoderFilter(decoder_.Pass())); | 
 |  112     decoder_ = wrapper.Pass(); | 
 |  113   } | 
|   51 } |  114 } | 
|   52  |  115  | 
|   53 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, |  116 void RectangleUpdateDecoder::DecodePacket(scoped_ptr<VideoPacket> packet, | 
|   54                                           const base::Closure& done) { |  117                                           const base::Closure& done) { | 
|   55   DCHECK(decode_task_runner_->BelongsToCurrentThread()); |  118   DCHECK(decode_task_runner_->BelongsToCurrentThread()); | 
|   56  |  119  | 
|   57   base::ScopedClosureRunner done_runner(done); |  120   base::ScopedClosureRunner done_runner(done); | 
|   58  |  121  | 
|   59   bool decoder_needs_reset = false; |  122   bool decoder_needs_reset = false; | 
|   60   bool notify_size_or_dpi_change = false; |  123   bool notify_size_or_dpi_change = false; | 
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  275  |  338  | 
|  276   done.Run(); |  339   done.Run(); | 
|  277 } |  340 } | 
|  278  |  341  | 
|  279 ChromotingStats* RectangleUpdateDecoder::GetStats() { |  342 ChromotingStats* RectangleUpdateDecoder::GetStats() { | 
|  280   DCHECK(main_task_runner_->BelongsToCurrentThread()); |  343   DCHECK(main_task_runner_->BelongsToCurrentThread()); | 
|  281   return &stats_; |  344   return &stats_; | 
|  282 } |  345 } | 
|  283  |  346  | 
|  284 }  // namespace remoting |  347 }  // namespace remoting | 
| OLD | NEW |