Re: [FFmpeg-devel] [PATCH] ffmpeg_filter: use nb_threads=1 on unused filtergraph
On 11/18/2017 05:56 AM, Michael Niedermayer wrote: > On Thu, Nov 16, 2017 at 08:25:50PM -0500, DeHackEd wrote: >> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c >> index aacc185..877fd67 100644 >> --- a/fftools/ffmpeg_filter.c >> +++ b/fftools/ffmpeg_filter.c >> @@ -340,6 +340,7 @@ int init_complex_filtergraph(FilterGraph *fg) >> graph = avfilter_graph_alloc(); >> if (!graph) >> return AVERROR(ENOMEM); >> +graph->nb_threads = 1; > > if you checked that it doesnt reduce threads for simple & complex > graphs that are used then LGTM > Yes I have verified that to be the case. Test method was $ strace -e trace=clone ./ffmpeg_g -filter_complex 'testsrc2[out]' ... The graph is disposed of within the same function. This is why I am proposing this change. Number of threads is a complex filtergraph is handled by the parameter -filter_complex_threads > thanks > > [...] > > > > ___ > 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] ffmpeg_filter: use nb_threads=1 on unused filtergraph
Hello, Simple one-line patch to avoid creating threads on a filtergrpah which does not get used during execution. This saves a superfluous thread creation and tear-down cycle. Besides cleanliness, the main driver for this feature is a system I have access to with a large number of cores/threads. Threads count towards ulimits and the default of 1 filtergraph thread per CPU thread is undesirable. >From 999a38ae38178c2ab3ba8a9ef116e7ec08474302 Mon Sep 17 00:00:00 2001 From: DHEDate: Thu, 16 Nov 2017 20:09:37 -0500 Subject: [PATCH] ffmpeg_filter: use nb_threads=1 on unused filtergraph Signed-off-by: DHE --- fftools/ffmpeg_filter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index aacc185..877fd67 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -340,6 +340,7 @@ int init_complex_filtergraph(FilterGraph *fg) graph = avfilter_graph_alloc(); if (!graph) return AVERROR(ENOMEM); +graph->nb_threads = 1; ret = avfilter_graph_parse2(graph, fg->graph_desc, , ); if (ret < 0) -- 2.9.5 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v3] libaf/hlsenc: allow dynamic encryption key rotation
Makes behaviour of 805ce25b1d2f optional, re-enables HLS key rotation feature Signed-off-by: DHE--- doc/muxers.texi | 7 ++- libavformat/hlsenc.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) v1->v2: Actually works this time v2->v3: Documentation fix, parameter reference was incorrect diff --git a/doc/muxers.texi b/doc/muxers.texi index 94472ce..2bec5f8 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -551,7 +551,7 @@ format. The optional third line specifies the initialization vector (IV) as a hexadecimal string to be used instead of the segment sequence number (default) for encryption. Changes to @var{key_info_file} will result in segment encryption with the new key/IV and an entry in the playlist for the new key -URI/IV. +URI/IV if @code{hls_flags periodic_rekey} is enabled. Key info file format: @example @@ -665,6 +665,11 @@ first segment's information. @item omit_endlist Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist. +@item periodic_rekey +The file specified by @code{hls_key_info_file} will be checked periodically and +detect updates to the encryption info. Be sure to replace this file atomically, +including the file containing the AES encryption key. + @item split_by_time Allow segments to start on frames other than keyframes. This improves behavior on some players when the time between keyframes is inconsistent, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5cf8c89..74a3249 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -85,6 +85,7 @@ typedef enum HLSFlags { HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s HLS_TEMP_FILE = (1 << 11), +HLS_PERIODIC_REKEY = (1 << 12), } HLSFlags; typedef enum { @@ -1236,7 +1237,7 @@ static int hls_start(AVFormatContext *s) " will use -hls_key_info_file priority\n"); } -if (c->number <= 1) { +if (c->number <= 1 || (c->flags & HLS_PERIODIC_REKEY)) { if (c->key_info_file) { if ((err = hls_encryption_start(s)) < 0) goto fail; @@ -1804,6 +1805,7 @@ static const AVOption options[] = { {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, +{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2] libaf/hlsenc: allow dynamic encryption key rotation
Makes behaviour of 805ce25b1d2f optional, re-enables HLS key rotation feature Signed-off-by: DHE--- doc/muxers.texi | 7 ++- libavformat/hlsenc.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) v1->v2: Actually works this time diff --git a/doc/muxers.texi b/doc/muxers.texi index 94472ce..a7324a4 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -551,7 +551,7 @@ format. The optional third line specifies the initialization vector (IV) as a hexadecimal string to be used instead of the segment sequence number (default) for encryption. Changes to @var{key_info_file} will result in segment encryption with the new key/IV and an entry in the playlist for the new key -URI/IV. +URI/IV if @code{hls_flags periodic_rekey} is enabled. Key info file format: @example @@ -665,6 +665,11 @@ first segment's information. @item omit_endlist Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist. +@item periodic_rekey +The file specified by @code{hls_key_info} will be checked periodically and +detect updates to the encryption info. Be sure to replace this file atomically, +including the file containing the AES encryption key. + @item split_by_time Allow segments to start on frames other than keyframes. This improves behavior on some players when the time between keyframes is inconsistent, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5cf8c89..74a3249 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -85,6 +85,7 @@ typedef enum HLSFlags { HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s HLS_TEMP_FILE = (1 << 11), +HLS_PERIODIC_REKEY = (1 << 12), } HLSFlags; typedef enum { @@ -1236,7 +1237,7 @@ static int hls_start(AVFormatContext *s) " will use -hls_key_info_file priority\n"); } -if (c->number <= 1) { +if (c->number <= 1 || (c->flags & HLS_PERIODIC_REKEY)) { if (c->key_info_file) { if ((err = hls_encryption_start(s)) < 0) goto fail; @@ -1804,6 +1805,7 @@ static const AVOption options[] = { {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, +{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libaf/hlsenc: allow dynamic encryption key rotation
On 08/04/2017 10:36 PM, Steven Liu wrote: > 2017-08-05 8:17 GMT+08:00 DeHackEd <g...@dehacked.net>: >> Signed-off-by: DHE <g...@dehacked.net> >> --- >> doc/muxers.texi | 7 ++- >> libavformat/hlsenc.c | 4 +++- >> 2 files changed, 9 insertions(+), 2 deletions(-) >> >> diff --git a/doc/muxers.texi b/doc/muxers.texi >> index 94472ce..a7324a4 100644 >> --- a/doc/muxers.texi >> +++ b/doc/muxers.texi >> @@ -551,7 +551,7 @@ format. The optional third line specifies the >> initialization vector (IV) as a >> hexadecimal string to be used instead of the segment sequence number >> (default) >> for encryption. Changes to @var{key_info_file} will result in segment >> encryption with the new key/IV and an entry in the playlist for the new key >> -URI/IV. >> +URI/IV if @code{hls_flags periodic_rekey} is enabled. >> >> Key info file format: >> @example >> @@ -665,6 +665,11 @@ first segment's information. >> @item omit_endlist >> Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist. >> >> +@item periodic_rekey >> +The file specified by @code{hls_key_info} will be checked periodically and >> +detect updates to the encryption info. Be sure to replace this file >> atomically, >> +including the file containing the AES encryption key. >> + >> @item split_by_time >> Allow segments to start on frames other than keyframes. This improves >> behavior on some players when the time between keyframes is inconsistent, >> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >> index 5cf8c89..4d2e7fb 100644 >> --- a/libavformat/hlsenc.c >> +++ b/libavformat/hlsenc.c >> @@ -85,6 +85,7 @@ typedef enum HLSFlags { >> HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment >> duration (microsec) in segment filenames when use_localtime e.g.: %%09t >> HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size >> (bytes) in segment filenames when use_localtime e.g.: %%014s >> HLS_TEMP_FILE = (1 << 11), >> +HLS_PERIODIC_REKEY = (1 << 12), >> } HLSFlags; >> >> typedef enum { >> @@ -1236,7 +1237,7 @@ static int hls_start(AVFormatContext *s) >>" will use -hls_key_info_file priority\n"); >> } >> >> -if (c->number <= 1) { >> +if (c->number <= 1 && !(c->flags & HLS_PERIODIC_REKEY)) { > it will always false when use HLS_PERIODIC_REKEY, then will not enable > hls encryption. Oops. Yeah I screwed that up pretty bad. I'll redo it. >> if (c->key_info_file) { >> if ((err = hls_encryption_start(s)) < 0) >> goto fail; >> @@ -1804,6 +1805,7 @@ static const AVOption options[] = { >> {"second_level_segment_index", "include segment index in segment >> filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = >> HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"}, >> {"second_level_segment_duration", "include segment duration in segment >> filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = >> HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, >> {"second_level_segment_size", "include segment size in segment >> filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = >> HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, >> +{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, >> AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, >> {"use_localtime", "set filename expansion with strftime at segment >> creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, >> {"use_localtime_mkdir", "create last directory component in >> strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, >> {.i64 = 0 }, 0, 1, E }, >> {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), >> AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, >> "pl_type" }, >> -- >> 1.8.4.1 >> ___ >> 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] libaf/hlsenc: allow dynamic encryption key rotation
Signed-off-by: DHE--- doc/muxers.texi | 7 ++- libavformat/hlsenc.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 94472ce..a7324a4 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -551,7 +551,7 @@ format. The optional third line specifies the initialization vector (IV) as a hexadecimal string to be used instead of the segment sequence number (default) for encryption. Changes to @var{key_info_file} will result in segment encryption with the new key/IV and an entry in the playlist for the new key -URI/IV. +URI/IV if @code{hls_flags periodic_rekey} is enabled. Key info file format: @example @@ -665,6 +665,11 @@ first segment's information. @item omit_endlist Do not append the @code{EXT-X-ENDLIST} tag at the end of the playlist. +@item periodic_rekey +The file specified by @code{hls_key_info} will be checked periodically and +detect updates to the encryption info. Be sure to replace this file atomically, +including the file containing the AES encryption key. + @item split_by_time Allow segments to start on frames other than keyframes. This improves behavior on some players when the time between keyframes is inconsistent, diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5cf8c89..4d2e7fb 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -85,6 +85,7 @@ typedef enum HLSFlags { HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s HLS_TEMP_FILE = (1 << 11), +HLS_PERIODIC_REKEY = (1 << 12), } HLSFlags; typedef enum { @@ -1236,7 +1237,7 @@ static int hls_start(AVFormatContext *s) " will use -hls_key_info_file priority\n"); } -if (c->number <= 1) { +if (c->number <= 1 && !(c->flags & HLS_PERIODIC_REKEY)) { if (c->key_info_file) { if ((err = hls_encryption_start(s)) < 0) goto fail; @@ -1804,6 +1805,7 @@ static const AVOption options[] = { {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, "flags"}, {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, "flags"}, +{"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"}, {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, "pl_type" }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v3] ffmpeg: parameters for filter thread counts
On 11/06/2016 06:44 AM, Michael Niedermayer wrote: > On Sun, Oct 30, 2016 at 09:25:39AM -0400, DeHackEd wrote: > [...] > >> if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, , >> )) < 0) >> diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c >> index 4d25fff..dc94380 100644 >> --- a/ffmpeg_opt.c >> +++ b/ffmpeg_opt.c >> @@ -3365,12 +3365,16 @@ const OptionDef options[] = { >> "set profile", "profile" }, >> { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { >> .off = OFFSET(filters) }, >> "set stream filtergraph", "filter_graph" }, >> +{ "filter_threads", HAS_ARG | OPT_INT, { >> _nbthreads }, >> +"number of non-complex filter threads" }, >> { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { >> .off = OFFSET(filter_scripts) }, >> "read stream filtergraph description from a file", "filename" }, >> { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,{ .off >> = OFFSET(reinit_filters) }, >> "reinit filtergraph on input parameter changes", "" }, >> { "filter_complex", HAS_ARG | OPT_EXPERT,{ >> .func_arg = opt_filter_complex }, >> "create a complex filtergraph", "graph_description" }, >> +{ "filter_complex_threads", HAS_ARG | OPT_INT, { >> _complex_nbthreads }, >> +"number of threads for -filter_complex" }, >> { "lavfi", HAS_ARG | OPT_EXPERT,{ >> .func_arg = opt_filter_complex }, >> "create a complex filtergraph", "graph_description" }, >> { "filter_complex_script", HAS_ARG | OPT_EXPERT, { >> .func_arg = opt_filter_complex_script }, > > why are there 2 options instead of 1 ? > One affects -filter_complex filtergraphs, one affects -af and -vf filtergraphs... The main motivation was that you typically have one -filter_complex graph, but could have many -af and -vf filtergraphs, so if you are trying to limit how many threads you use then you would have different needs depending on which type you are using. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v3] ffmpeg: parameters for filter thread counts
On 11/05/2016 02:51 PM, Michael Niedermayer wrote: > On Sun, Oct 30, 2016 at 09:25:39AM -0400, DeHackEd wrote: >> Enables specifying how many threads are available to each filtergraph. >> --- >> v2->v3: >> - Typos in docs fixed >> >> v1->v2: >> - Reworded documentation >> - Removed hunk from ffmpeg_filter.c not directly applicable to patch >> >> doc/ffmpeg.texi | 10 ++ >> ffmpeg.h| 3 +++ >> ffmpeg_filter.c | 7 +++ >> ffmpeg_opt.c| 4 >> 4 files changed, 24 insertions(+) > > Is "DeHackEd" the intended Author name for the commit ? > "DeHackEd" is the name I usually go by, but some patches read "DHE". That's my own fault, but either is fine. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v3] ffmpeg: parameters for filter thread counts
On 10/30/2016 09:25 AM, DeHackEd wrote: > Enables specifying how many threads are available to each filtergraph. > --- > v2->v3: > - Typos in docs fixed > > v1->v2: > - Reworded documentation > - Removed hunk from ffmpeg_filter.c not directly applicable to patch > > doc/ffmpeg.texi | 10 ++ > ffmpeg.h| 3 +++ > ffmpeg_filter.c | 7 +++ > ffmpeg_opt.c| 4 > 4 files changed, 24 insertions(+) > > diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi > index 47c8935..fd8a0c1 100644 > --- a/doc/ffmpeg.texi > +++ b/doc/ffmpeg.texi > @@ -415,6 +415,11 @@ This option is similar to @option{-filter}, the only > difference is that its > argument is the name of the file from which a filtergraph description is to > be > read. > > +@item -filter_threads @var{nb_threads} (@emph{global}) > +Defines how many threads are used to process a filter pipeline. Each pipeline > +will produce a thread pool with this many threads available for parallel > processing. > +The default is the number of available CPUs. > + > @item -pre[:@var{stream_specifier}] @var{preset_name} > (@emph{output,per-stream}) > Specify the preset for matching stream(s). > > @@ -1201,6 +1206,11 @@ To generate 5 seconds of pure red video using lavfi > @code{color} source: > ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv > @end example > > +@item -filter_complex_threads @var{nb_threads} (@emph{global}) > +Defines how many threads are used to process a filter_complex graph. > +Similar to filter_threads but used for @code{-filter_complex} graphs only. > +The default is the number of available CPUs. > + > @item -lavfi @var{filtergraph} (@emph{global}) > Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or > outputs. Equivalent to @option{-filter_complex}. > diff --git a/ffmpeg.h b/ffmpeg.h > index e1d4593..9a4389f 100644 > --- a/ffmpeg.h > +++ b/ffmpeg.h > @@ -569,6 +569,9 @@ extern AVIOContext *progress_avio; > extern float max_error_rate; > extern char *videotoolbox_pixfmt; > > +extern int filter_nbthreads; > +extern int filter_complex_nbthreads; > + > extern const AVIOInterruptCB int_cb; > > extern const OptionDef options[]; > diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c > index 27aeca0..95b9c43 100644 > --- a/ffmpeg_filter.c > +++ b/ffmpeg_filter.c > @@ -39,6 +39,9 @@ > #include "libavutil/imgutils.h" > #include "libavutil/samplefmt.h" > > +int filter_nbthreads = -1; > +int filter_complex_nbthreads = -1; > + > static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum > AVCodecID codec_id, const enum AVPixelFormat default_formats[]) > { > static const enum AVPixelFormat mjpeg_formats[] = > @@ -992,6 +995,8 @@ int configure_filtergraph(FilterGraph *fg) > char args[512]; > AVDictionaryEntry *e = NULL; > > +fg->graph->nb_threads = filter_complex_nbthreads; > + > args[0] = 0; > while ((e = av_dict_get(ost->sws_dict, "", e, > AV_DICT_IGNORE_SUFFIX))) { > @@ -1022,6 +1027,8 @@ int configure_filtergraph(FilterGraph *fg) > e = av_dict_get(ost->encoder_opts, "threads", NULL, 0); > if (e) > av_opt_set(fg->graph, "threads", e->value, 0); > +} else { > +fg->graph->nb_threads = filter_nbthreads; > } > > if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, , > )) < 0) > diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c > index 4d25fff..dc94380 100644 > --- a/ffmpeg_opt.c > +++ b/ffmpeg_opt.c > @@ -3365,12 +3365,16 @@ const OptionDef options[] = { > "set profile", "profile" }, > { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off > = OFFSET(filters) }, > "set stream filtergraph", "filter_graph" }, > +{ "filter_threads", HAS_ARG | OPT_INT, { > _nbthreads }, > +"number of non-complex filter threads" }, > { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off > = OFFSET(filter_scripts) }, > "read stream filtergraph description from a file", "filename" }, > { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,{ .off > = OFFSET(reinit_filters) }, > "reinit filtergraph on input parameter changes", "" }, > { "filter_complex", HAS_ARG | OPT_EXPERT,{ > .func_arg = opt_filter_complex }, > "
Re: [FFmpeg-devel] [PATCH v3] ffmpeg: parameters for filter thread counts
On 10/30/2016 12:09 PM, Paul B Mahol wrote: > On 10/30/16, DeHackEd <g...@dehacked.net> wrote: >> Enables specifying how many threads are available to each filtergraph. >> --- >> v2->v3: >> - Typos in docs fixed >> >> v1->v2: >> - Reworded documentation >> - Removed hunk from ffmpeg_filter.c not directly applicable to patch >> >> doc/ffmpeg.texi | 10 ++ >> ffmpeg.h| 3 +++ >> ffmpeg_filter.c | 7 +++ >> ffmpeg_opt.c| 4 >> 4 files changed, 24 insertions(+) >> ... >> diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c >> index 4d25fff..dc94380 100644 >> --- a/ffmpeg_opt.c >> +++ b/ffmpeg_opt.c >> @@ -3365,12 +3365,16 @@ const OptionDef options[] = { >> "set profile", "profile" }, >> { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { >> .off = OFFSET(filters) }, >> "set stream filtergraph", "filter_graph" }, >> +{ "filter_threads", HAS_ARG | OPT_INT, { >> _nbthreads }, >> +"number of non-complex filter threads" }, >> { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { >> .off = OFFSET(filter_scripts) }, >> "read stream filtergraph description from a file", "filename" }, >> { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,{ .off >> = OFFSET(reinit_filters) }, >> "reinit filtergraph on input parameter changes", "" }, >> { "filter_complex", HAS_ARG | OPT_EXPERT,{ >> .func_arg = opt_filter_complex }, >> "create a complex filtergraph", "graph_description" }, >> +{ "filter_complex_threads", HAS_ARG | OPT_INT, { >> _complex_nbthreads }, >> +"number of threads for -filter_complex" }, >> { "lavfi", HAS_ARG | OPT_EXPERT,{ >> .func_arg = opt_filter_complex }, >> "create a complex filtergraph", "graph_description" }, >> { "filter_complex_script", HAS_ARG | OPT_EXPERT, { >> .func_arg = opt_filter_complex_script }, >> -- >> 1.8.4.1 >> >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > How this plays out with number of threads one can set for each filter > instance? Each individual filter uses MIN(filter_specific_limit, filtergrpah_limit) threads, but regardless the filtergraph will create filtergraph_limit threads each time. This patch adds user control to the filtergraph_limit. My main motivation for this parameter is a system I have with 80 CPUs (including hyperthreads). The video filtering workload does not benefit from so many threads being created or used, and I suffer from a significant ulimit hit and greater difficulty debugging. > ___ > 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 v3] ffmpeg: parameters for filter thread counts
Enables specifying how many threads are available to each filtergraph. --- v2->v3: - Typos in docs fixed v1->v2: - Reworded documentation - Removed hunk from ffmpeg_filter.c not directly applicable to patch doc/ffmpeg.texi | 10 ++ ffmpeg.h| 3 +++ ffmpeg_filter.c | 7 +++ ffmpeg_opt.c| 4 4 files changed, 24 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 47c8935..fd8a0c1 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -415,6 +415,11 @@ This option is similar to @option{-filter}, the only difference is that its argument is the name of the file from which a filtergraph description is to be read. +@item -filter_threads @var{nb_threads} (@emph{global}) +Defines how many threads are used to process a filter pipeline. Each pipeline +will produce a thread pool with this many threads available for parallel processing. +The default is the number of available CPUs. + @item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream}) Specify the preset for matching stream(s). @@ -1201,6 +1206,11 @@ To generate 5 seconds of pure red video using lavfi @code{color} source: ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv @end example +@item -filter_complex_threads @var{nb_threads} (@emph{global}) +Defines how many threads are used to process a filter_complex graph. +Similar to filter_threads but used for @code{-filter_complex} graphs only. +The default is the number of available CPUs. + @item -lavfi @var{filtergraph} (@emph{global}) Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or outputs. Equivalent to @option{-filter_complex}. diff --git a/ffmpeg.h b/ffmpeg.h index e1d4593..9a4389f 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -569,6 +569,9 @@ extern AVIOContext *progress_avio; extern float max_error_rate; extern char *videotoolbox_pixfmt; +extern int filter_nbthreads; +extern int filter_complex_nbthreads; + extern const AVIOInterruptCB int_cb; extern const OptionDef options[]; diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 27aeca0..95b9c43 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -39,6 +39,9 @@ #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" +int filter_nbthreads = -1; +int filter_complex_nbthreads = -1; + static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum AVCodecID codec_id, const enum AVPixelFormat default_formats[]) { static const enum AVPixelFormat mjpeg_formats[] = @@ -992,6 +995,8 @@ int configure_filtergraph(FilterGraph *fg) char args[512]; AVDictionaryEntry *e = NULL; +fg->graph->nb_threads = filter_complex_nbthreads; + args[0] = 0; while ((e = av_dict_get(ost->sws_dict, "", e, AV_DICT_IGNORE_SUFFIX))) { @@ -1022,6 +1027,8 @@ int configure_filtergraph(FilterGraph *fg) e = av_dict_get(ost->encoder_opts, "threads", NULL, 0); if (e) av_opt_set(fg->graph, "threads", e->value, 0); +} else { +fg->graph->nb_threads = filter_nbthreads; } if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, , )) < 0) diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 4d25fff..dc94380 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -3365,12 +3365,16 @@ const OptionDef options[] = { "set profile", "profile" }, { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) }, "set stream filtergraph", "filter_graph" }, +{ "filter_threads", HAS_ARG | OPT_INT, { _nbthreads }, +"number of non-complex filter threads" }, { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) }, "read stream filtergraph description from a file", "filename" }, { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,{ .off = OFFSET(reinit_filters) }, "reinit filtergraph on input parameter changes", "" }, { "filter_complex", HAS_ARG | OPT_EXPERT,{ .func_arg = opt_filter_complex }, "create a complex filtergraph", "graph_description" }, +{ "filter_complex_threads", HAS_ARG | OPT_INT, { _complex_nbthreads }, +"number of threads for -filter_complex" }, { "lavfi", HAS_ARG | OPT_EXPERT,{ .func_arg = opt_filter_complex }, "create a complex filtergraph", "graph_description" }, { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] ffmpeg: parameters for filter thread counts
On 10/28/2016 10:30 AM, DHE wrote: > Enables specifying how many threads are available to each filtergraph. > --- > doc/ffmpeg.texi | 10 ++ > ffmpeg.h| 3 +++ > ffmpeg_filter.c | 9 + > ffmpeg_opt.c| 4 > 4 files changed, 26 insertions(+) > > diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi > index 47c8935..8be24b2 100644 > --- a/doc/ffmpeg.texi > +++ b/doc/ffmpeg.texi > @@ -415,6 +415,11 @@ This option is similar to @option{-filter}, the only > difference is that its > argument is the name of the file from which a filtergraph description is to > be > read. > > +@item -filter_threads @var{nb_thraeds} (@emph{global}) > +Defines how many threads are used to process a filter pipeline. > +Some filters support parallel processing. The default is the number of > available > +CPUs. > + > @item -pre[:@var{stream_specifier}] @var{preset_name} > (@emph{output,per-stream}) > Specify the preset for matching stream(s). > > @@ -1201,6 +1206,11 @@ To generate 5 seconds of pure red video using lavfi > @code{color} source: > ffmpeg -filter_complex 'color=c=red' -t 5 out.mkv > @end example > > +@item -filter_complex_threads @var{nb_threads} (@emph{global}) > +Defines how many threads are used to process a @code{-filter_complex} > pipeline. > +Some filters support parallel processing. The default is the number of > available > +CPUs. > + > @item -lavfi @var{filtergraph} (@emph{global}) > Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or > outputs. Equivalent to @option{-filter_complex}. > diff --git a/ffmpeg.h b/ffmpeg.h > index e1d4593..9a4389f 100644 > --- a/ffmpeg.h > +++ b/ffmpeg.h > @@ -569,6 +569,9 @@ extern AVIOContext *progress_avio; > extern float max_error_rate; > extern char *videotoolbox_pixfmt; > > +extern int filter_nbthreads; > +extern int filter_complex_nbthreads; > + > extern const AVIOInterruptCB int_cb; > > extern const OptionDef options[]; > diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c > index 27aeca0..4554456 100644 > --- a/ffmpeg_filter.c > +++ b/ffmpeg_filter.c > @@ -39,6 +39,9 @@ > #include "libavutil/imgutils.h" > #include "libavutil/samplefmt.h" > > +int filter_nbthreads = -1; > +int filter_complex_nbthreads = -1; > + > static const enum AVPixelFormat *get_compliance_unofficial_pix_fmts(enum > AVCodecID codec_id, const enum AVPixelFormat default_formats[]) > { > static const enum AVPixelFormat mjpeg_formats[] = > @@ -309,6 +312,8 @@ int init_complex_filtergraph(FilterGraph *fg) > if (!graph) > return AVERROR(ENOMEM); > > +// As a temporary graph, don't bother making threads > +graph->nb_threads = 1; I just noticed, this hunk arguably doens't belong in this patch as it isn't directly related to the command-line parameters I added. I meant to split this into a different patch depending on how well this one was received. > ret = avfilter_graph_parse2(graph, fg->graph_desc, , ); > if (ret < 0) > goto fail; > @@ -992,6 +997,8 @@ int configure_filtergraph(FilterGraph *fg) > char args[512]; > AVDictionaryEntry *e = NULL; > > +fg->graph->nb_threads = filter_complex_nbthreads; > + > args[0] = 0; > while ((e = av_dict_get(ost->sws_dict, "", e, > AV_DICT_IGNORE_SUFFIX))) { > @@ -1022,6 +1029,8 @@ int configure_filtergraph(FilterGraph *fg) > e = av_dict_get(ost->encoder_opts, "threads", NULL, 0); > if (e) > av_opt_set(fg->graph, "threads", e->value, 0); > +} else { > +fg->graph->nb_threads = filter_nbthreads; > } > > if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, , > )) < 0) > diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c > index 4d25fff..dc94380 100644 > --- a/ffmpeg_opt.c > +++ b/ffmpeg_opt.c > @@ -3365,12 +3365,16 @@ const OptionDef options[] = { > "set profile", "profile" }, > { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off > = OFFSET(filters) }, > "set stream filtergraph", "filter_graph" }, > +{ "filter_threads", HAS_ARG | OPT_INT, { > _nbthreads }, > +"number of non-complex filter threads" }, > { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off > = OFFSET(filter_scripts) }, > "read stream filtergraph description from a file", "filename" }, > { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC | OPT_INPUT,{ .off > = OFFSET(reinit_filters) }, > "reinit filtergraph on input parameter changes", "" }, > { "filter_complex", HAS_ARG | OPT_EXPERT,{ > .func_arg = opt_filter_complex }, > "create a complex filtergraph", "graph_description" }, > +{ "filter_complex_threads", HAS_ARG | OPT_INT, { > _complex_nbthreads }, > +"number of threads for -filter_complex" }, > { "lavfi", HAS_ARG | OPT_EXPERT,
Re: [FFmpeg-devel] [PATCH] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
On 06/12/2016 02:31 PM, Carl Eugen Hoyos wrote: > DeHackEd dehacked.net> writes: > >> The effects vary a bit. One guy in IRC basically had ffmpeg >> crash for him every 26.5 hours when he was saving to HLS > > And when I asked him how I can reproduce this issue he > unfortunately couldn't answer;-( I pasted output from ffmpeg way back at the start of this thread. If you're not using libav (or you are and your application doesn't correct for the timestamp wrap itself) then you can get the API experience with -copyts in the ffmpeg command. $ ffmpeg -i longvideo.ts -c copy -f mpegts -copyts output.ts [mpegts @ 0x245f460] Invalid timestamps stream=0, pts=43408, dts=8589888000, size=535 [mpegts @ 0x245f460] Invalid timestamps stream=0, pts=7408, dts=8589906000, size=157 [null @ 0x2465180] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 8589924000 >= 7408 [null @ 0x2465180] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 8589924000 >= 25408 [null @ 0x2465180] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 8589924000 >= 43408 ... In libav calling av_write_frame() with non-monontonic timestamps will return an error. In ffmpeg the video will be cut off or otherwise damaged at 26.5 hours. The guy in IRC had this convoluted command-line where he piped from ffmpeg to NvTranscoder (sample app in the nvenc SDK) and back through ffmpeg. The commend-line pasted was: /home/ffmpeg-3.0.1/ffmpeg -i - -codec copy -f mpegts - 2>/var/log/channels/${CHN}/input.txt < "$fifo" & encode+=($!)|NvTranscoder -size 1280 720 -i /dev/stdin -o /dev/stdout -bitrate 180 -vbvMaxBitrate 250 -vbvSize 100 -deviceID $2 $NVENC_OPTS |/home/ffmpeg-3.0.1/ffmpeg -fflags +genpts -i - -c:v copy -c:a aac -b:a 128k -ac 2 -timestamp now -f hls -hls_time 6 -hls_flags delete_segments -hls_list_size 5 ${HLS_PATH}/${CHN}/${CHN}2M.m3u8 2>/var/log/channels/${CHN}/720p.txt ... and as for the outputs, all his pastebin records have expired. > > Carl Eugen > > ___ > 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] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
On 06/12/2016 01:57 PM, Carl Eugen Hoyos wrote: > DeHackEd dehacked.net> writes: > >>> So the bug is that the file gets longer when read with FFmpeg? >> >> Heh... that's my fault for copy/pasting from the wrong invocation. >> I have two test cases, one generated from the above testsrc and >> one that actually consists of a 28+ hour recording from a real TV >> source. It's a "real world" scenario but the file is about 90 >> gigabytes. > > I am both able to record arbitrarily long mpegts files and to run > FFmpeg to produce long samples. > > But my question is: What goes wrong with the file? > And how can I reproduce this with a self-produced (or self- > recorded) file? The effects vary a bit. One guy in IRC basically had ffmpeg crash for him every 26.5 hours when he was saving to HLS - I don't have his actual output on me right now. I have an libav* application fail because av_write_frame() returns an error when the DTS moves backwards. Based on chatting with other people in #ffmpeg-devel it seemed like it was best to implement this correction into the demuxers themselves. Now it seems fixing libavformat/utils.c user functions may be the better way to go based on this thread so far. > > Carl Eugen > > ___ > 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] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
On 06/12/2016 12:06 PM, Carl Eugen Hoyos wrote: > DeHackEd dehacked.net> writes: > >> $ ffmpeg -r 5 -f lavfi -i testsrc -c:v libx264 -profile:v veryfast >> -t 97000 bigfile.ts > >> $ ffmpeg -i bigfile.ts -c:v copy -f null /dev/null > >> frame=487718 fps=228472 q=-1.0 Lsize=N/A time=27:05:43.00 > > So the bug is that the file gets longer when read with FFmpeg? Heh... that's my fault for copy/pasting from the wrong invocation. I have two test cases, one generated from the above testsrc and one that actually consists of a 28+ hour recording from a real TV source. It's a "real world" scenario but the file is about 90 gigabytes. > > Carl Eugen > > ___ > 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] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
On 06/12/2016 08:23 AM, Michael Niedermayer wrote: > On Sat, Jun 11, 2016 at 06:55:32PM -0400, DeHackEd wrote: >> Presently the mpegts demuxer passes the timestamps from received packets >> directly to the output AVPackets. 2^33 / 9 >> seconds is about 26.5 hours at which point applications start having a fit, >> and that's assuming timestamps begin at time 0. >> >> So here's a first revision of a patch to fix that issue. >> >> Improvements possible: >> * In its current form intended for continuous sources like over-the-air >> receivers and multicast sources. When used on >> files there will be problems with seeking. >> * Constants such as 2^33 could be turned into macros for readability > >> mpegts.c | 56 >> 1 file changed, 48 insertions(+), 8 deletions(-) >> b95c5f58685106dab1f434a3bb465ad5a0ba1636 new-pts-dts.patch >> From d06a3bd39fc4f01b9ce6132d80634dd31be7b1aa Mon Sep 17 00:00:00 2001 >> From: DHE <g...@dehacked.net> >> Date: Mon, 30 May 2016 18:31:43 -0400 >> Subject: [PATCH] libavformat/mpegts: Prevent wrapping of PTS & DTS > > this could cause issues with seeking (as the same packet could > result in different timestamps depending on luck) as well as subtitles > (which could get misidentified as wraps) Yes, I found that in testing. Unfortunately I don't know enough about ffmpeg to fix that myself at this time. It's a big reason I'm posting this patch as [RFC]. > also mpeg-ps has the same kind of timestamps, > If there is an issue that would affect it too, a fix should be in > common code > iam not sure what issue there is though, it seems you expect something > from the demuxer that its not supposed to do. I did it this way because 1) it's the issue I personally ran into, and 2) I was talking about it in #ffmpeg-devel and was told "mpegts demuxer should handle the wrapping in itself and just output timestamps that are rising"[1], so I did. > mpeg-ps/ts have 33bit timestamps and they wrap, anything done to > the wraping belongs to the user applications or common code in > libavformat. > > If you want to remove timestamp discontinuities in libavformat properly > or just wraps, thats more complex and will require keeping track of > where the discontinuities are so that seeking around in the virtual > continuous timeline works and is fully consistant > -- [1] http://ffmpeg.gusari.org/irclogs/2016/05/30/ffmpeg-devel.log.20160530 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
On 06/12/2016 04:07 AM, Carl Eugen Hoyos wrote: > DeHackEd dehacked.net> writes: > >> So here's a first revision of a patch to fix that issue. > > How can I reproduce the issue? 1) Produce a very long video, around 27 hours long or so, in mpegts format $ ffmpeg -r 5 -f lavfi -i testsrc -c:v libx264 -profile:v veryfast -t 97000 bigfile.ts 2) Process the created video to anything else. $ ffmpeg -i bigfile.ts -c:v copy -f null /dev/null What I saw output (I think this is going to get mangled by my mail client): Input #0, mpegts, from 'longvideo.ts': Duration: 00:34:59.88, start: 1.80, bitrate: 697 kb/s Program 1 Metadata: service_name: Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High 4:4:4 Predictive) ([27][0][0][0] / 0x001B), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 5 fps, 5 tbr, 90k tbn [null @ 0x341f160] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead. Output #0, null, to '/dev/null': Metadata: encoder : Lavf57.36.100 Stream #0:0: Video: h264 ([27][0][0][0] / 0x001B), yuv444p, 320x240 [SAR 1:1 DAR 4:3], q=2-31, 5 fps, 5 tbr, 90k tbn Stream mapping: Stream #0:0 -> #0:0 (copy) Press [q] to stop, [?] for help [mpegts @ 0x3419440] Invalid timestamps stream=0, pts=43408, dts=8589888000, size=535 [mpegts @ 0x3419440] Invalid timestamps stream=0, pts=7408, dts=8589906000, size=157 frame=487718 fps=228472 q=-1.0 Lsize=N/A time=27:05:43.00 bitrate=N/A speed=4.57e+04x video:121012kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown > > Imo, the reindentation makes your patch very difficult to read. > Yeah, sorry but it seemed like the thing to do for that one block. It just adds initializers for the two new fields in the PESContext. > Carl Eugen > > ___ > 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] [RFC] libavformat/mpegts: Prevent wrapping of PTS & DTS
Presently the mpegts demuxer passes the timestamps from received packets directly to the output AVPackets. 2^33 / 9 seconds is about 26.5 hours at which point applications start having a fit, and that's assuming timestamps begin at time 0. So here's a first revision of a patch to fix that issue. Improvements possible: * In its current form intended for continuous sources like over-the-air receivers and multicast sources. When used on files there will be problems with seeking. * Constants such as 2^33 could be turned into macros for readability >From d06a3bd39fc4f01b9ce6132d80634dd31be7b1aa Mon Sep 17 00:00:00 2001 From: DHEDate: Mon, 30 May 2016 18:31:43 -0400 Subject: [PATCH] libavformat/mpegts: Prevent wrapping of PTS & DTS --- libavformat/mpegts.c | 56 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 7d78c41..a4d6bce 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -237,6 +237,10 @@ typedef struct PESContext { int extended_stream_id; uint8_t stream_id; int64_t pts, dts; +/* for makings pts/dts consistent on long-running feeds */ +int64_t last_dts; +unsigned int dts_wraps; + int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ uint8_t header[MAX_PES_HEADER_SIZE]; AVBufferRef *buffer; @@ -341,6 +345,39 @@ static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int } } +static void fix_pts_dts(PESContext *pes) { +int64_t currdts; + +if (pes->last_dts == AV_NOPTS_VALUE) { +pes->last_dts = pes->dts; +return; +} + +// calculate the value we use for measurements against the last good value +currdts = pes->dts + (1ULL << 33) * pes->dts_wraps; + +if (currdts < pes->last_dts) { +/* While wrapping backwards should never happen unless we overflow, bad + * input does happen. Don't wrap if the reverse in timestamps is small. + * I have selected 9 (1 second) semi-arbitrarily. + */ +if ((pes->last_dts - currdts) < 9) { +pes->last_dts = currdts; +return; +} +currdts += 1ULL << 33; +pes->dts_wraps++; +av_log(pes->ts->stream, AV_LOG_INFO, "Stream timestamps wrapping\n"); +} + +pes->last_dts = pes->dts = currdts; + +// Now fix the pts in the much the same way. It is always true that dts <= pts +pes->pts += (1ULL << 33) * pes->dts_wraps; +while (pes->pts < pes->dts) +pes->pts += 1ULL << 33; +} + /** * @brief discard_pid() decides if the pid is to be discarded according * to caller's programs selection @@ -1136,6 +1173,7 @@ skip: pes->dts = ff_parse_pes_pts(r); r += 5; } +fix_pts_dts(pes); pes->extended_stream_id = -1; if (flags & 0x01) { /* PES extension */ pes_ext = *r++; @@ -1268,14 +1306,16 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) pes = av_mallocz(sizeof(PESContext)); if (!pes) return 0; -pes->ts = ts; -pes->stream = ts->stream; -pes->pid = pid; -pes->pcr_pid = pcr_pid; -pes->state = MPEGTS_SKIP; -pes->pts = AV_NOPTS_VALUE; -pes->dts = AV_NOPTS_VALUE; -tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); +pes->ts= ts; +pes->stream= ts->stream; +pes->pid = pid; +pes->pcr_pid = pcr_pid; +pes->state = MPEGTS_SKIP; +pes->pts = AV_NOPTS_VALUE; +pes->dts = AV_NOPTS_VALUE; +pes->last_dts = AV_NOPTS_VALUE; +pes->dts_wraps = 0; +tss= mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); if (!tss) { av_free(pes); return 0; -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libavformat/hlsenc: Use of uninitialized memory unlinking old files
Pinging this issue. While likely not a security concern it does cause uninitialized memory to be printed to the user's terminal and that's pretty bad. On 10/01/2015 07:21 PM, DeHackEd wrote: > From: DHE <g...@dehacked.net> > > Fixes ticket#4900 > > Signed-off-by: DHE <g...@dehacked.net> > --- > libavformat/hlsenc.c | 29 + > 1 file changed, 17 insertions(+), 12 deletions(-) > > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index 473ca3a..8daf53f 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -165,12 +165,6 @@ static int hls_delete_old_segments(HLSContext *hls) { > ret = AVERROR(ENOMEM); > goto fail; > } > -sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1; > -sub_path = av_malloc(sub_path_size); > -if (!sub_path) { > -ret = AVERROR(ENOMEM); > -goto fail; > -} > > av_strlcpy(path, dirname, path_size); > av_strlcat(path, segment->filename, path_size); > @@ -179,14 +173,23 @@ static int hls_delete_old_segments(HLSContext *hls) { > path, strerror(errno)); > } > > -av_strlcpy(sub_path, dirname, sub_path_size); > -av_strlcat(sub_path, segment->sub_filename, sub_path_size); > -if (unlink(sub_path) < 0) { > -av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: > %s\n", > - sub_path, strerror(errno)); > +if (segment->sub_filename[0] != '\0') { > +sub_path_size = strlen(dirname) + strlen(segment->sub_filename) > + 1; > +sub_path = av_malloc(sub_path_size); > +if (!sub_path) { > +ret = AVERROR(ENOMEM); > +goto fail; > +} > + > +av_strlcpy(sub_path, dirname, sub_path_size); > +av_strlcat(sub_path, segment->sub_filename, sub_path_size); > +if (unlink(sub_path) < 0) { > +av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: > %s\n", > + sub_path, strerror(errno)); > +} > +av_free(sub_path); > } > av_freep(); > -av_free(sub_path); > previous_segment = segment; > segment = previous_segment->next; > av_free(previous_segment); > @@ -312,6 +315,8 @@ static int hls_append_segment(HLSContext *hls, double > duration, int64_t pos, > > if(hls->has_subtitle) > av_strlcpy(en->sub_filename, av_basename(hls->vtt_avf->filename), > sizeof(en->sub_filename)); > +else > +en->sub_filename[0] = '\0'; > > en->duration = duration; > en->pos = pos; > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libavformat/hlsenc: Use of uninitialized memory unlinking old files
From: DHEFixes ticket#4900 Signed-off-by: DHE --- libavformat/hlsenc.c | 29 + 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 473ca3a..8daf53f 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -165,12 +165,6 @@ static int hls_delete_old_segments(HLSContext *hls) { ret = AVERROR(ENOMEM); goto fail; } -sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1; -sub_path = av_malloc(sub_path_size); -if (!sub_path) { -ret = AVERROR(ENOMEM); -goto fail; -} av_strlcpy(path, dirname, path_size); av_strlcat(path, segment->filename, path_size); @@ -179,14 +173,23 @@ static int hls_delete_old_segments(HLSContext *hls) { path, strerror(errno)); } -av_strlcpy(sub_path, dirname, sub_path_size); -av_strlcat(sub_path, segment->sub_filename, sub_path_size); -if (unlink(sub_path) < 0) { -av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n", - sub_path, strerror(errno)); +if (segment->sub_filename[0] != '\0') { +sub_path_size = strlen(dirname) + strlen(segment->sub_filename) + 1; +sub_path = av_malloc(sub_path_size); +if (!sub_path) { +ret = AVERROR(ENOMEM); +goto fail; +} + +av_strlcpy(sub_path, dirname, sub_path_size); +av_strlcat(sub_path, segment->sub_filename, sub_path_size); +if (unlink(sub_path) < 0) { +av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n", + sub_path, strerror(errno)); +} +av_free(sub_path); } av_freep(); -av_free(sub_path); previous_segment = segment; segment = previous_segment->next; av_free(previous_segment); @@ -312,6 +315,8 @@ static int hls_append_segment(HLSContext *hls, double duration, int64_t pos, if(hls->has_subtitle) av_strlcpy(en->sub_filename, av_basename(hls->vtt_avf->filename), sizeof(en->sub_filename)); +else +en->sub_filename[0] = '\0'; en->duration = duration; en->pos = pos; -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libx264: copy A53 closed captions from source
Assumes 'GA94' format (ATSC standard) Signed-off-by: DHE--- doc/encoders.texi| 4 libavcodec/libx264.c | 45 + 2 files changed, 49 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 3550bcc..f2d46dc 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2069,6 +2069,10 @@ For example to specify libx264 encoding options with @command{ffmpeg}: ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv @end example +@item a53cc @var{boolean} +Import closed captions (which must be ATSC compatible format) into output. +Only the mpeg2 and h264 decoders provide these. Default is 0 (off). + @item x264-params (N.A.) Override the x264 configuration using a :-separated list of key=value parameters. diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 58fcfb0..d4509d6 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -25,6 +25,7 @@ #include "libavutil/mem.h" #include "libavutil/pixdesc.h" #include "libavutil/stereo3d.h" +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" @@ -83,6 +84,7 @@ typedef struct X264Context { int avcintra_class; int motion_est; int forced_idr; +int a53_cc; char *x264_params; } X264Context; @@ -256,6 +258,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; +AVFrameSideData *side_data; x264_picture_init( >pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -278,7 +281,48 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264_TYPE_AUTO; reconfig_encoder(ctx, frame); + +if (x4->a53_cc) { +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); +if (side_data) { +x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); +if (x4->pic.extra_sei.payloads == NULL) { +av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); +goto skip_a53cc; +} +x4->pic.extra_sei.sei_free = av_free; + +x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11; +x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); +if (x4->pic.extra_sei.payloads[0].payload == NULL) { +av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); +av_freep(>pic.extra_sei.payloads); +goto skip_a53cc; +} +x4->pic.extra_sei.num_payloads = 1; +x4->pic.extra_sei.payloads[0].payload_type = 4; +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size); +x4->pic.extra_sei.payloads[0].payload[0] = 181; +x4->pic.extra_sei.payloads[0].payload[1] = 0; +x4->pic.extra_sei.payloads[0].payload[2] = 49; + +/** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ +AV_WL32(x4->pic.extra_sei.payloads[0].payload + 3, +MKTAG('G', 'A', '9', '4')); +x4->pic.extra_sei.payloads[0].payload[7] = 3; +x4->pic.extra_sei.payloads[0].payload[8] = +((side_data->size/3) & 0x1f) | 0x40; +x4->pic.extra_sei.payloads[0].payload[9] = 0; +x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255; +} +} } +skip_a53cc: do { if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0) return AVERROR_EXTERNAL; @@ -821,6 +865,7 @@ static const AVOption options[] = { {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, +{"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE}, {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, {
Re: [FFmpeg-devel] [PATCH] libx264: copy A53 closed captions from source
Assumes 'GA94' format (ATSC standard) Signed-off-by: DHE--- doc/encoders.texi| 4 libavcodec/libx264.c | 46 ++ 2 files changed, 50 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 3550bcc..f2d46dc 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2069,6 +2069,10 @@ For example to specify libx264 encoding options with @command{ffmpeg}: ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv @end example +@item a53cc @var{boolean} +Import closed captions (which must be ATSC compatible format) into output. +Only the mpeg2 and h264 decoders provide these. Default is 0 (off). + @item x264-params (N.A.) Override the x264 configuration using a :-separated list of key=value parameters. diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 58fcfb0..9dc342a 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -83,6 +83,7 @@ typedef struct X264Context { int avcintra_class; int motion_est; int forced_idr; +int a53_cc; char *x264_params; } X264Context; @@ -256,6 +257,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; +AVFrameSideData *side_data; x264_picture_init( >pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -278,7 +280,50 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264_TYPE_AUTO; reconfig_encoder(ctx, frame); + +if (x4->a53_cc) { +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); +if (side_data) { +x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); +if (x4->pic.extra_sei.payloads == NULL) { +av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); +goto skip_a53cc; +} +x4->pic.extra_sei.sei_free = av_free; + +x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11; +x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); +if (x4->pic.extra_sei.payloads[0].payload == NULL) { +av_log(ctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n"); +av_freep(>pic.extra_sei.payloads); +goto skip_a53cc; +} +x4->pic.extra_sei.num_payloads = 1; +x4->pic.extra_sei.payloads[0].payload_type = 4; +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size); +x4->pic.extra_sei.payloads[0].payload[0] = 181; +x4->pic.extra_sei.payloads[0].payload[1] = 0; +x4->pic.extra_sei.payloads[0].payload[2] = 49; + +/** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ +x4->pic.extra_sei.payloads[0].payload[3] = 'G'; +x4->pic.extra_sei.payloads[0].payload[4] = 'A'; +x4->pic.extra_sei.payloads[0].payload[5] = '9'; +x4->pic.extra_sei.payloads[0].payload[6] = '4'; +x4->pic.extra_sei.payloads[0].payload[7] = 3; +x4->pic.extra_sei.payloads[0].payload[8] = +((side_data->size/3) & 0x1f) | 0x40; +x4->pic.extra_sei.payloads[0].payload[9] = 0; +x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255; +} +} } +skip_a53cc: do { if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0) return AVERROR_EXTERNAL; @@ -821,6 +866,7 @@ static const AVOption options[] = { {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, +{"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, VE}, {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, { "crf_max", "In CRF mode, prevents VBV from
Re: [FFmpeg-devel] [PATCH] libx264: copy A53 closed captions from source
On 09/26/2015 05:26 AM, Anshul wrote: > > > On 09/26/2015 05:46 AM, DeHackEd wrote: >> Assumes 'GA94' format (ATSC standard) >> >> Signed-off-by: DHE <g...@dehacked.net> >> --- >> doc/encoders.texi| 5 + >> libavcodec/libx264.c | 37 + >> 2 files changed, 42 insertions(+) >> >> diff --git a/doc/encoders.texi b/doc/encoders.texi >> index 3550bcc..bb16dea 100644 >> --- a/doc/encoders.texi >> +++ b/doc/encoders.texi >> @@ -2069,6 +2069,11 @@ For example to specify libx264 encoding options with >> @command{ffmpeg}: >> ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an >> out.mkv >> @end example >> >> +@item a53cc >> +Import closed captions (which must be ATSC compatible format) into output. >> +Only the mpeg2 and h264 decoders provide these. Default is 0 (off). >> + >> + >> @item x264-params (N.A.) >> Override the x264 configuration using a :-separated list of key=value >> parameters. >> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c >> index 58fcfb0..4227bcc 100644 >> --- a/libavcodec/libx264.c >> +++ b/libavcodec/libx264.c >> @@ -83,6 +83,7 @@ typedef struct X264Context { >> int avcintra_class; >> int motion_est; >> int forced_idr; >> +int a53_cc; >> char *x264_params; >> } X264Context; >> >> @@ -256,6 +257,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket >> *pkt, const AVFrame *frame, >> int nnal, i, ret; >> x264_picture_t pic_out = {0}; >> int pict_type; >> +AVFrameSideData *side_data; >> >> x264_picture_init( >pic ); >> x4->pic.img.i_csp = x4->params.i_csp; >> @@ -278,6 +280,40 @@ static int X264_frame(AVCodecContext *ctx, AVPacket >> *pkt, const AVFrame *frame, >> X264_TYPE_AUTO; >> >> reconfig_encoder(ctx, frame); >> + >> +if (x4->a53_cc) { >> +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); >> +if (side_data) { >> +x4->pic.extra_sei.num_payloads = 1; >> +x4->pic.extra_sei.payloads = >> av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); >> +x4->pic.extra_sei.sei_free = av_free; >> + >> +x4->pic.extra_sei.payloads[0].payload_size = >> side_data->size + 11; >> +x4->pic.extra_sei.payloads[0].payload = >> av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); >> +x4->pic.extra_sei.payloads[0].payload_type = 4; >> +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, >> side_data->data, side_data->size); >> +x4->pic.extra_sei.payloads[0].payload[0] = 181; >> +x4->pic.extra_sei.payloads[0].payload[1] = 0; >> +x4->pic.extra_sei.payloads[0].payload[2] = 49; >> + >> +/** >> + * 'GA94' is standard in North America for ATSC, but hard >> coding >> + * this style may not be the right thing to do -- other >> formats >> + * do exist. This information is not available in the >> side_data >> + * so we are going with this right now. >> + */ > I think GA94 is correct for this situation, since in our x264 decoder we > don't consider any other standard > for extracting closed caption. > > I don't know if we have any logic which differentiate between ATSC, ISDB or > DVB we parse all transport stream > in same manner. if someone know where we differentiate atsc and dvb in FFmpeg > please point me there. > > Note: This logic will also fail when x264 is muxed in formats like gxf where > closed caption are kept in vbi instead > of GA94. > > Overall LGTM. > > I don't know how to apply encrypted mails using git, and when I save your > email in Thunderbird, git am is unable to apply. > if you can send the same patch as attachment or command to convert encrypted > .eml file to normal patch I would test this > too. I think the easiest solution is to grab the patch from the github repo I use: https://github.com/DeHackEd/FFmpeg/commit/16b4c7fc2311d672e99f.patch I think my mail client wrapped some lines. Sorry, this is my first patch-by-email. > > -Anshul > > > ___ > 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] libx264: copy A53 closed captions from source
Assumes 'GA94' format (ATSC standard) Signed-off-by: DHE--- doc/encoders.texi| 5 + libavcodec/libx264.c | 37 + 2 files changed, 42 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 3550bcc..aabbda0 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2069,6 +2069,11 @@ For example to specify libx264 encoding options with @command{ffmpeg}: ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv @end example +@item a53cc @var{boolean} +Import closed captions (which must be ATSC compatible format) into output. +Only the mpeg2 and h264 decoders provide these. Default is 0 (off). + + @item x264-params (N.A.) Override the x264 configuration using a :-separated list of key=value parameters. diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 58fcfb0..8540ff9 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -83,6 +83,7 @@ typedef struct X264Context { int avcintra_class; int motion_est; int forced_idr; +int a53_cc; char *x264_params; } X264Context; @@ -256,6 +257,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; +AVFrameSideData *side_data; x264_picture_init( >pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -278,6 +280,40 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264_TYPE_AUTO; reconfig_encoder(ctx, frame); + +if (x4->a53_cc) { +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); +if (side_data) { +x4->pic.extra_sei.num_payloads = 1; +x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); +x4->pic.extra_sei.sei_free = av_free; + +x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11; +x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); +x4->pic.extra_sei.payloads[0].payload_type = 4; +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size); +x4->pic.extra_sei.payloads[0].payload[0] = 181; +x4->pic.extra_sei.payloads[0].payload[1] = 0; +x4->pic.extra_sei.payloads[0].payload[2] = 49; + +/** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ +x4->pic.extra_sei.payloads[0].payload[3] = 'G'; +x4->pic.extra_sei.payloads[0].payload[4] = 'A'; +x4->pic.extra_sei.payloads[0].payload[5] = '9'; +x4->pic.extra_sei.payloads[0].payload[6] = '4'; +x4->pic.extra_sei.payloads[0].payload[7] = 3; +x4->pic.extra_sei.payloads[0].payload[8] = +((side_data->size/3) & 0x1f) | 0x40; +x4->pic.extra_sei.payloads[0].payload[9] = 0; +x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255; +} +} + } do { if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0) @@ -821,6 +857,7 @@ static const AVOption options[] = { {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, +{"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_INT,{.i64 = 0}, 0, 1, VE}, {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] libx264: copy A53 closed captions from source
Assumes 'GA94' format (ATSC standard) Signed-off-by: DHE--- doc/encoders.texi| 5 + libavcodec/libx264.c | 37 + 2 files changed, 42 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 3550bcc..8e3770b 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2069,6 +2069,11 @@ For example to specify libx264 encoding options with @command{ffmpeg}: ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv @end example +@item a53cc +Import closed captions (which must be ATSC compatible format) into output. +At this time only the mpeg2 decoder provides these. Default is 0 (off). + + @item x264-params (N.A.) Override the x264 configuration using a :-separated list of key=value parameters. diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 58fcfb0..4227bcc 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -83,6 +83,7 @@ typedef struct X264Context { int avcintra_class; int motion_est; int forced_idr; +int a53_cc; char *x264_params; } X264Context; @@ -256,6 +257,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; +AVFrameSideData *side_data; x264_picture_init( >pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -278,6 +280,40 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264_TYPE_AUTO; reconfig_encoder(ctx, frame); + +if (x4->a53_cc) { +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); +if (side_data) { +x4->pic.extra_sei.num_payloads = 1; +x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); +x4->pic.extra_sei.sei_free = av_free; + +x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11; +x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); +x4->pic.extra_sei.payloads[0].payload_type = 4; +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size); +x4->pic.extra_sei.payloads[0].payload[0] = 181; +x4->pic.extra_sei.payloads[0].payload[1] = 0; +x4->pic.extra_sei.payloads[0].payload[2] = 49; + +/** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ +x4->pic.extra_sei.payloads[0].payload[3] = 'G'; +x4->pic.extra_sei.payloads[0].payload[4] = 'A'; +x4->pic.extra_sei.payloads[0].payload[5] = '9'; +x4->pic.extra_sei.payloads[0].payload[6] = '4'; +x4->pic.extra_sei.payloads[0].payload[7] = 3; +x4->pic.extra_sei.payloads[0].payload[8] = + ((side_data->size/3) & 0x1f) | 0x40; +x4->pic.extra_sei.payloads[0].payload[9] = 0; +x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255; +} +} + } do { if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0) @@ -821,6 +857,7 @@ static const AVOption options[] = { {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, +{"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, VE}, {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libx264: copy A53 closed captions from source
On 09/25/2015 07:45 PM, Carl Eugen Hoyos wrote: > DeHackEd dehacked.net> writes: > >> + item a53cc >> +Import closed captions (which must be ATSC compatible format) into output. >> +At this time only the mpeg2 decoder provides these. > > I thought the h264 decoder also provides them, no? Indeed, you are correct. Not sure how I missed that. A quick test (using my own output) came up positive so I'll just update the docs. > > Carl Eugen > > ___ > 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] libx264: copy A53 closed captions from source
Assumes 'GA94' format (ATSC standard) Signed-off-by: DHE--- doc/encoders.texi| 5 + libavcodec/libx264.c | 37 + 2 files changed, 42 insertions(+) diff --git a/doc/encoders.texi b/doc/encoders.texi index 3550bcc..bb16dea 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -2069,6 +2069,11 @@ For example to specify libx264 encoding options with @command{ffmpeg}: ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv @end example +@item a53cc +Import closed captions (which must be ATSC compatible format) into output. +Only the mpeg2 and h264 decoders provide these. Default is 0 (off). + + @item x264-params (N.A.) Override the x264 configuration using a :-separated list of key=value parameters. diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 58fcfb0..4227bcc 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -83,6 +83,7 @@ typedef struct X264Context { int avcintra_class; int motion_est; int forced_idr; +int a53_cc; char *x264_params; } X264Context; @@ -256,6 +257,7 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int nnal, i, ret; x264_picture_t pic_out = {0}; int pict_type; +AVFrameSideData *side_data; x264_picture_init( >pic ); x4->pic.img.i_csp = x4->params.i_csp; @@ -278,6 +280,40 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, X264_TYPE_AUTO; reconfig_encoder(ctx, frame); + +if (x4->a53_cc) { +side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_A53_CC); +if (side_data) { +x4->pic.extra_sei.num_payloads = 1; +x4->pic.extra_sei.payloads = av_mallocz(sizeof(x4->pic.extra_sei.payloads[0])); +x4->pic.extra_sei.sei_free = av_free; + +x4->pic.extra_sei.payloads[0].payload_size = side_data->size + 11; +x4->pic.extra_sei.payloads[0].payload = av_mallocz(x4->pic.extra_sei.payloads[0].payload_size); +x4->pic.extra_sei.payloads[0].payload_type = 4; +memcpy(x4->pic.extra_sei.payloads[0].payload + 10, side_data->data, side_data->size); +x4->pic.extra_sei.payloads[0].payload[0] = 181; +x4->pic.extra_sei.payloads[0].payload[1] = 0; +x4->pic.extra_sei.payloads[0].payload[2] = 49; + +/** + * 'GA94' is standard in North America for ATSC, but hard coding + * this style may not be the right thing to do -- other formats + * do exist. This information is not available in the side_data + * so we are going with this right now. + */ +x4->pic.extra_sei.payloads[0].payload[3] = 'G'; +x4->pic.extra_sei.payloads[0].payload[4] = 'A'; +x4->pic.extra_sei.payloads[0].payload[5] = '9'; +x4->pic.extra_sei.payloads[0].payload[6] = '4'; +x4->pic.extra_sei.payloads[0].payload[7] = 3; +x4->pic.extra_sei.payloads[0].payload[8] = + ((side_data->size/3) & 0x1f) | 0x40; +x4->pic.extra_sei.payloads[0].payload[9] = 0; +x4->pic.extra_sei.payloads[0].payload[side_data->size+10] = 255; +} +} + } do { if (x264_encoder_encode(x4->enc, , , frame? >pic: NULL, _out) < 0) @@ -821,6 +857,7 @@ static const AVOption options[] = { {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, +{"a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc),AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, VE}, {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE}, { "crf", "Select the quality for constant quality mode", OFFSET(crf), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, { "crf_max", "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE }, -- 1.8.4.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel