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

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

Issue 1403713002: MediaCodecVideoEncoder add support to encode from textures (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed factory. Deprecated setVideoHwAccelerationOptions Created 5 years, 1 month 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 * 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 15 matching lines...) Expand all
26 */ 26 */
27 27
28 package org.webrtc; 28 package org.webrtc;
29 29
30 import android.annotation.TargetApi; 30 import android.annotation.TargetApi;
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.opengl.GLES20;
36 import android.os.Build; 37 import android.os.Build;
37 import android.os.Bundle; 38 import android.os.Bundle;
39 import android.view.Surface;
38 40
39 import org.webrtc.Logging; 41 import org.webrtc.Logging;
40 42
41 import java.nio.ByteBuffer; 43 import java.nio.ByteBuffer;
42 import java.util.Arrays; 44 import java.util.Arrays;
43 import java.util.List; 45 import java.util.List;
44 import java.util.concurrent.CountDownLatch; 46 import java.util.concurrent.CountDownLatch;
45 47
48 import javax.microedition.khronos.egl.EGLContext;
49
46 // Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder. 50 // Java-side of peerconnection_jni.cc:MediaCodecVideoEncoder.
47 // This class is an implementation detail of the Java PeerConnection API. 51 // This class is an implementation detail of the Java PeerConnection API.
48 @TargetApi(19) 52 @TargetApi(19)
49 @SuppressWarnings("deprecation") 53 @SuppressWarnings("deprecation")
50 public class MediaCodecVideoEncoder { 54 public class MediaCodecVideoEncoder {
51 // This class is constructed, operated, and destroyed by its C++ incarnation, 55 // This class is constructed, operated, and destroyed by its C++ incarnation,
52 // so the class and its methods have non-public visibility. The API this 56 // so the class and its methods have non-public visibility. The API this
53 // class exposes aims to mimic the webrtc::VideoEncoder API as closely as 57 // class exposes aims to mimic the webrtc::VideoEncoder API as closely as
54 // possibly to minimize the amount of translation work necessary. 58 // possibly to minimize the amount of translation work necessary.
55 59
(...skipping 10 matching lines...) Expand all
66 private static final int DEQUEUE_TIMEOUT = 0; // Non-blocking, no wait. 70 private static final int DEQUEUE_TIMEOUT = 0; // Non-blocking, no wait.
67 // Active running encoder instance. Set in initEncode() (called from native co de) 71 // Active running encoder instance. Set in initEncode() (called from native co de)
68 // and reset to null in release() call. 72 // and reset to null in release() call.
69 private static MediaCodecVideoEncoder runningInstance = null; 73 private static MediaCodecVideoEncoder runningInstance = null;
70 private static MediaCodecVideoEncoderErrorCallback errorCallback = null; 74 private static MediaCodecVideoEncoderErrorCallback errorCallback = null;
71 private static int codecErrors = 0; 75 private static int codecErrors = 0;
72 76
73 private Thread mediaCodecThread; 77 private Thread mediaCodecThread;
74 private MediaCodec mediaCodec; 78 private MediaCodec mediaCodec;
75 private ByteBuffer[] outputBuffers; 79 private ByteBuffer[] outputBuffers;
80 private EglBase eglBase;
81 private Surface inputSurface;
82 private GlRectDrawer drawer;
76 private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8"; 83 private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8";
77 private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9"; 84 private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
78 private static final String H264_MIME_TYPE = "video/avc"; 85 private static final String H264_MIME_TYPE = "video/avc";
79 // List of supported HW VP8 codecs. 86 // List of supported HW VP8 codecs.
80 private static final String[] supportedVp8HwCodecPrefixes = 87 private static final String[] supportedVp8HwCodecPrefixes =
81 {"OMX.qcom.", "OMX.Intel." }; 88 {"OMX.qcom.", "OMX.Intel." };
82 // List of supported HW VP9 decoders. 89 // List of supported HW VP9 decoders.
83 private static final String[] supportedVp9HwCodecPrefixes = 90 private static final String[] supportedVp9HwCodecPrefixes =
84 {"OMX.qcom."}; 91 {"OMX.qcom."};
85 // List of supported HW H.264 codecs. 92 // List of supported HW H.264 codecs.
(...skipping 16 matching lines...) Expand all
102 // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h 109 // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h
103 private static final int 110 private static final int
104 COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04; 111 COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04;
105 // Allowable color formats supported by codec - in order of preference. 112 // Allowable color formats supported by codec - in order of preference.
106 private static final int[] supportedColorList = { 113 private static final int[] supportedColorList = {
107 CodecCapabilities.COLOR_FormatYUV420Planar, 114 CodecCapabilities.COLOR_FormatYUV420Planar,
108 CodecCapabilities.COLOR_FormatYUV420SemiPlanar, 115 CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
109 CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar, 116 CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
110 COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m 117 COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m
111 }; 118 };
119 private static final int[] supportedSurfaceColorList = {
120 CodecCapabilities.COLOR_FormatSurface
121 };
112 private VideoCodecType type; 122 private VideoCodecType type;
113 private int colorFormat; // Used by native code. 123 private int colorFormat; // Used by native code.
114 124
115 // SPS and PPS NALs (Config frame) for H.264. 125 // SPS and PPS NALs (Config frame) for H.264.
116 private ByteBuffer configData = null; 126 private ByteBuffer configData = null;
117 127
118 // MediaCodec error handler - invoked when critical error happens which may pr event 128 // MediaCodec error handler - invoked when critical error happens which may pr event
119 // further use of media codec API. Now it means that one of media codec instan ces 129 // further use of media codec API. Now it means that one of media codec instan ces
120 // is hanging and can no longer be used in the next call. 130 // is hanging and can no longer be used in the next call.
121 public static interface MediaCodecVideoEncoderErrorCallback { 131 public static interface MediaCodecVideoEncoderErrorCallback {
122 void onMediaCodecVideoEncoderCriticalError(int codecErrors); 132 void onMediaCodecVideoEncoderCriticalError(int codecErrors);
123 } 133 }
124 134
125 public static void setErrorCallback(MediaCodecVideoEncoderErrorCallback errorC allback) { 135 public static void setErrorCallback(MediaCodecVideoEncoderErrorCallback errorC allback) {
126 Logging.d(TAG, "Set error callback"); 136 Logging.d(TAG, "Set error callback");
127 MediaCodecVideoEncoder.errorCallback = errorCallback; 137 MediaCodecVideoEncoder.errorCallback = errorCallback;
128 } 138 }
129 139
130 // Helper struct for findHwEncoder() below. 140 // Helper struct for findHwEncoder() below.
131 private static class EncoderProperties { 141 private static class EncoderProperties {
132 public EncoderProperties(String codecName, int colorFormat) { 142 public EncoderProperties(String codecName, int colorFormat) {
133 this.codecName = codecName; 143 this.codecName = codecName;
134 this.colorFormat = colorFormat; 144 this.colorFormat = colorFormat;
135 } 145 }
136 public final String codecName; // OpenMax component name for HW codec. 146 public final String codecName; // OpenMax component name for HW codec.
137 public final int colorFormat; // Color format supported by codec. 147 public final int colorFormat; // Color format supported by codec.
138 } 148 }
139 149
140 private static EncoderProperties findHwEncoder( 150 private static EncoderProperties findHwEncoder(
141 String mime, String[] supportedHwCodecPrefixes) { 151 String mime, String[] supportedHwCodecPrefixes, int[] colorList) {
142 // MediaCodec.setParameters is missing for JB and below, so bitrate 152 // MediaCodec.setParameters is missing for JB and below, so bitrate
143 // can not be adjusted dynamically. 153 // can not be adjusted dynamically.
144 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 154 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
145 return null; 155 return null;
146 } 156 }
147 157
148 // Check if device is in H.264 exception list. 158 // Check if device is in H.264 exception list.
149 if (mime.equals(H264_MIME_TYPE)) { 159 if (mime.equals(H264_MIME_TYPE)) {
150 List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS); 160 List<String> exceptionModels = Arrays.asList(H264_HW_EXCEPTION_MODELS);
151 if (exceptionModels.contains(Build.MODEL)) { 161 if (exceptionModels.contains(Build.MODEL)) {
(...skipping 29 matching lines...) Expand all
181 } 191 }
182 if (!supportedCodec) { 192 if (!supportedCodec) {
183 continue; 193 continue;
184 } 194 }
185 195
186 CodecCapabilities capabilities = info.getCapabilitiesForType(mime); 196 CodecCapabilities capabilities = info.getCapabilitiesForType(mime);
187 for (int colorFormat : capabilities.colorFormats) { 197 for (int colorFormat : capabilities.colorFormats) {
188 Logging.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat)); 198 Logging.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat));
189 } 199 }
190 200
191 // Check if codec supports either yuv420 or nv12. 201 for (int supportedColorFormat : colorList) {
192 for (int supportedColorFormat : supportedColorList) {
193 for (int codecColorFormat : capabilities.colorFormats) { 202 for (int codecColorFormat : capabilities.colorFormats) {
194 if (codecColorFormat == supportedColorFormat) { 203 if (codecColorFormat == supportedColorFormat) {
195 // Found supported HW encoder. 204 // Found supported HW encoder.
196 Logging.d(TAG, "Found target encoder for mime " + mime + " : " + nam e + 205 Logging.d(TAG, "Found target encoder for mime " + mime + " : " + nam e +
197 ". Color: 0x" + Integer.toHexString(codecColorFormat)); 206 ". Color: 0x" + Integer.toHexString(codecColorFormat));
198 return new EncoderProperties(name, codecColorFormat); 207 return new EncoderProperties(name, codecColorFormat);
199 } 208 }
200 } 209 }
201 } 210 }
202 } 211 }
203 return null; // No HW encoder. 212 return null; // No HW encoder.
204 } 213 }
205 214
206 public static boolean isVp8HwSupported() { 215 public static boolean isVp8HwSupported() {
207 return findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes) != null; 216 return findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes, supportedCo lorList) != null;
208 } 217 }
209 218
210 public static boolean isVp9HwSupported() { 219 public static boolean isVp9HwSupported() {
211 return findHwEncoder(VP9_MIME_TYPE, supportedVp9HwCodecPrefixes) != null; 220 return findHwEncoder(VP9_MIME_TYPE, supportedVp9HwCodecPrefixes, supportedCo lorList) != null;
212 } 221 }
222
213 public static boolean isH264HwSupported() { 223 public static boolean isH264HwSupported() {
214 return findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null; 224 return findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes, supported ColorList) != null;
225 }
226
227 public static boolean isVp8HwSupportedUsingTextures() {
228 return findHwEncoder(
229 VP8_MIME_TYPE, supportedVp8HwCodecPrefixes, supportedSurfaceColorList) ! = null;
230 }
231
232 public static boolean isVp9HwSupportedUsingTextures() {
233 return findHwEncoder(
234 VP9_MIME_TYPE, supportedVp9HwCodecPrefixes, supportedSurfaceColorList) ! = null;
235 }
236
237 public static boolean isH264HwSupportedUsingTextures() {
238 return findHwEncoder(
239 H264_MIME_TYPE, supportedH264HwCodecPrefixes, supportedSurfaceColorList) != null;
215 } 240 }
216 241
217 private void checkOnMediaCodecThread() { 242 private void checkOnMediaCodecThread() {
218 if (mediaCodecThread.getId() != Thread.currentThread().getId()) { 243 if (mediaCodecThread.getId() != Thread.currentThread().getId()) {
219 throw new RuntimeException( 244 throw new RuntimeException(
220 "MediaCodecVideoEncoder previously operated on " + mediaCodecThread + 245 "MediaCodecVideoEncoder previously operated on " + mediaCodecThread +
221 " but is now called on " + Thread.currentThread()); 246 " but is now called on " + Thread.currentThread());
222 } 247 }
223 } 248 }
224 249
(...skipping 12 matching lines...) Expand all
237 static MediaCodec createByCodecName(String codecName) { 262 static MediaCodec createByCodecName(String codecName) {
238 try { 263 try {
239 // In the L-SDK this call can throw IOException so in order to work in 264 // In the L-SDK this call can throw IOException so in order to work in
240 // both cases catch an exception. 265 // both cases catch an exception.
241 return MediaCodec.createByCodecName(codecName); 266 return MediaCodec.createByCodecName(codecName);
242 } catch (Exception e) { 267 } catch (Exception e) {
243 return null; 268 return null;
244 } 269 }
245 } 270 }
246 271
247 // Returns false if the hardware encoder currently can't be used. 272 boolean initEncode(VideoCodecType type, int width, int height, int kbps, int f ps,
248 boolean initEncode(VideoCodecType type, int width, int height, int kbps, int f ps) { 273 EGLContext sharedContext) {
274 final boolean useSurface = sharedContext != null;
249 Logging.d(TAG, "Java initEncode: " + type + " : " + width + " x " + height + 275 Logging.d(TAG, "Java initEncode: " + type + " : " + width + " x " + height +
250 ". @ " + kbps + " kbps. Fps: " + fps + "."); 276 ". @ " + kbps + " kbps. Fps: " + fps + ". Encode from texture : " + useS urface);
251 277
252 if (mediaCodecThread != null) { 278 if (mediaCodecThread != null) {
253 throw new RuntimeException("Forgot to release()?"); 279 throw new RuntimeException("Forgot to release()?");
254 } 280 }
255 EncoderProperties properties = null; 281 EncoderProperties properties = null;
256 String mime = null; 282 String mime = null;
257 int keyFrameIntervalSec = 0; 283 int keyFrameIntervalSec = 0;
258 if (type == VideoCodecType.VIDEO_CODEC_VP8) { 284 if (type == VideoCodecType.VIDEO_CODEC_VP8) {
259 mime = VP8_MIME_TYPE; 285 mime = VP8_MIME_TYPE;
260 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes); 286 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes,
287 useSurface ? supportedSurfaceColorList : supportedColorList);
261 keyFrameIntervalSec = 100; 288 keyFrameIntervalSec = 100;
262 } else if (type == VideoCodecType.VIDEO_CODEC_VP9) { 289 } else if (type == VideoCodecType.VIDEO_CODEC_VP9) {
263 mime = VP9_MIME_TYPE; 290 mime = VP9_MIME_TYPE;
264 properties = findHwEncoder(VP9_MIME_TYPE, supportedH264HwCodecPrefixes); 291 properties = findHwEncoder(VP9_MIME_TYPE, supportedH264HwCodecPrefixes,
292 useSurface ? supportedSurfaceColorList : supportedColorList);
265 keyFrameIntervalSec = 100; 293 keyFrameIntervalSec = 100;
266 } else if (type == VideoCodecType.VIDEO_CODEC_H264) { 294 } else if (type == VideoCodecType.VIDEO_CODEC_H264) {
267 mime = H264_MIME_TYPE; 295 mime = H264_MIME_TYPE;
268 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes); 296 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes,
297 useSurface ? supportedSurfaceColorList : supportedColorList);
269 keyFrameIntervalSec = 20; 298 keyFrameIntervalSec = 20;
270 } 299 }
271 if (properties == null) { 300 if (properties == null) {
272 throw new RuntimeException("Can not find HW encoder for " + type); 301 throw new RuntimeException("Can not find HW encoder for " + type);
273 } 302 }
274 runningInstance = this; // Encoder is now running and can be queried for sta ck traces. 303 runningInstance = this; // Encoder is now running and can be queried for sta ck traces.
275 colorFormat = properties.colorFormat; 304 colorFormat = properties.colorFormat;
276 Logging.d(TAG, "Color format: " + colorFormat); 305 Logging.d(TAG, "Color format: " + colorFormat);
277 306
278 mediaCodecThread = Thread.currentThread(); 307 mediaCodecThread = Thread.currentThread();
279 try { 308 try {
280 MediaFormat format = MediaFormat.createVideoFormat(mime, width, height); 309 MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
281 format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps); 310 format.setInteger(MediaFormat.KEY_BIT_RATE, 1000 * kbps);
282 format.setInteger("bitrate-mode", VIDEO_ControlRateConstant); 311 format.setInteger("bitrate-mode", VIDEO_ControlRateConstant);
283 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat); 312 format.setInteger(MediaFormat.KEY_COLOR_FORMAT, properties.colorFormat);
284 format.setInteger(MediaFormat.KEY_FRAME_RATE, fps); 313 format.setInteger(MediaFormat.KEY_FRAME_RATE, fps);
285 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec); 314 format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameIntervalSec);
286 Logging.d(TAG, " Format: " + format); 315 Logging.d(TAG, " Format: " + format);
287 mediaCodec = createByCodecName(properties.codecName); 316 mediaCodec = createByCodecName(properties.codecName);
288 this.type = type; 317 this.type = type;
289 if (mediaCodec == null) { 318 if (mediaCodec == null) {
290 Logging.e(TAG, "Can not create media encoder"); 319 Logging.e(TAG, "Can not create media encoder");
291 return false; 320 return false;
292 } 321 }
293 mediaCodec.configure( 322 mediaCodec.configure(
294 format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 323 format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
295 324
325 if (useSurface) {
326 eglBase = new EglBase(sharedContext, EglBase.ConfigType.RECORDABLE);
327 // Create an input surface and keep a reference since we must release th e surface when done.
328 inputSurface = mediaCodec.createInputSurface();
329 eglBase.createSurface(inputSurface);
330 drawer = new GlRectDrawer();
331 }
296 mediaCodec.start(); 332 mediaCodec.start();
297 outputBuffers = mediaCodec.getOutputBuffers(); 333 outputBuffers = mediaCodec.getOutputBuffers();
298 Logging.d(TAG, "Output buffers: " + outputBuffers.length); 334 Logging.d(TAG, "Output buffers: " + outputBuffers.length);
299 335
300 } catch (IllegalStateException e) { 336 } catch (IllegalStateException e) {
301 Logging.e(TAG, "initEncode failed", e); 337 Logging.e(TAG, "initEncode failed", e);
302 return false; 338 return false;
303 } 339 }
304 return true; 340 return true;
305 } 341 }
(...skipping 22 matching lines...) Expand all
328 mediaCodec.queueInputBuffer( 364 mediaCodec.queueInputBuffer(
329 inputBuffer, 0, size, presentationTimestampUs, 0); 365 inputBuffer, 0, size, presentationTimestampUs, 0);
330 return true; 366 return true;
331 } 367 }
332 catch (IllegalStateException e) { 368 catch (IllegalStateException e) {
333 Logging.e(TAG, "encodeBuffer failed", e); 369 Logging.e(TAG, "encodeBuffer failed", e);
334 return false; 370 return false;
335 } 371 }
336 } 372 }
337 373
374 boolean encodeTexture(boolean isKeyframe, int oesTextureId, float[] transforma tionMatrix,
375 long presentationTimestampUs) {
376 checkOnMediaCodecThread();
377 try {
378 if (isKeyframe) {
379 Logging.d(TAG, "Sync frame request");
380 Bundle b = new Bundle();
381 b.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
382 mediaCodec.setParameters(b);
383 }
384 eglBase.makeCurrent();
385 drawer.drawOes(oesTextureId, transformationMatrix);
386 // TODO(perkj): Do we have to call EGLExt.eglPresentationTimeANDROID ?
387 // If not, remove |presentationTimestampUs|.
388 eglBase.swapBuffers();
389 return true;
390 }
391 catch (RuntimeException e) {
392 Logging.e(TAG, "encodeTexture failed", e);
393 return false;
394 }
395 }
396
338 void release() { 397 void release() {
339 Logging.d(TAG, "Java releaseEncoder"); 398 Logging.d(TAG, "Java releaseEncoder");
340 checkOnMediaCodecThread(); 399 checkOnMediaCodecThread();
341 400
342 // Run Mediacodec stop() and release() on separate thread since sometime 401 // Run Mediacodec stop() and release() on separate thread since sometime
343 // Mediacodec.stop() may hang. 402 // Mediacodec.stop() may hang.
344 final CountDownLatch releaseDone = new CountDownLatch(1); 403 final CountDownLatch releaseDone = new CountDownLatch(1);
345 404
346 Runnable runMediaCodecRelease = new Runnable() { 405 Runnable runMediaCodecRelease = new Runnable() {
347 @Override 406 @Override
(...skipping 15 matching lines...) Expand all
363 Logging.e(TAG, "Media encoder release timeout"); 422 Logging.e(TAG, "Media encoder release timeout");
364 codecErrors++; 423 codecErrors++;
365 if (errorCallback != null) { 424 if (errorCallback != null) {
366 Logging.e(TAG, "Invoke codec error callback. Errors: " + codecErrors); 425 Logging.e(TAG, "Invoke codec error callback. Errors: " + codecErrors);
367 errorCallback.onMediaCodecVideoEncoderCriticalError(codecErrors); 426 errorCallback.onMediaCodecVideoEncoderCriticalError(codecErrors);
368 } 427 }
369 } 428 }
370 429
371 mediaCodec = null; 430 mediaCodec = null;
372 mediaCodecThread = null; 431 mediaCodecThread = null;
432 if (drawer != null) {
433 drawer.release();
434 drawer = null;
435 }
436 if (eglBase != null) {
437 eglBase.release();
438 eglBase = null;
439 }
440 if (inputSurface != null) {
441 inputSurface.release();
442 inputSurface = null;
443 }
373 runningInstance = null; 444 runningInstance = null;
374 Logging.d(TAG, "Java releaseEncoder done"); 445 Logging.d(TAG, "Java releaseEncoder done");
375 } 446 }
376 447
377 private boolean setRates(int kbps, int frameRateIgnored) { 448 private boolean setRates(int kbps, int frameRateIgnored) {
378 // frameRate argument is ignored - HW encoder is supposed to use 449 // frameRate argument is ignored - HW encoder is supposed to use
379 // video frame timestamps for bit allocation. 450 // video frame timestamps for bit allocation.
380 checkOnMediaCodecThread(); 451 checkOnMediaCodecThread();
381 Logging.v(TAG, "setRates: " + kbps + " kbps. Fps: " + frameRateIgnored); 452 Logging.v(TAG, "setRates: " + kbps + " kbps. Fps: " + frameRateIgnored);
382 try { 453 try {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 checkOnMediaCodecThread(); 565 checkOnMediaCodecThread();
495 try { 566 try {
496 mediaCodec.releaseOutputBuffer(index, false); 567 mediaCodec.releaseOutputBuffer(index, false);
497 return true; 568 return true;
498 } catch (IllegalStateException e) { 569 } catch (IllegalStateException e) {
499 Logging.e(TAG, "releaseOutputBuffer failed", e); 570 Logging.e(TAG, "releaseOutputBuffer failed", e);
500 return false; 571 return false;
501 } 572 }
502 } 573 }
503 } 574 }
OLDNEW
« no previous file with comments | « talk/app/webrtc/java/jni/peerconnection_jni.cc ('k') | talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698