summaryrefslogtreecommitdiffstats
path: root/remoting/client/rectangle_update_decoder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/client/rectangle_update_decoder.cc')
-rw-r--r--remoting/client/rectangle_update_decoder.cc114
1 files changed, 64 insertions, 50 deletions
diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc
index 2690e14..5659fc5 100644
--- a/remoting/client/rectangle_update_decoder.cc
+++ b/remoting/client/rectangle_update_decoder.cc
@@ -44,15 +44,16 @@ class PartialFrameCleanup : public Task {
RectangleUpdateDecoder::RectangleUpdateDecoder(MessageLoop* message_loop,
FrameConsumer* consumer)
: message_loop_(message_loop),
- consumer_(consumer) {
+ consumer_(consumer),
+ frame_is_new_(false) {
}
RectangleUpdateDecoder::~RectangleUpdateDecoder() {
}
void RectangleUpdateDecoder::Initialize(const SessionConfig* config) {
- screen_size_ = gfx::Size(config->initial_resolution().width,
- config->initial_resolution().height);
+ initial_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;
@@ -87,77 +88,90 @@ void RectangleUpdateDecoder::DecodePacket(const VideoPacket* packet,
TraceContext::tracer()->PrintString("Decode Packet called.");
- if (!decoder_->IsReadyForData()) {
- InitializeDecoder(
- NewTracedMethod(this,
- &RectangleUpdateDecoder::ProcessPacketData,
- packet, done_runner.release()));
- } else {
- ProcessPacketData(packet, done_runner.release());
- }
+ AllocateFrame(packet, done_runner.release());
}
-void RectangleUpdateDecoder::ProcessPacketData(
- const VideoPacket* packet, Task* done) {
- AutoTaskRunner done_runner(done);
-
- if (!decoder_->IsReadyForData()) {
- // TODO(ajwong): This whole thing should move into an invalid state.
- LOG(ERROR) << "Decoder is unable to process data. Dropping packet.";
- return;
- }
-
- TraceContext::tracer()->PrintString("Executing Decode.");
-
- Decoder::DecodeResult result = decoder_->DecodePacket(packet);
-
- if (result == Decoder::DECODE_DONE) {
- UpdatedRects* rects = new UpdatedRects();
- decoder_->GetUpdatedRects(rects);
- consumer_->OnPartialFrameOutput(frame_, rects,
- new PartialFrameCleanup(frame_, rects));
- }
-}
-
-void RectangleUpdateDecoder::InitializeDecoder(Task* done) {
+void RectangleUpdateDecoder::AllocateFrame(const VideoPacket* packet,
+ Task* done) {
if (message_loop_ != MessageLoop::current()) {
message_loop_->PostTask(
FROM_HERE,
NewTracedMethod(this,
- &RectangleUpdateDecoder::InitializeDecoder, done));
+ &RectangleUpdateDecoder::AllocateFrame, packet, done));
return;
}
AutoTaskRunner done_runner(done);
- // Check if we need to request a new frame.
- if (!frame_ ||
- frame_->width() != static_cast<size_t>(screen_size_.width()) ||
- frame_->height() != static_cast<size_t>(screen_size_.height())) {
+ TraceContext::tracer()->PrintString("AllocateFrame called.");
+
+ // Find the required frame size.
+ bool has_screen_size = packet->format().has_screen_width() &&
+ packet->format().has_screen_height();
+ gfx::Size screen_size(packet->format().screen_width(),
+ packet->format().screen_height());
+ if (!has_screen_size)
+ screen_size = initial_screen_size_;
+
+ // Find the current frame size.
+ gfx::Size frame_size(0, 0);
+ if (frame_)
+ frame_size = gfx::Size(static_cast<int>(frame_->width()),
+ static_cast<int>(frame_->height()));
+
+ // Allocate a new frame, if necessary.
+ if ((!frame_) || (has_screen_size && (screen_size != frame_size))) {
if (frame_) {
TraceContext::tracer()->PrintString("Releasing old frame.");
consumer_->ReleaseFrame(frame_);
frame_ = NULL;
}
TraceContext::tracer()->PrintString("Requesting new frame.");
+
consumer_->AllocateFrame(media::VideoFrame::RGB32,
- screen_size_.width(), screen_size_.height(),
+ screen_size.width(), screen_size.height(),
base::TimeDelta(), base::TimeDelta(),
&frame_,
- NewTracedMethod(
- this,
- &RectangleUpdateDecoder::InitializeDecoder,
- done_runner.release()));
+ NewRunnableMethod(this,
+ &RectangleUpdateDecoder::ProcessPacketData,
+ packet, done_runner.release()));
+ frame_is_new_ = true;
return;
}
+ ProcessPacketData(packet, done_runner.release());
+}
+
+void RectangleUpdateDecoder::ProcessPacketData(
+ const VideoPacket* packet, Task* done) {
+ if (message_loop_ != MessageLoop::current()) {
+ message_loop_->PostTask(
+ FROM_HERE,
+ NewTracedMethod(this,
+ &RectangleUpdateDecoder::ProcessPacketData, packet,
+ done));
+ return;
+ }
+ AutoTaskRunner done_runner(done);
+
+ if (frame_is_new_) {
+ decoder_->Reset();
+ decoder_->Initialize(frame_);
+ frame_is_new_ = false;
+ }
- // TODO(ajwong): We need to handle the allocator failing to create a frame
- // and properly disable this class.
- CHECK(frame_);
+ if (!decoder_->IsReadyForData()) {
+ // TODO(ajwong): This whole thing should move into an invalid state.
+ LOG(ERROR) << "Decoder is unable to process data. Dropping packet.";
+ return;
+ }
- decoder_->Reset();
- decoder_->Initialize(frame_);
+ TraceContext::tracer()->PrintString("Executing Decode.");
- TraceContext::tracer()->PrintString("Decoder is Initialized");
+ if (decoder_->DecodePacket(packet) == Decoder::DECODE_DONE) {
+ UpdatedRects* rects = new UpdatedRects();
+ decoder_->GetUpdatedRects(rects);
+ consumer_->OnPartialFrameOutput(frame_, rects,
+ new PartialFrameCleanup(frame_, rects));
+ }
}
} // namespace remoting