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

Side by Side Diff: webrtc/modules/video_processing/deflickering.cc

Issue 1482913003: Initial VideoProcessing refactoring. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Based on pbos review Created 5 years 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 23 matching lines...) Expand all
34 enum { kDownsamplingFactor = 8 }; 34 enum { kDownsamplingFactor = 8 };
35 enum { kLog2OfDownsamplingFactor = 3 }; 35 enum { kLog2OfDownsamplingFactor = 3 };
36 36
37 // To generate in Matlab: 37 // To generate in Matlab:
38 // >> probUW16 = round(2^11 * 38 // >> probUW16 = round(2^11 *
39 // [0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.95,0.97]); 39 // [0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.95,0.97]);
40 // >> fprintf('%d, ', probUW16) 40 // >> fprintf('%d, ', probUW16)
41 // Resolution reduced to avoid overflow when multiplying with the 41 // Resolution reduced to avoid overflow when multiplying with the
42 // (potentially) large number of pixels. 42 // (potentially) large number of pixels.
43 const uint16_t VPMDeflickering::prob_uw16_[kNumProbs] = {102, 205, 410, 614, 43 const uint16_t VPMDeflickering::prob_uw16_[kNumProbs] = {102, 205, 410, 614,
44 819, 1024, 1229, 1434, 1638, 1843, 1946, 1987}; // <Q11> 44 819, 1024, 1229, 1434, 1638, 1843, 1946, 1987}; // <Q11>
45 45
46 // To generate in Matlab: 46 // To generate in Matlab:
47 // >> numQuants = 14; maxOnlyLength = 5; 47 // >> numQuants = 14; maxOnlyLength = 5;
48 // >> weightUW16 = round(2^15 * 48 // >> weightUW16 = round(2^15 *
49 // [linspace(0.5, 1.0, numQuants - maxOnlyLength)]); 49 // [linspace(0.5, 1.0, numQuants - maxOnlyLength)]);
50 // >> fprintf('%d, %d,\n ', weightUW16); 50 // >> fprintf('%d, %d,\n ', weightUW16);
51 const uint16_t VPMDeflickering::weight_uw16_[kNumQuants - kMaxOnlyLength] = 51 const uint16_t VPMDeflickering::weight_uw16_[kNumQuants - kMaxOnlyLength] =
52 {16384, 18432, 20480, 22528, 24576, 26624, 28672, 30720, 32768}; // <Q15> 52 {16384, 18432, 20480, 22528, 24576, 26624, 28672, 30720, 32768}; // <Q15>
53 53
54 VPMDeflickering::VPMDeflickering() { 54 VPMDeflickering::VPMDeflickering() {
55 Reset(); 55 Reset();
56 } 56 }
57 57
58 VPMDeflickering::~VPMDeflickering() {} 58 VPMDeflickering::~VPMDeflickering() {}
59 59
60 void VPMDeflickering::Reset() { 60 void VPMDeflickering::Reset() {
61 mean_buffer_length_ = 0; 61 mean_buffer_length_ = 0;
62 detection_state_ = 0; 62 detection_state_ = 0;
(...skipping 12 matching lines...) Expand all
75 } 75 }
76 76
77 for (int32_t i = 1; i < kFrameHistory_size; i++) { 77 for (int32_t i = 1; i < kFrameHistory_size; i++) {
78 memcpy(quant_hist_uw8_[i], quant_hist_uw8_[0], 78 memcpy(quant_hist_uw8_[i], quant_hist_uw8_[0],
79 sizeof(uint8_t) * kNumQuants); 79 sizeof(uint8_t) * kNumQuants);
80 } 80 }
81 } 81 }
82 82
83 int32_t VPMDeflickering::ProcessFrame( 83 int32_t VPMDeflickering::ProcessFrame(
84 VideoFrame* frame, 84 VideoFrame* frame,
85 VideoProcessingModule::FrameStats* stats) { 85 VideoProcessing::FrameStats* stats) {
86 assert(frame); 86 assert(frame);
87 uint32_t frame_memory; 87 uint32_t frame_memory;
88 uint8_t quant_uw8[kNumQuants]; 88 uint8_t quant_uw8[kNumQuants];
89 uint8_t maxquant_uw8[kNumQuants]; 89 uint8_t maxquant_uw8[kNumQuants];
90 uint8_t minquant_uw8[kNumQuants]; 90 uint8_t minquant_uw8[kNumQuants];
91 uint16_t target_quant_uw16[kNumQuants]; 91 uint16_t target_quant_uw16[kNumQuants];
92 uint16_t increment_uw16; 92 uint16_t increment_uw16;
93 uint8_t map_uw8[256]; 93 uint8_t map_uw8[256];
94 94
95 uint16_t tmp_uw16; 95 uint16_t tmp_uw16;
96 uint32_t tmp_uw32; 96 uint32_t tmp_uw32;
97 int width = frame->width(); 97 int width = frame->width();
98 int height = frame->height(); 98 int height = frame->height();
99 99
100 if (frame->IsZeroSize()) { 100 if (frame->IsZeroSize()) {
101 return VPM_GENERAL_ERROR; 101 return VPM_GENERAL_ERROR;
102 } 102 }
103 103
104 // Stricter height check due to subsampling size calculation below. 104 // Stricter height check due to subsampling size calculation below.
105 if (height < 2) { 105 if (height < 2) {
106 LOG(LS_ERROR) << "Invalid frame size."; 106 LOG(LS_ERROR) << "Invalid frame size.";
107 return VPM_GENERAL_ERROR; 107 return VPM_GENERAL_ERROR;
108 } 108 }
109 109
110 if (!VideoProcessingModule::ValidFrameStats(*stats)) { 110 if (!VideoProcessing::ValidFrameStats(*stats)) {
111 return VPM_GENERAL_ERROR; 111 return VPM_GENERAL_ERROR;
112 } 112 }
113 113
114 if (PreDetection(frame->timestamp(), *stats) == -1) return VPM_GENERAL_ERROR; 114 if (PreDetection(frame->timestamp(), *stats) == -1) return VPM_GENERAL_ERROR;
115 115
116 // Flicker detection 116 // Flicker detection
117 int32_t det_flicker = DetectFlicker(); 117 int32_t det_flicker = DetectFlicker();
118 if (det_flicker < 0) { 118 if (det_flicker < 0) {
119 return VPM_GENERAL_ERROR; 119 return VPM_GENERAL_ERROR;
120 } else if (det_flicker != 1) { 120 } else if (det_flicker != 1) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // Compute the map from input to output pixels. 202 // Compute the map from input to output pixels.
203 uint16_t mapUW16; // <Q7> 203 uint16_t mapUW16; // <Q7>
204 for (int32_t i = 1; i < kNumQuants; i++) { 204 for (int32_t i = 1; i < kNumQuants; i++) {
205 // As quant and targetQuant are limited to UWord8, it's safe to use Q7 here. 205 // As quant and targetQuant are limited to UWord8, it's safe to use Q7 here.
206 tmp_uw32 = static_cast<uint32_t>(target_quant_uw16[i] - 206 tmp_uw32 = static_cast<uint32_t>(target_quant_uw16[i] -
207 target_quant_uw16[i - 1]); 207 target_quant_uw16[i - 1]);
208 tmp_uw16 = static_cast<uint16_t>(quant_uw8[i] - quant_uw8[i - 1]); // <Q0> 208 tmp_uw16 = static_cast<uint16_t>(quant_uw8[i] - quant_uw8[i - 1]); // <Q0>
209 209
210 if (tmp_uw16 > 0) { 210 if (tmp_uw16 > 0) {
211 increment_uw16 = static_cast<uint16_t>(WebRtcSpl_DivU32U16(tmp_uw32, 211 increment_uw16 = static_cast<uint16_t>(WebRtcSpl_DivU32U16(tmp_uw32,
212 tmp_uw16)); // <Q7> 212 tmp_uw16)); // <Q7>
213 } else { 213 } else {
214 // The value is irrelevant; the loop below will only iterate once. 214 // The value is irrelevant; the loop below will only iterate once.
215 increment_uw16 = 0; 215 increment_uw16 = 0;
216 } 216 }
217 217
218 mapUW16 = target_quant_uw16[i - 1]; 218 mapUW16 = target_quant_uw16[i - 1];
219 for (uint32_t j = quant_uw8[i - 1]; j < (uint32_t)(quant_uw8[i] + 1); j++) { 219 for (uint32_t j = quant_uw8[i - 1]; j < (uint32_t)(quant_uw8[i] + 1); j++) {
220 // Unsigned round. <Q0> 220 // Unsigned round. <Q0>
221 map_uw8[j] = (uint8_t)((mapUW16 + (1 << 6)) >> 7); 221 map_uw8[j] = (uint8_t)((mapUW16 + (1 << 6)) >> 7);
222 mapUW16 += increment_uw16; 222 mapUW16 += increment_uw16;
223 } 223 }
224 } 224 }
225 225
226 // Map to the output frame. 226 // Map to the output frame.
227 uint8_t* buffer = frame->buffer(kYPlane); 227 uint8_t* buffer = frame->buffer(kYPlane);
228 for (uint32_t i = 0; i < y_size; i++) { 228 for (uint32_t i = 0; i < y_size; i++) {
229 buffer[i] = map_uw8[buffer[i]]; 229 buffer[i] = map_uw8[buffer[i]];
230 } 230 }
231 231
232 // Frame was altered, so reset stats. 232 // Frame was altered, so reset stats.
233 VideoProcessingModule::ClearFrameStats(stats); 233 VideoProcessing::ClearFrameStats(stats);
234 234
235 return VPM_OK; 235 return VPM_OK;
236 } 236 }
237 237
238 /** 238 /**
239 Performs some pre-detection operations. Must be called before 239 Performs some pre-detection operations. Must be called before
240 DetectFlicker(). 240 DetectFlicker().
241 241
242 \param[in] timestamp Timestamp of the current frame. 242 \param[in] timestamp Timestamp of the current frame.
243 \param[in] stats Statistics of the current frame. 243 \param[in] stats Statistics of the current frame.
244 244
245 \return 0: Success\n 245 \return 0: Success\n
246 2: Detection not possible due to flickering frequency too close to 246 2: Detection not possible due to flickering frequency too close to
247 zero.\n 247 zero.\n
248 -1: Error 248 -1: Error
249 */ 249 */
250 int32_t VPMDeflickering::PreDetection(const uint32_t timestamp, 250 int32_t VPMDeflickering::PreDetection(const uint32_t timestamp,
251 const VideoProcessingModule::FrameStats& stats) { 251 const VideoProcessing::FrameStats& stats) {
252 int32_t mean_val; // Mean value of frame (Q4) 252 int32_t mean_val; // Mean value of frame (Q4)
253 uint32_t frame_rate = 0; 253 uint32_t frame_rate = 0;
254 int32_t meanBufferLength; // Temp variable. 254 int32_t meanBufferLength; // Temp variable.
255 255
256 mean_val = ((stats.sum << kmean_valueScaling) / stats.num_pixels); 256 mean_val = ((stats.sum << kmean_valueScaling) / stats.num_pixels);
257 // Update mean value buffer. 257 // Update mean value buffer.
258 // This should be done even though we might end up in an unreliable detection. 258 // This should be done even though we might end up in an unreliable detection.
259 memmove(mean_buffer_ + 1, mean_buffer_, 259 memmove(mean_buffer_ + 1, mean_buffer_,
260 (kMeanBufferLength - 1) * sizeof(int32_t)); 260 (kMeanBufferLength - 1) * sizeof(int32_t));
261 mean_buffer_[0] = mean_val; 261 mean_buffer_[0] = mean_val;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 (timestamp_buffer_[0] - timestamp_buffer_[mean_buffer_length_ - 1]); 364 (timestamp_buffer_[0] - timestamp_buffer_[mean_buffer_length_ - 1]);
365 365
366 /* Translate frequency estimate to regions close to 100 and 120 Hz */ 366 /* Translate frequency estimate to regions close to 100 and 120 Hz */
367 uint8_t freqState = 0; // Current translation state; 367 uint8_t freqState = 0; // Current translation state;
368 // (0) Not in interval, 368 // (0) Not in interval,
369 // (1) Within valid interval, 369 // (1) Within valid interval,
370 // (2) Out of range 370 // (2) Out of range
371 int32_t freqAlias = freqEst; 371 int32_t freqAlias = freqEst;
372 if (freqEst > kMinFrequencyToDetect) { 372 if (freqEst > kMinFrequencyToDetect) {
373 uint8_t aliasState = 1; 373 uint8_t aliasState = 1;
374 while(freqState == 0) { 374 while (freqState == 0) {
375 /* Increase frequency */ 375 /* Increase frequency */
376 freqAlias += (aliasState * frame_rate_); 376 freqAlias += (aliasState * frame_rate_);
377 freqAlias += ((freqEst << 1) * (1 - (aliasState << 1))); 377 freqAlias += ((freqEst << 1) * (1 - (aliasState << 1)));
378 /* Compute state */ 378 /* Compute state */
379 freqState = (abs(freqAlias - (100 << 4)) <= kFrequencyDeviation); 379 freqState = (abs(freqAlias - (100 << 4)) <= kFrequencyDeviation);
380 freqState += (abs(freqAlias - (120 << 4)) <= kFrequencyDeviation); 380 freqState += (abs(freqAlias - (120 << 4)) <= kFrequencyDeviation);
381 freqState += 2 * (freqAlias > ((120 << 4) + kFrequencyDeviation)); 381 freqState += 2 * (freqAlias > ((120 << 4) + kFrequencyDeviation));
382 /* Switch alias state */ 382 /* Switch alias state */
383 aliasState++; 383 aliasState++;
384 aliasState &= 0x01; 384 aliasState &= 0x01;
385 } 385 }
386 } 386 }
387 /* Is frequency estimate within detection region? */ 387 /* Is frequency estimate within detection region? */
388 if (freqState == 1) { 388 if (freqState == 1) {
389 ret_val = 1; 389 ret_val = 1;
390 } else if (freqState == 0) { 390 } else if (freqState == 0) {
391 ret_val = 2; 391 ret_val = 2;
392 } else { 392 } else {
393 ret_val = 0; 393 ret_val = 0;
394 } 394 }
395 return ret_val; 395 return ret_val;
396 } 396 }
397 397
398 } // namespace webrtc 398 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698