| OLD | NEW |
| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 // Active running encoder instance. Set in initEncode() (called from native co
de) | 67 // Active running encoder instance. Set in initEncode() (called from native co
de) |
| 68 // and reset to null in release() call. | 68 // and reset to null in release() call. |
| 69 private static MediaCodecVideoEncoder runningInstance = null; | 69 private static MediaCodecVideoEncoder runningInstance = null; |
| 70 private static MediaCodecVideoEncoderErrorCallback errorCallback = null; | 70 private static MediaCodecVideoEncoderErrorCallback errorCallback = null; |
| 71 private static int codecErrors = 0; | 71 private static int codecErrors = 0; |
| 72 | 72 |
| 73 private Thread mediaCodecThread; | 73 private Thread mediaCodecThread; |
| 74 private MediaCodec mediaCodec; | 74 private MediaCodec mediaCodec; |
| 75 private ByteBuffer[] outputBuffers; | 75 private ByteBuffer[] outputBuffers; |
| 76 private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8"; | 76 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"; |
| 77 private static final String H264_MIME_TYPE = "video/avc"; | 78 private static final String H264_MIME_TYPE = "video/avc"; |
| 78 // List of supported HW VP8 codecs. | 79 // List of supported HW VP8 codecs. |
| 79 private static final String[] supportedVp8HwCodecPrefixes = | 80 private static final String[] supportedVp8HwCodecPrefixes = |
| 80 {"OMX.qcom.", "OMX.Intel." }; | 81 {"OMX.qcom.", "OMX.Intel." }; |
| 82 // List of supported HW VP9 decoders. |
| 83 private static final String[] supportedVp9HwCodecPrefixes = |
| 84 {"OMX.qcom."}; |
| 81 // List of supported HW H.264 codecs. | 85 // List of supported HW H.264 codecs. |
| 82 private static final String[] supportedH264HwCodecPrefixes = | 86 private static final String[] supportedH264HwCodecPrefixes = |
| 83 {"OMX.qcom." }; | 87 {"OMX.qcom." }; |
| 84 // List of devices with poor H.264 encoder quality. | 88 // List of devices with poor H.264 encoder quality. |
| 85 private static final String[] H264_HW_EXCEPTION_MODELS = new String[] { | 89 private static final String[] H264_HW_EXCEPTION_MODELS = new String[] { |
| 86 // HW H.264 encoder on below devices has poor bitrate control - actual | 90 // HW H.264 encoder on below devices has poor bitrate control - actual |
| 87 // bitrates deviates a lot from the target value. | 91 // bitrates deviates a lot from the target value. |
| 88 "SAMSUNG-SGH-I337", | 92 "SAMSUNG-SGH-I337", |
| 89 "Nexus 7", | 93 "Nexus 7", |
| 90 "Nexus 4" | 94 "Nexus 4" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 for (int codecColorFormat : capabilities.colorFormats) { | 193 for (int codecColorFormat : capabilities.colorFormats) { |
| 190 if (codecColorFormat == supportedColorFormat) { | 194 if (codecColorFormat == supportedColorFormat) { |
| 191 // Found supported HW encoder. | 195 // Found supported HW encoder. |
| 192 Logging.d(TAG, "Found target encoder for mime " + mime + " : " + nam
e + | 196 Logging.d(TAG, "Found target encoder for mime " + mime + " : " + nam
e + |
| 193 ". Color: 0x" + Integer.toHexString(codecColorFormat)); | 197 ". Color: 0x" + Integer.toHexString(codecColorFormat)); |
| 194 return new EncoderProperties(name, codecColorFormat); | 198 return new EncoderProperties(name, codecColorFormat); |
| 195 } | 199 } |
| 196 } | 200 } |
| 197 } | 201 } |
| 198 } | 202 } |
| 199 return null; // No HW VP8 encoder. | 203 return null; // No HW encoder. |
| 200 } | 204 } |
| 201 | 205 |
| 202 public static boolean isVp8HwSupported() { | 206 public static boolean isVp8HwSupported() { |
| 203 return findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes) != null; | 207 return findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes) != null; |
| 204 } | 208 } |
| 205 | 209 |
| 210 public static boolean isVp9HwSupported() { |
| 211 return findHwEncoder(VP9_MIME_TYPE, supportedVp9HwCodecPrefixes) != null; |
| 212 } |
| 206 public static boolean isH264HwSupported() { | 213 public static boolean isH264HwSupported() { |
| 207 return findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null; | 214 return findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null; |
| 208 } | 215 } |
| 209 | 216 |
| 210 private void checkOnMediaCodecThread() { | 217 private void checkOnMediaCodecThread() { |
| 211 if (mediaCodecThread.getId() != Thread.currentThread().getId()) { | 218 if (mediaCodecThread.getId() != Thread.currentThread().getId()) { |
| 212 throw new RuntimeException( | 219 throw new RuntimeException( |
| 213 "MediaCodecVideoEncoder previously operated on " + mediaCodecThread + | 220 "MediaCodecVideoEncoder previously operated on " + mediaCodecThread + |
| 214 " but is now called on " + Thread.currentThread()); | 221 " but is now called on " + Thread.currentThread()); |
| 215 } | 222 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 245 if (mediaCodecThread != null) { | 252 if (mediaCodecThread != null) { |
| 246 throw new RuntimeException("Forgot to release()?"); | 253 throw new RuntimeException("Forgot to release()?"); |
| 247 } | 254 } |
| 248 EncoderProperties properties = null; | 255 EncoderProperties properties = null; |
| 249 String mime = null; | 256 String mime = null; |
| 250 int keyFrameIntervalSec = 0; | 257 int keyFrameIntervalSec = 0; |
| 251 if (type == VideoCodecType.VIDEO_CODEC_VP8) { | 258 if (type == VideoCodecType.VIDEO_CODEC_VP8) { |
| 252 mime = VP8_MIME_TYPE; | 259 mime = VP8_MIME_TYPE; |
| 253 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes); | 260 properties = findHwEncoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes); |
| 254 keyFrameIntervalSec = 100; | 261 keyFrameIntervalSec = 100; |
| 262 } else if (type == VideoCodecType.VIDEO_CODEC_VP9) { |
| 263 mime = VP9_MIME_TYPE; |
| 264 properties = findHwEncoder(VP9_MIME_TYPE, supportedH264HwCodecPrefixes); |
| 265 keyFrameIntervalSec = 100; |
| 255 } else if (type == VideoCodecType.VIDEO_CODEC_H264) { | 266 } else if (type == VideoCodecType.VIDEO_CODEC_H264) { |
| 256 mime = H264_MIME_TYPE; | 267 mime = H264_MIME_TYPE; |
| 257 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes); | 268 properties = findHwEncoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes); |
| 258 keyFrameIntervalSec = 20; | 269 keyFrameIntervalSec = 20; |
| 259 } | 270 } |
| 260 if (properties == null) { | 271 if (properties == null) { |
| 261 throw new RuntimeException("Can not find HW encoder for " + type); | 272 throw new RuntimeException("Can not find HW encoder for " + type); |
| 262 } | 273 } |
| 263 runningInstance = this; // Encoder is now running and can be queried for sta
ck traces. | 274 runningInstance = this; // Encoder is now running and can be queried for sta
ck traces. |
| 264 colorFormat = properties.colorFormat; | 275 colorFormat = properties.colorFormat; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 checkOnMediaCodecThread(); | 494 checkOnMediaCodecThread(); |
| 484 try { | 495 try { |
| 485 mediaCodec.releaseOutputBuffer(index, false); | 496 mediaCodec.releaseOutputBuffer(index, false); |
| 486 return true; | 497 return true; |
| 487 } catch (IllegalStateException e) { | 498 } catch (IllegalStateException e) { |
| 488 Logging.e(TAG, "releaseOutputBuffer failed", e); | 499 Logging.e(TAG, "releaseOutputBuffer failed", e); |
| 489 return false; | 500 return false; |
| 490 } | 501 } |
| 491 } | 502 } |
| 492 } | 503 } |
| OLD | NEW |