Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(782)

Side by Side Diff: remoting/base/decoder_row_based.cc

Issue 4476003: Add VideoPacket struct for video packets. Refactor Decode interface to use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed compilation on windows and mac Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/base/decoder_row_based.h" 5 #include "remoting/base/decoder_row_based.h"
6 6
7 #include "remoting/base/decompressor.h" 7 #include "remoting/base/decompressor.h"
8 #include "remoting/base/decompressor_zlib.h" 8 #include "remoting/base/decompressor_zlib.h"
9 #include "remoting/base/decompressor_verbatim.h" 9 #include "remoting/base/decompressor_verbatim.h"
10 #include "remoting/base/util.h" 10 #include "remoting/base/util.h"
11 11
12 namespace remoting { 12 namespace remoting {
13 13
14 namespace {
15 // Both input and output data are assumed to be RGBA32.
16 const int kBytesPerPixel = 4;
17 }
18
14 DecoderRowBased* DecoderRowBased::CreateZlibDecoder() { 19 DecoderRowBased* DecoderRowBased::CreateZlibDecoder() {
15 return new DecoderRowBased(new DecompressorZlib(), 20 return new DecoderRowBased(new DecompressorZlib(),
16 VideoPacketFormat::ENCODING_ZLIB); 21 VideoPacketFormat::ENCODING_ZLIB);
17 } 22 }
18 23
19 DecoderRowBased* DecoderRowBased::CreateVerbatimDecoder() { 24 DecoderRowBased* DecoderRowBased::CreateVerbatimDecoder() {
20 return new DecoderRowBased(new DecompressorVerbatim(), 25 return new DecoderRowBased(new DecompressorVerbatim(),
21 VideoPacketFormat::ENCODING_VERBATIM); 26 VideoPacketFormat::ENCODING_VERBATIM);
22 } 27 }
23 28
24 DecoderRowBased::DecoderRowBased(Decompressor* decompressor, 29 DecoderRowBased::DecoderRowBased(Decompressor* decompressor,
25 VideoPacketFormat::Encoding encoding) 30 VideoPacketFormat::Encoding encoding)
26 : state_(kUninitialized), 31 : state_(kUninitialized),
27 decompressor_(decompressor), 32 decompressor_(decompressor),
28 encoding_(encoding), 33 encoding_(encoding),
29 bytes_per_src_pixel_(0),
30 row_pos_(0), 34 row_pos_(0),
31 row_y_(0), 35 row_y_(0),
32 // TODO(hclam): We should use the information from the update stream 36 // TODO(hclam): We should use the information from the update stream
33 // to determine whether we should reverse the rows or not. 37 // to determine whether we should reverse the rows or not.
34 // But for simplicity we set to be always true. 38 // But for simplicity we set to be always true.
35 reverse_rows_(true) { 39 reverse_rows_(true) {
36 } 40 }
37 41
38 DecoderRowBased::~DecoderRowBased() { 42 DecoderRowBased::~DecoderRowBased() {
39 } 43 }
40 44
41 void DecoderRowBased::Reset() { 45 void DecoderRowBased::Reset() {
42 frame_ = NULL; 46 frame_ = NULL;
43 decompressor_->Reset(); 47 decompressor_->Reset();
44 state_ = kUninitialized; 48 state_ = kUninitialized;
45 } 49 }
46 50
47 bool DecoderRowBased::IsReadyForData() { 51 bool DecoderRowBased::IsReadyForData() {
48 return state_ == kReady; 52 return state_ != kUninitialized && state_ != kError;
awong 2010/11/09 01:54:38 Positive filters are usually a little more robust
Sergey Ulanov 2010/11/09 21:34:42 Done.
49 } 53 }
50 54
51 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame, 55 void DecoderRowBased::Initialize(scoped_refptr<media::VideoFrame> frame) {
52 const gfx::Rect& clip,
53 int bytes_per_src_pixel) {
54 // Make sure we are not currently initialized. 56 // Make sure we are not currently initialized.
55 CHECK_EQ(kUninitialized, state_); 57 CHECK_EQ(kUninitialized, state_);
56 58
57 if (static_cast<PixelFormat>(frame->format()) != PIXEL_FORMAT_RGB32) { 59 if (frame->format() != media::VideoFrame::RGB32) {
58 LOG(WARNING) << "DecoderRowBased only supports RGB32."; 60 LOG(WARNING) << "DecoderRowBased only supports RGB32.";
59 state_ = kError; 61 state_ = kError;
60 return; 62 return;
61 } 63 }
62 64
63 frame_ = frame; 65 frame_ = frame;
64
65 // Reset the buffer location status variables.
66 clip_ = clip;
67 row_pos_ = 0;
68 row_y_ = 0;
69 bytes_per_src_pixel_ = bytes_per_src_pixel;
70
71 state_ = kReady; 66 state_ = kReady;
72 } 67 }
73 68
74 void DecoderRowBased::DecodeBytes(const std::string& encoded_bytes) { 69 Decoder::DecodeResult DecoderRowBased::DecodePacket(
75 DCHECK_EQ(kReady, state_); 70 const VideoPacket* packet) {
71 if (state_ == kError) {
72 return DECODE_ERROR;
73 }
76 74
77 const uint8* in = reinterpret_cast<const uint8*>(encoded_bytes.data()); 75 if (packet->flags() & VideoPacket::FIRST_PACKET) {
awong 2010/11/09 01:54:38 Can we pull the state transition logic out into a
Sergey Ulanov 2010/11/09 21:34:42 Done.
78 const int in_size = encoded_bytes.size(); 76 if (state_ != kReady && state_ != kDone) {
79 const int row_size = clip_.width() * bytes_per_src_pixel_; 77 state_ = kError;
78 LOG(WARNING) << "Received unexpected FIRST_PACKET.";
79 return DECODE_ERROR;
80 }
81 state_ = kProcessing;
82
83 // Reset the buffer location status variables on the first packet.
84 clip_.SetRect(packet->format().x(), packet->format().y(),
85 packet->format().width(), packet->format().height());
86 row_pos_ = 0;
87 row_y_ = 0;
88 }
89
90 if (state_ != kProcessing) {
91 state_ = kError;
92 LOG(WARNING) << "Received unexpected packet.";
93 return DECODE_ERROR;
94 }
95
96 if (packet->flags() & VideoPacket::LAST_PACKET) {
97 if (state_ != kProcessing) {
98 state_ = kError;
99 LOG(WARNING) << "Received unexpected LAST_PACKET.";
100 return DECODE_ERROR;
101 }
102 state_ = kDone;
103 }
104
105 const uint8* in = reinterpret_cast<const uint8*>(packet->data().data());
106 const int in_size = packet->data().size();
107
108 const int row_size = clip_.width() * kBytesPerPixel;
80 int stride = frame_->stride(media::VideoFrame::kRGBPlane); 109 int stride = frame_->stride(media::VideoFrame::kRGBPlane);
81 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane); 110 uint8* rect_begin = frame_->data(media::VideoFrame::kRGBPlane);
82 111
83 if (reverse_rows_) { 112 if (reverse_rows_) {
84 // Advance the pointer to the last row. 113 // Advance the pointer to the last row.
85 rect_begin += (frame_->height() - 1) * stride; 114 rect_begin += (frame_->height() - 1) * stride;
86 115
87 // And then make the stride negative. 116 // And then make the stride negative.
88 stride = -stride; 117 stride = -stride;
89 } 118 }
90 119
91 // TODO(ajwong): This should be bytes_per_dst_pixel shouldn't this.? 120 uint8* out = rect_begin + stride * (clip_.y() + row_y_) +
92 uint8* out = rect_begin + 121 kBytesPerPixel * clip_.x();
93 stride * (clip_.y() + row_y_) +
94 bytes_per_src_pixel_ * clip_.x();
95 122
96 // Consume all the data in the message. 123 // Consume all the data in the message.
97 bool decompress_again = true; 124 bool decompress_again = true;
98 int used = 0; 125 int used = 0;
99 while (decompress_again && used < in_size) { 126 while (decompress_again && used < in_size) {
127 if (row_y_ >= clip_.height()) {
128 state_ = kError;
129 LOG(WARNING) << "Too much data is received for the given rectangle.";
130 return DECODE_ERROR;
131 }
132
100 int written = 0; 133 int written = 0;
101 int consumed = 0; 134 int consumed = 0;
102 // TODO(ajwong): This assume source and dest stride are the same, which is 135 // TODO(ajwong): This assume source and dest stride are the same, which is
103 // incorrect. 136 // incorrect.
104 decompress_again = decompressor_->Process( 137 decompress_again = decompressor_->Process(
105 in + used, in_size - used, out + row_pos_, row_size - row_pos_, 138 in + used, in_size - used, out + row_pos_, row_size - row_pos_,
106 &consumed, &written); 139 &consumed, &written);
107 used += consumed; 140 used += consumed;
108 row_pos_ += written; 141 row_pos_ += written;
109 142
110 // If this row is completely filled then move onto the next row. 143 // If this row is completely filled then move onto the next row.
111 if (row_pos_ == row_size) { 144 if (row_pos_ == row_size) {
112 ++row_y_; 145 ++row_y_;
113 row_pos_ = 0; 146 row_pos_ = 0;
114 out += stride; 147 out += stride;
115 } 148 }
116 } 149 }
150
151 if (state_ == kDone && row_y_ < clip_.height()) {
152 state_ = kError;
153 LOG(WARNING) << "Received LAST_PACKET, but didn't get enough data.";
154 return DECODE_ERROR;
155 }
156
157 return state_ == kDone ? DECODE_DONE : DECODE_IN_PROGRESS;
158 }
159
160 UpdatedRects* DecoderRowBased::GetUpdatedRects() {
161 UpdatedRects* rects = new UpdatedRects();
162 rects->push_back(clip_);
163 return rects;
164 }
165
166 VideoPacketFormat::Encoding DecoderRowBased::Encoding() {
167 return encoding_;
117 } 168 }
118 169
119 } // namespace remoting 170 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698