Index: remoting/base/decoder_vp8.cc |
=================================================================== |
--- remoting/base/decoder_vp8.cc (revision 64676) |
+++ remoting/base/decoder_vp8.cc (working copy) |
@@ -18,7 +18,12 @@ |
namespace remoting { |
DecoderVp8::DecoderVp8() |
- : state_(kUninitialized), |
+ : state_(kWaitingForBeginRect), |
+ rect_x_(0), |
+ rect_y_(0), |
+ rect_width_(0), |
+ rect_height_(0), |
+ updated_rects_(NULL), |
codec_(NULL) { |
} |
@@ -30,23 +35,72 @@ |
delete codec_; |
} |
-void DecoderVp8::Initialize(scoped_refptr<media::VideoFrame> frame, |
- const gfx::Rect& clip, int bytes_per_src_pixel) { |
- DCHECK_EQ(kUninitialized, state_); |
+bool DecoderVp8::BeginDecode(scoped_refptr<media::VideoFrame> frame, |
+ UpdatedRects* updated_rects, |
+ Task* partial_decode_done, |
+ Task* decode_done) { |
+ DCHECK(!partial_decode_done_.get()); |
+ DCHECK(!decode_done_.get()); |
+ DCHECK(!updated_rects_); |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
+ partial_decode_done_.reset(partial_decode_done); |
+ decode_done_.reset(decode_done); |
+ updated_rects_ = updated_rects; |
+ |
if (frame->format() != media::VideoFrame::RGB32) { |
LOG(INFO) << "DecoderVp8 only supports RGB32 as output"; |
- state_ = kError; |
- return; |
+ return false; |
} |
frame_ = frame; |
+ return true; |
+} |
- state_ = kReady; |
+bool DecoderVp8::PartialDecode(ChromotingHostMessage* message) { |
+ scoped_ptr<ChromotingHostMessage> msg_deleter(message); |
+ DCHECK(message->has_update_stream_packet()); |
+ |
+ bool ret = true; |
+ if (message->update_stream_packet().has_begin_rect()) |
+ ret = HandleBeginRect(message); |
+ if (ret && message->update_stream_packet().has_rect_data()) |
+ ret = HandleRectData(message); |
+ if (ret && message->update_stream_packet().has_end_rect()) |
+ ret = HandleEndRect(message); |
+ return ret; |
} |
-void DecoderVp8::DecodeBytes(const std::string& encoded_bytes) { |
- DCHECK_EQ(kReady, state_); |
+void DecoderVp8::EndDecode() { |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
+ decode_done_->Run(); |
+ partial_decode_done_.reset(); |
+ decode_done_.reset(); |
+ frame_ = NULL; |
+ updated_rects_ = NULL; |
+} |
+ |
+bool DecoderVp8::HandleBeginRect(ChromotingHostMessage* message) { |
+ DCHECK_EQ(kWaitingForBeginRect, state_); |
+ state_ = kWaitingForRectData; |
+ |
+ rect_width_ = message->update_stream_packet().begin_rect().width(); |
+ rect_height_ = message->update_stream_packet().begin_rect().height(); |
+ rect_x_ = message->update_stream_packet().begin_rect().x(); |
+ rect_y_ = message->update_stream_packet().begin_rect().y(); |
+ |
+ PixelFormat pixel_format = |
+ message->update_stream_packet().begin_rect().pixel_format(); |
+ if (pixel_format != PixelFormatYv12) |
+ return false; |
+ return true; |
+} |
+ |
+bool DecoderVp8::HandleRectData(ChromotingHostMessage* message) { |
+ DCHECK_EQ(kWaitingForRectData, state_); |
+ DCHECK_EQ(0, |
+ message->update_stream_packet().rect_data().sequence_number()); |
+ |
// Initialize the codec as needed. |
if (!codec_) { |
codec_ = new vpx_codec_ctx_t(); |
@@ -58,21 +112,25 @@ |
LOG(INFO) << "Cannot initialize codec."; |
delete codec_; |
codec_ = NULL; |
- state_ = kError; |
- return; |
+ return false; |
} |
} |
- LOG(WARNING) << "Decoding " << encoded_bytes.size(); |
- |
// Do the actual decoding. |
vpx_codec_err_t ret = vpx_codec_decode( |
- codec_, reinterpret_cast<const uint8*>(encoded_bytes.data()), |
- encoded_bytes.size(), NULL, 0); |
+ codec_, |
+ (uint8_t*)message->update_stream_packet().rect_data().data().c_str(), |
+ message->update_stream_packet().rect_data().data().size(), |
+ NULL, 0); |
if (ret != VPX_CODEC_OK) { |
- LOG(INFO) << "Decoding failed:" << vpx_codec_err_to_string(ret) << "\n" |
- << "Details: " << vpx_codec_error(codec_) << "\n" |
+ LOG(INFO) << "Decoding failed:" |
+ << vpx_codec_err_to_string(ret) |
+ << "\n" |
+ << "Details: " |
+ << vpx_codec_error(codec_) |
+ << "\n" |
<< vpx_codec_error_detail(codec_); |
+ return false; |
} |
// Gets the decoded data. |
@@ -80,28 +138,28 @@ |
vpx_image_t* image = vpx_codec_get_frame(codec_, &iter); |
if (!image) { |
LOG(INFO) << "No video frame decoded"; |
+ return false; |
} |
// Perform YUV conversion. |
media::ConvertYUVToRGB32(image->planes[0], image->planes[1], image->planes[2], |
frame_->data(media::VideoFrame::kRGBPlane), |
- frame_->width(), frame_->height(), |
+ rect_width_, rect_height_, |
image->stride[0], image->stride[1], |
frame_->stride(media::VideoFrame::kRGBPlane), |
media::YV12); |
-} |
-void DecoderVp8::Reset() { |
- frame_ = NULL; |
- state_ = kUninitialized; |
+ updated_rects_->clear(); |
+ updated_rects_->push_back(gfx::Rect(rect_x_, rect_y_, |
+ rect_width_, rect_height_)); |
+ partial_decode_done_->Run(); |
+ return true; |
} |
-bool DecoderVp8::IsReadyForData() { |
- return state_ == kReady; |
+bool DecoderVp8::HandleEndRect(ChromotingHostMessage* message) { |
+ DCHECK_EQ(kWaitingForRectData, state_); |
+ state_ = kWaitingForBeginRect; |
+ return true; |
} |
-VideoPacketFormat::Encoding DecoderVp8::Encoding() { |
- return VideoPacketFormat::ENCODING_VP8; |
-} |
- |
} // namespace remoting |