MediaCodec: report message from CodecErrorLog
Bug: 267190033 Test: atest android.mediav2.cts.CodecUnitTest Merged-In: Idd1adae38328ada955999a8cecb7ce14c75ea52e 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>
|
||||
@@ -1099,7 +1101,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;
|
||||
}
|
||||
|
||||
@@ -1121,7 +1124,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;
|
||||
}
|
||||
|
||||
@@ -1134,7 +1138,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;
|
||||
}
|
||||
|
||||
@@ -1166,7 +1172,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;
|
||||
}
|
||||
|
||||
@@ -1187,7 +1194,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;
|
||||
}
|
||||
|
||||
@@ -1198,6 +1206,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:
|
||||
@@ -1347,9 +1367,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;
|
||||
@@ -1364,23 +1392,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,
|
||||
@@ -1388,13 +1431,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(
|
||||
@@ -1404,13 +1447,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(
|
||||
@@ -1420,13 +1463,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(
|
||||
@@ -1440,7 +1483,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;
|
||||
}
|
||||
|
||||
@@ -1478,7 +1521,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(
|
||||
@@ -1488,7 +1531,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;
|
||||
}
|
||||
|
||||
@@ -1507,7 +1550,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(
|
||||
@@ -1611,7 +1654,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;
|
||||
}
|
||||
|
||||
@@ -1625,7 +1668,7 @@ static void android_media_MediaCodec_setInputSurface(
|
||||
}
|
||||
status_t err = codec->setInputSurface(persistentSurface);
|
||||
if (err != NO_ERROR) {
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1635,7 +1678,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;
|
||||
}
|
||||
|
||||
@@ -1643,7 +1686,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;
|
||||
}
|
||||
|
||||
@@ -1658,13 +1701,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) {
|
||||
@@ -1673,13 +1716,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) {
|
||||
@@ -1688,7 +1731,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;
|
||||
}
|
||||
|
||||
@@ -1701,7 +1744,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) {
|
||||
@@ -1710,13 +1753,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(
|
||||
@@ -1732,7 +1775,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;
|
||||
}
|
||||
|
||||
@@ -1742,7 +1785,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 {
|
||||
@@ -1766,7 +1810,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;
|
||||
}
|
||||
|
||||
@@ -1902,7 +1948,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;
|
||||
}
|
||||
|
||||
@@ -1932,7 +1978,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;
|
||||
}
|
||||
|
||||
@@ -2051,8 +2099,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) {
|
||||
@@ -2394,14 +2442,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;
|
||||
}
|
||||
|
||||
@@ -2421,15 +2471,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 =
|
||||
@@ -2453,14 +2511,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(
|
||||
@@ -2471,14 +2537,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;
|
||||
}
|
||||
|
||||
@@ -2503,7 +2571,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);
|
||||
@@ -2512,7 +2582,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(
|
||||
@@ -2522,13 +2594,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2539,7 +2611,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;
|
||||
}
|
||||
|
||||
@@ -2550,7 +2622,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(
|
||||
@@ -2560,7 +2632,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;
|
||||
}
|
||||
|
||||
@@ -2572,7 +2644,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(
|
||||
@@ -2583,13 +2655,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,
|
||||
@@ -2598,13 +2670,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(
|
||||
@@ -2614,7 +2686,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;
|
||||
}
|
||||
|
||||
@@ -2625,7 +2697,7 @@ static jobject android_media_MediaCodec_getFormatNative(
|
||||
return format;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2637,7 +2709,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;
|
||||
}
|
||||
|
||||
@@ -2648,7 +2720,7 @@ static jobject android_media_MediaCodec_getOutputFormatForIndexNative(
|
||||
return format;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2660,7 +2732,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;
|
||||
}
|
||||
|
||||
@@ -2673,7 +2745,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;
|
||||
@@ -2686,7 +2758,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;
|
||||
}
|
||||
|
||||
@@ -2699,7 +2771,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;
|
||||
@@ -2712,7 +2784,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;
|
||||
}
|
||||
|
||||
@@ -2725,7 +2797,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;
|
||||
@@ -2738,7 +2810,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;
|
||||
}
|
||||
|
||||
@@ -2749,7 +2821,7 @@ static jobject android_media_MediaCodec_getName(
|
||||
return name;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2761,7 +2833,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;
|
||||
}
|
||||
|
||||
@@ -2772,7 +2844,7 @@ static jobject android_media_MediaCodec_getOwnCodecInfo(
|
||||
return codecInfoObj;
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -2784,7 +2856,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;
|
||||
}
|
||||
|
||||
@@ -2813,7 +2886,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;
|
||||
}
|
||||
|
||||
@@ -2824,7 +2897,7 @@ static void android_media_MediaCodec_setParameters(
|
||||
err = codec->setParameters(params);
|
||||
}
|
||||
|
||||
throwExceptionAsNecessary(env, err);
|
||||
throwExceptionAsNecessary(env, err, codec);
|
||||
}
|
||||
|
||||
static void android_media_MediaCodec_setVideoScalingMode(
|
||||
@@ -2832,13 +2905,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;
|
||||
}
|
||||
|
||||
@@ -2850,7 +2924,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;
|
||||
}
|
||||
|
||||
@@ -2862,14 +2936,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;
|
||||
@@ -2880,7 +2954,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;
|
||||
}
|
||||
|
||||
@@ -2897,13 +2971,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;
|
||||
}
|
||||
@@ -2913,13 +2987,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;
|
||||
}
|
||||
@@ -3310,11 +3384,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();
|
||||
@@ -3362,7 +3440,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;
|
||||
}
|
||||
|
||||
@@ -3385,7 +3465,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);
|
||||
@@ -3437,6 +3519,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