MediaCodec: report message from CodecErrorLog
Bug: 267190033 Test: atest android.mediav2.cts.CodecUnitTest Change-Id: Idd1adae38328ada955999a8cecb7ce14c75ea52e
This commit is contained in:
@@ -43,6 +43,8 @@
|
||||
|
||||
#include <android_runtime/android_hardware_HardwareBuffer.h>
|
||||
|
||||
#include <android-base/stringprintf.h>
|
||||
|
||||
#include <binder/MemoryDealer.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
@@ -1276,7 +1278,8 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
|
||||
ALOGE("Could not create MediaCodec.BufferInfo.");
|
||||
env->ExceptionClear();
|
||||
}
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Fatal error: could not create MediaCodec.BufferInfo object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1309,7 +1312,8 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
|
||||
ALOGE("Could not create CodecException object.");
|
||||
env->ExceptionClear();
|
||||
}
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Fatal error: could not create CodecException object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1322,7 +1326,9 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
|
||||
CHECK(msg->findMessage("format", &format));
|
||||
|
||||
if (OK != ConvertMessageToMap(env, format, &obj)) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Fatal error: failed to convert format "
|
||||
"from native to Java object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1353,7 +1359,8 @@ void JMediaCodec::handleFirstTunnelFrameReadyNotification(const sp<AMessage> &ms
|
||||
|
||||
status_t err = ConvertMessageToMap(env, data, &obj);
|
||||
if (err != OK) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Fatal error: failed to convert format from native to Java object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1374,7 +1381,8 @@ void JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
|
||||
|
||||
status_t err = ConvertMessageToMap(env, data, &obj);
|
||||
if (err != OK) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
"Fatal error: failed to convert format from native to Java object");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1385,6 +1393,18 @@ void JMediaCodec::handleFrameRenderedNotification(const sp<AMessage> &msg) {
|
||||
env->DeleteLocalRef(obj);
|
||||
}
|
||||
|
||||
std::string JMediaCodec::getExceptionMessage(const char *msg = nullptr) const {
|
||||
if (mCodec == nullptr) {
|
||||
return msg ?: "";
|
||||
}
|
||||
std::string prefix = "";
|
||||
if (msg && msg[0] != '\0') {
|
||||
prefix.append(msg);
|
||||
prefix.append("\n");
|
||||
}
|
||||
return prefix + mCodec->getErrorLog().extract();
|
||||
}
|
||||
|
||||
void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
|
||||
switch (msg->what()) {
|
||||
case kWhatCallbackNotify:
|
||||
@@ -1471,9 +1491,17 @@ static void throwCryptoException(JNIEnv *env, status_t err, const char *msg,
|
||||
env->Throw(exception);
|
||||
}
|
||||
|
||||
static std::string GetExceptionMessage(const sp<JMediaCodec> &codec, const char *msg) {
|
||||
if (codec == NULL) {
|
||||
return msg ?: "codec is released already";
|
||||
}
|
||||
return codec->getExceptionMessage(msg);
|
||||
}
|
||||
|
||||
static jint throwExceptionAsNecessary(
|
||||
JNIEnv *env, status_t err, int32_t actionCode = ACTION_CODE_FATAL,
|
||||
const char *msg = NULL, const sp<ICrypto>& crypto = NULL) {
|
||||
const char *msg = NULL, const sp<ICrypto>& crypto = NULL,
|
||||
const sp<JMediaCodec> &codec = NULL) {
|
||||
switch (err) {
|
||||
case OK:
|
||||
return 0;
|
||||
@@ -1488,23 +1516,38 @@ static jint throwExceptionAsNecessary(
|
||||
return DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED;
|
||||
|
||||
case INVALID_OPERATION:
|
||||
jniThrowException(env, "java/lang/IllegalStateException", msg);
|
||||
jniThrowException(
|
||||
env, "java/lang/IllegalStateException",
|
||||
GetExceptionMessage(codec, msg).c_str());
|
||||
return 0;
|
||||
|
||||
case BAD_VALUE:
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException", msg);
|
||||
jniThrowException(
|
||||
env, "java/lang/IllegalArgumentException",
|
||||
GetExceptionMessage(codec, msg).c_str());
|
||||
return 0;
|
||||
|
||||
default:
|
||||
if (isCryptoError(err)) {
|
||||
throwCryptoException(env, err, msg, crypto);
|
||||
throwCryptoException(
|
||||
env, err,
|
||||
GetExceptionMessage(codec, msg).c_str(),
|
||||
crypto);
|
||||
return 0;
|
||||
}
|
||||
throwCodecException(env, err, actionCode, msg);
|
||||
throwCodecException(
|
||||
env, err, actionCode,
|
||||
GetExceptionMessage(codec, msg).c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static jint throwExceptionAsNecessary(
|
||||
JNIEnv *env, status_t err, const sp<JMediaCodec> &codec,
|
||||
int32_t actionCode = ACTION_CODE_FATAL) {
|
||||
return throwExceptionAsNecessary(env, err, actionCode, NULL, NULL, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_enableOnFirstTunnelFrameReadyListener(
|
||||
JNIEnv *env,
|
||||
jobject thiz,
|
||||
@@ -1512,13 +1555,13 @@ static void android_media_MediaCodec_native_enableOnFirstTunnelFrameReadyListene
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->enableOnFirstTunnelFrameReadyListener(enabled);
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_enableOnFrameRenderedListener(
|
||||
@@ -1528,13 +1571,13 @@ static void android_media_MediaCodec_native_enableOnFrameRenderedListener(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->enableOnFrameRenderedListener(enabled);
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_setCallback(
|
||||
@@ -1544,13 +1587,13 @@ static void android_media_MediaCodec_native_setCallback(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->setCallback(cb);
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_configure(
|
||||
@@ -1564,7 +1607,7 @@ static void android_media_MediaCodec_native_configure(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1602,7 +1645,7 @@ static void android_media_MediaCodec_native_configure(
|
||||
|
||||
err = codec->configure(format, bufferProducer, crypto, descrambler, flags);
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_setSurface(
|
||||
@@ -1612,7 +1655,7 @@ static void android_media_MediaCodec_native_setSurface(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1631,7 +1674,7 @@ static void android_media_MediaCodec_native_setSurface(
|
||||
}
|
||||
|
||||
status_t err = codec->setSurface(bufferProducer);
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface(
|
||||
@@ -1735,7 +1778,7 @@ static void android_media_MediaCodec_setInputSurface(
|
||||
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1749,7 +1792,7 @@ static void android_media_MediaCodec_setInputSurface(
|
||||
}
|
||||
status_t err = codec->setInputSurface(persistentSurface);
|
||||
if (err != NO_ERROR) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1759,7 +1802,7 @@ static jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
|
||||
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1767,7 +1810,7 @@ static jobject android_media_MediaCodec_createInputSurface(JNIEnv* env,
|
||||
sp<IGraphicBufferProducer> bufferProducer;
|
||||
status_t err = codec->createInputSurface(&bufferProducer);
|
||||
if (err != NO_ERROR) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1782,13 +1825,13 @@ static void android_media_MediaCodec_start(JNIEnv *env, jobject thiz) {
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->start();
|
||||
|
||||
throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, "start failed");
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
|
||||
@@ -1797,13 +1840,13 @@ static void android_media_MediaCodec_stop(JNIEnv *env, jobject thiz) {
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->stop();
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
|
||||
@@ -1812,7 +1855,7 @@ static void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1825,7 +1868,7 @@ static void android_media_MediaCodec_reset(JNIEnv *env, jobject thiz) {
|
||||
// trigger an IllegalStateException.
|
||||
err = UNKNOWN_ERROR;
|
||||
}
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
|
||||
@@ -1834,13 +1877,13 @@ static void android_media_MediaCodec_flush(JNIEnv *env, jobject thiz) {
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->flush();
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_queueInputBuffer(
|
||||
@@ -1856,7 +1899,7 @@ static void android_media_MediaCodec_queueInputBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1866,7 +1909,8 @@ static void android_media_MediaCodec_queueInputBuffer(
|
||||
index, offset, size, timestampUs, flags, &errorDetailMsg);
|
||||
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str());
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
codec->getExceptionMessage(errorDetailMsg.c_str()).c_str());
|
||||
}
|
||||
|
||||
struct NativeCryptoInfo {
|
||||
@@ -1890,7 +1934,9 @@ struct NativeCryptoInfo {
|
||||
} else if (jmode == gCryptoModes.AesCbc) {
|
||||
mMode = CryptoPlugin::kMode_AES_CBC;
|
||||
} else {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
base::StringPrintf("unrecognized crypto mode: %d", jmode).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2026,7 +2072,7 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2056,7 +2102,9 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
|
||||
} else if (jmode == gCryptoModes.AesCbc) {
|
||||
mode = CryptoPlugin::kMode_AES_CBC;
|
||||
} else {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
base::StringPrintf("Unrecognized crypto mode: %d", jmode).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2175,8 +2223,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
|
||||
subSamples = NULL;
|
||||
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL, errorDetailMsg.empty() ? NULL : errorDetailMsg.c_str(),
|
||||
codec->getCrypto());
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
codec->getExceptionMessage(errorDetailMsg.c_str()).c_str(), codec->getCrypto());
|
||||
}
|
||||
|
||||
static jobject android_media_MediaCodec_mapHardwareBuffer(JNIEnv *env, jclass, jobject bufferObj) {
|
||||
@@ -2518,14 +2566,16 @@ static void android_media_MediaCodec_native_queueLinearBlock(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == nullptr || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
sp<AMessage> tunings;
|
||||
status_t err = ConvertKeyValueListsToAMessage(env, keys, values, &tunings);
|
||||
if (err != OK) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
"error occurred while converting tunings from Java to native");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2545,15 +2595,23 @@ static void android_media_MediaCodec_native_queueLinearBlock(
|
||||
}
|
||||
env->MonitorExit(lock.get());
|
||||
} else {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
"Failed to grab lock for a LinearBlock object");
|
||||
return;
|
||||
}
|
||||
|
||||
AString errorDetailMsg;
|
||||
if (codec->hasCryptoOrDescrambler()) {
|
||||
if (!memory) {
|
||||
// It means there was an unexpected failure in extractMemoryFromContext above
|
||||
ALOGI("queueLinearBlock: no ashmem memory for encrypted content");
|
||||
throwExceptionAsNecessary(env, BAD_VALUE);
|
||||
throwExceptionAsNecessary(
|
||||
env, BAD_VALUE, ACTION_CODE_FATAL,
|
||||
"Unexpected error: the input buffer is not compatible with "
|
||||
"the secure codec, and a fallback logic failed.\n"
|
||||
"Suggestion: please try including the secure codec when calling "
|
||||
"MediaCodec.LinearBlock#obtain method to obtain a compatible buffer.");
|
||||
return;
|
||||
}
|
||||
auto cryptoInfo =
|
||||
@@ -2577,14 +2635,22 @@ static void android_media_MediaCodec_native_queueLinearBlock(
|
||||
ALOGI_IF(err != OK, "queueEncryptedLinearBlock returned err = %d", err);
|
||||
} else {
|
||||
if (!buffer) {
|
||||
// It means there was an unexpected failure in extractBufferFromContext above
|
||||
ALOGI("queueLinearBlock: no C2Buffer found");
|
||||
throwExceptionAsNecessary(env, BAD_VALUE);
|
||||
throwExceptionAsNecessary(
|
||||
env, BAD_VALUE, ACTION_CODE_FATAL,
|
||||
"Unexpected error: the input buffer is not compatible with "
|
||||
"the non-secure codec, and a fallback logic failed.\n"
|
||||
"Suggestion: please do not include the secure codec when calling "
|
||||
"MediaCodec.LinearBlock#obtain method to obtain a compatible buffer.");
|
||||
return;
|
||||
}
|
||||
err = codec->queueBuffer(
|
||||
index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg);
|
||||
}
|
||||
throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, errorDetailMsg.c_str());
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
codec->getExceptionMessage(errorDetailMsg.c_str()).c_str());
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_queueHardwareBuffer(
|
||||
@@ -2595,14 +2661,16 @@ static void android_media_MediaCodec_native_queueHardwareBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
sp<AMessage> tunings;
|
||||
status_t err = ConvertKeyValueListsToAMessage(env, keys, values, &tunings);
|
||||
if (err != OK) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
"error occurred while converting tunings from Java to native");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2627,7 +2695,9 @@ static void android_media_MediaCodec_native_queueHardwareBuffer(
|
||||
ALOGW("Failed to wrap AHardwareBuffer into C2GraphicAllocation");
|
||||
native_handle_close(handle);
|
||||
native_handle_delete(handle);
|
||||
throwExceptionAsNecessary(env, BAD_VALUE);
|
||||
throwExceptionAsNecessary(
|
||||
env, BAD_VALUE, ACTION_CODE_FATAL,
|
||||
"HardwareBuffer not recognized");
|
||||
return;
|
||||
}
|
||||
std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
|
||||
@@ -2636,7 +2706,9 @@ static void android_media_MediaCodec_native_queueHardwareBuffer(
|
||||
AString errorDetailMsg;
|
||||
err = codec->queueBuffer(
|
||||
index, buffer, presentationTimeUs, flags, tunings, &errorDetailMsg);
|
||||
throwExceptionAsNecessary(env, err, ACTION_CODE_FATAL, errorDetailMsg.c_str());
|
||||
throwExceptionAsNecessary(
|
||||
env, err, ACTION_CODE_FATAL,
|
||||
codec->getExceptionMessage(errorDetailMsg.c_str()).c_str());
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_native_getOutputFrame(
|
||||
@@ -2646,13 +2718,13 @@ static void android_media_MediaCodec_native_getOutputFrame(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->getOutputFrame(env, frame, index);
|
||||
if (err != OK) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2663,7 +2735,7 @@ static jint android_media_MediaCodec_dequeueInputBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2674,7 +2746,7 @@ static jint android_media_MediaCodec_dequeueInputBuffer(
|
||||
return (jint) index;
|
||||
}
|
||||
|
||||
return throwExceptionAsNecessary(env, err);
|
||||
return throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static jint android_media_MediaCodec_dequeueOutputBuffer(
|
||||
@@ -2684,7 +2756,7 @@ static jint android_media_MediaCodec_dequeueOutputBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2696,7 +2768,7 @@ static jint android_media_MediaCodec_dequeueOutputBuffer(
|
||||
return (jint) index;
|
||||
}
|
||||
|
||||
return throwExceptionAsNecessary(env, err);
|
||||
return throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_releaseOutputBuffer(
|
||||
@@ -2707,13 +2779,13 @@ static void android_media_MediaCodec_releaseOutputBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->releaseOutputBuffer(index, render, updatePTS, timestampNs);
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
|
||||
@@ -2722,13 +2794,13 @@ static void android_media_MediaCodec_signalEndOfInputStream(JNIEnv* env,
|
||||
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t err = codec->signalEndOfInputStream();
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static jobject android_media_MediaCodec_getFormatNative(
|
||||
@@ -2738,7 +2810,7 @@ static jobject android_media_MediaCodec_getFormatNative(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2749,7 +2821,7 @@ static jobject android_media_MediaCodec_getFormatNative(
|
||||
return format;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2761,7 +2833,7 @@ static jobject android_media_MediaCodec_getOutputFormatForIndexNative(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2772,7 +2844,7 @@ static jobject android_media_MediaCodec_getOutputFormatForIndexNative(
|
||||
return format;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2784,7 +2856,7 @@ static jobjectArray android_media_MediaCodec_getBuffers(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2797,7 +2869,7 @@ static jobjectArray android_media_MediaCodec_getBuffers(
|
||||
|
||||
// if we're out of memory, an exception was already thrown
|
||||
if (err != NO_MEMORY) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2810,7 +2882,7 @@ static jobject android_media_MediaCodec_getBuffer(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2823,7 +2895,7 @@ static jobject android_media_MediaCodec_getBuffer(
|
||||
|
||||
// if we're out of memory, an exception was already thrown
|
||||
if (err != NO_MEMORY) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2836,7 +2908,7 @@ static jobject android_media_MediaCodec_getImage(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2849,7 +2921,7 @@ static jobject android_media_MediaCodec_getImage(
|
||||
|
||||
// if we're out of memory, an exception was already thrown
|
||||
if (err != NO_MEMORY) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -2862,7 +2934,7 @@ static jobject android_media_MediaCodec_getName(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2873,7 +2945,7 @@ static jobject android_media_MediaCodec_getName(
|
||||
return name;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2885,7 +2957,7 @@ static jobject android_media_MediaCodec_getOwnCodecInfo(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2896,7 +2968,7 @@ static jobject android_media_MediaCodec_getOwnCodecInfo(
|
||||
return codecInfoObj;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2908,7 +2980,8 @@ android_media_MediaCodec_native_getMetrics(JNIEnv *env, jobject thiz)
|
||||
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalStateException",
|
||||
GetExceptionMessage(codec, NULL).c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2937,7 +3010,7 @@ static void android_media_MediaCodec_setParameters(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2948,7 +3021,7 @@ static void android_media_MediaCodec_setParameters(
|
||||
err = codec->setParameters(params);
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_setVideoScalingMode(
|
||||
@@ -2956,13 +3029,14 @@ static void android_media_MediaCodec_setVideoScalingMode(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode != NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW
|
||||
&& mode != NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
|
||||
jniThrowException(env, "java/lang/IllegalArgumentException",
|
||||
String8::format("Unrecognized mode: %d", mode));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2974,7 +3048,7 @@ static void android_media_MediaCodec_setAudioPresentation(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2986,14 +3060,14 @@ static jobject android_media_MediaCodec_getSupportedVendorParameters(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jobject ret = NULL;
|
||||
status_t status = codec->querySupportedVendorParameters(env, &ret);
|
||||
if (status != OK) {
|
||||
throwExceptionAsNecessary(env, status);
|
||||
throwExceptionAsNecessary(env, status, codec);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -3004,7 +3078,7 @@ static jobject android_media_MediaCodec_getParameterDescriptor(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3021,13 +3095,13 @@ static void android_media_MediaCodec_subscribeToVendorParameters(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t status = codec->subscribeToVendorParameters(env, names);
|
||||
if (status != OK) {
|
||||
throwExceptionAsNecessary(env, status);
|
||||
throwExceptionAsNecessary(env, status, codec);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3037,13 +3111,13 @@ static void android_media_MediaCodec_unsubscribeFromVendorParameters(
|
||||
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
|
||||
|
||||
if (codec == NULL || codec->initCheck() != OK) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
|
||||
return;
|
||||
}
|
||||
|
||||
status_t status = codec->unsubscribeFromVendorParameters(env, names);
|
||||
if (status != OK) {
|
||||
throwExceptionAsNecessary(env, status);
|
||||
throwExceptionAsNecessary(env, status, codec);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3440,11 +3514,15 @@ static jobject android_media_MediaCodec_LinearBlock_native_map(
|
||||
if (!context->mReadonlyMapping) {
|
||||
const C2BufferData data = buffer->data();
|
||||
if (data.type() != C2BufferData::LINEAR) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
"Underlying buffer is not a linear buffer");
|
||||
return nullptr;
|
||||
}
|
||||
if (data.linearBlocks().size() != 1u) {
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
"Underlying buffer contains more than one block");
|
||||
return nullptr;
|
||||
}
|
||||
C2ConstLinearBlock block = data.linearBlocks().front();
|
||||
@@ -3492,7 +3570,9 @@ static jobject android_media_MediaCodec_LinearBlock_native_map(
|
||||
false, // readOnly
|
||||
true /* clearBuffer */);
|
||||
}
|
||||
throwExceptionAsNecessary(env, INVALID_OPERATION);
|
||||
throwExceptionAsNecessary(
|
||||
env, INVALID_OPERATION, ACTION_CODE_FATAL,
|
||||
"Underlying buffer is empty");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -3515,7 +3595,9 @@ static void PopulateNamesVector(
|
||||
}
|
||||
const char *cstr = env->GetStringUTFChars(jstr, nullptr);
|
||||
if (cstr == nullptr) {
|
||||
throwExceptionAsNecessary(env, BAD_VALUE);
|
||||
throwExceptionAsNecessary(
|
||||
env, BAD_VALUE, ACTION_CODE_FATAL,
|
||||
"Error converting Java string to native");
|
||||
return;
|
||||
}
|
||||
names->emplace_back(cstr);
|
||||
@@ -3567,6 +3649,7 @@ static jboolean android_media_MediaCodec_LinearBlock_checkCompatible(
|
||||
}
|
||||
status_t err = MediaCodec::CanFetchLinearBlock(names, &isCompatible);
|
||||
if (err != OK) {
|
||||
// TODO: CodecErrorLog
|
||||
throwExceptionAsNecessary(env, err);
|
||||
}
|
||||
return isCompatible;
|
||||
|
||||
@@ -176,6 +176,8 @@ struct JMediaCodec : public AHandler {
|
||||
|
||||
const sp<ICrypto> &getCrypto() { return mCrypto; }
|
||||
|
||||
std::string getExceptionMessage(const char *msg) const;
|
||||
|
||||
protected:
|
||||
virtual ~JMediaCodec();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user