OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 // Routines for encoding and decoding a small number of bits into an image | 5 // Routines for encoding and decoding a small number of bits into an image |
6 // in a way that is decodable even after scaling/encoding/cropping. | 6 // in a way that is decodable even after scaling/encoding/cropping. |
7 // | 7 // |
8 // The encoding is very simple: | 8 // The encoding is very simple: |
9 // | 9 // |
10 // #### #### ######## #### #### #### | 10 // #### #### ######## #### #### #### |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // Now replicate this one row into all rows in kYPlane. | 72 // Now replicate this one row into all rows in kYPlane. |
73 for (int row = 0; row < output_frame->rows(VideoFrame::kYPlane); row++) { | 73 for (int row = 0; row < output_frame->rows(VideoFrame::kYPlane); row++) { |
74 memcpy(output_frame->data(VideoFrame::kYPlane) + | 74 memcpy(output_frame->data(VideoFrame::kYPlane) + |
75 output_frame->stride(VideoFrame::kYPlane) * row, | 75 output_frame->stride(VideoFrame::kYPlane) * row, |
76 &bytes.front(), | 76 &bytes.front(), |
77 row_bytes); | 77 row_bytes); |
78 } | 78 } |
79 return true; | 79 return true; |
80 } | 80 } |
81 | 81 |
82 // Note that "output" is assumed to be the right size already. This | 82 namespace { |
83 // could be inferred from the data, but the decoding is more robust | 83 bool DecodeBarCodeRows(const scoped_refptr<VideoFrame>& frame, |
84 // if we can assume that we know how many bits we want. | 84 std::vector<bool>* output, |
85 bool DecodeBarcode(const scoped_refptr<VideoFrame>& frame, | 85 int min_row, |
86 std::vector<bool>* output) { | 86 int max_row) { |
87 DCHECK(frame->format() == VideoFrame::YV12 || | |
88 frame->format() == VideoFrame::YV16 || | |
89 frame->format() == VideoFrame::I420 || | |
90 frame->format() == VideoFrame::YV12J); | |
91 int min_row = std::max(0, frame->rows(VideoFrame::kYPlane) / 2 - 10); | |
92 int max_row = std::min(frame->rows(VideoFrame::kYPlane), | |
93 frame->rows(VideoFrame::kYPlane) / 2 + 10); | |
94 | |
95 // Do a basic run-length encoding | 87 // Do a basic run-length encoding |
96 std::deque<int> runs; | 88 std::deque<int> runs; |
97 bool is_black = true; | 89 bool is_black = true; |
98 int length = 0; | 90 int length = 0; |
99 for (int pos = 0; pos < frame->row_bytes(VideoFrame::kYPlane); pos++) { | 91 for (int pos = 0; pos < frame->row_bytes(VideoFrame::kYPlane); pos++) { |
100 float value = 0.0; | 92 float value = 0.0; |
101 for (int row = min_row; row < max_row; row++) { | 93 for (int row = min_row; row < max_row; row++) { |
102 value += frame->data(VideoFrame::kYPlane)[ | 94 value += frame->data(VideoFrame::kYPlane)[ |
103 frame->stride(VideoFrame::kYPlane) * row + pos]; | 95 frame->stride(VideoFrame::kYPlane) * row + pos]; |
104 } | 96 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 if (valid) { | 136 if (valid) { |
145 // Decoding successful, return true | 137 // Decoding successful, return true |
146 return true; | 138 return true; |
147 } | 139 } |
148 runs.pop_front(); | 140 runs.pop_front(); |
149 runs.pop_front(); | 141 runs.pop_front(); |
150 } | 142 } |
151 return false; | 143 return false; |
152 } | 144 } |
153 | 145 |
| 146 } // namespace |
| 147 |
| 148 // Note that "output" is assumed to be the right size already. This |
| 149 // could be inferred from the data, but the decoding is more robust |
| 150 // if we can assume that we know how many bits we want. |
| 151 bool DecodeBarcode(const scoped_refptr<VideoFrame>& frame, |
| 152 std::vector<bool>* output) { |
| 153 DCHECK(frame->format() == VideoFrame::YV12 || |
| 154 frame->format() == VideoFrame::YV16 || |
| 155 frame->format() == VideoFrame::I420 || |
| 156 frame->format() == VideoFrame::YV12J); |
| 157 int rows = frame->rows(VideoFrame::kYPlane); |
| 158 // Middle 10 lines |
| 159 if (DecodeBarCodeRows(frame, |
| 160 output, |
| 161 std::max(0, rows / 2 - 5), |
| 162 std::min(rows, rows / 2 + 5))) { |
| 163 return true; |
| 164 } |
| 165 |
| 166 // Top 5 lines |
| 167 if (DecodeBarCodeRows(frame, output, 0, std::min(5, rows))) { |
| 168 return true; |
| 169 } |
| 170 |
| 171 return false; |
| 172 } |
| 173 |
154 } // namespace test | 174 } // namespace test |
155 } // namespace cast | 175 } // namespace cast |
156 } // namespace media | 176 } // namespace media |
OLD | NEW |