static int func_run_sync(IJKFF_Pipenode *node) { IJKFF_Pipenode_Opaque *opaque = node->opaque; return ffp_video_thread(opaque->ffp); }
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; Decoder *d = &is->viddec; PacketQueue *q = d->queue; 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; } if (opaque->frame_rotate_degrees == 90 || opaque->frame_rotate_degrees == 270) { opaque->frame_width = opaque->avctx->height; opaque->frame_height = opaque->avctx->width; } else { opaque->frame_width = opaque->avctx->width; opaque->frame_height = opaque->avctx->height; } 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 (!q->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->n_buf_out) { int i; if (opaque->acodec) { for (i = 0; i < opaque->n_buf_out; i++) { if (opaque->amc_buf_out[i].pts != AV_NOPTS_VALUE) SDL_AMediaCodec_releaseOutputBuffer(opaque->acodec, opaque->amc_buf_out[i].port, false); } } free(opaque->amc_buf_out); opaque->n_buf_out = 0; opaque->amc_buf_out = NULL; opaque->off_buf_out = 0; opaque->last_queued_pts = AV_NOPTS_VALUE; } if (opaque->acodec) SDL_AMediaCodec_stop(opaque->acodec); SDL_WaitThread(opaque->enqueue_thread, NULL); 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 }
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; Decoder *d = &is->viddec; PacketQueue *q = d->queue; int ret = 0; int dequeue_count = 0; AVFrame *frame = NULL; int got_frame = 0; AVRational tb = is->video_st->time_base; AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, NULL); double duration; double pts; if (!opaque->acodec) { return ffp_video_thread(ffp); } if (JNI_OK != SDL_JNI_SetupThreadEnv(&env)) { ALOGE("%s: SetupThreadEnv failed\n", __func__); return -1; } frame = av_frame_alloc(); if (!frame) goto fail; if (opaque->frame_rotate_degrees == 90 || opaque->frame_rotate_degrees == 270) { opaque->frame_width = opaque->avctx->height; opaque->frame_height = opaque->avctx->width; } else { opaque->frame_width = opaque->avctx->width; opaque->frame_height = opaque->avctx->height; } 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 (!q->abort_request) { int64_t timeUs = opaque->acodec_first_dequeue_output_request ? 0 : AMC_OUTPUT_TIMEOUT_US; got_frame = 0; ret = drain_output_buffer(env, node, timeUs, &dequeue_count, frame, &got_frame); 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; if (got_frame && frame->opaque) SDL_VoutAndroid_releaseBufferProxyP(opaque->weak_vout, (SDL_AMediaCodecBufferProxy **)&frame->opaque, false); goto fail; } if (got_frame) { duration = (frame_rate.num && frame_rate.den ? av_q2d((AVRational){frame_rate.den, frame_rate.num}) : 0); pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb); ret = ffp_queue_picture(ffp, frame, pts, duration, av_frame_get_pkt_pos(frame), is->viddec.pkt_serial); if (ret) { if (frame->opaque) SDL_VoutAndroid_releaseBufferProxyP(opaque->weak_vout, (SDL_AMediaCodecBufferProxy **)&frame->opaque, false); } av_frame_unref(frame); } } fail: av_frame_free(&frame); SDL_AMediaCodecFake_abort(opaque->acodec); if (opaque->n_buf_out) { free(opaque->amc_buf_out); opaque->n_buf_out = 0; opaque->amc_buf_out = NULL; opaque->off_buf_out = 0; opaque->last_queued_pts = AV_NOPTS_VALUE; } if (opaque->acodec) { SDL_VoutAndroid_invalidateAllBuffers(opaque->weak_vout); SDL_LockMutex(opaque->acodec_mutex); SDL_AMediaCodec_stop(opaque->acodec); SDL_UnlockMutex(opaque->acodec_mutex); } 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 }