Message ID | 1470144262-13167-5-git-send-email-sebechlebskyjan@gmail.com |
---|---|
State | Superseded |
Headers | show |
On Tue, Aug 02, 2016 at 03:24:15PM +0200, sebechlebskyjan@gmail.com wrote: > From: Jan Sebechlebsky <sebechlebskyjan@gmail.com> > > This makes av_write_trailer not to free the resources if write_trailer > call returns AVERROR(EAGAIN) allowing repeated calls of write_trailer of > non-blocking muxer. > > Signed-off-by: Jan Sebechlebsky <sebechlebskyjan@gmail.com> > --- > libavformat/avformat.h | 6 +++++- > libavformat/mux.c | 3 +++ > 2 files changed, 8 insertions(+), 1 deletion(-) > > diff --git a/libavformat/avformat.h b/libavformat/avformat.h > index 818184e..9191c69 100644 > --- a/libavformat/avformat.h > +++ b/libavformat/avformat.h > @@ -2508,8 +2508,12 @@ int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index); > * > * May only be called after a successful call to avformat_write_header. > * > + * If AVFMT_FLAG_NONBLOCK is set, this call may return AVERROR(EAGAIN) > + * meaning the operation is pending and the call should be repeated. > + * > * @param s media file handle > - * @return 0 if OK, AVERROR_xxx on error > + * @return 0 if OK, AVERROR(EAGAIN) in case call should be repeated, > + * other AVERROR on error > */ > int av_write_trailer(AVFormatContext *s); > > diff --git a/libavformat/mux.c b/libavformat/mux.c > index e9973ed..b58e4c1 100644 > --- a/libavformat/mux.c > +++ b/libavformat/mux.c > @@ -1238,6 +1238,9 @@ fail: > } > } > > + if (ret == AVERROR(EAGAIN)) > + return ret; IIUC the non blocking code works only if packet interleaving is not used (which is implied by AVFMT_FLAG_NONBLOCK being set) is there an assert ensuring that EAGAIN only occurs in such case somewhere ? if it would occur with the interleave code then ret could be set before or maybe even set to EAGAIN and then if (s->internal->header_written && s->oformat->write_trailer) { if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER); if (ret >= 0) { ret = s->oformat->write_trailer(s); } else { s->oformat->write_trailer(s); } } would do all kinds of unexpected things like ignoring the write_trailer return or returning to the user EAGAIN even when trailer didnt return that, ... [...]
On 08/10/2016 07:04 PM, Michael Niedermayer wrote: > On Tue, Aug 02, 2016 at 03:24:15PM +0200, sebechlebskyjan@gmail.com wrote: >> From: Jan Sebechlebsky <sebechlebskyjan@gmail.com> >> >> This makes av_write_trailer not to free the resources if write_trailer >> call returns AVERROR(EAGAIN) allowing repeated calls of write_trailer of >> non-blocking muxer. >> >> Signed-off-by: Jan Sebechlebsky <sebechlebskyjan@gmail.com> >> --- >> libavformat/avformat.h | 6 +++++- >> libavformat/mux.c | 3 +++ >> 2 files changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h >> index 818184e..9191c69 100644 >> --- a/libavformat/avformat.h >> +++ b/libavformat/avformat.h >> @@ -2508,8 +2508,12 @@ int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index); >> * >> * May only be called after a successful call to avformat_write_header. >> * >> + * If AVFMT_FLAG_NONBLOCK is set, this call may return AVERROR(EAGAIN) >> + * meaning the operation is pending and the call should be repeated. >> + * >> * @param s media file handle >> - * @return 0 if OK, AVERROR_xxx on error >> + * @return 0 if OK, AVERROR(EAGAIN) in case call should be repeated, >> + * other AVERROR on error >> */ >> int av_write_trailer(AVFormatContext *s); >> >> diff --git a/libavformat/mux.c b/libavformat/mux.c >> index e9973ed..b58e4c1 100644 >> --- a/libavformat/mux.c >> +++ b/libavformat/mux.c >> @@ -1238,6 +1238,9 @@ fail: >> } >> } >> >> + if (ret == AVERROR(EAGAIN)) >> + return ret; > IIUC the non blocking code works only if packet interleaving is not > used (which is implied by AVFMT_FLAG_NONBLOCK being set) > > is there an assert ensuring that EAGAIN only occurs in such case > somewhere ? I've just added comment to av_interleaved_write_frame that it cannot be used with muxer operating in non-blocking mode, but it is certainly good idea to add assert as well. I'll modify and resend the patch with the comment change to add assert too. > if it would occur with the interleave code then > ret could be set before or maybe even set to EAGAIN and then > > if (s->internal->header_written && s->oformat->write_trailer) { > if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) > avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER); > if (ret >= 0) { > ret = s->oformat->write_trailer(s); > } else { > s->oformat->write_trailer(s); > } > } > > would do all kinds of unexpected things like ignoring the write_trailer > return or returning to the user EAGAIN even when trailer didnt return > that, ... > > [...] > > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Regards, Jan
diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 818184e..9191c69 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2508,8 +2508,12 @@ int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index); * * May only be called after a successful call to avformat_write_header. * + * If AVFMT_FLAG_NONBLOCK is set, this call may return AVERROR(EAGAIN) + * meaning the operation is pending and the call should be repeated. + * * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error + * @return 0 if OK, AVERROR(EAGAIN) in case call should be repeated, + * other AVERROR on error */ int av_write_trailer(AVFormatContext *s); diff --git a/libavformat/mux.c b/libavformat/mux.c index e9973ed..b58e4c1 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1238,6 +1238,9 @@ fail: } } + if (ret == AVERROR(EAGAIN)) + return ret; + if (s->oformat->deinit) s->oformat->deinit(s);