SDL_AMediaCodec* SDL_AMediaCodecDummy_create()
{
    ALOGI("%s\n", __func__);

    SDL_AMediaCodec *acodec = SDL_AMediaCodec_CreateInternal(sizeof(SDL_AMediaCodec_Opaque));
    if (!acodec)
        return NULL;

    SDL_AMediaCodec_Opaque *opaque = acodec->opaque;
    SDL_AMediaCodec_FakeFifo_init(&opaque->dummy_fifo);

    acodec->opaque_class                = &g_amediacodec_class;
    acodec->func_delete                 = SDL_AMediaCodecDummy_delete;
    acodec->func_configure              = NULL;
    acodec->func_configure_surface      = SDL_AMediaCodecDummy_configure_surface;

    acodec->func_start                  = SDL_AMediaCodecDummy_start;
    acodec->func_stop                   = SDL_AMediaCodecDummy_stop;
    acodec->func_flush                  = SDL_AMediaCodecDummy_flush;

    acodec->func_writeInputData         = SDL_AMediaCodecDummy_writeInputData;

    acodec->func_dequeueInputBuffer     = SDL_AMediaCodecDummy_dequeueInputBuffer;
    acodec->func_queueInputBuffer       = SDL_AMediaCodecDummy_queueInputBuffer;

    acodec->func_dequeueOutputBuffer    = SDL_AMediaCodecDummy_dequeueOutputBuffer;
    acodec->func_getOutputFormat        = SDL_AMediaCodecDummy_getOutputFormat;
    acodec->func_releaseOutputBuffer    = SDL_AMediaCodecDummy_releaseOutputBuffer;

    acodec->func_isInputBuffersValid    = SDL_AMediaCodecDummy_isInputBuffersValid;

    SDL_AMediaCodec_increaseReference(acodec);
    return acodec;
}
static void SDL_VoutAndroid_setAMediaCodec_l(SDL_Vout *vout, SDL_AMediaCodec *acodec)
{
    AMCTRACE("%s(%p)\n", __func__, acodec);
    SDL_Vout_Opaque *opaque = vout->opaque;
    if (opaque->acodec == acodec)
        return;

    SDL_VoutAndroid_invalidateAllBuffers_l(vout);

    SDL_AMediaCodec_decreaseReferenceP(&opaque->acodec);
    opaque->acodec = acodec;
    if (opaque->acodec)
        SDL_AMediaCodec_increaseReference(opaque->acodec);
}
int SDL_VoutOverlayAMediaCodec_attachFrame(
    SDL_VoutOverlay *overlay,
    SDL_AMediaCodec *acodec,
    int output_buffer_index,
    SDL_AMediaCodecBufferInfo *buffer_info)
{
    if (!check_object(overlay, __func__))
        return -1;

    SDL_VoutOverlay_Opaque *opaque = overlay->opaque;
    opaque->acodec        = acodec;
    opaque->buffer_index  = output_buffer_index;
    opaque->buffer_info   = *buffer_info;
    opaque->is_buffer_own = true;

    SDL_AMediaCodec_increaseReference(acodec);
    return 0;
}
static SDL_AMediaCodec* SDL_AMediaCodecJava_init(JNIEnv *env, jobject android_media_codec)
{
    SDLTRACE("%s", __func__);

    jobject global_android_media_codec = (*env)->NewGlobalRef(env, android_media_codec);
    if (SDL_JNI_CatchException(env) || !global_android_media_codec) {
        return NULL;
    }

    SDL_AMediaCodec *acodec = SDL_AMediaCodec_CreateInternal(sizeof(SDL_AMediaCodec_Opaque));
    if (!acodec) {
        SDL_JNI_DeleteGlobalRefP(env, &global_android_media_codec);
        return NULL;
    }

    SDL_AMediaCodec_Opaque *opaque = acodec->opaque;
    opaque->android_media_codec         = global_android_media_codec;

    acodec->opaque_class                = &g_amediacodec_class;
    acodec->func_delete                 = SDL_AMediaCodecJava_delete;
    acodec->func_configure              = NULL;
    acodec->func_configure_surface      = SDL_AMediaCodecJava_configure_surface;

    acodec->func_start                  = SDL_AMediaCodecJava_start;
    acodec->func_stop                   = SDL_AMediaCodecJava_stop;
    acodec->func_flush                  = SDL_AMediaCodecJava_flush;

    acodec->func_getInputBuffer         = SDL_AMediaCodecJava_getInputBuffer;
    acodec->func_getOutputBuffer        = SDL_AMediaCodecJava_getOutputBuffer;

    acodec->func_dequeueInputBuffer     = SDL_AMediaCodecJava_dequeueInputBuffer;
    acodec->func_queueInputBuffer       = SDL_AMediaCodecJava_queueInputBuffer;

    acodec->func_dequeueOutputBuffer    = SDL_AMediaCodecJava_dequeueOutputBuffer;
    acodec->func_getOutputFormat        = SDL_AMediaCodecJava_getOutputFormat;
    acodec->func_releaseOutputBuffer    = SDL_AMediaCodecJava_releaseOutputBuffer;

    acodec->func_isInputBuffersValid    = SDL_AMediaCodecJava_isInputBuffersValid;

    SDL_AMediaCodec_increaseReference(acodec);
    return acodec;
}