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