Message ID | 20170330150536.13390-1-nfxjfg@googlemail.com |
---|---|
State | Accepted |
Commit | 2a88ebd096f3c748a2d99ed1b60b22879b3c567c |
Headers | show |
On Thu, Mar 30, 2017 at 05:05:36PM +0200, wm4 wrote: > Not sure if it behaves ideally in presence of decoding errors. > --- > The original version of this patch is actually 1 year old. > --- > ffprobe.c | 42 +++++++++++++++++++++++++++++------------- > 1 file changed, 29 insertions(+), 13 deletions(-) changes: http://samples.mplayerhq.hu/A-codecs/WMA/wav/FLCL_Ending_My.wav ./ffprobe -v 0 -show_frames -of compact=nk=1:p=0 ~/tickets/1905/FLCL_Ending_My.wav after the patch there are alot of "N/A" in the output where numbers where before [...]
On Fri, 31 Mar 2017 03:49:16 +0200 Michael Niedermayer <michael@niedermayer.cc> wrote: > On Thu, Mar 30, 2017 at 05:05:36PM +0200, wm4 wrote: > > Not sure if it behaves ideally in presence of decoding errors. > > --- > > The original version of this patch is actually 1 year old. > > --- > > ffprobe.c | 42 +++++++++++++++++++++++++++++------------- > > 1 file changed, 29 insertions(+), 13 deletions(-) > > changes: > http://samples.mplayerhq.hu/A-codecs/WMA/wav/FLCL_Ending_My.wav > ./ffprobe -v 0 -show_frames -of compact=nk=1:p=0 ~/tickets/1905/FLCL_Ending_My.wav > > after the patch there are alot of "N/A" in the output where numbers > where before This is just what the API returns. It has nothing to do with this patch. One packet results in multiple frames in this case, and with the new decode API, the timestamp fields in subsequent frames have the timestamp fields unset, while the old API duplicates the ones from the first frame of a packet. This in turn happens because the "emulation" code in utils.c resets the timestamps on subsequent frames explicitly: avctx->internal->buffer_pkt->pts = AV_NOPTS_VALUE; avctx->internal->buffer_pkt->dts = AV_NOPTS_VALUE; So this is very much by design, and I think the result with the new API is better too. (Old API users probably had to explicitly handle this case themselves, because nobody wants non-increasing timestamps.)
On Fri, 31 Mar 2017 03:49:16 +0200 Michael Niedermayer <michael@niedermayer.cc> wrote: > On Thu, Mar 30, 2017 at 05:05:36PM +0200, wm4 wrote: > > Not sure if it behaves ideally in presence of decoding errors. > > --- > > The original version of this patch is actually 1 year old. > > --- > > ffprobe.c | 42 +++++++++++++++++++++++++++++------------- > > 1 file changed, 29 insertions(+), 13 deletions(-) > > changes: > http://samples.mplayerhq.hu/A-codecs/WMA/wav/FLCL_Ending_My.wav > ./ffprobe -v 0 -show_frames -of compact=nk=1:p=0 ~/tickets/1905/FLCL_Ending_My.wav > > after the patch there are alot of "N/A" in the output where numbers > where before > > [...] Pushed.
diff --git a/ffprobe.c b/ffprobe.c index fa60894833..c35d4cfcd9 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -2134,7 +2134,8 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, static av_always_inline int process_frame(WriterContext *w, InputFile *ifile, - AVFrame *frame, AVPacket *pkt) + AVFrame *frame, AVPacket *pkt, + int *packet_new) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; AVCodecContext *dec_ctx = ifile->streams[pkt->stream_index].dec_ctx; @@ -2146,24 +2147,39 @@ static av_always_inline int process_frame(WriterContext *w, if (dec_ctx && dec_ctx->codec) { switch (par->codec_type) { case AVMEDIA_TYPE_VIDEO: - ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, pkt); - break; - case AVMEDIA_TYPE_AUDIO: - ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt); + if (*packet_new) { + ret = avcodec_send_packet(dec_ctx, pkt); + if (ret == AVERROR(EAGAIN)) { + ret = 0; + } else if (ret >= 0 || ret == AVERROR_EOF) { + ret = 0; + *packet_new = 0; + } + } + if (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + if (ret >= 0) { + got_frame = 1; + } else if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + ret = 0; + } + } break; case AVMEDIA_TYPE_SUBTITLE: ret = avcodec_decode_subtitle2(dec_ctx, &sub, &got_frame, pkt); + *packet_new = 0; break; + default: + *packet_new = 0; } + } else { + *packet_new = 0; } if (ret < 0) return ret; - ret = FFMIN(ret, pkt->size); /* guard against bogus return values */ - pkt->data += ret; - pkt->size -= ret; if (got_frame) { int is_sub = (par->codec_type == AVMEDIA_TYPE_SUBTITLE); nb_streams_frames[pkt->stream_index]++; @@ -2175,7 +2191,7 @@ static av_always_inline int process_frame(WriterContext *w, if (is_sub) avsubtitle_free(&sub); } - return got_frame; + return got_frame || *packet_new; } static void log_read_interval(const ReadInterval *interval, void *log_ctx, int log_level) @@ -2206,7 +2222,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, const ReadInterval *interval, int64_t *cur_ts) { AVFormatContext *fmt_ctx = ifile->fmt_ctx; - AVPacket pkt, pkt1; + AVPacket pkt; AVFrame *frame = NULL; int ret = 0, i = 0, frame_count = 0; int64_t start = -INT64_MAX, end = interval->end; @@ -2283,8 +2299,8 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, nb_streams_packets[pkt.stream_index]++; } if (do_read_frames) { - pkt1 = pkt; - while (pkt1.size && process_frame(w, ifile, frame, &pkt1) > 0); + int packet_new = 1; + while (process_frame(w, ifile, frame, &pkt, &packet_new) > 0); } } av_packet_unref(&pkt); @@ -2296,7 +2312,7 @@ static int read_interval_packets(WriterContext *w, InputFile *ifile, for (i = 0; i < fmt_ctx->nb_streams; i++) { pkt.stream_index = i; if (do_read_frames) - while (process_frame(w, ifile, frame, &pkt) > 0); + while (process_frame(w, ifile, frame, &pkt, &(int){1}) > 0); } end: