Commit 85766391 authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

mediacodec: don't loop in GetOutput

DecodeVideo is already looping.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 9d997cdf
...@@ -849,179 +849,156 @@ static int PutInput(decoder_t *p_dec, JNIEnv *env, block_t **pp_block, jlong tim ...@@ -849,179 +849,156 @@ static int PutInput(decoder_t *p_dec, JNIEnv *env, block_t **pp_block, jlong tim
static int GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, jlong timeout) static int GetOutput(decoder_t *p_dec, JNIEnv *env, picture_t **pp_pic, jlong timeout)
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
while (1) { int index = (*env)->CallIntMethod(env, p_sys->codec, p_sys->dequeue_output_buffer,
int index = (*env)->CallIntMethod(env, p_sys->codec, p_sys->dequeue_output_buffer, p_sys->buffer_info, timeout);
p_sys->buffer_info, timeout); if (CHECK_EXCEPTION()) {
if (CHECK_EXCEPTION()) { msg_Err(p_dec, "Exception in MediaCodec.dequeueOutputBuffer (GetOutput)");
msg_Err(p_dec, "Exception in MediaCodec.dequeueOutputBuffer (GetOutput)"); return -1;
return -1; }
}
if (index >= 0) {
if (!p_sys->pixel_format) {
msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
if (ReleaseOutputBuffer(p_dec, env, index, false) != 0)
return -1;
continue;
}
if (!*pp_pic) {
*pp_pic = decoder_NewPicture(p_dec);
} else if (p_sys->direct_rendering) {
picture_t *p_pic = *pp_pic;
picture_sys_t *p_picsys = p_pic->p_sys;
int i_prev_index = p_picsys->priv.hw.i_index;
if (ReleaseOutputBuffer(p_dec, env, i_prev_index, false) != 0)
return -1;
// No need to lock here since the previous picture was not sent. if (index >= 0) {
InsertInflightPicture(p_dec, NULL, i_prev_index); if (!p_sys->pixel_format) {
} msg_Warn(p_dec, "Buffers returned before output format is set, dropping frame");
if (*pp_pic) { return ReleaseOutputBuffer(p_dec, env, index, false);
}
picture_t *p_pic = *pp_pic;
/* If the oldest input block had no PTS, the timestamp
* of the frame returned by MediaCodec might be wrong
* so we overwrite it with the corresponding dts. */
int64_t forced_ts = timestamp_FifoGet(p_sys->timestamp_fifo);
if (forced_ts == VLC_TS_INVALID)
p_pic->date = (*env)->GetLongField(env, p_sys->buffer_info, p_sys->pts_field);
else
p_pic->date = forced_ts;
if (p_sys->direct_rendering) { *pp_pic = decoder_NewPicture(p_dec);
picture_sys_t *p_picsys = p_pic->p_sys; if (!*pp_pic) {
p_picsys->pf_lock_pic = NULL; msg_Warn(p_dec, "NewPicture failed");
p_picsys->pf_unlock_pic = UnlockPicture; return ReleaseOutputBuffer(p_dec, env, index, false);
p_picsys->priv.hw.p_dec = p_dec; }
p_picsys->priv.hw.i_index = index; picture_t *p_pic = *pp_pic;
p_picsys->priv.hw.b_valid = true; /* If the oldest input block had no PTS, the timestamp
* of the frame returned by MediaCodec might be wrong
vlc_mutex_lock(get_android_opaque_mutex()); * so we overwrite it with the corresponding dts. */
InsertInflightPicture(p_dec, p_pic, index); int64_t forced_ts = timestamp_FifoGet(p_sys->timestamp_fifo);
vlc_mutex_unlock(get_android_opaque_mutex()); if (forced_ts == VLC_TS_INVALID)
} else { p_pic->date = (*env)->GetLongField(env, p_sys->buffer_info, p_sys->pts_field);
jobject buf; else
if (p_sys->get_output_buffers) p_pic->date = forced_ts;
buf = (*env)->GetObjectArrayElement(env, p_sys->output_buffers, index);
else if (p_sys->direct_rendering) {
buf = (*env)->CallObjectMethod(env, p_sys->codec, picture_sys_t *p_picsys = p_pic->p_sys;
p_sys->get_output_buffer, index); p_picsys->pf_lock_pic = NULL;
//jsize buf_size = (*env)->GetDirectBufferCapacity(env, buf); p_picsys->pf_unlock_pic = UnlockPicture;
uint8_t *ptr = (*env)->GetDirectBufferAddress(env, buf); p_picsys->priv.hw.p_dec = p_dec;
p_picsys->priv.hw.i_index = index;
//int size = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->size_field); p_picsys->priv.hw.b_valid = true;
int offset = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->offset_field);
ptr += offset; // Check the size parameter as well vlc_mutex_lock(get_android_opaque_mutex());
InsertInflightPicture(p_dec, p_pic, index);
unsigned int chroma_div; vlc_mutex_unlock(get_android_opaque_mutex());
GetVlcChromaSizes(p_dec->fmt_out.i_codec, p_dec->fmt_out.video.i_width, } else {
p_dec->fmt_out.video.i_height, NULL, NULL, &chroma_div); jobject buf;
CopyOmxPicture(p_sys->pixel_format, p_pic, p_sys->slice_height, p_sys->stride, if (p_sys->get_output_buffers)
ptr, chroma_div, &p_sys->architecture_specific_data); buf = (*env)->GetObjectArrayElement(env, p_sys->output_buffers, index);
(*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer, index, false); else
buf = (*env)->CallObjectMethod(env, p_sys->codec,
jthrowable exception = (*env)->ExceptionOccurred(env); p_sys->get_output_buffer, index);
if (exception != NULL) { //jsize buf_size = (*env)->GetDirectBufferCapacity(env, buf);
jclass illegalStateException = (*env)->FindClass(env, "java/lang/IllegalStateException"); uint8_t *ptr = (*env)->GetDirectBufferAddress(env, buf);
if((*env)->IsInstanceOf(env, exception, illegalStateException)) {
msg_Err(p_dec, "Codec error (IllegalStateException) in MediaCodec.releaseOutputBuffer"); //int size = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->size_field);
(*env)->ExceptionClear(env); int offset = (*env)->GetIntField(env, p_sys->buffer_info, p_sys->offset_field);
(*env)->DeleteLocalRef(env, illegalStateException); ptr += offset; // Check the size parameter as well
(*env)->DeleteLocalRef(env, buf);
return -1; unsigned int chroma_div;
} GetVlcChromaSizes(p_dec->fmt_out.i_codec, p_dec->fmt_out.video.i_width,
} p_dec->fmt_out.video.i_height, NULL, NULL, &chroma_div);
CopyOmxPicture(p_sys->pixel_format, p_pic, p_sys->slice_height, p_sys->stride,
ptr, chroma_div, &p_sys->architecture_specific_data);
(*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer, index, false);
jthrowable exception = (*env)->ExceptionOccurred(env);
if (exception != NULL) {
jclass illegalStateException = (*env)->FindClass(env, "java/lang/IllegalStateException");
if((*env)->IsInstanceOf(env, exception, illegalStateException)) {
msg_Err(p_dec, "Codec error (IllegalStateException) in MediaCodec.releaseOutputBuffer");
(*env)->ExceptionClear(env);
(*env)->DeleteLocalRef(env, illegalStateException);
(*env)->DeleteLocalRef(env, buf); (*env)->DeleteLocalRef(env, buf);
}
} else {
msg_Warn(p_dec, "NewPicture failed");
if (ReleaseOutputBuffer(p_dec, env, index, false) != 0)
return -1; return -1;
}
} }
(*env)->DeleteLocalRef(env, buf);
}
} else if (index == INFO_OUTPUT_BUFFERS_CHANGED) {
msg_Dbg(p_dec, "output buffers changed");
if (!p_sys->get_output_buffers)
return 0; return 0;
(*env)->DeleteGlobalRef(env, p_sys->output_buffers);
} else if (index == INFO_OUTPUT_BUFFERS_CHANGED) { p_sys->output_buffers = (*env)->CallObjectMethod(env, p_sys->codec,
msg_Dbg(p_dec, "output buffers changed"); p_sys->get_output_buffers);
if (!p_sys->get_output_buffers) if (CHECK_EXCEPTION()) {
continue; msg_Err(p_dec, "Exception in MediaCodec.getOutputBuffer (GetOutput)");
(*env)->DeleteGlobalRef(env, p_sys->output_buffers); p_sys->output_buffers = NULL;
return -1;
}
p_sys->output_buffers = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->output_buffers = (*env)->NewGlobalRef(env, p_sys->output_buffers);
p_sys->get_output_buffers); } else if (index == INFO_OUTPUT_FORMAT_CHANGED) {
if (CHECK_EXCEPTION()) { jobject format = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_output_format);
msg_Err(p_dec, "Exception in MediaCodec.getOutputBuffer (GetOutput)"); if (CHECK_EXCEPTION()) {
p_sys->output_buffers = NULL; msg_Err(p_dec, "Exception in MediaCodec.getOutputFormat (GetOutput)");
return -1; return -1;
} }
p_sys->output_buffers = (*env)->NewGlobalRef(env, p_sys->output_buffers); jobject format_string = (*env)->CallObjectMethod(env, format, p_sys->tostring);
} else if (index == INFO_OUTPUT_FORMAT_CHANGED) {
jobject format = (*env)->CallObjectMethod(env, p_sys->codec, p_sys->get_output_format); jsize format_len = (*env)->GetStringUTFLength(env, format_string);
if (CHECK_EXCEPTION()) { const char *format_ptr = (*env)->GetStringUTFChars(env, format_string, NULL);
msg_Err(p_dec, "Exception in MediaCodec.getOutputFormat (GetOutput)"); msg_Dbg(p_dec, "output format changed: %.*s", format_len, format_ptr);
(*env)->ReleaseStringUTFChars(env, format_string, format_ptr);
ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
int width = GET_INTEGER(format, "width");
int height = GET_INTEGER(format, "height");
p_sys->stride = GET_INTEGER(format, "stride");
p_sys->slice_height = GET_INTEGER(format, "slice-height");
p_sys->pixel_format = GET_INTEGER(format, "color-format");
int crop_left = GET_INTEGER(format, "crop-left");
int crop_top = GET_INTEGER(format, "crop-top");
int crop_right = GET_INTEGER(format, "crop-right");
int crop_bottom = GET_INTEGER(format, "crop-bottom");
const char *name = "unknown";
if (!p_sys->direct_rendering) {
if (!GetVlcChromaFormat(p_sys->pixel_format,
&p_dec->fmt_out.i_codec, &name)) {
msg_Err(p_dec, "color-format not recognized");
return -1; return -1;
} }
}
jobject format_string = (*env)->CallObjectMethod(env, format, p_sys->tostring); msg_Err(p_dec, "output: %d %s, %dx%d stride %d %d, crop %d %d %d %d",
p_sys->pixel_format, name, width, height, p_sys->stride, p_sys->slice_height,
jsize format_len = (*env)->GetStringUTFLength(env, format_string); crop_left, crop_top, crop_right, crop_bottom);
const char *format_ptr = (*env)->GetStringUTFChars(env, format_string, NULL);
msg_Dbg(p_dec, "output format changed: %.*s", format_len, format_ptr);
(*env)->ReleaseStringUTFChars(env, format_string, format_ptr);
ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
int width = GET_INTEGER(format, "width");
int height = GET_INTEGER(format, "height");
p_sys->stride = GET_INTEGER(format, "stride");
p_sys->slice_height = GET_INTEGER(format, "slice-height");
p_sys->pixel_format = GET_INTEGER(format, "color-format");
int crop_left = GET_INTEGER(format, "crop-left");
int crop_top = GET_INTEGER(format, "crop-top");
int crop_right = GET_INTEGER(format, "crop-right");
int crop_bottom = GET_INTEGER(format, "crop-bottom");
const char *name = "unknown";
if (!p_sys->direct_rendering) {
if (!GetVlcChromaFormat(p_sys->pixel_format,
&p_dec->fmt_out.i_codec, &name)) {
msg_Err(p_dec, "color-format not recognized");
return -1;
}
}
msg_Err(p_dec, "output: %d %s, %dx%d stride %d %d, crop %d %d %d %d",
p_sys->pixel_format, name, width, height, p_sys->stride, p_sys->slice_height,
crop_left, crop_top, crop_right, crop_bottom);
p_dec->fmt_out.video.i_width = crop_right + 1 - crop_left; p_dec->fmt_out.video.i_width = crop_right + 1 - crop_left;
p_dec->fmt_out.video.i_height = crop_bottom + 1 - crop_top; p_dec->fmt_out.video.i_height = crop_bottom + 1 - crop_top;
if (p_dec->fmt_out.video.i_width <= 1 if (p_dec->fmt_out.video.i_width <= 1
|| p_dec->fmt_out.video.i_height <= 1) { || p_dec->fmt_out.video.i_height <= 1) {
p_dec->fmt_out.video.i_width = width; p_dec->fmt_out.video.i_width = width;
p_dec->fmt_out.video.i_height = height; p_dec->fmt_out.video.i_height = height;
} }
p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width; p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width;
p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height; p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height;
if (p_sys->stride <= 0) if (p_sys->stride <= 0)
p_sys->stride = width; p_sys->stride = width;
if (p_sys->slice_height <= 0) if (p_sys->slice_height <= 0)
p_sys->slice_height = height; p_sys->slice_height = height;
CHECK_EXCEPTION(); CHECK_EXCEPTION();
ArchitectureSpecificCopyHooks(p_dec, p_sys->pixel_format, p_sys->slice_height, ArchitectureSpecificCopyHooks(p_dec, p_sys->pixel_format, p_sys->slice_height,
p_sys->stride, &p_sys->architecture_specific_data); p_sys->stride, &p_sys->architecture_specific_data);
if (p_sys->pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar) if (p_sys->pixel_format == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar)
p_sys->slice_height -= crop_top/2; p_sys->slice_height -= crop_top/2;
if (IgnoreOmxDecoderPadding(p_sys->name)) { if (IgnoreOmxDecoderPadding(p_sys->name)) {
p_sys->slice_height = 0; p_sys->slice_height = 0;
p_sys->stride = p_dec->fmt_out.video.i_width; p_sys->stride = p_dec->fmt_out.video.i_width;
}
} else {
return 0;
} }
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment