[FFmpeg-devel] [PATCH] avformat/concatdec: don't call open_file when seek position within a file

2016-09-19 Thread 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


[FFmpeg-devel] FFplay: progress bar feature proposal

2017-04-13 Thread 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?--- 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

2017-04-13 Thread Raymond Pierce
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

2017-05-10 Thread raymond zheng
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

2017-05-18 Thread 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).


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

2017-05-21 Thread raymond zheng
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

2017-05-22 Thread 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.

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

2017-05-22 Thread 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.

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

2017-05-22 Thread raymond zheng
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

2017-05-23 Thread raymond zheng
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

2017-05-26 Thread 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).

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

2017-05-31 Thread raymond zheng
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

2016-09-20 Thread 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

2016-09-21 Thread raymond zheng
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

2016-09-26 Thread raymond zheng
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

2016-01-05 Thread Raymond Hilseth


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

2016-01-06 Thread Raymond Hilseth
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

2022-07-06 Thread Raymond Cheng
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.

2022-07-06 Thread Raymond Cheng
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

2022-07-07 Thread Raymond Cheng
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.

2022-07-08 Thread Raymond Cheng
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.

2022-07-08 Thread Raymond Cheng
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.

2022-07-09 Thread Raymond Cheng
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