[FFmpeg-devel] [PATCH] avformat/concatdec: don't call open_file when seek position within a file
--- libavformat/concatdec.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index b3a430e..1cd9ec1 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -64,6 +64,8 @@ typedef struct { ConcatMatchMode stream_match_mode; unsigned auto_convert; int segment_time_metadata; +int cur_fileno; +AVFormatContext *cur_avf_saved; } ConcatContext; static int concat_probe(AVProbeData *probe) @@ -333,6 +335,8 @@ static int open_file(AVFormatContext *avf, unsigned fileno) avformat_close_input(&cat->avf); return ret; } + +cat->cur_fileno = fileno; cat->cur_file = file; if (file->start_time == AV_NOPTS_VALUE) file->start_time = !fileno ? 0 : @@ -711,13 +715,18 @@ static int real_seek(AVFormatContext *avf, int stream, left = mid; } -if ((ret = open_file(avf, left)) < 0) -return ret; +if (cat->cur_fileno != left) { +if ((ret = open_file(avf, left)) < 0) +return ret; +} else { +cat->avf = cat->cur_avf_saved; +} ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); if (ret < 0 && left < cat->nb_files - 1 && cat->files[left + 1].start_time < max_ts) { +cat->avf = NULL; if ((ret = open_file(avf, left + 1)) < 0) return ret; ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); @@ -730,7 +739,7 @@ static int concat_seek(AVFormatContext *avf, int stream, { ConcatContext *cat = avf->priv_data; ConcatFile *cur_file_saved = cat->cur_file; -AVFormatContext *cur_avf_saved = cat->avf; +cat->cur_avf_saved = cat->avf; int ret; if (!cat->seekable) @@ -739,12 +748,16 @@ static int concat_seek(AVFormatContext *avf, int stream, return AVERROR(ENOSYS); cat->avf = NULL; if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) { -if (cat->avf) -avformat_close_input(&cat->avf); -cat->avf = cur_avf_saved; +if (cat->cur_file != cur_file_saved) { +if (cat->avf) +avformat_close_input(&cat->avf); +} +cat->avf = cat->cur_avf_saved; cat->cur_file = cur_file_saved; } else { -avformat_close_input(&cur_avf_saved); +if (cat->cur_file != cur_file_saved) { +avformat_close_input(&cat->cur_avf_saved); +} cat->eof = 0; } return ret; -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] FFplay: progress bar feature proposal
Hi. Currently FFplay has no visible progress bar and it is hard to tell where a stream is currently positioned. So if one wants, for example, to rewind a little back relative to current position using right mouse click it is always guessing and trying. I propose very simple 1-pixel progress bar which can be turned on or off during playback by pressing a button (I use 'L', from 'line'). By default the bar is off. I choose bright green color (#00ff00) for the part to the left of a current position and pure black for the part to the right. You can see how it looks on the attached image. Draft patch is applied. One global variable ('static int show_progress_line') and one function ('static void video_progress_line_display(VideoState *is)') have been added. Also the existing 'video_display()' function has been moved below 'get_master_clock()' as the latter is used in the new function. What do you think?--- ffplay.c 2017-04-12 11:46:21.543322000 +0500 +++ ffplay.c 2017-04-12 14:26:47.693278504 +0500 @@ -344,6 +344,7 @@ static const char *video_codec_name; double rdftspeed = 0.02; static int64_t cursor_last_shown; static int cursor_hidden = 0; +static int show_progress_line = 0; #if CONFIG_AVFILTER static const char **vfilters_list = NULL; static int nb_vfilters = 0; @@ -1299,21 +1300,6 @@ static int video_open(VideoState *is) return 0; } -/* display the current picture, if any */ -static void video_display(VideoState *is) -{ -if (!window) -video_open(is); - -SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); -SDL_RenderClear(renderer); -if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO) -video_audio_display(is); -else if (is->video_st) -video_image_display(is); -SDL_RenderPresent(renderer); -} - static double get_clock(Clock *c) { if (*c->queue_serial != c->serial) @@ -1513,6 +1499,37 @@ static void update_video_pts(VideoState sync_clock_to_slave(&is->extclk, &is->vidclk); } +static void video_progress_line_display(VideoState *is) { +double d = is->ic->duration / 1.0e6; +if (d > 0) { +double t = get_master_clock(is); +int w = is->width * t / d; +SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); +fill_rectangle(0, is->height-1, w, 1); +SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); +fill_rectangle(w, is->height-1, is->width-w, 1); +} else { +show_progress_line = 0; +} +} + +/* display the current picture, if any */ +static void video_display(VideoState *is) +{ +if (!window) +video_open(is); + +SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); +SDL_RenderClear(renderer); +if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO) +video_audio_display(is); +else if (is->video_st) +video_image_display(is); +if (show_progress_line) +video_progress_line_display(is); +SDL_RenderPresent(renderer); +} + /* called to display each frame */ static void video_refresh(void *opaque, double *remaining_time) { @@ -3265,6 +3282,9 @@ static void event_loop(VideoState *cur_s toggle_audio_display(cur_stream); #endif break; +case SDLK_l: +show_progress_line = !show_progress_line; +break; case SDLK_PAGEUP: if (cur_stream->ic->nb_chapters <= 1) { incr = 600.0; @@ -3543,6 +3563,7 @@ static const OptionDef options[] = { #endif { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" }, { "showmode", HAS_ARG, { .func_arg = opt_show_mode}, "select show mode (0 = video, 1 = waves, 2 = RDFT)", "mode" }, +{ "progress", OPT_BOOL, { &show_progress_line}, "show progress line at the bottom", ""}, { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default }, "generic catch all option", "" }, { "i", OPT_BOOL, { &dummy}, "read specified file", "input_file"}, { "codec", HAS_ARG, { .func_arg = opt_codec}, "force decoder", "decoder_name" }, @@ -3587,6 +3608,7 @@ void show_help_default(const char *opt, "c cycle program\n" "w cycle video filters or show modes\n" "s activate frame-step mode\n" + "l toggle progress line at the bottom\n" "left/right seek backward/forward 10 seconds\n" "down/up seek backward/forward 1 minute\n" "page down/page up seek backward/forward 10 minutes\n" ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] FFplay: progress bar feature proposal
13.04.2017, 09:40, "Steven Liu" : > 2017-04-13 20:48 GMT+08:00 Raymond Pierce : > >> Hi. Currently FFplay has no visible progress bar and it is hard to tell >> where a stream is currently positioned. So if one wants, for example, to >> rewind >> a little back relative to current position using right mouse click it is >> always >> guessing and trying. >> >> I propose very simple 1-pixel progress bar which can be turned on or off >> during >> playback by pressing a button (I use 'L', from 'line'). By default the bar >> is off. >> >> I choose bright green color (#00ff00) for the part to the left of a current >> position and pure black for the part to the right. >> >> You can see how it looks on the attached image. >> >> Draft patch is applied. One global variable ('static int >> show_progress_line') >> and one function ('static void video_progress_line_display(VideoState >> *is)') >> have been added. Also the existing 'video_display()' function has been >> moved >> below 'get_master_clock()' as the latter is used in the new function. >> >> What do you think? >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > git commit -a > git format-patch -s -1 > > You should use the command looks like the above git command to make patch > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Hello, Steven. Thank you for the advice. New patch in the attachment. Should I post a new message with the patch to ffmpeg-devel@ffmpeg.org list? From e780cfa4330ae87cd4506ec2ccfe39ea045f2134 Mon Sep 17 00:00:00 2001 From: Ray Pierce Date: Thu, 13 Apr 2017 20:41:59 +0500 Subject: [PATCH] Add FFplay progress bar feature Signed-off-by: Ray Pierce --- ffplay.c | 52 +--- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/ffplay.c b/ffplay.c index cf138dc515..a73699475b 100644 --- a/ffplay.c +++ b/ffplay.c @@ -344,6 +344,7 @@ static const char *video_codec_name; double rdftspeed = 0.02; static int64_t cursor_last_shown; static int cursor_hidden = 0; +static int show_progress_line = 0; #if CONFIG_AVFILTER static const char **vfilters_list = NULL; static int nb_vfilters = 0; @@ -1299,21 +1300,6 @@ static int video_open(VideoState *is) return 0; } -/* display the current picture, if any */ -static void video_display(VideoState *is) -{ -if (!window) -video_open(is); - -SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); -SDL_RenderClear(renderer); -if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO) -video_audio_display(is); -else if (is->video_st) -video_image_display(is); -SDL_RenderPresent(renderer); -} - static double get_clock(Clock *c) { if (*c->queue_serial != c->serial) @@ -1513,6 +1499,37 @@ static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial sync_clock_to_slave(&is->extclk, &is->vidclk); } +static void video_progress_line_display(VideoState *is) { +double d = is->ic->duration / 1.0e6; +if (d > 0) { +double t = get_master_clock(is); +int w = is->width * t / d; +SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); +fill_rectangle(0, is->height-1, w, 1); +SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); +fill_rectangle(w, is->height-1, is->width-w, 1); +} else { +show_progress_line = 0; +} +} + +/* display the current picture, if any */ +static void video_display(VideoState *is) +{ +if (!window) +video_open(is); + +SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); +SDL_RenderClear(renderer); +if (is->audio_st && is->show_mode != SHOW_MODE_VIDEO) +video_audio_display(is); +else if (is->video_st) +video_image_display(is); +if (show_progress_line) +video_progress_line_display(is); +SDL_RenderPresent(renderer); +} + /* called to display each frame */ static void video_refresh(void *opaque, double *remaining_time) { @@ -3265,6 +3282,9 @@ static void event_loop(VideoState *cur_stream) toggle_audio_display(cur_stream); #endif break; +case SDLK_l: +show_progress_line = !show_progress_line; +break; case SDLK_PAGEUP: if (cur_stream->ic->nb_chapters <= 1) { incr = 600.0; @@ -3543,6 +3563,7 @@ static const OptionDef options[] =
Re: [FFmpeg-devel] [PATCH] libavformat/avio: fix fill_buffer return error eof when offset1 == buffer_size
ping... 2017-05-08 18:57 GMT+08:00 raymondzheng : > --- > libavformat/aviobuf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c > index 0a7c39eacd..20d3b7a02a 100644 > --- a/libavformat/aviobuf.c > +++ b/libavformat/aviobuf.c > @@ -270,7 +270,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int > whence) > > offset1 = offset - pos; // "offset1" is the relative offset from the > beginning of s->buffer > if (!s->must_flush && (!s->direct || !s->seek) && > -offset1 >= 0 && offset1 <= buffer_size - s->write_flag) { > +offset1 >= 0 && offset1 < buffer_size - s->write_flag) { > /* can do the seek inside the buffer */ > s->buf_ptr = s->buffer + offset1; > } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) || > -- > 2.11.0 (Apple Git-81) > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
Hi: I find an issue about http. I don't use chunked, so s->chunksize will be set as UINT64_MAX when http open, but because of "if (s->chunksize > 0) s->chunksize -= len;" then chunksize will not be UINT64_MAX. If ffurl_read return to 0, s->off < target_end, http_buf_read will return to 0, then this will lead to eof, so this is incorrect, and http_buf_read should return to AVERROR(EIO). 0001-libavformat-http-return-EIO-when-ffurl_read-return-0.patch Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
ping... 2017-05-18 15:19 GMT+08:00 raymond zheng : > Hi: > I find an issue about http. I don't use chunked, so s->chunksize will > be set as UINT64_MAX when http open, but because of "if (s->chunksize > > 0) s->chunksize -= len;" then chunksize will not be UINT64_MAX. > > If ffurl_read return to 0, s->off < target_end, http_buf_read will > return to 0, then this will lead to eof, so this is incorrect, and > http_buf_read should return to AVERROR(EIO). > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
I don't think it need a timeout event to disconnect the link, because when ffurl_read return to 0, it means the link disconnect. If s->off < target_end, it means AVERROR, otherwise, it's normal eof. I don't use chunked in HTTP, so s->chunksize should be initial value, and shouldn't be changed or even decreased. 2017-05-22 18:51 GMT+08:00 Steven Liu : > 2017-05-18 15:19 GMT+08:00 raymond zheng : > > > Hi: > > I find an issue about http. I don't use chunked, so s->chunksize will > > be set as UINT64_MAX when http open, but because of "if (s->chunksize > > 0) > > s->chunksize -= len;" then chunksize will not be UINT64_MAX. > > > > If ffurl_read return to 0, s->off < target_end, http_buf_read will > > return to 0, then this will lead to eof, so this is incorrect, and > > http_buf_read should return to AVERROR(EIO). > > > > if connect to CDN http edge server, this maybe incorrect. or need a > timeout event to disconnect the link. > > > > > ___ > > 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 > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
1. An exception occurred in the CDN edge server, that will lead to close the http connection. 2. Because http is disconnected, so ffurl_read will return 0 3. Avformat will consider I/O is eof 4. Right now http is actually disconnect abnormally, it should return to ERROR, rather than return to EOF. 2017-05-22 23:05 GMT+08:00 Steven Liu : > 2017-05-22 22:36 GMT+08:00 raymond zheng : > > > I don't think it need a timeout event to disconnect the link, because > > when ffurl_read > > return to 0, it means the link disconnect. If s->off < target_end, it > > means AVERROR, > > otherwise, it's normal eof. > > I don't use chunked in HTTP, so s->chunksize should be initial value, and > > shouldn't be changed or even decreased. > > > > What will happen if not apply this patch? can you reproduce the bug step > by step. > > > 2017-05-22 18:51 GMT+08:00 Steven Liu : > > > > > 2017-05-18 15:19 GMT+08:00 raymond zheng : > > > > > > > Hi: > > > > I find an issue about http. I don't use chunked, so s->chunksize > > will > > > > be set as UINT64_MAX when http open, but because of "if > (s->chunksize > > > > 0) > > > > s->chunksize -= len;" then chunksize will not be UINT64_MAX. > > > > > > > > If ffurl_read return to 0, s->off < target_end, http_buf_read > will > > > > return to 0, then this will lead to eof, so this is incorrect, and > > > > http_buf_read should return to AVERROR(EIO). > > > > > > > > > > if connect to CDN http edge server, this maybe incorrect. or need a > > > timeout event to disconnect the link. > > > > > > > > > > > ___ > > > > 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 > > > > > ___ > > 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 > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
You can close http link on your http server, and check ffurl_read result. Besides, this problem was caused by commit: 2a05c8f813de6f2278827734bf8102291e7484aa 2017-05-23 13:37 GMT+08:00 Steven Liu : > 2017-05-23 10:47 GMT+08:00 raymond zheng : > > > 1. An exception occurred in the CDN edge server, that will lead to close > > the http connection. > > > > 2. Because http is disconnected, so ffurl_read will return 0 > > > > 3. Avformat will consider I/O is eof > > > > 4. Right now http is actually disconnect abnormally, it should return to > > ERROR, rather than return to EOF. > > > Can you reproduce it? and provide me try to reproduce it. > I cannot sure if apply this patch will influence other people require > function, for example: retry or reconnect again. > > > > 2017-05-22 23:05 GMT+08:00 Steven Liu : > > > > > 2017-05-22 22:36 GMT+08:00 raymond zheng : > > > > > > > I don't think it need a timeout event to disconnect the link, because > > > > when ffurl_read > > > > return to 0, it means the link disconnect. If s->off < target_end, it > > > > means AVERROR, > > > > otherwise, it's normal eof. > > > > I don't use chunked in HTTP, so s->chunksize should be initial value, > > and > > > > shouldn't be changed or even decreased. > > > > > > > > What will happen if not apply this patch? can you reproduce the bug > > step > > > by step. > > > > > > > 2017-05-22 18:51 GMT+08:00 Steven Liu : > > > > > > > > > 2017-05-18 15:19 GMT+08:00 raymond zheng < > raymondzheng1...@gmail.com > > >: > > > > > > > > > > > Hi: > > > > > > I find an issue about http. I don't use chunked, so > > s->chunksize > > > > will > > > > > > be set as UINT64_MAX when http open, but because of "if > > > (s->chunksize > > > > > > 0) > > > > > > s->chunksize -= len;" then chunksize will not be UINT64_MAX. > > > > > > > > > > > > If ffurl_read return to 0, s->off < target_end, http_buf_read > > > will > > > > > > return to 0, then this will lead to eof, so this is incorrect, > and > > > > > > http_buf_read should return to AVERROR(EIO). > > > > > > > > > > > > > > > > if connect to CDN http edge server, this maybe incorrect. or need > a > > > > > timeout event to disconnect the link. > > > > > > > > > > > > > > > > > ___ > > > > > > 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 > > > > > > > > > ___ > > > > 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 > > > > > ___ > > 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 > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
ping Ronald S. Bultje 2017-05-23 15:02 GMT+08:00 Steven Liu : > 2017-05-23 14:01 GMT+08:00 raymond zheng : > > > You can close http link on your http server, and check ffurl_read > result. > > > > Besides, this problem was caused by commit: > > 2a05c8f813de6f2278827734bf8102291e7484aa > > > ping Ronald S. Bultje > > > > > 2017-05-23 13:37 GMT+08:00 Steven Liu : > > > > > 2017-05-23 10:47 GMT+08:00 raymond zheng : > > > > > > > 1. An exception occurred in the CDN edge server, that will lead to > > close > > > > the http connection. > > > > > > > > 2. Because http is disconnected, so ffurl_read will return 0 > > > > > > > > 3. Avformat will consider I/O is eof > > > > > > > > 4. Right now http is actually disconnect abnormally, it should return > > to > > > > ERROR, rather than return to EOF. > > > > > > > Can you reproduce it? and provide me try to reproduce it. > > > I cannot sure if apply this patch will influence other people require > > > function, for example: retry or reconnect again. > > > > > > > > > > 2017-05-22 23:05 GMT+08:00 Steven Liu : > > > > > > > > > 2017-05-22 22:36 GMT+08:00 raymond zheng < > raymondzheng1...@gmail.com > > >: > > > > > > > > > > > I don't think it need a timeout event to disconnect the link, > > because > > > > > > when ffurl_read > > > > > > return to 0, it means the link disconnect. If s->off < > target_end, > > it > > > > > > means AVERROR, > > > > > > otherwise, it's normal eof. > > > > > > I don't use chunked in HTTP, so s->chunksize should be initial > > value, > > > > and > > > > > > shouldn't be changed or even decreased. > > > > > > > > > > > > What will happen if not apply this patch? can you reproduce the > bug > > > > step > > > > > by step. > > > > > > > > > > > 2017-05-22 18:51 GMT+08:00 Steven Liu : > > > > > > > > > > > > > 2017-05-18 15:19 GMT+08:00 raymond zheng < > > > raymondzheng1...@gmail.com > > > > >: > > > > > > > > > > > > > > > Hi: > > > > > > > > I find an issue about http. I don't use chunked, so > > > > s->chunksize > > > > > > will > > > > > > > > be set as UINT64_MAX when http open, but because of "if > > > > > (s->chunksize > > > > > > > > 0) > > > > > > > > s->chunksize -= len;" then chunksize will not be UINT64_MAX. > > > > > > > > > > > > > > > > If ffurl_read return to 0, s->off < target_end, > > http_buf_read > > > > > will > > > > > > > > return to 0, then this will lead to eof, so this is > incorrect, > > > and > > > > > > > > http_buf_read should return to AVERROR(EIO). > > > > > > > > > > > > > > > > > > > > > > if connect to CDN http edge server, this maybe incorrect. or > > need > > > a > > > > > > > timeout event to disconnect the link. > > > > > > > > > > > > > > > > > > > > > > > ___ > > > > > > > > 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 > > > > > > > > > > > > > ___ > > > > > > 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 > > > > > > > > > ___ > > > > 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 > > > > > ___ > > 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 > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
Hi: I find an issue about http. I don't use chunked, so s->chunksize will be set as UINT64_MAX when http open, but because of "if (s->chunksize > 0) s->chunksize -= len;" then chunksize will not be UINT64_MAX. If ffurl_read return to 0, s->off < target_end, http_buf_read will return to 0, then this will lead to eof, so this is incorrect, and http_buf_read should return to AVERROR(EIO). the bug reproduce step: 1. An exception occurred in the CDN edge server, that will lead to close the http connection. 2. Because http is disconnected, so ffurl_read will return 0 3. Avformat will consider I/O is eof 4. Right now http is actually disconnect abnormally, it should return to ERROR, rather than return to EOF. this problem was caused by commit: 2a05c8f813de6f2278827734bf8102291e7484aa 0001-libavformat-http-return-EIO-when-ffurl_read-return-0.patch Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH]libavformat/http: fix http error eof
This patch is only for solving the bug introduced by chunksize has been initial set as UINT64 MAX. 2017-05-27 19:24 GMT+08:00 Ronald S. Bultje : > Hi, > > On Fri, May 26, 2017 at 10:36 PM, raymond zheng < > raymondzheng1...@gmail.com> wrote: > >> Hi: >> I find an issue about http. I don't use chunked, so s->chunksize >> will be set as UINT64_MAX when http open, but because of "if >> (s->chunksize > 0) s->chunksize -= len;" then chunksize will not be >> UINT64_MAX. >> >> If ffurl_read return to 0, s->off < target_end, http_buf_read will >> return to 0, then this will lead to eof, so this is incorrect, and >> http_buf_read should return to AVERROR(EIO). >> >> the bug reproduce step: >> >> 1. An exception occurred in the CDN edge server, that will lead to close >> the http connection. >> >> 2. Because http is disconnected, so ffurl_read will return 0 >> >> 3. Avformat will consider I/O is eof >> >> 4. Right now http is actually disconnect abnormally, it should return to >> ERROR, rather than return to EOF. >> >> >> this problem was caused by commit: 2a05c8f813de6f2278827734bf8102 >> 291e7484aa >> > What if the server legitimately responds that the chunksize is actually > UINT64_MAX? I almost feel like these special values should be replaced by a > new flag. > > Ronald > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/concatdec: don't call open_file when seek position within a file
Submit reasons: I have enabled concat and async protocol,but ffmpeg will flush async buffer when doing seek. I don't want flush async buffer when doing seek within the same segment file. I found, the concatdev will call open_file everytime I try to do seek, which will cause call async_open,and then flush async buffer. Solution: I will judge if seek range in the same segment file, if so, I‘ll only call try_seek. 2016-09-20 12:31 GMT+08:00 raymond : > --- > libavformat/concatdec.c | 27 --- > 1 file changed, 20 insertions(+), 7 deletions(-) > > diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c > index b3a430e..1cd9ec1 100644 > --- a/libavformat/concatdec.c > +++ b/libavformat/concatdec.c > @@ -64,6 +64,8 @@ typedef struct { > ConcatMatchMode stream_match_mode; > unsigned auto_convert; > int segment_time_metadata; > +int cur_fileno; > +AVFormatContext *cur_avf_saved; > } ConcatContext; > > static int concat_probe(AVProbeData *probe) > @@ -333,6 +335,8 @@ static int open_file(AVFormatContext *avf, unsigned > fileno) > avformat_close_input(&cat->avf); > return ret; > } > + > +cat->cur_fileno = fileno; > cat->cur_file = file; > if (file->start_time == AV_NOPTS_VALUE) > file->start_time = !fileno ? 0 : > @@ -711,13 +715,18 @@ static int real_seek(AVFormatContext *avf, int > stream, > left = mid; > } > > -if ((ret = open_file(avf, left)) < 0) > -return ret; > +if (cat->cur_fileno != left) { > +if ((ret = open_file(avf, left)) < 0) > +return ret; > +} else { > +cat->avf = cat->cur_avf_saved; > +} > > ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); > if (ret < 0 && > left < cat->nb_files - 1 && > cat->files[left + 1].start_time < max_ts) { > +cat->avf = NULL; > if ((ret = open_file(avf, left + 1)) < 0) > return ret; > ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); > @@ -730,7 +739,7 @@ static int concat_seek(AVFormatContext *avf, int > stream, > { > ConcatContext *cat = avf->priv_data; > ConcatFile *cur_file_saved = cat->cur_file; > -AVFormatContext *cur_avf_saved = cat->avf; > +cat->cur_avf_saved = cat->avf; > int ret; > > if (!cat->seekable) > @@ -739,12 +748,16 @@ static int concat_seek(AVFormatContext *avf, int > stream, > return AVERROR(ENOSYS); > cat->avf = NULL; > if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) { > -if (cat->avf) > -avformat_close_input(&cat->avf); > -cat->avf = cur_avf_saved; > +if (cat->cur_file != cur_file_saved) { > +if (cat->avf) > +avformat_close_input(&cat->avf); > +} > +cat->avf = cat->cur_avf_saved; > cat->cur_file = cur_file_saved; > } else { > -avformat_close_input(&cur_avf_saved); > +if (cat->cur_file != cur_file_saved) { > +avformat_close_input(&cat->cur_avf_saved); > +} > cat->eof = 0; > } > return ret; > -- > 2.7.4 > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/concatdec: don't call open_file when seek position within a file
ping... 2016-09-20 15:04 GMT+08:00 raymond zheng : > Submit reasons: > > I have enabled concat and async protocol,but ffmpeg will flush async > buffer when doing seek. I don't want flush async buffer when doing seek > within the same segment file. > I found, the concatdev will call open_file everytime I try to do seek, > which will cause call async_open,and then flush async buffer. > > > Solution: > > I will judge if seek range in the same segment file, if so, I‘ll only call > try_seek. > > > 2016-09-20 12:31 GMT+08:00 raymond : > >> --- >> libavformat/concatdec.c | 27 --- >> 1 file changed, 20 insertions(+), 7 deletions(-) >> >> diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c >> index b3a430e..1cd9ec1 100644 >> --- a/libavformat/concatdec.c >> +++ b/libavformat/concatdec.c >> @@ -64,6 +64,8 @@ typedef struct { >> ConcatMatchMode stream_match_mode; >> unsigned auto_convert; >> int segment_time_metadata; >> +int cur_fileno; >> +AVFormatContext *cur_avf_saved; >> } ConcatContext; >> >> static int concat_probe(AVProbeData *probe) >> @@ -333,6 +335,8 @@ static int open_file(AVFormatContext *avf, unsigned >> fileno) >> avformat_close_input(&cat->avf); >> return ret; >> } >> + >> +cat->cur_fileno = fileno; >> cat->cur_file = file; >> if (file->start_time == AV_NOPTS_VALUE) >> file->start_time = !fileno ? 0 : >> @@ -711,13 +715,18 @@ static int real_seek(AVFormatContext *avf, int >> stream, >> left = mid; >> } >> >> -if ((ret = open_file(avf, left)) < 0) >> -return ret; >> +if (cat->cur_fileno != left) { >> +if ((ret = open_file(avf, left)) < 0) >> +return ret; >> +} else { >> +cat->avf = cat->cur_avf_saved; >> +} >> >> ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); >> if (ret < 0 && >> left < cat->nb_files - 1 && >> cat->files[left + 1].start_time < max_ts) { >> +cat->avf = NULL; >> if ((ret = open_file(avf, left + 1)) < 0) >> return ret; >> ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); >> @@ -730,7 +739,7 @@ static int concat_seek(AVFormatContext *avf, int >> stream, >> { >> ConcatContext *cat = avf->priv_data; >> ConcatFile *cur_file_saved = cat->cur_file; >> -AVFormatContext *cur_avf_saved = cat->avf; >> +cat->cur_avf_saved = cat->avf; >> int ret; >> >> if (!cat->seekable) >> @@ -739,12 +748,16 @@ static int concat_seek(AVFormatContext *avf, int >> stream, >> return AVERROR(ENOSYS); >> cat->avf = NULL; >> if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) { >> -if (cat->avf) >> -avformat_close_input(&cat->avf); >> -cat->avf = cur_avf_saved; >> +if (cat->cur_file != cur_file_saved) { >> +if (cat->avf) >> +avformat_close_input(&cat->avf); >> +} >> +cat->avf = cat->cur_avf_saved; >> cat->cur_file = cur_file_saved; >> } else { >> -avformat_close_input(&cur_avf_saved); >> +if (cat->cur_file != cur_file_saved) { >> +avformat_close_input(&cat->cur_avf_saved); >> +} >> cat->eof = 0; >> } >> return ret; >> -- >> 2.7.4 >> >> > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/concatdec: don't call open_file when seek position within a file
ping... 2016-09-23 11:48 GMT+08:00 raymondzheng1...@gmail.com < raymondzheng1...@gmail.com>: > Thanks for your suggest, I have modified patch. see below. > --- > libavformat/concatdec.c | 24 +--- > 1 file changed, 17 insertions(+), 7 deletions(-) > > diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c > index b3a430e..5cc239a 100644 > --- a/libavformat/concatdec.c > +++ b/libavformat/concatdec.c > @@ -689,7 +689,7 @@ static int try_seek(AVFormatContext *avf, int stream, > } > > static int real_seek(AVFormatContext *avf, int stream, > - int64_t min_ts, int64_t ts, int64_t max_ts, int > flags) > + int64_t min_ts, int64_t ts, int64_t max_ts, int > flags, AVFormatContext *cur_avf) > { > ConcatContext *cat = avf->priv_data; > int ret, left, right; > @@ -711,13 +711,19 @@ static int real_seek(AVFormatContext *avf, int > stream, > left = mid; > } > > -if ((ret = open_file(avf, left)) < 0) > -return ret; > +if (cat->cur_file != &cat->files[left]) { > +if ((ret = open_file(avf, left)) < 0) > +return ret; > +} else { > +cat->avf = cur_avf; > +} > > ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); > if (ret < 0 && > left < cat->nb_files - 1 && > cat->files[left + 1].start_time < max_ts) { > +if (cat->cur_file == &cat->files[left]) > +cat->avf = NULL; > if ((ret = open_file(avf, left + 1)) < 0) > return ret; > ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); > @@ -738,13 +744,17 @@ static int concat_seek(AVFormatContext *avf, int > stream, > if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME)) > return AVERROR(ENOSYS); > cat->avf = NULL; > -if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) { > -if (cat->avf) > -avformat_close_input(&cat->avf); > +if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags, > cur_avf_saved)) < 0) { > +if (cat->cur_file != cur_file_saved) { > +if (cat->avf) > +avformat_close_input(&cat->avf); > +} > cat->avf = cur_avf_saved; > cat->cur_file = cur_file_saved; > } else { > -avformat_close_input(&cur_avf_saved); > +if (cat->cur_file != cur_file_saved) { > +avformat_close_input(&cur_avf_saved); > +} > cat->eof = 0; > } > return ret; > -- > 2.7.4 > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] Enable dash output to work when the output isn't a local file
On 04/01/16 17:36, "ffmpeg-devel on behalf of Hendrik Leppkes" wrote: >On Mon, Jan 4, 2016 at 3:58 PM, wrote: >> From: Raymond Hilseth >> >> Signed-off-by: Raymond Hilseth >> --- >> libavformat/dashenc.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >> index 4509ee4..378c4e4 100644 >> --- a/libavformat/dashenc.c >> +++ b/libavformat/dashenc.c >> @@ -549,7 +549,7 @@ static int write_manifest(AVFormatContext *s, int >>final) >> avio_printf(out, "\n"); >> avio_flush(out); >> avio_close(out); >> -return ff_rename(temp_filename, s->filename, s); >> +return avpriv_io_move(temp_filename, s->filename); >> } >> >> static int dash_write_header(AVFormatContext *s) >> @@ -856,7 +856,7 @@ static int dash_flush(AVFormatContext *s, int >>final, int stream) >> } else { >> ffurl_close(os->out); >> os->out = NULL; >> -ret = ff_rename(temp_path, full_path, s); >> +ret = avpriv_io_move(temp_path, full_path); >> if (ret < 0) >> break; >> } >> -- > >For unknown reasons, url_move(which avpriv_io_move uses) in the "file" >protocol depends on unistd.h, which is not available everywhere. >So commiting this without making sure file.url_move is available on >all systems where ff_rename works would introduce a regression. > >- Hendrik Are there any supported platforms other than Windows where unistd.h isn¹t available? As far as I can see, the existing code for dash encoding cannot work on Windows, since rename on Windows will fail when the destination file already exists, and the manifest file will already exist after the first segment has been written. - Raymond Hilseth ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2] Enable dash output to work when the output isn't a local file
Use avpriv_io_move instead of ff_rename to support more than only the file protocol. Enabled the implementation of file_move in libavformat/file.c for systems not having unistd.h since it only requires the rename function from os_support.h. Signed-off-by: Raymond Hilseth --- libavformat/dashenc.c | 4 ++-- libavformat/file.c| 4 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 4509ee4..378c4e4 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -549,7 +549,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\n"); avio_flush(out); avio_close(out); -return ff_rename(temp_filename, s->filename, s); +return avpriv_io_move(temp_filename, s->filename); } static int dash_write_header(AVFormatContext *s) @@ -856,7 +856,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) } else { ffurl_close(os->out); os->out = NULL; -ret = ff_rename(temp_path, full_path, s); +ret = avpriv_io_move(temp_path, full_path); if (ret < 0) break; } diff --git a/libavformat/file.c b/libavformat/file.c index a318408..e56ea79 100644 --- a/libavformat/file.c +++ b/libavformat/file.c @@ -176,7 +176,6 @@ static int file_delete(URLContext *h) static int file_move(URLContext *h_src, URLContext *h_dst) { -#if HAVE_UNISTD_H const char *filename_src = h_src->filename; const char *filename_dst = h_dst->filename; av_strstart(filename_src, "file:", &filename_src); @@ -186,9 +185,6 @@ static int file_move(URLContext *h_src, URLContext *h_dst) return AVERROR(errno); return 0; -#else -return AVERROR(ENOSYS); -#endif /* HAVE_UNISTD_H */ } #if CONFIG_FILE_PROTOCOL -- 2.4.3 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] Support bidirectional metadata in drawtext filter
The drawtext filter supports static bidi text via a function called shape_text(). Fixed so that it calls shape_text() when rendering non-static text from metadata (so that bidi text is rendered properly). As an example, "Hello world" is "مرحبا بالعالم" in Arabic. The following command line worked just fine before, and still works after this change: ffmpeg -i input -vf drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text='مرحبا بالعالم' out.mp4 However, this command line did NOT work: ffmpeg -i input -vf metadata=mode=add:key=transcription:value='مرحبا بالعالم',drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text="'From metadata\: %{metadata\:transcription}'" out.mp4 This commit fixes it so that this second command line now works. NOTE that the above command lines are for example only. They render the proper text, but improperly justified (left-justified instead of right-justified). For one-line transcriptions, this is easily fixed by replacing x=30 with x=\(700-tw\). Two-line transcriptions do not have a simple solution. Signed-off-by: Raymond Cheng --- libavfilter/vf_drawtext.c | 57 +-- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index feb6898848..9e4a63b7fd 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -608,7 +608,7 @@ static int load_textfile(AVFilterContext *ctx) } #if CONFIG_LIBFRIBIDI -static int shape_text(AVFilterContext *ctx) +static int shape_text_arg(AVFilterContext *ctx, char **ppText) { DrawTextContext *s = ctx->priv; uint8_t *tmp; @@ -625,12 +625,15 @@ static int shape_text(AVFilterContext *ctx) FriBidiCharType *bidi_types = NULL; FriBidiStrIndex i,j; -len = strlen(s->text); +if (!s->text_shaping) +return 0; // Do nothing + +len = strlen(*ppText); if (!(unicodestr = av_malloc_array(len, sizeof(*unicodestr { goto out; } len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, - s->text, len, unicodestr); + *ppText, len, unicodestr); bidi_types = av_malloc_array(len, sizeof(*bidi_types)); if (!bidi_types) { @@ -676,14 +679,14 @@ static int shape_text(AVFilterContext *ctx) unicodestr[j++] = unicodestr[i]; len = j; -if (!(tmp = av_realloc(s->text, (len * 4 + 1) * sizeof(*s->text { +if (!(tmp = av_realloc(*ppText, (len * 4 + 1) * sizeof(**ppText { /* Use len * 4, as a unicode character can be up to 4 bytes in UTF-8 */ goto out; } -s->text = tmp; +*ppText = tmp; len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, - unicodestr, len, s->text); + unicodestr, len, *ppText); ret = 0; out: @@ -693,8 +696,19 @@ out: av_free(bidi_types); return ret; } +#else +static int shape_text_arg(AVFilterContext *ctx, char **ppText) +{ +return 0; +} #endif +static int shape_text(AVFilterContext *ctx) +{ +DrawTextContext *s = ctx->priv; +return shape_text_arg(ctx, (char **)&s->text); +} + static enum AVFrameSideDataType text_source_string_parse(const char *text_source_string) { av_assert0(text_source_string); @@ -771,11 +785,8 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(EINVAL); } -#if CONFIG_LIBFRIBIDI -if (s->text_shaping) -if ((err = shape_text(ctx)) < 0) -return err; -#endif +if ((err = shape_text(ctx)) < 0) +return err; if ((err = FT_Init_FreeType(&(s->library { av_log(ctx, AV_LOG_ERROR, @@ -1034,11 +1045,19 @@ static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, { DrawTextContext *s = ctx->priv; AVDictionaryEntry *e = av_dict_get(s->metadata, argv[0], NULL, 0); +int err; + +if (e && e->value) { +if ((err = shape_text_arg(ctx, &e->value)) < 0) +return err; -if (e && e->value) av_bprintf(bp, "%s", e->value); -else if (argc >= 2) +} else if (argc >= 2) { +if ((err = shape_text_arg(ctx, &argv[1])) < 0) +return err; + av_bprintf(bp, "%s", argv[1]); +} return 0; } @@ -1634,13 +1653,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) av_frame_free(&frame); return ret; } -#if CONFIG_LIBFRIBIDI -if (s->text_shaping) -if ((ret = shape_text(ctx)) < 0) { -av_frame_free(&frame); -return ret; -} -#endif + +if ((ret = shape_text(ctx)) < 0) { +av_frame_free(&frame); +return ret; +
[FFmpeg-devel] [PATCH] Add metadatareader filter.
FFmpeg has a handy set of filters, metadata/ametadata, which allow us to add, print or save per-frame metadata to a file. I will use these filters when I want to save the results from speech transcription, for instance. What is missing is a way to round-trip the saved metadata, so I decided to add filters which go in the opposite direction: metadatareader/ametadatareader. These filters inject per-frame metadata into the filter graph from a previously saved metadata/ametadata file. If you had a speech transcription filter called speech_recognition which produced per-frame metadata using the key "transcription", here is how you might use the metadata reader to burn hard subtitles: Pass 1: ffmpeg -i input -vn -sn -af speech_recognition,ametadata=mode=print:file=transcription.txt -f null /dev/null Pass 2: ffmpeg -i input -vf metadatareader=file=transcription.txt,drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text="'%{metadata\:transcription}'" out.mp4 It should be noted in the example above that the metadata crossed over from audio to video. It was saved from audio in Pass 1, and applied to video on Pass 2. This is perfectly valid, as well as non-crossover applications. Signed-off-by: Raymond Cheng --- Changelog | 1 + configure | 2 + libavfilter/Makefile | 2 + libavfilter/allfilters.c | 2 + libavfilter/f_metadatareader.c| 455 + libavutil/error_tracing.h | 126 + tests/fate-run.sh | 3 + tests/fate/filter-audio.mak | 7 + tests/fate/filter-video.mak | 6 + tests/ref/fate/filter-ametadatareader | 690 ++ tests/ref/fate/filter-metadatareader | 14 + 11 files changed, 1308 insertions(+) create mode 100644 libavfilter/f_metadatareader.c create mode 100644 libavutil/error_tracing.h create mode 100644 tests/ref/fate/filter-ametadatareader create mode 100644 tests/ref/fate/filter-metadatareader diff --git a/Changelog b/Changelog index ba679aa64e..646eac87e9 100644 --- a/Changelog +++ b/Changelog @@ -23,6 +23,7 @@ version 5.1: - virtualbass audio filter - VDPAU AV1 hwaccel - PHM image format support +- metadatareader video and ametadatareader audio filter version 5.0: diff --git a/configure b/configure index fea512e8ef..8262f8d708 100755 --- a/configure +++ b/configure @@ -3614,6 +3614,7 @@ libzmq_protocol_select="network" # filters ametadata_filter_deps="avformat" +ametadatareader_filter_deps="avformat" amovie_filter_deps="avcodec avformat" aresample_filter_deps="swresample" asr_filter_deps="pocketsphinx" @@ -3679,6 +3680,7 @@ libplacebo_filter_deps="libplacebo vulkan" lv2_filter_deps="lv2" mcdeint_filter_deps="avcodec gpl" metadata_filter_deps="avformat" +metadatareader_filter_deps="avformat" movie_filter_deps="avcodec avformat" mpdecimate_filter_deps="gpl" mpdecimate_filter_select="pixelutils" diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 22b0a0ca15..15de9b3815 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -71,6 +71,7 @@ OBJS-$(CONFIG_ALLPASS_FILTER)+= af_biquads.o OBJS-$(CONFIG_ALOOP_FILTER) += f_loop.o OBJS-$(CONFIG_AMERGE_FILTER) += af_amerge.o OBJS-$(CONFIG_AMETADATA_FILTER) += f_metadata.o +OBJS-$(CONFIG_AMETADATAREADER_FILTER)+= f_metadatareader.o OBJS-$(CONFIG_AMIX_FILTER) += af_amix.o OBJS-$(CONFIG_AMULTIPLY_FILTER) += af_amultiply.o OBJS-$(CONFIG_ANEQUALIZER_FILTER)+= af_anequalizer.o @@ -365,6 +366,7 @@ OBJS-$(CONFIG_MEDIAN_FILTER) += vf_median.o OBJS-$(CONFIG_MERGEPLANES_FILTER)+= vf_mergeplanes.o framesync.o OBJS-$(CONFIG_MESTIMATE_FILTER) += vf_mestimate.o motion_estimation.o OBJS-$(CONFIG_METADATA_FILTER) += f_metadata.o +OBJS-$(CONFIG_METADATAREADER_FILTER) += f_metadatareader.o OBJS-$(CONFIG_MIDEQUALIZER_FILTER) += vf_midequalizer.o framesync.o OBJS-$(CONFIG_MINTERPOLATE_FILTER) += vf_minterpolate.o motion_estimation.o OBJS-$(CONFIG_MIX_FILTER)+= vf_mix.o framesync.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index ec70feef11..3e58e52ea7 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -58,6 +58,7 @@ extern const AVFilter ff_af_allpass; extern const AVFilter ff_af_aloop; extern const AVFilter ff_af_amerge; extern const AVFilter ff_af_ametadata; +extern const AVFilter ff_af_ametadatareader; extern const AVFilter ff_af_amix; extern const AVFilter ff_af_amultiply; extern const AVFilter ff_af_anequalizer; @@ -346,6 +347,7 @@ extern const AVFilter ff_vf_median; extern const AVFi
[FFmpeg-devel] [PATCH] avfilter/drawtext: Support bidirectional metadata in drawtext filter
The drawtext filter supports static bidi text via a function called shape_text(). Fixed so that it calls shape_text() when rendering non-static text from metadata (so that bidi text is rendered properly). As an example, "Hello world" is "مرحبا بالعالم" in Arabic. The following command line worked just fine before, and still works after this change: ffmpeg -i input -vf drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text='مرحبا بالعالم' out.mp4 However, this command line did NOT work: ffmpeg -i input -vf metadata=mode=add:key=transcription:value='مرحبا بالعالم',drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text="'From metadata\: %{metadata\:transcription}'" out.mp4 This commit fixes it so that this second command line now works. NOTE that the above command lines are for example only. They render the proper text, but improperly justified (left-justified instead of right-justified). For one-line transcriptions, this is easily fixed by replacing x=30 with x=\(700-tw\). Two-line transcriptions do not have a simple solution. Signed-off-by: Raymond Cheng --- libavfilter/vf_drawtext.c | 57 +-- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index feb6898848..9e4a63b7fd 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -608,7 +608,7 @@ static int load_textfile(AVFilterContext *ctx) } #if CONFIG_LIBFRIBIDI -static int shape_text(AVFilterContext *ctx) +static int shape_text_arg(AVFilterContext *ctx, char **ppText) { DrawTextContext *s = ctx->priv; uint8_t *tmp; @@ -625,12 +625,15 @@ static int shape_text(AVFilterContext *ctx) FriBidiCharType *bidi_types = NULL; FriBidiStrIndex i,j; -len = strlen(s->text); +if (!s->text_shaping) +return 0; // Do nothing + +len = strlen(*ppText); if (!(unicodestr = av_malloc_array(len, sizeof(*unicodestr { goto out; } len = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, - s->text, len, unicodestr); + *ppText, len, unicodestr); bidi_types = av_malloc_array(len, sizeof(*bidi_types)); if (!bidi_types) { @@ -676,14 +679,14 @@ static int shape_text(AVFilterContext *ctx) unicodestr[j++] = unicodestr[i]; len = j; -if (!(tmp = av_realloc(s->text, (len * 4 + 1) * sizeof(*s->text { +if (!(tmp = av_realloc(*ppText, (len * 4 + 1) * sizeof(**ppText { /* Use len * 4, as a unicode character can be up to 4 bytes in UTF-8 */ goto out; } -s->text = tmp; +*ppText = tmp; len = fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, - unicodestr, len, s->text); + unicodestr, len, *ppText); ret = 0; out: @@ -693,8 +696,19 @@ out: av_free(bidi_types); return ret; } +#else +static int shape_text_arg(AVFilterContext *ctx, char **ppText) +{ +return 0; +} #endif +static int shape_text(AVFilterContext *ctx) +{ +DrawTextContext *s = ctx->priv; +return shape_text_arg(ctx, (char **)&s->text); +} + static enum AVFrameSideDataType text_source_string_parse(const char *text_source_string) { av_assert0(text_source_string); @@ -771,11 +785,8 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(EINVAL); } -#if CONFIG_LIBFRIBIDI -if (s->text_shaping) -if ((err = shape_text(ctx)) < 0) -return err; -#endif +if ((err = shape_text(ctx)) < 0) +return err; if ((err = FT_Init_FreeType(&(s->library { av_log(ctx, AV_LOG_ERROR, @@ -1034,11 +1045,19 @@ static int func_metadata(AVFilterContext *ctx, AVBPrint *bp, { DrawTextContext *s = ctx->priv; AVDictionaryEntry *e = av_dict_get(s->metadata, argv[0], NULL, 0); +int err; + +if (e && e->value) { +if ((err = shape_text_arg(ctx, &e->value)) < 0) +return err; -if (e && e->value) av_bprintf(bp, "%s", e->value); -else if (argc >= 2) +} else if (argc >= 2) { +if ((err = shape_text_arg(ctx, &argv[1])) < 0) +return err; + av_bprintf(bp, "%s", argv[1]); +} return 0; } @@ -1634,13 +1653,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) av_frame_free(&frame); return ret; } -#if CONFIG_LIBFRIBIDI -if (s->text_shaping) -if ((ret = shape_text(ctx)) < 0) { -av_frame_free(&frame); -return ret; -} -#endif + +if ((ret = shape_text(ctx)) < 0) { +av_frame_free(&frame); +return ret; +
Re: [FFmpeg-devel] [PATCH] Add metadatareader filter.
Thanks, it will probably take me a couple days to incorporate some of the feedback regarding style, but some comments: 1) The intent of metadatareader is to read what the metadata filter wrote to a file, which as you already know, does not make use of any established format. It simply calls vsnprintf. This intent is backed by FATE test, so any breaking changes ought to hopefully be caught (and if not, the tests can be enhanced). If I were to follow your suggestion of adopting a format, then I think I'd choose VTT, and this would be a much bigger change. It would necessitate that the metadata filter also be modified to output to VTT rather than use its current log format. I think if we wanted to do that, I'd still prefer to do that as a stage 2, and start with a stage 1 where f_metadata.c is UNMODIFIED but we still have a f_metadatareader.c which can read what it writes to a log file. Are you suggesting that we can have such a stage 1, with unmodified f_metadata.c, where f_metadatareader.c is using an already established format already available in ffmpeg? I think I would be hesitant to go that path d ue to the asymmetry (f_metadatareader.c uses an existing libavformat to parse, but f_metadata.c does not and calls vsnprintf directly). 2) Regarding error_tracing.h, I'm all for having a discussion (I assume you are suggesting to start a new discussion thread), but perhaps also as a stage 2, maybe for stage 1, I will just delete the file and only move the macros currently being used into f_metadatareader.c so that they are self-contained and not intended for general use. ...Cheng -Original Message- From: ffmpeg-devel On Behalf Of Nicolas George Sent: Thursday, July 7, 2022 3:09 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] Add metadatareader filter. Raymond Cheng (12022-07-06): > FFmpeg has a handy set of filters, metadata/ametadata, which allow us > to add, print or save per-frame metadata to a file. I will use these > filters when I want to save the results from speech transcription, > for instance. What is missing is a way to round-trip the saved > metadata, so I decided to add filters which go in the opposite > direction: metadatareader/ametadatareader. These filters inject > per-frame metadata into the filter graph from a previously saved > metadata/ametadata file. > > If you had a speech transcription filter called speech_recognition > which produced per-frame metadata using the key "transcription", > here is how you might use the metadata reader to burn hard subtitles: > > Pass 1: ffmpeg -i input -vn -sn -af > speech_recognition,ametadata=mode=print:file=transcription.txt -f null > /dev/null > Pass 2: ffmpeg -i input -vf > metadatareader=file=transcription.txt,drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text="'%{metadata\:transcription}'" > out.mp4 > > It should be noted in the example above that the metadata crossed > over from audio to video. It was saved from audio in Pass 1, and > applied to video on Pass 2. This is perfectly valid, as well as > non-crossover applications. Thanks for the contribution. The feature is interesting, but details will need to be worked on. The coding style needs to be consistent with the rest of FFmpeg's code. In particular, only use CamelCase for types, not for variables and functions. And we definitely do not include the type of variables in their names. > > Signed-off-by: Raymond Cheng > --- > Changelog | 1 + > configure | 2 + > libavfilter/Makefile | 2 + > libavfilter/allfilters.c | 2 + > libavfilter/f_metadatareader.c| 455 + It looks to me the file from which the metadata is taken gets parsed in this patch, and the syntax was invented for the occasion. First, if the syntax is invented for the occasion, it must be documented. Second, we try to avoid inventing a syntax for the occasion. Note that this objection could have been applied to the print option of the metadata filter; but printing is a much simpler task than parsing and is often done the quick-and-dirty way. I suggest to use libavformat to read frames metadata from a supported format. If libavformat does not contain a format that supports frame metadata and is easy to write, then we can invent a syntax there. But before inventing a syntax for the whole format, we can consider using a subtitle format and only invent a syntax to encode frame metadata in the subtitles text. > libavutil/error_tracing.h | 126 + I am all for adding syntactic sugar in libavutil to make error checking more lightweight. But it needs to be discussed in its own right to meet the needs and style of more developers. > tests/fate-run.sh
Re: [FFmpeg-devel] [PATCH] Add metadatareader filter.
I also feel, btw, that there is already precedent for this kind of implied relationship between f_metadata.c and f_metadatareader.c. For example, the demuxer/muxer pairs in libavformat, such as movenc.c and mov.c are complimentary, the latter is implicitly meant to read what the former has written, and there is no obligation to go to some third component as neutral ground. Same goes for the encoder/decoder pairs in libavcodec. I want the same "mated pair" status for f_metadata.c and f_metadatareader.c. Having said that, I am not at all opposed to modifying f_metadata.c to write VTT instead of its current format, and having f_metadatareader.c read VTT. The benefit of that is that VTT is a standalone format understood everywhere, so that producing such a VTT file can be used by browsers, not just f_metadatareader.c. You wouldn't have to burn hard subs by reading the VTT into f_metadatareader.c, you could just place it alongside the MP4 and the browser will render soft subs. But I'd prefer to do that in stages, with first stage making no modifications to f_metadata.c. ...Cheng -Original Message- From: Raymond Cheng Sent: Saturday, July 9, 2022 9:26 AM To: FFmpeg development discussions and patches Subject: RE: [FFmpeg-devel] [PATCH] Add metadatareader filter. Thanks, it will probably take me a couple days to incorporate some of the feedback regarding style, but some comments: 1) The intent of metadatareader is to read what the metadata filter wrote to a file, which as you already know, does not make use of any established format. It simply calls vsnprintf. This intent is backed by FATE test, so any breaking changes ought to hopefully be caught (and if not, the tests can be enhanced). If I were to follow your suggestion of adopting a format, then I think I'd choose VTT, and this would be a much bigger change. It would necessitate that the metadata filter also be modified to output to VTT rather than use its current log format. I think if we wanted to do that, I'd still prefer to do that as a stage 2, and start with a stage 1 where f_metadata.c is UNMODIFIED but we still have a f_metadatareader.c which can read what it writes to a log file. Are you suggesting that we can have such a stage 1, with unmodified f_metadata.c, where f_metadatareader.c is using an already established format already available in ffmpeg? I think I would be hesitant to go that path d ue to the asymmetry (f_metadatareader.c uses an existing libavformat to parse, but f_metadata.c does not and calls vsnprintf directly). 2) Regarding error_tracing.h, I'm all for having a discussion (I assume you are suggesting to start a new discussion thread), but perhaps also as a stage 2, maybe for stage 1, I will just delete the file and only move the macros currently being used into f_metadatareader.c so that they are self-contained and not intended for general use. ...Cheng -Original Message- From: ffmpeg-devel On Behalf Of Nicolas George Sent: Thursday, July 7, 2022 3:09 PM To: FFmpeg development discussions and patches Subject: Re: [FFmpeg-devel] [PATCH] Add metadatareader filter. Raymond Cheng (12022-07-06): > FFmpeg has a handy set of filters, metadata/ametadata, which allow us > to add, print or save per-frame metadata to a file. I will use these > filters when I want to save the results from speech transcription, > for instance. What is missing is a way to round-trip the saved > metadata, so I decided to add filters which go in the opposite > direction: metadatareader/ametadatareader. These filters inject > per-frame metadata into the filter graph from a previously saved > metadata/ametadata file. > > If you had a speech transcription filter called speech_recognition > which produced per-frame metadata using the key "transcription", > here is how you might use the metadata reader to burn hard subtitles: > > Pass 1: ffmpeg -i input -vn -sn -af > speech_recognition,ametadata=mode=print:file=transcription.txt -f null > /dev/null > Pass 2: ffmpeg -i input -vf > metadatareader=file=transcription.txt,drawtext=fontsize=30:x=30:y=30:fontcolor=yellow:text="'%{metadata\:transcription}'" > out.mp4 > > It should be noted in the example above that the metadata crossed > over from audio to video. It was saved from audio in Pass 1, and > applied to video on Pass 2. This is perfectly valid, as well as > non-crossover applications. Thanks for the contribution. The feature is interesting, but details will need to be worked on. The coding style needs to be consistent with the rest of FFmpeg's code. In particular, only use CamelCase for types, not for variables and functions. And we definitely do not include the type of variables in their names. > > Signed-off-by: Raymond Cheng > --- > Changelog
Re: [FFmpeg-devel] [PATCH] Add metadatareader filter.
Well, I do think VTT is useful for the reasons I gave below, but also remember that I am fine not doing VTT. 😊 Regarding the complexity, I think I started out simple, and that works fine when not crossing between audio/video, but it got more complex in order to perform the audio-to-video crossover. When the audio metadata indicates that somebody said “Hello world” from 0.3s to 0.6s, then this metadata has to be applied to 10 video frames at 30 fps. Do you prefer that I paste the contents of f_metadatareader.c into f_metadata.c and expose a new mode? So I provided an example in the commit message, the Pass 2 command line to burn hard subs would change from -vf metadatareader=file=transcription.txt to -vf metadata=mode=read:file=transcription.txt? That could be an interesting complement to the Pass 1 -vf metadata=mode=print:file=transcription.txt. …Cheng From: Paul B Mahol Sent: Saturday, July 9, 2022 1:00 AM To: FFmpeg development discussions and patches Cc: Raymond Cheng Subject: Re: [FFmpeg-devel] [PATCH] Add metadatareader filter. On Sat, Jul 9, 2022 at 8:44 AM Raymond Cheng mailto:raycheng...@hotmail.com>> wrote: I also feel, btw, that there is already precedent for this kind of implied relationship between f_metadata.c and f_metadatareader.c. For example, the demuxer/muxer pairs in libavformat, such as movenc.c and mov.c are complimentary, the latter is implicitly meant to read what the former has written, and there is no obligation to go to some third component as neutral ground. Same goes for the encoder/decoder pairs in libavcodec. I want the same "mated pair" status for f_metadata.c and f_metadatareader.c. Having said that, I am not at all opposed to modifying f_metadata.c to write VTT instead of its current format, and having f_metadatareader.c read VTT. The benefit of that is that VTT is a standalone format understood everywhere, so that producing such a VTT file can be used by browsers, not just f_metadatareader.c. You wouldn't have to burn hard subs by reading the VTT into f_metadatareader.c, you could just place it alongside the MP4 and the browser will render soft subs. But I'd prefer to do that in stages, with first stage making no modifications to f_metadata.c. VTT is not good pick at all. This functionality should be in metadata filter instead, and not in separate filter. Also it is too much complex implementation of interesting idea. ...Cheng -Original Message- From: Raymond Cheng mailto:raycheng...@hotmail.com>> Sent: Saturday, July 9, 2022 9:26 AM To: FFmpeg development discussions and patches mailto:ffmpeg-devel@ffmpeg.org>> Subject: RE: [FFmpeg-devel] [PATCH] Add metadatareader filter. Thanks, it will probably take me a couple days to incorporate some of the feedback regarding style, but some comments: 1) The intent of metadatareader is to read what the metadata filter wrote to a file, which as you already know, does not make use of any established format. It simply calls vsnprintf. This intent is backed by FATE test, so any breaking changes ought to hopefully be caught (and if not, the tests can be enhanced). If I were to follow your suggestion of adopting a format, then I think I'd choose VTT, and this would be a much bigger change. It would necessitate that the metadata filter also be modified to output to VTT rather than use its current log format. I think if we wanted to do that, I'd still prefer to do that as a stage 2, and start with a stage 1 where f_metadata.c is UNMODIFIED but we still have a f_metadatareader.c which can read what it writes to a log file. Are you suggesting that we can have such a stage 1, with unmodified f_metadata.c, where f_metadatareader.c is using an already established format already available in ffmpeg? I think I would be hesitant to go that path d ue to the asymmetry (f_metadatareader.c uses an existing libavformat to parse, but f_metadata.c does not and calls vsnprintf directly). 2) Regarding error_tracing.h, I'm all for having a discussion (I assume you are suggesting to start a new discussion thread), but perhaps also as a stage 2, maybe for stage 1, I will just delete the file and only move the macros currently being used into f_metadatareader.c so that they are self-contained and not intended for general use. ...Cheng -Original Message- From: ffmpeg-devel mailto:ffmpeg-devel-boun...@ffmpeg.org>> On Behalf Of Nicolas George Sent: Thursday, July 7, 2022 3:09 PM To: FFmpeg development discussions and patches mailto:ffmpeg-devel@ffmpeg.org>> Subject: Re: [FFmpeg-devel] [PATCH] Add metadatareader filter. Raymond Cheng (12022-07-06): > FFmpeg has a handy set of filters, metadata/ametadata, which allow us > to add, print or save per-frame metadata to a file. I will use these > filters when I want to save the results from speech transcription, > for instance. What is missing i