static int reconfigure_codec_l(JNIEnv *env, IJKFF_Pipenode *node) { IJKFF_Pipenode_Opaque *opaque = node->opaque; IJKFF_Pipeline *pipeline = opaque->pipeline; int ret = 0; sdl_amedia_status_t amc_ret = 0; jobject prev_jsurface = NULL; ffpipeline_set_surface_need_reconfigure(pipeline, false); prev_jsurface = opaque->jsurface; opaque->jsurface = ffpipeline_get_surface_as_global_ref(env, pipeline); SDL_JNI_DeleteGlobalRefP(env, &prev_jsurface); if (!opaque->acodec) { opaque->acodec = create_codec_l(env, node); if (!opaque->acodec) { ALOGE("%s:open_video_decoder: create_codec failed\n", __func__); ret = -1; goto fail; } } if (SDL_AMediaCodec_isConfigured(opaque->acodec)) { if (opaque->acodec) { if (SDL_AMediaCodec_isStarted(opaque->acodec)) { SDL_AMediaCodec_stop(opaque->acodec); } if (opaque->quirk_reconfigure_with_new_codec) { ALOGI("quirk: reconfigure with new codec"); SDL_AMediaCodec_decreaseReferenceP(&opaque->acodec); opaque->acodec = create_codec_l(env, node); if (!opaque->acodec) { ALOGE("%s:open_video_decoder: create_codec failed\n", __func__); ret = -1; goto fail; } } } assert(opaque->weak_vout); SDL_VoutAndroid_setAMediaCodec(opaque->weak_vout, opaque->acodec); } amc_ret = SDL_AMediaCodec_configure_surface(env, opaque->acodec, opaque->input_aformat, opaque->jsurface, NULL, 0); if (amc_ret != SDL_AMEDIA_OK) { ALOGE("%s:configure_surface: failed\n", __func__); ret = -1; goto fail; } SDL_AMediaCodec_start(opaque->acodec); opaque->acodec_first_dequeue_output_request = true; fail: return ret; }
static int func_run_sync(IJKFF_Pipenode *node) { JNIEnv *env = NULL; IJKFF_Pipenode_Opaque *opaque = node->opaque; FFPlayer *ffp = opaque->ffp; VideoState *is = ffp->is; int ret = 0; int dequeue_count = 0; if (!opaque->acodec) { return ffp_video_thread(ffp); } if (JNI_OK != SDL_JNI_SetupThreadEnv(&env)) { ALOGE("%s: SetupThreadEnv failed\n", __func__); return -1; } opaque->frame_width = opaque->avctx->width; opaque->frame_height = opaque->avctx->height; ffpipeline_set_surface_need_reconfigure(opaque->pipeline, true); ret = reconfigure_codec_l(env, node); if (ret != 0) { ALOGE("%s: reconfigure_codec failed\n", __func__); goto fail; } opaque->enqueue_thread = SDL_CreateThreadEx(&opaque->_enqueue_thread, enqueue_thread_func, node, "amediacodec_input_thread"); if (!opaque->enqueue_thread) { ALOGE("%s: SDL_CreateThreadEx failed\n", __func__); ret = -1; goto fail; } while (!is->abort_request) { int64_t timeUs = opaque->acodec_first_dequeue_output_request ? 0 : AMC_OUTPUT_TIMEOUT_US; ret = drain_output_buffer(env, node, timeUs, &dequeue_count); if (opaque->acodec_first_dequeue_output_request) { SDL_LockMutex(opaque->acodec_first_dequeue_output_mutex); opaque->acodec_first_dequeue_output_request = false; SDL_CondSignal(opaque->acodec_first_dequeue_output_cond); SDL_UnlockMutex(opaque->acodec_first_dequeue_output_mutex); } if (ret != 0) { ret = -1; goto fail; } } fail: ffp_packet_queue_abort(&opaque->fake_pictq); if (opaque->acodec) SDL_AMediaCodec_stop(opaque->acodec); SDL_WaitThread(opaque->enqueue_thread, NULL); SDL_AMediaCodec_decreaseReferenceP(&opaque->acodec); ALOGI("MediaCodec: %s: exit: %d", __func__, ret); return ret; #if 0 fallback_to_ffplay: ALOGW("fallback to ffplay decoder\n"); return ffp_video_thread(opaque->ffp); #endif }