static void func_destroy(IJKFF_Pipenode *node)
{
    if (!node || !node->opaque)
        return;

    IJKFF_Pipenode_Opaque *opaque = node->opaque;

    SDL_DestroyCondP(&opaque->acodec_cond);
    SDL_DestroyMutexP(&opaque->acodec_mutex);
    SDL_DestroyCondP(&opaque->acodec_first_dequeue_output_cond);
    SDL_DestroyMutexP(&opaque->acodec_first_dequeue_output_mutex);

    SDL_AMediaCodec_decreaseReferenceP(&opaque->acodec);
    SDL_AMediaFormat_deleteP(&opaque->input_aformat);
    SDL_AMediaFormat_deleteP(&opaque->output_aformat);

#if AMC_USE_AVBITSTREAM_FILTER
    av_freep(&opaque->orig_extradata);
#endif

    ffp_packet_queue_destroy(&opaque->fake_pictq);

    if (opaque->bsfc) {
        av_bitstream_filter_close(opaque->bsfc);
        opaque->bsfc = NULL;
    }

    JNIEnv *env = NULL;
    if (JNI_OK == SDL_JNI_SetupThreadEnv(&env)) {
        SDL_JNI_DeleteGlobalRefP(env, &opaque->jsurface);
    }
}
void SDL_AMediaCodec_FakeFifo_destroy(SDL_AMediaCodec_FakeFifo *fifo)
{
    if (!fifo)
        return;

    if (fifo->mutex)
        SDL_AMediaCodec_FakeFifo_abort(fifo);

    SDL_DestroyMutexP(&fifo->mutex);
    SDL_DestroyCondP(&fifo->wakeup_enqueue_cond);
    SDL_DestroyCondP(&fifo->wakeup_dequeue_cond);

    memset(fifo, 0, sizeof(SDL_AMediaCodec_FakeFifo));
}
static void aout_free_l(SDL_Aout *aout)
{
    SDLTRACE("%s\n", __func__);
    if (!aout)
        return;

    aout_close_audio(aout);

    SDL_Aout_Opaque *opaque = aout->opaque;

    if (opaque->slOutputMixObject) {
        (*opaque->slOutputMixObject)->Destroy(opaque->slOutputMixObject);
        opaque->slOutputMixObject = NULL;
    }

    opaque->slEngine = NULL;
    if (opaque->slObject) {
        (*opaque->slObject)->Destroy(opaque->slObject);
        opaque->slObject = NULL;
    }

    SDL_DestroyCondP(&opaque->wakeup_cond);
    SDL_DestroyMutexP(&opaque->wakeup_mutex);

    SDL_Aout_FreeInternal(aout);
}