Merge Issue: google/ExoPlayer#10762: Fix ffmpeg jni wrapper returning invalid result codes
Imported from GitHub PR Issue: google/ExoPlayer#10762 This ensure that ffmpeg error code are properly translated to values that the ExoPlayer decoder understand. The main gain is that it allows the decoder to properly ignore more cases of invalid data and recover. The second gain is that the other errors are now proper ExoPlayer errors and no more obscure buffer ones. Fixes: Issue: google/ExoPlayer#10760 Merge 82ceeb77d6df71f5ffb0474db66a36fd6eb8e51a into 972e169bd85b14848dcae75e34f9e95fe87e1f4b COPYBARA_INTEGRATE_REVIEW=go/exoghi/10762 from Tolriq:ffmpeg_error_code 82ceeb77d6df71f5ffb0474db66a36fd6eb8e51a PiperOrigin-RevId: 487189910
This commit is contained in:
parent
714e556505
commit
a1c04cd473
@ -89,6 +89,11 @@ AVCodecContext *createContext(JNIEnv *env, AVCodec *codec, jbyteArray extraData,
|
||||
int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
uint8_t *outputBuffer, int outputSize);
|
||||
|
||||
/**
|
||||
* Transforms ffmpeg AVERROR into a negative AUDIO_DECODER_ERROR constant value.
|
||||
*/
|
||||
int transformError(const char *functionName, int errorNumber);
|
||||
|
||||
/**
|
||||
* Outputs a log message describing the avcodec error number.
|
||||
*/
|
||||
@ -265,8 +270,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
result = avcodec_send_packet(context, packet);
|
||||
if (result) {
|
||||
logError("avcodec_send_packet", result);
|
||||
return result == AVERROR_INVALIDDATA ? AUDIO_DECODER_ERROR_INVALID_DATA
|
||||
: AUDIO_DECODER_ERROR_OTHER;
|
||||
return transformError(result);
|
||||
}
|
||||
|
||||
// Dequeue output data until it runs out.
|
||||
@ -275,7 +279,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
LOGE("Failed to allocate output frame.");
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
result = avcodec_receive_frame(context, frame);
|
||||
if (result) {
|
||||
@ -284,7 +288,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
break;
|
||||
}
|
||||
logError("avcodec_receive_frame", result);
|
||||
return result;
|
||||
return transformError(result);
|
||||
}
|
||||
|
||||
// Resample output.
|
||||
@ -312,7 +316,7 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
if (result < 0) {
|
||||
logError("swr_init", result);
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
return transformError(result);
|
||||
}
|
||||
context->opaque = resampleContext;
|
||||
}
|
||||
@ -324,20 +328,20 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
LOGE("Output buffer size (%d) too small for output data (%d).",
|
||||
outputSize, outSize + bufferOutSize);
|
||||
av_frame_free(&frame);
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
result = swr_convert(resampleContext, &outputBuffer, bufferOutSize,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
av_frame_free(&frame);
|
||||
if (result < 0) {
|
||||
logError("swr_convert", result);
|
||||
return result;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
int available = swr_get_out_samples(resampleContext, 0);
|
||||
if (available != 0) {
|
||||
LOGE("Expected no samples remaining after resampling, but found %d.",
|
||||
available);
|
||||
return -1;
|
||||
return AUDIO_DECODER_ERROR_INVALID_DATA;
|
||||
}
|
||||
outputBuffer += bufferOutSize;
|
||||
outSize += bufferOutSize;
|
||||
@ -345,6 +349,11 @@ int decodePacket(AVCodecContext *context, AVPacket *packet,
|
||||
return outSize;
|
||||
}
|
||||
|
||||
int transformError(int result) {
|
||||
return result == AVERROR_INVALIDDATA ? AUDIO_DECODER_ERROR_INVALID_DATA
|
||||
: AUDIO_DECODER_ERROR_OTHER;
|
||||
}
|
||||
|
||||
void logError(const char *functionName, int errorNumber) {
|
||||
char *buffer = (char *)malloc(ERROR_STRING_BUFFER_LENGTH * sizeof(char));
|
||||
av_strerror(errorNumber, buffer, ERROR_STRING_BUFFER_LENGTH);
|
||||
|
Loading…
x
Reference in New Issue
Block a user