| 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
|
|
|