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

Side by Side Diff: chrome/test/data/webrtc/video_extraction.js

Issue 2199653002: Revert of Use MediaRecorder to capture video for quality test. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months 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) 2012 The Chromium Authors. All rights reserved. 2 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /** 7 /**
8 * The gStartedAt when the capturing begins. Used for timeout adjustments.
9 * @private
10 */
11 var gStartedAt = 0;
12
13 /**
8 * The duration of the all frame capture in milliseconds. 14 * The duration of the all frame capture in milliseconds.
9 * @private 15 * @private
10 */ 16 */
11 var gCaptureDuration = 0; 17 var gCaptureDuration = 0;
12 18
13 /** 19 /**
14 * The recorded video encoded in Base64. 20 * The time interval at which the video is sampled.
15 * @private 21 * @private
16 */ 22 */
17 var gVideoBase64 = ''; 23 var gFrameCaptureInterval = 0;
18 24
19 /** 25 /**
20 * Chunks of the video recorded by MediaRecorded as they become available. 26 * The global array of frames. Frames are pushed, i.e. this should be treated as
27 * a queue and we should read from the start.
21 * @private 28 * @private
22 */ 29 */
23 var gChunks = []; 30 var gFrames = [];
31
32 /**
33 * We need to skip the first two frames due to timing issues.
34 * @private
35 */
36 var gHasThrownAwayFirstTwoFrames = false;
24 37
25 /** 38 /**
26 * A string to be returned to the test about the current status of capture. 39 * A string to be returned to the test about the current status of capture.
27 */ 40 */
28 var gCapturingStatus = 'capturing-not-started'; 41 var gCapturingStatus = 'capturing-not-started';
29 42
30 /** 43 /**
31 * Starts the frame capturing. 44 * Starts the frame capturing.
32 * 45 *
33 * @param {!Object} The video tag from which the height and width parameters are 46 * @param {!Object} The video tag from which the height and width parameters are
34 to be extracted. 47 to be extracted.
48 * @param {Number} The frame rate at which we would like to capture frames.
35 * @param {Number} The duration of the frame capture in seconds. 49 * @param {Number} The duration of the frame capture in seconds.
36 */ 50 */
37 function startFrameCapture(videoTag, duration) { 51 function startFrameCapture(videoTag, frameRate, duration) {
38 debug('inputElement stream: ' + getStreamFromElement_(videoTag)); 52 gFrameCaptureInterval = 1000 / frameRate;
39 var mediaRecorder = new MediaRecorder(getStreamFromElement_(videoTag)); 53 gCaptureDuration = 1000 * duration;
40 mediaRecorder.ondataavailable = function(recording) { 54 inputElement = document.getElementById("local-view");
41 gChunks.push(recording.data); 55 var width = inputElement.videoWidth;
56 var height = inputElement.videoHeight;
57
58 // The WebRTC code is free to start in VGA, so make sure that the output video
59 // tag scales up to whatever the input size is (otherwise the video quality
60 // comparison will go poorly.
61 videoTag.width = width;
62 videoTag.height = height;
63
64 if (width == 0 || height == 0) {
65 // Video must be playing at this point since this function is invoked from
66 // onplay on the <video> tag. See http://crbug.com/625943.
67 gCapturingStatus = 'failed-video-was-0x0-after-onplay'
68 return;
42 } 69 }
43 mediaRecorder.onstop = function() { 70
44 var videoBlob = new Blob(gChunks, {type: "video/webm"}); 71 console.log('Received width is: ' + width + ', received height is: ' + height
45 gChunks = []; 72 + ', capture interval is: ' + gFrameCaptureInterval +
46 var reader = new FileReader(); 73 ', duration is: ' + gCaptureDuration);
47 reader.onloadend = function() {
48 gVideoBase64 = reader.result.substr(reader.result.indexOf(',') + 1);
49 gCapturingStatus = 'done-capturing';
50 debug('done-capturing');
51 }
52 reader.readAsDataURL(videoBlob);
53 }
54 mediaRecorder.start();
55 gCaptureDuration = 1000 * duration;
56 setTimeout(function() { mediaRecorder.stop(); }, gCaptureDuration);
57 gCapturingStatus = 'still-capturing'; 74 gCapturingStatus = 'still-capturing';
75
76 var remoteCanvas = document.createElement('canvas');
77 remoteCanvas.width = width;
78 remoteCanvas.height = height;
79 document.body.appendChild(remoteCanvas);
80
81 gStartedAt = new Date().getTime();
82 gFrames = [];
83 setTimeout(function() { shoot_(videoTag, remoteCanvas, width, height); },
84 gFrameCaptureInterval);
58 } 85 }
59 86
60 /** 87 /**
61 * Returns the video recorded by RecordMedia encoded in Base64.
62 */
63 function getRecordedVideoAsBase64() {
64 silentReturnToTest(gVideoBase64);
65 }
66
67 /**
68 * Queries if we're done with the frame capturing yet. 88 * Queries if we're done with the frame capturing yet.
69 */ 89 */
70 function doneFrameCapturing() { 90 function doneFrameCapturing() {
71 returnToTest(gCapturingStatus); 91 returnToTest(gCapturingStatus);
72 } 92 }
73 93
74 /** 94 /**
75 * Returns the stream from the input element to be attached to MediaRecorder. 95 * Retrieves the number of captured frames.
96 */
97 function getTotalNumberCapturedFrames() {
98 returnToTest(gFrames.length.toString());
99 }
100
101 /**
102 * Retrieves one captured frame in ARGB format as a base64-encoded string.
103 *
104 * Also updates the page's progress bar.
105 *
106 * @param frameIndex A frame index in the range 0 to total-1 where total is
107 * given by getTotalNumberCapturedFrames.
108 */
109 function getOneCapturedFrame(frameIndex) {
110 var codedFrame = convertArrayBufferToBase64String_(gFrames[frameIndex]);
111 updateProgressBar_(frameIndex);
112 silentReturnToTest(codedFrame);
113 }
114
115 /**
116 * @private
117 *
118 * @param {ArrayBuffer} buffer An array buffer to convert to a base 64 string.
119 * @return {String} A base 64 string.
120 */
121 function convertArrayBufferToBase64String_(buffer) {
122 var binary = '';
123 var bytes = new Uint8Array(buffer);
124 for (var i = 0; i < bytes.byteLength; i++) {
125 binary += String.fromCharCode(bytes[i]);
126 }
127 return window.btoa(binary);
128 }
129
130 /**
131 * The function which is called at the end of every gFrameCaptureInterval. Gets
132 * the current frame from the video and extracts the data from it. Then it saves
133 * it in the frames array and adjusts the capture interval (timers in JavaScript
134 * aren't precise).
135 *
136 * @private
137 *
138 * @param {!Object} The video whose frames are to be captured.
139 * @param {Canvas} The canvas on which the image will be captured.
140 * @param {Number} The width of the video/canvas area to be captured.
141 * @param {Number} The height of the video area to be captured.
142 */
143 function shoot_(video, canvas, width, height) {
144 // The first two captured frames have big difference between the ideal time
145 // interval between two frames and the real one. As a consequence this affects
146 // enormously the interval adjustment for subsequent frames. That's why we
147 // have to reset the time after the first two frames and get rid of these two
148 // frames.
149 if (gFrames.length == 1 && !gHasThrownAwayFirstTwoFrames) {
150 gStartedAt = new Date().getTime();
151 gHasThrownAwayFirstTwoFrames = true;
152 gFrames = [];
153 }
154
155 // We capture the whole video frame.
156 var img = captureFrame_(video, canvas.getContext('2d'), width, height);
157 gFrames.push(img.data.buffer);
158
159 // Adjust the timer and try to account for timer incorrectness.
160 var currentTime = new Date().getTime();
161 var idealTime = gFrames.length * gFrameCaptureInterval;
162 var realTimeElapsed = currentTime - gStartedAt;
163 var diff = realTimeElapsed - idealTime;
164
165 if (realTimeElapsed < gCaptureDuration) {
166 // If duration isn't over shoot_ again.
167 setTimeout(function() { shoot_(video, canvas, width, height); },
168 gFrameCaptureInterval - diff);
169 } else {
170 // Done capturing!
171 gCapturingStatus = 'done-capturing';
172 prepareProgressBar_();
173 }
174 }
175
176 /**
76 * @private 177 * @private
77 */ 178 */
78 function getStreamFromElement_(element) { 179 function captureFrame_(video, context, width, height) {
79 if (typeof element.srcObject !== 'undefined') { 180 context.drawImage(video, 0, 0, width, height);
80 return element.srcObject; 181 return context.getImageData(0, 0, width, height);
81 } else if (typeof element.mozSrcObject !== 'undefined') {
82 return element.mozSrcObject;
83 } else if (typeof element.src !== 'undefined') {
84 return element.src;
85 } else {
86 console.log('Error attaching stream to element.');
87 }
88 } 182 }
183
184 /**
185 * @private
186 */
187 function prepareProgressBar_() {
188 document.body.innerHTML =
189 '<html><body>' +
190 '<p id="progressBar" style="position: absolute; top: 50%; left: 40%;">' +
191 'Preparing to send frames.</p>' +
192 '</body></html>';
193 }
194
195 /**
196 * @private
197 */
198 function updateProgressBar_(currentFrame) {
199 progressBar.innerHTML =
200 'Transferring captured frames: ' + '(' + currentFrame + '/' +
201 gFrames.length + ')';
202 }
OLDNEW
« no previous file with comments | « chrome/browser/media/webrtc_video_quality_browsertest.cc ('k') | chrome/test/data/webrtc/webrtc_video_quality_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698