I tried the patch. Once av_assert0 test is removed, the crystalhd decoder is running till send_packet triggers AVERROR(EAGAIN), now the crystalhd buffer is likely overflowed, the video freezes. A few seconds later the decoder displays a few frames and the cycle goes on.
Im not sure how to properly implement the function to stop or resend send_packet frames, this is likely the only mechanism missing. Best Regards, Wallak. ----- Mail original ----- De: "Marton Balint" <c...@passwd.hu> À: "FFmpeg development discussions and patches" <ffmpeg-devel@ffmpeg.org> Cc: wal...@free.fr Envoyé: Jeudi 16 Mars 2017 23:25:18 Objet: Re: [FFmpeg-devel] [PATCH 2/3] ffplay: convert to new decode API On Wed, 15 Mar 2017, Marton Balint wrote: > Since subtitles are not yet supported with the new API, CODEC_CAP_DELAY > subtitle codecs (only libzvbi so far) may loose the last few buffered frames > in > the end of the stream. > > The impact of this is so limited, it seemded better to accept it than losing > the simplification benefits of the new API. Hi Wallak, Have you had a chance to test this ffplay patch, and see if it fixes CrystalHD decoding in ffplay or not? Thanks, Marton > > Signed-off-by: Marton Balint <c...@passwd.hu> > --- > ffplay.c | 92 +++++++++++++++++++++++++++++----------------------------------- > 1 file changed, 41 insertions(+), 51 deletions(-) > > diff --git a/ffplay.c b/ffplay.c > index cf138dc..06d1d22 100644 > --- a/ffplay.c > +++ b/ffplay.c > @@ -186,13 +186,10 @@ enum { > }; > > typedef struct Decoder { > - AVPacket pkt; > - AVPacket pkt_temp; > PacketQueue *queue; > AVCodecContext *avctx; > int pkt_serial; > int finished; > - int packet_pending; > SDL_cond *empty_queue_cond; > int64_t start_pts; > AVRational start_pts_tb; > @@ -551,40 +548,24 @@ static void decoder_init(Decoder *d, AVCodecContext > *avctx, PacketQueue *queue, > d->queue = queue; > d->empty_queue_cond = empty_queue_cond; > d->start_pts = AV_NOPTS_VALUE; > + d->pkt_serial = -1; > } > > static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) { > - int got_frame = 0; > + int ret = AVERROR(EAGAIN); > > - do { > - int ret = -1; > + for (;;) { > + AVPacket pkt; > > + if (d->queue->serial == d->pkt_serial) { > + do { > if (d->queue->abort_request) > return -1; > > - if (!d->packet_pending || d->queue->serial != d->pkt_serial) { > - AVPacket pkt; > - do { > - if (d->queue->nb_packets == 0) > - SDL_CondSignal(d->empty_queue_cond); > - if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0) > - return -1; > - if (pkt.data == flush_pkt.data) { > - avcodec_flush_buffers(d->avctx); > - d->finished = 0; > - d->next_pts = d->start_pts; > - d->next_pts_tb = d->start_pts_tb; > - } > - } while (pkt.data == flush_pkt.data || d->queue->serial != > d->pkt_serial); > - av_packet_unref(&d->pkt); > - d->pkt_temp = d->pkt = pkt; > - d->packet_pending = 1; > - } > - > switch (d->avctx->codec_type) { > case AVMEDIA_TYPE_VIDEO: > - ret = avcodec_decode_video2(d->avctx, frame, &got_frame, > &d->pkt_temp); > - if (got_frame) { > + ret = avcodec_receive_frame(d->avctx, frame); > + if (ret >= 0) { > if (decoder_reorder_pts == -1) { > frame->pts = > av_frame_get_best_effort_timestamp(frame); > } else if (!decoder_reorder_pts) { > @@ -593,8 +574,8 @@ static int decoder_decode_frame(Decoder *d, AVFrame > *frame, AVSubtitle *sub) { > } > break; > case AVMEDIA_TYPE_AUDIO: > - ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, > &d->pkt_temp); > - if (got_frame) { > + ret = avcodec_receive_frame(d->avctx, frame); > + if (ret >= 0) { > AVRational tb = (AVRational){1, frame->sample_rate}; > if (frame->pts != AV_NOPTS_VALUE) > frame->pts = av_rescale_q(frame->pts, > av_codec_get_pkt_timebase(d->avctx), tb); > @@ -606,37 +587,46 @@ static int decoder_decode_frame(Decoder *d, AVFrame > *frame, AVSubtitle *sub) { > } > } > break; > - case AVMEDIA_TYPE_SUBTITLE: > - ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, > &d->pkt_temp); > - break; > + } > + if (ret == AVERROR_EOF) { > + d->finished = d->pkt_serial; > + avcodec_flush_buffers(d->avctx); > + return 0; > + } > + if (ret >= 0) > + return 1; > + } while (ret != AVERROR(EAGAIN)); > } > > - if (ret < 0) { > - d->packet_pending = 0; > + do { > + if (d->queue->nb_packets == 0) > + SDL_CondSignal(d->empty_queue_cond); > + if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0) > + return -1; > + } while (d->queue->serial != d->pkt_serial); > + > + if (pkt.data == flush_pkt.data) { > + avcodec_flush_buffers(d->avctx); > + d->finished = 0; > + d->next_pts = d->start_pts; > + d->next_pts_tb = d->start_pts_tb; > } else { > - d->pkt_temp.dts = > - d->pkt_temp.pts = AV_NOPTS_VALUE; > - if (d->pkt_temp.data) { > - if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO) > - ret = d->pkt_temp.size; > - d->pkt_temp.data += ret; > - d->pkt_temp.size -= ret; > - if (d->pkt_temp.size <= 0) > - d->packet_pending = 0; > + if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) { > + int got_frame = 0; > + ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, > &pkt); > + if (ret < 0) > + ret = AVERROR(EAGAIN); > + else > + ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : > AVERROR_EOF); > } else { > - if (!got_frame) { > - d->packet_pending = 0; > - d->finished = d->pkt_serial; > - } > + av_assert0(avcodec_send_packet(d->avctx, &pkt) != > AVERROR(EAGAIN)); > } > + av_packet_unref(&pkt); > } > - } while (!got_frame && !d->finished); > - > - return got_frame; > + } > } > > static void decoder_destroy(Decoder *d) { > - av_packet_unref(&d->pkt); > avcodec_free_context(&d->avctx); > } > > -- > 2.10.2 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel