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

Side by Side Diff: talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoEncoder.java

Issue 1338033003: Log to webrtc logging stream from java code. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2013 Google Inc. 3 * Copyright 2013 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 17 matching lines...) Expand all
28 28
29 package org.webrtc; 29 package org.webrtc;
30 30
31 import android.media.MediaCodec; 31 import android.media.MediaCodec;
32 import android.media.MediaCodecInfo.CodecCapabilities; 32 import android.media.MediaCodecInfo.CodecCapabilities;
33 import android.media.MediaCodecInfo; 33 import android.media.MediaCodecInfo;
34 import android.media.MediaCodecList; 34 import android.media.MediaCodecList;
35 import android.media.MediaFormat; 35 import android.media.MediaFormat;
36 import android.os.Build; 36 import android.os.Build;
37 import android.os.Bundle; 37 import android.os.Bundle;
38 import android.util.Log; 38
39 import org.webrtc.Logging;
39 40
40 import java.nio.ByteBuffer; 41 import java.nio.ByteBuffer;
41 import java.util.Arrays; 42 import java.util.Arrays;
42 import java.util.List; 43 import java.util.List;
43 44
44 // Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder. 45 // Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder.
45 // This class is an implementation detail of the Java PeerConnection API. 46 // This class is an implementation detail of the Java PeerConnection API.
46 // MediaCodec is thread-hostile so this class must be operated on a single 47 // MediaCodec is thread-hostile so this class must be operated on a single
47 // thread. 48 // thread.
48 public class MediaCodecVideoEncoder { 49 public class MediaCodecVideoEncoder {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // MediaCodec.setParameters is missing for JB and below, so bitrate 119 // MediaCodec.setParameters is missing for JB and below, so bitrate
119 // can not be adjusted dynamically. 120 // can not be adjusted dynamically.
120 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 121 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
121 return null; 122 return null;
122 } 123 }
123 124
124 // Check if device is in H.264 exception list. 125 // Check if device is in H.264 exception list.
125 if (mime.equals(H264_MIME_TYPE)) { 126 if (mime.equals(H264_MIME_TYPE)) {
126 List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS); 127 List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS);
127 if (exceptionModels.contains(Build.MODEL)) { 128 if (exceptionModels.contains(Build.MODEL)) {
128 Log.w(TAG, "Model: " + Build.MODEL + 129 Logging.w(TAG, "Model: " + Build.MODEL +
129 " has black listed H.264 encoder."); 130 " has black listed H.264 encoder.");
130 return null; 131 return null;
131 } 132 }
132 } 133 }
133 134
134 for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) { 135 for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
135 MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); 136 MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
136 if (!info.isEncoder()) { 137 if (!info.isEncoder()) {
137 continue; 138 continue;
138 } 139 }
139 String name = null; 140 String name = null;
140 for (String mimeType : info.getSupportedTypes()) { 141 for (String mimeType : info.getSupportedTypes()) {
141 if (mimeType.equals(mime)) { 142 if (mimeType.equals(mime)) {
142 name = info.getName(); 143 name = info.getName();
143 break; 144 break;
144 } 145 }
145 } 146 }
146 if (name == null) { 147 if (name == null) {
147 continue; // No HW support in this codec; try the next one. 148 continue; // No HW support in this codec; try the next one.
148 } 149 }
149 Log.v(TAG, "Found candidate encoder " + name); 150 Logging.v(TAG, "Found candidate encoder " + name);
150 151
151 // Check if this is supported HW encoder. 152 // Check if this is supported HW encoder.
152 boolean supportedCodec = false; 153 boolean supportedCodec = false;
153 for (String hwCodecPrefix : supportedHwCodecPrefixes) { 154 for (String hwCodecPrefix : supportedHwCodecPrefixes) {
154 if (name.startsWith(hwCodecPrefix)) { 155 if (name.startsWith(hwCodecPrefix)) {
155 supportedCodec = true; 156 supportedCodec = true;
156 break; 157 break;
157 } 158 }
158 } 159 }
159 if (!supportedCodec) { 160 if (!supportedCodec) {
160 continue; 161 continue;
161 } 162 }
162 163
163 CodecCapabilities capabilities = info.getCapabilitiesForType(mime); 164 CodecCapabilities capabilities = info.getCapabilitiesForType(mime);
164 for (int colorFormat : capabilities.colorFormats) { 165 for (int colorFormat : capabilities.colorFormats) {
165 Log.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat)); 166 Logging.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat));
166 } 167 }
167 168
168 // Check if codec supports either yuv420 or nv12. 169 // Check if codec supports either yuv420 or nv12.
169 for (int supportedColorFormat : supportedColorList) { 170 for (int supportedColorFormat : supportedColorList) {
170 for (int codecColorFormat : capabilities.colorFormats) { 171 for (int codecColorFormat : capabilities.colorFormats) {
171 if (codecColorFormat == supportedColorFormat) { 172 if (codecColorFormat == supportedColorFormat) {
172 // Found supported HW encoder. 173 // Found supported HW encoder.
173 Log.d(TAG, "Found target encoder for mime " + mime + " : " + name + 174 Logging.d(TAG, "Found target encoder for mime " + mime + " : " + nam e +
174 ". Color: 0x" + Integer.toHexString(codecColorFormat)); 175 ". Color: 0x" + Integer.toHexString(codecColorFormat));
175 return new EncoderProperties(name, codecColorFormat); 176 return new EncoderProperties(name, codecColorFormat);
176 } 177 }
177 } 178 }
178 } 179 }
179 } 180 }
180 return null; // No HW VP8 encoder. 181 return null; // No HW VP8 encoder.
181 } 182 }
182 183
183 public static boolean isVp8HwSupported() { 184 public static boolean isVp8HwSupported() {
(...skipping 18 matching lines...) Expand all
202 // both cases catch an exception. 203 // both cases catch an exception.
203 return MediaCodec.createByCodecName(codecName); 204 return MediaCodec.createByCodecName(codecName);
204 } catch (Exception e) { 205 } catch (Exception e) {
205 return null; 206 return null;
206 } 207 }
207 } 208 }
208 209
209 // Return the array of input buffers, or null on failure. 210 // Return the array of input buffers, or null on failure.
210 private ByteBuffer[] initEncode( 211 private ByteBuffer[] initEncode(
211 VideoCodecType type, int width, int height, int kbps, int fps) { 212 VideoCodecType type, int width, int height, int kbps, int fps) {
212 Log.d(TAG, "Java initEncode: " + type + " : " + width + " x " + height + 213 Logging.d(TAG, "Java initEncode: " + type + " : " + width + " x " + height +
213 ". @ " + kbps + " kbps. Fps: " + fps + 214 ". @ " + kbps + " kbps. Fps: " + fps +
214 ". Color: 0x" + Integer.toHexString(colorFormat)); 215 ". Color: 0x" + Integer.toHexString(colorFormat));
215 if (mediaCodecThread != null) { 216 if (mediaCodecThread != null) {
216 throw new RuntimeException("Forgot to release()?"); 217 throw new RuntimeException("Forgot to release()?");
217 } 218 }
218 this.type = type; 219 this.type = type;
219 EncoderProperties properties = null; 220 EncoderProperties properties = null;
220 String mime = null; 221 String mime = null;
221 int keyFrameIntervalSec = 0; 222 int keyFrameIntervalSec = 0;
222 if (type == VideoCodecType.VIDEO_CODEC_VP8) { 223 if (type == VideoCodecType.VIDEO_CODEC_VP8) {
223 mime = VP8_MIME_TYPE; 224 mime = VP8_MIME_TYPE;
224 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes); 225 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes);
225 keyFrameIntervalSec = 100; 226 keyFrameIntervalSec = 100;
226 } else if (type == VideoCodecType.VIDEO_CODEC_H264) { 227 } else if (type == VideoCodecType.VIDEO_CODEC_H264) {
227 mime = H264_MIME_TYPE; 228 mime = H264_MIME_TYPE;
228 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes); 229 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes);
229 keyFrameIntervalSec = 20; 230 keyFrameIntervalSec = 20;
230 } 231 }
231 if (properties == null) { 232 if (properties == null) {
232 throw new RuntimeException("Can not find HW encoder for " + type); 233 throw new RuntimeException("Can not find HW encoder for " + type);
233 } 234 }
234 mediaCodecThread = Thread.currentThread(); 235 mediaCodecThread = Thread.currentThread();
235 try { 236 try {
236 MediaFormat format = MediaFormat.createVideoFormat(mime, width, height); 237 MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
237 format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps); 238 format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps);
238 format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); 239 format.setInteger("bitrate-mode", VIDEO_ControlRateConstant);
239 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat); 240 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
240 format.setInteger(MediaFormat.KEY_FRAME_RATE, fps); 241 format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);
241 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec); 242 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
242 Log.d(TAG, " Format: " + format); 243 Logging.d(TAG, " Format: " + format);
243 mediaCodec = createByCodecName(properties.codecName); 244 mediaCodec = createByCodecName(properties.codecName);
244 if (mediaCodec == null) { 245 if (mediaCodec == null) {
245 return null; 246 return null;
246 } 247 }
247 mediaCodec.configure( 248 mediaCodec.configure(
248 format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 249 format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
249 mediaCodec.start(); 250 mediaCodec.start();
250 colorFormat = properties.colorFormat; 251 colorFormat = properties.colorFormat;
251 outputBuffers = mediaCodec.getOutputBuffers(); 252 outputBuffers = mediaCodec.getOutputBuffers();
252 ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers(); 253 ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
253 Log.d(TAG, "Input buffers: " + inputBuffers.length + 254 Logging.d(TAG, "Input buffers: " + inputBuffers.length +
254 ". Output buffers: " + outputBuffers.length); 255 ". Output buffers: " + outputBuffers.length);
255 return inputBuffers; 256 return inputBuffers;
256 } catch (IllegalStateException e) { 257 } catch (IllegalStateException e) {
257 Log.e(TAG, "initEncode failed", e); 258 Logging.e(TAG, "initEncode failed", e);
258 return null; 259 return null;
259 } 260 }
260 } 261 }
261 262
262 private boolean encode( 263 private boolean encode(
263 boolean isKeyframe, int inputBuffer, int size, 264 boolean isKeyframe, int inputBuffer, int size,
264 long presentationTimestampUs) { 265 long presentationTimestampUs) {
265 checkOnMediaCodecThread(); 266 checkOnMediaCodecThread();
266 try { 267 try {
267 if (isKeyframe) { 268 if (isKeyframe) {
268 // Ideally MediaCodec would honor BUFFER_FLAG_SYNC_FRAME so we could 269 // Ideally MediaCodec would honor BUFFER_FLAG_SYNC_FRAME so we could
269 // indicate this in queueInputBuffer() below and guarantee _this_ frame 270 // indicate this in queueInputBuffer() below and guarantee _this_ frame
270 // be encoded as a key frame, but sadly that flag is ignored. Instead, 271 // be encoded as a key frame, but sadly that flag is ignored. Instead,
271 // we request a key frame "soon". 272 // we request a key frame "soon".
272 Log.d(TAG, "Sync frame request"); 273 Logging.d(TAG, "Sync frame request");
273 Bundle b = new Bundle(); 274 Bundle b = new Bundle();
274 b.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0); 275 b.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
275 mediaCodec.setParameters(b); 276 mediaCodec.setParameters(b);
276 } 277 }
277 mediaCodec.queueInputBuffer( 278 mediaCodec.queueInputBuffer(
278 inputBuffer, 0, size, presentationTimestampUs, 0); 279 inputBuffer, 0, size, presentationTimestampUs, 0);
279 return true; 280 return true;
280 } 281 }
281 catch (IllegalStateException e) { 282 catch (IllegalStateException e) {
282 Log.e(TAG, "encode failed", e); 283 Logging.e(TAG, "encode failed", e);
283 return false; 284 return false;
284 } 285 }
285 } 286 }
286 287
287 private void release() { 288 private void release() {
288 Log.d(TAG, "Java releaseEncoder"); 289 Logging.d(TAG, "Java releaseEncoder");
289 checkOnMediaCodecThread(); 290 checkOnMediaCodecThread();
290 try { 291 try {
291 mediaCodec.stop(); 292 mediaCodec.stop();
292 mediaCodec.release(); 293 mediaCodec.release();
293 } catch (IllegalStateException e) { 294 } catch (IllegalStateException e) {
294 Log.e(TAG, "release failed", e); 295 Logging.e(TAG, "release failed", e);
295 } 296 }
296 mediaCodec = null; 297 mediaCodec = null;
297 mediaCodecThread = null; 298 mediaCodecThread = null;
298 } 299 }
299 300
300 private boolean setRates(int kbps, int frameRateIgnored) { 301 private boolean setRates(int kbps, int frameRateIgnored) {
301 // frameRate argument is ignored - HW encoder is supposed to use 302 // frameRate argument is ignored - HW encoder is supposed to use
302 // video frame timestamps for bit allocation. 303 // video frame timestamps for bit allocation.
303 checkOnMediaCodecThread(); 304 checkOnMediaCodecThread();
304 Log.v(TAG, "setRates: " + kbps + " kbps. Fps: " + frameRateIgnored); 305 Logging.v(TAG, "setRates: " + kbps + " kbps. Fps: " + frameRateIgnored);
305 try { 306 try {
306 Bundle params = new Bundle(); 307 Bundle params = new Bundle();
307 params.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, 1000 * kbps); 308 params.putInt(MediaCodec.PARAMETER_KEY_VIDEO_BITRATE, 1000 * kbps);
308 mediaCodec.setParameters(params); 309 mediaCodec.setParameters(params);
309 return true; 310 return true;
310 } catch (IllegalStateException e) { 311 } catch (IllegalStateException e) {
311 Log.e(TAG, "setRates failed", e); 312 Logging.e(TAG, "setRates failed", e);
312 return false; 313 return false;
313 } 314 }
314 } 315 }
315 316
316 // Dequeue an input buffer and return its index, -1 if no input buffer is 317 // Dequeue an input buffer and return its index, -1 if no input buffer is
317 // available, or -2 if the codec is no longer operative. 318 // available, or -2 if the codec is no longer operative.
318 private int dequeueInputBuffer() { 319 private int dequeueInputBuffer() {
319 checkOnMediaCodecThread(); 320 checkOnMediaCodecThread();
320 try { 321 try {
321 return mediaCodec.dequeueInputBuffer(DEQUEUE_TIMEOUT); 322 return mediaCodec.dequeueInputBuffer(DEQUEUE_TIMEOUT);
322 } catch (IllegalStateException e) { 323 } catch (IllegalStateException e) {
323 Log.e(TAG, "dequeueIntputBuffer failed", e); 324 Logging.e(TAG, "dequeueIntputBuffer failed", e);
324 return -2; 325 return -2;
325 } 326 }
326 } 327 }
327 328
328 // Helper struct for dequeueOutputBuffer() below. 329 // Helper struct for dequeueOutputBuffer() below.
329 private static class OutputBufferInfo { 330 private static class OutputBufferInfo {
330 public OutputBufferInfo( 331 public OutputBufferInfo(
331 int index, ByteBuffer buffer, 332 int index, ByteBuffer buffer,
332 boolean isKeyFrame, long presentationTimestampUs) { 333 boolean isKeyFrame, long presentationTimestampUs) {
333 this.index = index; 334 this.index = index;
(...skipping 13 matching lines...) Expand all
347 private OutputBufferInfo dequeueOutputBuffer() { 348 private OutputBufferInfo dequeueOutputBuffer() {
348 checkOnMediaCodecThread(); 349 checkOnMediaCodecThread();
349 try { 350 try {
350 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); 351 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
351 int result = mediaCodec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT); 352 int result = mediaCodec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT);
352 // Check if this is config frame and save configuration data. 353 // Check if this is config frame and save configuration data.
353 if (result >= 0) { 354 if (result >= 0) {
354 boolean isConfigFrame = 355 boolean isConfigFrame =
355 (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0; 356 (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0;
356 if (isConfigFrame) { 357 if (isConfigFrame) {
357 Log.d(TAG, "Config frame generated. Offset: " + info.offset + 358 Logging.d(TAG, "Config frame generated. Offset: " + info.offset +
358 ". Size: " + info.size); 359 ". Size: " + info.size);
359 configData = ByteBuffer.allocateDirect(info.size); 360 configData = ByteBuffer.allocateDirect(info.size);
360 outputBuffers[result].position(info.offset); 361 outputBuffers[result].position(info.offset);
361 outputBuffers[result].limit(info.offset + info.size); 362 outputBuffers[result].limit(info.offset + info.size);
362 configData.put(outputBuffers[result]); 363 configData.put(outputBuffers[result]);
363 // Release buffer back. 364 // Release buffer back.
364 mediaCodec.releaseOutputBuffer(result, false); 365 mediaCodec.releaseOutputBuffer(result, false);
365 // Query next output. 366 // Query next output.
366 result = mediaCodec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT); 367 result = mediaCodec.dequeueOutputBuffer(info, DEQUEUE_TIMEOUT);
367 } 368 }
368 } 369 }
369 if (result >= 0) { 370 if (result >= 0) {
370 // MediaCodec doesn't care about Buffer position/remaining/etc so we can 371 // MediaCodec doesn't care about Buffer position/remaining/etc so we can
371 // mess with them to get a slice and avoid having to pass extra 372 // mess with them to get a slice and avoid having to pass extra
372 // (BufferInfo-related) parameters back to C++. 373 // (BufferInfo-related) parameters back to C++.
373 ByteBuffer outputBuffer = outputBuffers[result].duplicate(); 374 ByteBuffer outputBuffer = outputBuffers[result].duplicate();
374 outputBuffer.position(info.offset); 375 outputBuffer.position(info.offset);
375 outputBuffer.limit(info.offset + info.size); 376 outputBuffer.limit(info.offset + info.size);
376 // Check key frame flag. 377 // Check key frame flag.
377 boolean isKeyFrame = 378 boolean isKeyFrame =
378 (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0; 379 (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0;
379 if (isKeyFrame) { 380 if (isKeyFrame) {
380 Log.d(TAG, "Sync frame generated"); 381 Logging.d(TAG, "Sync frame generated");
381 } 382 }
382 if (isKeyFrame && type == VideoCodecType.VIDEO_CODEC_H264) { 383 if (isKeyFrame && type == VideoCodecType.VIDEO_CODEC_H264) {
383 Log.d(TAG, "Appending config frame of size " + configData.capacity() + 384 Logging.d(TAG, "Appending config frame of size " + configData.capacity () +
384 " to output buffer with offset " + info.offset + ", size " + 385 " to output buffer with offset " + info.offset + ", size " +
385 info.size); 386 info.size);
386 // For H.264 key frame append SPS and PPS NALs at the start 387 // For H.264 key frame append SPS and PPS NALs at the start
387 ByteBuffer keyFrameBuffer = ByteBuffer.allocateDirect( 388 ByteBuffer keyFrameBuffer = ByteBuffer.allocateDirect(
388 configData.capacity() + info.size); 389 configData.capacity() + info.size);
389 configData.rewind(); 390 configData.rewind();
390 keyFrameBuffer.put(configData); 391 keyFrameBuffer.put(configData);
391 keyFrameBuffer.put(outputBuffer); 392 keyFrameBuffer.put(outputBuffer);
392 keyFrameBuffer.position(0); 393 keyFrameBuffer.position(0);
393 return new OutputBufferInfo(result, keyFrameBuffer, 394 return new OutputBufferInfo(result, keyFrameBuffer,
394 isKeyFrame, info.presentationTimeUs); 395 isKeyFrame, info.presentationTimeUs);
395 } else { 396 } else {
396 return new OutputBufferInfo(result, outputBuffer.slice(), 397 return new OutputBufferInfo(result, outputBuffer.slice(),
397 isKeyFrame, info.presentationTimeUs); 398 isKeyFrame, info.presentationTimeUs);
398 } 399 }
399 } else if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 400 } else if (result == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
400 outputBuffers = mediaCodec.getOutputBuffers(); 401 outputBuffers = mediaCodec.getOutputBuffers();
401 return dequeueOutputBuffer(); 402 return dequeueOutputBuffer();
402 } else if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 403 } else if (result == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
403 return dequeueOutputBuffer(); 404 return dequeueOutputBuffer();
404 } else if (result == MediaCodec.INFO_TRY_AGAIN_LATER) { 405 } else if (result == MediaCodec.INFO_TRY_AGAIN_LATER) {
405 return null; 406 return null;
406 } 407 }
407 throw new RuntimeException("dequeueOutputBuffer: " + result); 408 throw new RuntimeException("dequeueOutputBuffer: " + result);
408 } catch (IllegalStateException e) { 409 } catch (IllegalStateException e) {
409 Log.e(TAG, "dequeueOutputBuffer failed", e); 410 Logging.e(TAG, "dequeueOutputBuffer failed", e);
410 return new OutputBufferInfo(-1, null, false, -1); 411 return new OutputBufferInfo(-1, null, false, -1);
411 } 412 }
412 } 413 }
413 414
414 // Release a dequeued output buffer back to the codec for re-use. Return 415 // Release a dequeued output buffer back to the codec for re-use. Return
415 // false if the codec is no longer operable. 416 // false if the codec is no longer operable.
416 private boolean releaseOutputBuffer(int index) { 417 private boolean releaseOutputBuffer(int index) {
417 checkOnMediaCodecThread(); 418 checkOnMediaCodecThread();
418 try { 419 try {
419 mediaCodec.releaseOutputBuffer(index, false); 420 mediaCodec.releaseOutputBuffer(index, false);
420 return true; 421 return true;
421 } catch (IllegalStateException e) { 422 } catch (IllegalStateException e) {
422 Log.e(TAG, "releaseOutputBuffer failed", e); 423 Logging.e(TAG, "releaseOutputBuffer failed", e);
423 return false; 424 return false;
424 } 425 }
425 } 426 }
426 } 427 }
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/src/org/webrtc/MediaCodecVideoDecoder.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698