static void libav_video_eof(media_codec_t *mc, video_decoder_t *vd, struct media_queue *mq) { int got_pic = 0; media_pipe_t *mp = vd->vd_mp; AVCodecContext *ctx = mc->ctx; AVFrame *frame = vd->vd_frame; AVPacket avpkt; int t; av_init_packet(&avpkt); avpkt.data = NULL; avpkt.size = 0; while(1) { avgtime_start(&vd->vd_decode_time); avcodec_decode_video2(ctx, vd->vd_frame, &got_pic, &avpkt); t = avgtime_stop(&vd->vd_decode_time, mq->mq_prop_decode_avg, mq->mq_prop_decode_peak); if(!got_pic) break; const media_buf_meta_t *mbm = &vd->vd_reorder[frame->reordered_opaque]; if(!mbm->mbm_skip) libav_deliver_frame(vd, mp, mq, ctx, frame, mbm, t, mc); av_frame_unref(frame); }; avcodec_flush_buffers(ctx); }
static void vd_decode_video(video_decoder_t *vd, media_queue_t *mq, media_buf_t *mb) { int got_pic = 0; media_pipe_t *mp = vd->vd_mp; media_codec_t *cw = mb->mb_cw; AVCodecContext *ctx = cw->codec_ctx; AVFrame *frame = vd->vd_frame; int t; if(vd->vd_do_flush) { AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = NULL; avpkt.size = 0; do { avcodec_decode_video2(ctx, frame, &got_pic, &avpkt); } while(got_pic); vd->vd_do_flush = 0; vd->vd_prevpts = AV_NOPTS_VALUE; vd->vd_nextpts = AV_NOPTS_VALUE; vd->vd_estimated_duration = 0; avcodec_flush_buffers(ctx); vd->vd_compensate_thres = 5; } ctx->opaque = mb; ctx->get_buffer = vd_get_buffer; ctx->release_buffer = vd_release_buffer; /* * If we are seeking, drop any non-reference frames */ ctx->skip_frame = mb->mb_skip == 1 ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; avgtime_start(&vd->vd_decode_time); AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = mb->mb_data; avpkt.size = mb->mb_size; avcodec_decode_video2(ctx, frame, &got_pic, &avpkt); t = avgtime_stop(&vd->vd_decode_time, mq->mq_prop_decode_avg, mq->mq_prop_decode_peak); if(mp->mp_stats) mp_set_mq_meta(mq, cw->codec, cw->codec_ctx); mb = frame->opaque; if(got_pic == 0 || mb->mb_skip == 1) return; vd->vd_skip = 0; video_deliver_frame(vd, mp, mq, ctx, frame, mb, t); }
static void libav_decode_video(struct media_codec *mc, struct video_decoder *vd, struct media_queue *mq, struct media_buf *mb, int reqsize) { int got_pic = 0; media_pipe_t *mp = vd->vd_mp; AVCodecContext *ctx = mc->ctx; AVFrame *frame = vd->vd_frame; int t; vd->vd_reorder[vd->vd_reorder_ptr] = mb->mb_meta; ctx->reordered_opaque = vd->vd_reorder_ptr; vd->vd_reorder_ptr = (vd->vd_reorder_ptr + 1) & VIDEO_DECODER_REORDER_MASK; /* * If we are seeking, drop any non-reference frames */ ctx->skip_frame = mb->mb_skip == 1 ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; avgtime_start(&vd->vd_decode_time); AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = mb->mb_data; avpkt.size = mb->mb_size; avcodec_decode_video2(ctx, frame, &got_pic, &avpkt); t = avgtime_stop(&vd->vd_decode_time, mq->mq_prop_decode_avg, mq->mq_prop_decode_peak); if(mp->mp_stats) mp_set_mq_meta(mq, ctx->codec, ctx); const media_buf_meta_t *mbm = &vd->vd_reorder[frame->reordered_opaque]; if(got_pic == 0 || mbm->mbm_skip == 1) return; video_deliver_frame_avctx(vd, mp, mq, ctx, frame, mbm, t); }
static void libav_decode_video(struct media_codec *mc, struct video_decoder *vd, struct media_queue *mq, struct media_buf *mb, int reqsize) { int got_pic = 0; media_pipe_t *mp = vd->vd_mp; AVCodecContext *ctx = mc->ctx; AVFrame *frame = vd->vd_frame; int t; if(mb->mb_flush) libav_video_eof(mc, vd, mq); copy_mbm_from_mb(&vd->vd_reorder[vd->vd_reorder_ptr], mb); ctx->reordered_opaque = vd->vd_reorder_ptr; vd->vd_reorder_ptr = (vd->vd_reorder_ptr + 1) & VIDEO_DECODER_REORDER_MASK; /* * If we are seeking, drop any non-reference frames */ ctx->skip_frame = mb->mb_skip == 1 ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; avgtime_start(&vd->vd_decode_time); avcodec_decode_video2(ctx, frame, &got_pic, &mb->mb_pkt); t = avgtime_stop(&vd->vd_decode_time, mq->mq_prop_decode_avg, mq->mq_prop_decode_peak); if(mp->mp_stats) mp_set_mq_meta(mq, ctx->codec, ctx); if(got_pic == 0) return; const media_buf_meta_t *mbm = &vd->vd_reorder[frame->reordered_opaque]; if(!mbm->mbm_skip) libav_deliver_frame(vd, mp, mq, ctx, frame, mbm, t, mc); av_frame_unref(frame); }