| Index: remoting/client/rectangle_update_decoder.cc
|
| diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc
|
| index 4023b30f988b508f04331f47c6a80d7314ebbd0b..2690e1421b08c2e5d62fd049e1f6e2432eebd682 100644
|
| --- a/remoting/client/rectangle_update_decoder.cc
|
| +++ b/remoting/client/rectangle_update_decoder.cc
|
| @@ -13,8 +13,11 @@
|
| #include "remoting/base/tracer.h"
|
| #include "remoting/base/util.h"
|
| #include "remoting/client/frame_consumer.h"
|
| +#include "remoting/protocol/session_config.h"
|
|
|
| using media::AutoTaskRunner;
|
| +using remoting::protocol::ChannelConfig;
|
| +using remoting::protocol::SessionConfig;
|
|
|
| namespace remoting {
|
|
|
| @@ -47,7 +50,30 @@ RectangleUpdateDecoder::RectangleUpdateDecoder(MessageLoop* message_loop,
|
| RectangleUpdateDecoder::~RectangleUpdateDecoder() {
|
| }
|
|
|
| -void RectangleUpdateDecoder::DecodePacket(const VideoPacket& packet,
|
| +void RectangleUpdateDecoder::Initialize(const SessionConfig* config) {
|
| + screen_size_ = gfx::Size(config->initial_resolution().width,
|
| + config->initial_resolution().height);
|
| +
|
| + // Initialize decoder based on the selected codec.
|
| + ChannelConfig::Codec codec = config->video_config().codec;
|
| + if (codec == ChannelConfig::CODEC_VERBATIM) {
|
| + TraceContext::tracer()->PrintString("Creating Verbatim decoder.");
|
| + decoder_.reset(DecoderRowBased::CreateVerbatimDecoder());
|
| + } else if (codec == ChannelConfig::CODEC_ZIP) {
|
| + TraceContext::tracer()->PrintString("Creating Zlib decoder");
|
| + decoder_.reset(DecoderRowBased::CreateZlibDecoder());
|
| + // TODO(sergeyu): Enable VP8 on ARM builds.
|
| +#if !defined(ARCH_CPU_ARM_FAMILY)
|
| + } else if (codec == ChannelConfig::CODEC_VP8) {
|
| + TraceContext::tracer()->PrintString("Creating VP8 decoder");
|
| + decoder_.reset(new DecoderVp8());
|
| +#endif
|
| + } else {
|
| + NOTREACHED() << "Invalid Encoding found: " << codec;
|
| + }
|
| +}
|
| +
|
| +void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet,
|
| Task* done) {
|
| if (message_loop_ != MessageLoop::current()) {
|
| message_loop_->PostTask(
|
| @@ -61,28 +87,18 @@ void RectangleUpdateDecoder::DecodePacket(const VideoPacket& packet,
|
|
|
| TraceContext::tracer()->PrintString("Decode Packet called.");
|
|
|
| - if (!IsValidPacket(packet)) {
|
| - LOG(ERROR) << "Received invalid packet.";
|
| - return;
|
| - }
|
| -
|
| - Task* process_packet_data =
|
| - NewTracedMethod(this,
|
| - &RectangleUpdateDecoder::ProcessPacketData,
|
| - packet, done_runner.release());
|
| -
|
| - if (packet.flags() | VideoPacket::FIRST_PACKET) {
|
| - const VideoPacketFormat& format = packet.format();
|
| -
|
| - InitializeDecoder(format, process_packet_data);
|
| + if (!decoder_->IsReadyForData()) {
|
| + InitializeDecoder(
|
| + NewTracedMethod(this,
|
| + &RectangleUpdateDecoder::ProcessPacketData,
|
| + packet, done_runner.release()));
|
| } else {
|
| - process_packet_data->Run();
|
| - delete process_packet_data;
|
| + ProcessPacketData(packet, done_runner.release());
|
| }
|
| }
|
|
|
| void RectangleUpdateDecoder::ProcessPacketData(
|
| - const VideoPacket& packet, Task* done) {
|
| + const VideoPacket* packet, Task* done) {
|
| AutoTaskRunner done_runner(done);
|
|
|
| if (!decoder_->IsReadyForData()) {
|
| @@ -92,70 +108,31 @@ void RectangleUpdateDecoder::ProcessPacketData(
|
| }
|
|
|
| TraceContext::tracer()->PrintString("Executing Decode.");
|
| - decoder_->DecodeBytes(packet.data());
|
|
|
| - if (packet.flags() | VideoPacket::LAST_PACKET) {
|
| - decoder_->Reset();
|
| + Decoder::DecodeResult result = decoder_->DecodePacket(packet);
|
|
|
| + if (result == Decoder::DECODE_DONE) {
|
| UpdatedRects* rects = new UpdatedRects();
|
| -
|
| - // Empty out the list of current updated rects so the decoder can keep
|
| - // writing new ones while these are processed.
|
| - rects->swap(updated_rects_);
|
| -
|
| + decoder_->GetUpdatedRects(rects);
|
| consumer_->OnPartialFrameOutput(frame_, rects,
|
| new PartialFrameCleanup(frame_, rects));
|
| }
|
| }
|
|
|
| -// static
|
| -bool RectangleUpdateDecoder::IsValidPacket(const VideoPacket& packet) {
|
| - if (!packet.IsInitialized()) {
|
| - LOG(WARNING) << "Protobuf consistency checks fail.";
|
| - return false;
|
| - }
|
| -
|
| - // First packet must have a format.
|
| - if (packet.flags() | VideoPacket::FIRST_PACKET) {
|
| - if (!packet.has_format()) {
|
| - LOG(WARNING) << "First packet must have format.";
|
| - return false;
|
| - }
|
| -
|
| - // TODO(ajwong): Verify that we don't need to whitelist encodings.
|
| - const VideoPacketFormat& format = packet.format();
|
| - if (!format.has_encoding() ||
|
| - format.encoding() == VideoPacketFormat::ENCODING_INVALID) {
|
| - LOG(WARNING) << "Invalid encoding specified.";
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - // We shouldn't generate null packets.
|
| - if (!packet.has_data()) {
|
| - LOG(WARNING) << "Packet w/o data received.";
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -void RectangleUpdateDecoder::InitializeDecoder(const VideoPacketFormat& format,
|
| - Task* done) {
|
| +void RectangleUpdateDecoder::InitializeDecoder(Task* done) {
|
| if (message_loop_ != MessageLoop::current()) {
|
| message_loop_->PostTask(
|
| FROM_HERE,
|
| NewTracedMethod(this,
|
| - &RectangleUpdateDecoder::InitializeDecoder,
|
| - format, done));
|
| + &RectangleUpdateDecoder::InitializeDecoder, done));
|
| return;
|
| }
|
| AutoTaskRunner done_runner(done);
|
|
|
| // Check if we need to request a new frame.
|
| if (!frame_ ||
|
| - frame_->width() < static_cast<size_t>(format.width()) ||
|
| - frame_->height() < static_cast<size_t>(format.height())) {
|
| + frame_->width() != static_cast<size_t>(screen_size_.width()) ||
|
| + frame_->height() != static_cast<size_t>(screen_size_.height())) {
|
| if (frame_) {
|
| TraceContext::tracer()->PrintString("Releasing old frame.");
|
| consumer_->ReleaseFrame(frame_);
|
| @@ -163,13 +140,12 @@ void RectangleUpdateDecoder::InitializeDecoder(const VideoPacketFormat& format,
|
| }
|
| TraceContext::tracer()->PrintString("Requesting new frame.");
|
| consumer_->AllocateFrame(media::VideoFrame::RGB32,
|
| - format.width(), format.height(),
|
| + screen_size_.width(), screen_size_.height(),
|
| base::TimeDelta(), base::TimeDelta(),
|
| &frame_,
|
| NewTracedMethod(
|
| this,
|
| &RectangleUpdateDecoder::InitializeDecoder,
|
| - format,
|
| done_runner.release()));
|
| return;
|
| }
|
| @@ -178,45 +154,9 @@ void RectangleUpdateDecoder::InitializeDecoder(const VideoPacketFormat& format,
|
| // and properly disable this class.
|
| CHECK(frame_);
|
|
|
| - if (decoder_.get()) {
|
| - // TODO(ajwong): We need to handle changing decoders midstream correctly
|
| - // since someone may feed us a corrupt stream, or manually create a
|
| - // stream that changes decoders. At the very leask, we should not
|
| - // crash the process.
|
| - //
|
| - // For now though, assume that only one encoding is used throughout.
|
| - //
|
| - // Note, this may be as simple as just deleting the current decoder.
|
| - // However, we need to verify the flushing semantics of the decoder first.
|
| - CHECK(decoder_->Encoding() == format.encoding());
|
| - } else {
|
| - // Initialize a new decoder based on this message encoding.
|
| - if (format.encoding() == VideoPacketFormat::ENCODING_VERBATIM) {
|
| - TraceContext::tracer()->PrintString("Creating Verbatim decoder.");
|
| - decoder_.reset(DecoderRowBased::CreateVerbatimDecoder());
|
| - } else if (format.encoding() == VideoPacketFormat::ENCODING_ZLIB) {
|
| - TraceContext::tracer()->PrintString("Creating Zlib decoder");
|
| - decoder_.reset(DecoderRowBased::CreateZlibDecoder());
|
| -// TODO(sergeyu): Enable VP8 on ARM builds.
|
| -#if !defined(ARCH_CPU_ARM_FAMILY)
|
| - } else if (format.encoding() == VideoPacketFormat::ENCODING_VP8) {
|
| - TraceContext::tracer()->PrintString("Creating VP8 decoder");
|
| - decoder_.reset(new DecoderVp8());
|
| -#endif
|
| - } else {
|
| - NOTREACHED() << "Invalid Encoding found: " << format.encoding();
|
| - }
|
| - }
|
| -
|
| - // TODO(ajwong): This can happen in the face of corrupt input data. Figure
|
| - // out the right behavior and make this more resilient.
|
| - CHECK(updated_rects_.empty());
|
| + decoder_->Reset();
|
| + decoder_->Initialize(frame_);
|
|
|
| - gfx::Rect rectangle_size(format.x(), format.y(),
|
| - format.width(), format.height());
|
| - updated_rects_.push_back(rectangle_size);
|
| - decoder_->Initialize(frame_, rectangle_size,
|
| - GetBytesPerPixel(format.pixel_format()));
|
| TraceContext::tracer()->PrintString("Decoder is Initialized");
|
| }
|
|
|
|
|