[FFmpeg-cvslog] avformat/hlsenc: fix default AES key file url with variant streams
ffmpeg | branch: master | Bela Bodecs | Sun Jan 19 23:01:32 2020 +0100| [8c3e9c9cbb725b6fdfe008ded702f3dd8025a58d] | committer: Steven Liu avformat/hlsenc: fix default AES key file url with variant streams Currently when hls_enc is active and there are multiple variant stream outputs, default key file url construction does not work, because it is based on the FormatContext' url field. But in case of multiple variant streams, it contains the variant m3u8 output playlist url that contains the %v placeholder. So the result key file url will hold the %v placeholder causing run time error message about "could not write the key file". This patch correct this behaviour, and use the master playlist url for constructing the output key file url when master playlist is vailable. Signed-off-by: Bela Bodecs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8c3e9c9cbb725b6fdfe008ded702f3dd8025a58d --- libavformat/hlsenc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 13f34197ed..2b3d3742d9 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -642,13 +642,14 @@ static int do_encrypt(AVFormatContext *s, VariantStream *vs) int len; AVIOContext *pb; uint8_t key[KEYSIZE]; +char * key_basename_source = (hls->master_m3u8_url) ? hls->master_m3u8_url : s->url; -len = strlen(s->url) + 4 + 1; +len = strlen(key_basename_source) + 4 + 1; hls->key_basename = av_mallocz(len); if (!hls->key_basename) return AVERROR(ENOMEM); -av_strlcpy(hls->key_basename, s->url, len); +av_strlcpy(hls->key_basename, key_basename_source, len); av_strlcat(hls->key_basename, ".key", len); if (hls->key_url) { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/hlsenc: program_date_time and append_list flags conflict
ffmpeg | branch: master | Bela Bodecs | Sat Jan 18 17:41:55 2020 +0100| [dd5c7378bb92f174e7b3b36df3d7685ed60f29c6] | committer: Steven Liu avformat/hlsenc: program_date_time and append_list flags conflict When program_date_time flag is present, in m3u8 playlist file each segment has a corresponding EXT-X-PROGRAM-DATE-TIME value. The intial program-date-time value is the actual current time at init and each new segment increments this value by its duration. When append_list flags is also present, existing playlist parsing by hls_append_segment treats existing segments as new segments regarding the program-date-time calculation. But it should not do that, because this way all real the new segments' EXT-X-PROGRAM-DATE-TIME values will be shifted erroneously by the sum duration of existing segments. Instead it should have decremented the initial program-date-time value by its duration. This would ensure that the first new segment's program-date-time value had the current time as it is expected. This patch corrects this behaviour and prevent existing segments to increment the value of initial_prog_date_time variable but decrements it. Reviewed-by: Steven Liu Signed-off-by: Bela Bodecs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dd5c7378bb92f174e7b3b36df3d7685ed60f29c6 --- libavformat/hlsenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index e87f08b0e6..13f34197ed 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1187,6 +1187,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs is_segment = 0; new_start_pos = avio_tell(vs->avf->pb); vs->size = new_start_pos - vs->start_pos; +vs->initial_prog_date_time -= vs->duration; // this is a previously existing segment ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size); if (ret < 0) goto fail; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/hlsenc: changing all filename length to MAX_URL_SIZE
ffmpeg | branch: master | Bela Bodecs | Mon Jul 1 10:24:21 2019 +0800| [1476d82e7330623e2f105ff0f4a6d315325d7880] | committer: Steven Liu avformat/hlsenc: changing all filename length to MAX_URL_SIZE Throughout hlsenc code, all filename related buffer lengths are set hardcoded as 1024. This PATCH change it to general value as MAX_URL_SIZE in internal.h Reviewed-by: Steven Liu Signed-off-by: Bela Bodecs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1476d82e7330623e2f105ff0f4a6d315325d7880 --- libavformat/hlsenc.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 5b0121f016..057134f410 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -64,13 +64,13 @@ typedef enum { } CodecAttributeStatus; #define KEYSIZE 16 -#define LINE_BUFFER_SIZE 1024 +#define LINE_BUFFER_SIZE MAX_URL_SIZE #define HLS_MICROSECOND_UNIT 100 #define POSTFIX_PATTERN "_%d" typedef struct HLSSegment { -char filename[1024]; -char sub_filename[1024]; +char filename[MAX_URL_SIZE]; +char sub_filename[MAX_URL_SIZE]; double duration; /* in seconds */ int discont; int64_t pos; @@ -149,7 +149,7 @@ typedef struct VariantStream { char *m3u8_name; double initial_prog_date_time; -char current_segment_final_filename_fmt[1024]; // when renaming segments +char current_segment_final_filename_fmt[MAX_URL_SIZE]; // when renaming segments char *fmp4_init_filename; char *base_output_dirname; @@ -,7 +,7 @@ static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs AVIOContext *in; int ret = 0, is_segment = 0; int64_t new_start_pos; -char line[1024]; +char line[MAX_URL_SIZE]; const char *ptr; const char *end; @@ -1268,7 +1268,7 @@ static int create_master_playlist(AVFormatContext *s, const char *proto = avio_find_protocol_name(hls->master_m3u8_url); int is_file_proto = proto && !strcmp(proto, "file"); int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || hls->master_publish_rate); -char temp_filename[1024]; +char temp_filename[MAX_URL_SIZE]; input_vs->m3u8_created = 1; if (!hls->master_m3u8_created) { @@ -1433,8 +1433,8 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) HLSSegment *en; int target_duration = 0; int ret = 0; -char temp_filename[1024]; -char temp_vtt_filename[1024]; +char temp_filename[MAX_URL_SIZE]; +char temp_vtt_filename[MAX_URL_SIZE]; int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries); const char *proto = avio_find_protocol_name(vs->m3u8_name); int is_file_proto = proto && !strcmp(proto, "file"); @@ -1594,7 +1594,7 @@ static int hls_start(AVFormatContext *s, VariantStream *vs) if (c->use_localtime) { time_t now0; struct tm *tm, tmpbuf; -int bufsize = strlen(vs->basename) + 1024; +int bufsize = strlen(vs->basename) + MAX_URL_SIZE; char *buf = av_mallocz(bufsize); if (!buf) return AVERROR(ENOMEM); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/hlsenc: temp_file usage for master playlist and vtt playlist
ffmpeg | branch: master | Bela Bodecs | Fri Jun 28 13:54:27 2019 +0800| [098ab932579ea6d81e0b928f09b425fdd00a2890] | committer: Steven Liu avformat/hlsenc: temp_file usage for master playlist and vtt playlist currently master playlist and subtitle playlist creation does not use temporary files even when temp_file flag is set. Most of the use cases it is not a problem because master playlist creation happens once on the beginning of the whole process. But if master playlist is periodically re-created because of master_pl_refresh_rate is set, non-atomic playlist creation may cause problems in case of live streaming. This patch correct this behavior by adding this functionality. Reviewed-by: Steven Liu Signed-off-by: Bela Bodecs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=098ab932579ea6d81e0b928f09b425fdd00a2890 --- doc/muxers.texi | 6 +- libavformat/hlsenc.c | 30 +- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 59c93bc687..dd64672b85 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -893,7 +893,11 @@ This will produce segments like this: @item temp_file Write segment data to filename.tmp and rename to filename only once the segment is complete. A webserver serving up segments can be configured to reject requests to *.tmp to prevent access to in-progress segments -before they have been added to the m3u8 playlist. +before they have been added to the m3u8 playlist. This flag also affects how m3u8 playlist files are created. +If this flag is set, all playlist files will written into temporary file and renamed after they are complete, similarly as segments are handled. +But playlists with @code{file} protocol and with type (@code{hls_playlist_type}) other than @code{vod} +are always written into temporary file regardles of this flag. Master playlist files (@code{master_pl_name}), if any, with @code{file} protocol, +are always written into temporary file regardles of this flag if @code{master_pl_publish_rate} value is other than zero. @end table diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 37ae128f4f..5b0121f016 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1263,8 +1263,12 @@ static int create_master_playlist(AVFormatContext *s, AVDictionary *options = NULL; unsigned int i, j; int m3u8_name_size, ret, bandwidth; -char *m3u8_rel_name, *ccgroup; +char *m3u8_rel_name = NULL, *ccgroup; ClosedCaptionsStream *ccs; +const char *proto = avio_find_protocol_name(hls->master_m3u8_url); +int is_file_proto = proto && !strcmp(proto, "file"); +int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || hls->master_publish_rate); +char temp_filename[1024]; input_vs->m3u8_created = 1; if (!hls->master_m3u8_created) { @@ -1280,12 +1284,12 @@ static int create_master_playlist(AVFormatContext *s, } set_http_options(s, , hls); - -ret = hlsenc_io_open(s, >m3u8_out, hls->master_m3u8_url, ); +snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", hls->master_m3u8_url); +ret = hlsenc_io_open(s, >m3u8_out, temp_filename, ); av_dict_free(); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file '%s'\n", -hls->master_m3u8_url); +temp_filename); goto fail; } @@ -1416,7 +1420,10 @@ fail: if(ret >=0) hls->master_m3u8_created = 1; av_freep(_rel_name); -hlsenc_io_close(s, >m3u8_out, hls->master_m3u8_url); +hlsenc_io_close(s, >m3u8_out, temp_filename); +if (use_temp_file) +ff_rename(temp_filename, hls->master_m3u8_url, s); + return ret; } @@ -1427,6 +1434,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) int target_duration = 0; int ret = 0; char temp_filename[1024]; +char temp_vtt_filename[1024]; int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries); const char *proto = avio_find_protocol_name(vs->m3u8_name); int is_file_proto = proto && !strcmp(proto, "file"); @@ -1508,8 +1516,9 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs) if (last && (hls->flags & HLS_OMIT_ENDLIST)==0) ff_hls_write_end_list(hls->m3u8_out); -if( vs->vtt_m3u8_name ) { -if ((ret = hlsenc_io_open(s, >sub_m3u8_out, vs->vtt_m3u8_name, )) < 0) { +if (vs->vtt_m3u8_name) { +snprintf(temp_vtt_filename, sizeof(temp_vtt_filename), use_temp_file ? "%s.tmp" : "%s", vs->vtt_m3u8_name); +if ((ret = hlsenc_io_open(s, >sub_m3u8_out, temp_vtt_filename, )) < 0) { if (hls->i
[FFmpeg-cvslog] avformat/hlsenc: better error log message for var_stream_map content
ffmpeg | branch: master | Bela Bodecs | Sat Jun 22 15:55:54 2019 +0200| [2045dd0050f1ef0df348e11bd44657c2475aa7c3] | committer: Steven Liu avformat/hlsenc: better error log message for var_stream_map content When multiple variant streams are specified by var_stream_map option, %v is expected either in the filename or in the last sub-directory name, but only in one of them. When both of them contains %v string, current error message only states half of the truth. And even %v may appears several times inside the last sub-directory name or in filename pattern. This patch clarifies this in the log message and in the doc also. Signed-off-by: Bela Bodecs > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2045dd0050f1ef0df348e11bd44657c2475aa7c3 --- doc/muxers.texi | 3 ++- libavformat/hlsenc.c | 8 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 4410a5f5bb..6c5b4bb637 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -656,7 +656,8 @@ This example will produce the playlists segment file sets: @file{file_1_000.ts}, @file{file_1_001.ts}, @file{file_1_002.ts}, etc. The string "%v" may be present in the filename or in the last directory name -containing the file. If the string is present in the directory name, then +containing the file, but only in one of them. (Additionally, %v may appear multiple times in the last +sub-directory or filename.) If the string %v is present in the directory name, then sub-directories are created after expanding the directory name pattern. This enables creation of segments corresponding to different variant streams in subdirectories. diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index f6330ec2d5..9f5eee5491 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1792,15 +1792,15 @@ static int validate_name(int nb_vs, const char *fn) subdir_name = av_dirname(fn_dup); if (nb_vs > 1 && !av_stristr(filename, "%v") && !av_stristr(subdir_name, "%v")) { -av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected in the filename %s\n", -fn); +av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected " + "either in the filename or in the sub-directory name of file %s\n", fn); ret = AVERROR(EINVAL); goto fail; } if (av_stristr(filename, "%v") && av_stristr(subdir_name, "%v")) { -av_log(NULL, AV_LOG_ERROR, "%%v is expected either in filename or in the sub-directory name of file %s\n", -fn); +av_log(NULL, AV_LOG_ERROR, "%%v is expected either in the filename or " + "in the sub-directory name of file %s, but only in one of them\n", fn); ret = AVERROR(EINVAL); goto fail; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/hlsenc: better checking var_stream_map content
ffmpeg | branch: master | Bela Bodecs | Wed Jun 19 10:25:36 2019 +0200| [1beeb3b877d00385c80b1750b45fa4f5e2d96301] | committer: Steven Liu avformat/hlsenc: better checking var_stream_map content When multiple variant streams are specified by var_stream_map option, implementation assumes that each elementary stream is assigned only once to any variant. But this is not checked. This patch makes this checking. Signed-off-by: Bela Bodecs Reviewed-by: Steven Liu > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1beeb3b877d00385c80b1750b45fa4f5e2d96301 --- libavformat/hlsenc.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index b4cb0364b4..f6330ec2d5 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -1885,7 +1885,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) { HLSContext *hls = s->priv_data; VariantStream *vs; -int stream_index; +int stream_index, i, j; enum AVMediaType codec_type; int nb_varstreams, nb_streams; char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval; @@ -1987,6 +1987,23 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) atoi(val)); if (stream_index >= 0 && nb_streams < vs->nb_streams) { +for(i = 0; nb_streams > 0 && i < nb_streams; i++) { +if (vs->streams[i] == s->streams[stream_index]) { +av_log(s, AV_LOG_ERROR, "Same elementary stream found more than once inside " + "variant definition #%d\n", nb_varstreams - 1); +return AVERROR(EINVAL); +} +} +for(j = 0; nb_varstreams > 1 && j < nb_varstreams - 1; j++) { +for(i = 0; i < hls->var_streams[j].nb_streams; i++) { +if (hls->var_streams[j].streams[i] == s->streams[stream_index]) { +av_log(s, AV_LOG_ERROR, "Same elementary stream found more than once " + "in two different variant definitions #%d and #%d\n", + j, nb_varstreams - 1); +return AVERROR(EINVAL); +} +} +} vs->streams[nb_streams++] = s->streams[stream_index]; } else { av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-cvslog] avformat/utils: Stream specifier enhancement 2.
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Fri Apr 13 12:11:32 2018 +0200| [3e1204b94d1ab586e4a5b1fc7c51559bc2447dcd] | committer: Michael Niedermayer avformat/utils: Stream specifier enhancement 2. In some cases, mainly working with multiprogram mpeg-ts containers as input, it would be handy to select sub stream of a specific program by their metadata. This patch makes it possible to narrow the stream selection among streams of the specified program by stream metadata. Examples: p:601:m:language:hun will select all sub streams of program with id 601 where sub streams have metadata key named 'language' with value 'hun'. p:602:m:guide will select all sub streams of program with id 602 where sub streams have metadata key named 'guide'. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=3e1204b94d1ab586e4a5b1fc7c51559bc2447dcd --- doc/fftools-common-opts.texi | 10 -- libavformat/utils.c | 28 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index 79feb39ca7..84705c0b68 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -42,14 +42,20 @@ streams, 'V' only matches video streams which are not attached pictures, video thumbnails or cover arts. If @var{stream_index} is given, then it matches stream number @var{stream_index} of this type. Otherwise, it matches all streams of this type. -@item p:@var{program_id}[:@var{stream_index}] or p:@var{program_id}[:@var{stream_type}[:@var{stream_index}]] +@item p:@var{program_id}[:@var{stream_index}] or p:@var{program_id}[:@var{stream_type}[:@var{stream_index}]] or +p:@var{program_id}:m:@var{key}[:@var{value}] In first version, if @var{stream_index} is given, then it matches the stream with number @var{stream_index} in the program with the id @var{program_id}. Otherwise, it matches all streams in the -program. In the latter version, @var{stream_type} is one of following: 'v' for video, 'a' for audio, 's' +program. In the second version, @var{stream_type} is one of following: 'v' for video, 'a' for audio, 's' for subtitle, 'd' for data. If @var{stream_index} is also given, then it matches stream number @var{stream_index} of this type in the program with the id @var{program_id}. Otherwise, if only @var{stream_type} is given, it matches all streams of this type in the program with the id @var{program_id}. +In the third version matches streams in the program with the id @var{program_id} with the metadata +tag @var{key} having the specified value. If +@var{value} is not given, matches streams that contain the given tag with any +value. + @item #@var{stream_id} or i:@var{stream_id} Match the stream by stream id (e.g. PID in MPEG-TS container). @item m:@var{key}[:@var{value}] diff --git a/libavformat/utils.c b/libavformat/utils.c index cc35998336..84b926dc5a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -5124,6 +5124,34 @@ FF_ENABLE_DEPRECATION_WARNINGS } return 0; } + +} else if ( *endptr == 'm') { // p::m: +AVDictionaryEntry *tag; +char *key, *val; +int ret = 0; + +if (*(++endptr) != ':') { +av_log(s, AV_LOG_ERROR, "Invalid stream specifier syntax, missing ':' sign after :m.\n"); +return AVERROR(EINVAL); +} + +val = strchr(++endptr, ':'); +key = val ? av_strndup(endptr, val - endptr) : av_strdup(endptr); +if (!key) +return AVERROR(ENOMEM); + +for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) +if (st->index == s->programs[i]->stream_index[j]) { +tag = av_dict_get(st->metadata, key, NULL, 0); +if (tag && (!val || !strcmp(tag->value, val + 1))) +ret = 1; + +break; +} + +av_freep(); +return ret; + } else { // p:: int stream_idx = strtol(endptr, NULL, 0); return stream_idx >= 0 && ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/utils: Stream specifier enhancement
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Sun Apr 1 23:29:14 2018 +0200| [37d0213968a2b58499f52dfe09c8d7a27d4c5a86] | committer: Michael Niedermayer avformat/utils: Stream specifier enhancement Currently when specifying the program id you can only decide to select all stream of the specified program (e.g. p:103 will select all streams of program 103) or narrow the selection to a specific stream sub index (e.g. p:145:1 will select 2nd stream of program 145.) But you can not specify like all audio streams of program 145 or 3rd video stream of program 311. In some case, mainly working with multiprogram mpeg-ts containers as input, this feature would be handy. This patch makes it possible to narrow the stream selection among streams of the specified program by stream type and optionally its index. Handled types: a, v, s, d. Examples: p:601:a will select all audio streams of program 601, p:603:a:1 will select 2nd audio streams of program 603, p:604:v:0 will select first video stream of program 604. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=37d0213968a2b58499f52dfe09c8d7a27d4c5a86 --- doc/fftools-common-opts.texi | 10 +-- libavformat/utils.c | 65 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index 7787e11cda..79feb39ca7 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -42,10 +42,14 @@ streams, 'V' only matches video streams which are not attached pictures, video thumbnails or cover arts. If @var{stream_index} is given, then it matches stream number @var{stream_index} of this type. Otherwise, it matches all streams of this type. -@item p:@var{program_id}[:@var{stream_index}] -If @var{stream_index} is given, then it matches the stream with number @var{stream_index} +@item p:@var{program_id}[:@var{stream_index}] or p:@var{program_id}[:@var{stream_type}[:@var{stream_index}]] +In first version, if @var{stream_index} is given, then it matches the stream with number @var{stream_index} in the program with the id @var{program_id}. Otherwise, it matches all streams in the -program. +program. In the latter version, @var{stream_type} is one of following: 'v' for video, 'a' for audio, 's' +for subtitle, 'd' for data. If @var{stream_index} is also given, then it matches +stream number @var{stream_index} of this type in the program with the id @var{program_id}. +Otherwise, if only @var{stream_type} is given, it matches all +streams of this type in the program with the id @var{program_id}. @item #@var{stream_id} or i:@var{stream_id} Match the stream by stream id (e.g. PID in MPEG-TS container). @item m:@var{key}[:@var{value}] diff --git a/libavformat/utils.c b/libavformat/utils.c index 3e482a3bbc..cc35998336 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -5070,11 +5070,66 @@ FF_ENABLE_DEPRECATION_WARNINGS if (s->programs[i]->id != prog_id) continue; -if (*endptr++ == ':') { -int stream_idx = strtol(endptr, NULL, 0); -return stream_idx >= 0 && -stream_idx < s->programs[i]->nb_stream_indexes && -st->index == s->programs[i]->stream_index[stream_idx]; +if (*endptr++ == ':') { // p:: +if ( *endptr == 'a' || *endptr == 'v' || + *endptr == 's' || *endptr == 'd') { // p::[:] +enum AVMediaType type; + +switch (*endptr++) { +case 'v': type = AVMEDIA_TYPE_VIDEO; break; +case 'a': type = AVMEDIA_TYPE_AUDIO; break; +case 's': type = AVMEDIA_TYPE_SUBTITLE; break; +case 'd': type = AVMEDIA_TYPE_DATA; break; +default: av_assert0(0); +} +if (*endptr++ == ':') { // p::: +int stream_idx = strtol(endptr, NULL, 0), type_counter = 0; +for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) { +int stream_index = s->programs[i]->stream_index[j]; +if (st->index == s->programs[i]->stream_index[j]) { +#if FF_API_LAVF_AVCTX +FF_DISABLE_DEPRECATION_WARNINGS +return type_counter == stream_idx && + (type == st->codecpar->codec_type || +type == st->codec->codec_type); +FF_ENABLE_DEPRECATION_WARNINGS +#else +return type_counter == stream_idx && +
[FFmpeg-cvslog] fate: to test program sub stream selection by its type in mpegts
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Wed Apr 11 22:33:02 2018 +0200| [a06175d7392326201a131fc09b3ea52617f310df] | committer: Michael Niedermayer fate: to test program sub stream selection by its type in mpegts Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a06175d7392326201a131fc09b3ea52617f310df --- tests/fate/mpegts.mak | 6 ++ tests/ref/fate/mpegts-probe-program | 8 2 files changed, 14 insertions(+) diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak index bb0d9d98a7..2b128492e0 100644 --- a/tests/fate/mpegts.mak +++ b/tests/fate/mpegts.mak @@ -9,6 +9,12 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, HEVC, AAC_LATM) += fate-mpegts-probe-la fate-mpegts-probe-latm: SRC = $(TARGET_SAMPLES)/mpegts/loewe.ts fate-mpegts-probe-latm: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)" + +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, HEVC, AAC_LATM) += fate-mpegts-probe-program +fate-mpegts-probe-program: SRC = $(TARGET_SAMPLES)/mpegts/loewe.ts +fate-mpegts-probe-program: CMD = run $(PROBE_CODEC_NAME_COMMAND) -select_streams p:769:v:0 -i "$(SRC)" + + FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes) fate-mpegts: $(FATE_MPEGTS_PROBE-yes) diff --git a/tests/ref/fate/mpegts-probe-program b/tests/ref/fate/mpegts-probe-program new file mode 100644 index 00..bb1012c8c7 --- /dev/null +++ b/tests/ref/fate/mpegts-probe-program @@ -0,0 +1,8 @@ +[PROGRAM] +[STREAM] +codec_name=hevc +[/STREAM] +[/PROGRAM] +[STREAM] +codec_name=hevc +[/STREAM] ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: fix handling of delete_segments when %v is present
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Wed Apr 11 11:15:54 2018 +0800| [9825f77ac7ab102783aad4d2e0c42584a0dde466] | committer: Steven Liu avformat/hlsenc: fix handling of delete_segments when %v is present When var_stream_map option is used, %v must appear either in segment name template or in the directory path. This latter case currently is not handled and delete_segments flag of hls_flags is broken now. This patch fix this. The root cause of the bug was that HLSSegment struct only stores the final filename part, but not the final directory path. Most of the cases, final path info is unneded, It only necessary when you want to delete old segments (e.g in case of live streaming). Without variant streams it was unnecessary to store the final directory path, because all segment were stored into the same directory. But introducing %v in directory names either require to store the final directory path into HLSSegment or associate segments with their variant streams to be able deleting them later. I have choosen the second solution and introduced a variant index data member into the segment struct. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@onvideo.cn> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9825f77ac7ab102783aad4d2e0c42584a0dde466 --- libavformat/hlsenc.c | 26 +++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 2a54b4342e..8eb84212a0 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -75,6 +75,7 @@ typedef struct HLSSegment { int discont; int64_t pos; int64_t size; +unsigned var_stream_idx; char key_uri[LINE_BUFFER_SIZE + 1]; char iv_string[KEYSIZE*2 + 1]; @@ -106,6 +107,7 @@ typedef enum { } SegmentType; typedef struct VariantStream { +unsigned var_stream_idx; unsigned number; int64_t sequence; AVOutputFormat *oformat; @@ -478,9 +480,23 @@ static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, } p = (char *)av_basename(dirname); *p = '\0'; + } while (segment) { +char * r_dirname = dirname; + +/* if %v is present in the file's directory */ +if (av_stristr(dirname, "%v")) { + +if (replace_int_data_in_filename(_dirname, dirname, 'v', segment->var_stream_idx) < 1) { +ret = AVERROR(EINVAL); +goto fail; +} +av_free(dirname); +dirname = r_dirname; +} + av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n", segment->filename); path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1; @@ -965,6 +981,7 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, if (!en) return AVERROR(ENOMEM); +en->var_stream_idx = vs->var_stream_idx; ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size); if (ret < 0) { return ret; @@ -1824,9 +1841,11 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) while (varstr = av_strtok(p, " \t", )) { p = NULL; -if (nb_varstreams < hls->nb_varstreams) -vs = &(hls->var_streams[nb_varstreams++]); -else +if (nb_varstreams < hls->nb_varstreams) { +vs = &(hls->var_streams[nb_varstreams]); +vs->var_stream_idx = nb_varstreams; +nb_varstreams++; +} else return AVERROR(EINVAL); q = varstr; @@ -1984,6 +2003,7 @@ static int update_variant_stream_info(AVFormatContext *s) { if (!hls->var_streams) return AVERROR(ENOMEM); +hls->var_streams[0].var_stream_idx = 0; hls->var_streams[0].nb_streams = s->nb_streams; hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) * hls->var_streams[0].nb_streams); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] doc/filters: some more details and modified example to zmq/azmq
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Tue Apr 3 16:18:02 2018 +0200| [e54679b6c1def5a969d4a5c9db63b51efe7106d7] | committer: Lou Logan doc/filters: some more details and modified example to zmq/azmq Info about default value of bind_address option and its abbreviated version (b). Example modified to have named instanced filter and to show its use. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Lou Logan <l...@lrcd.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e54679b6c1def5a969d4a5c9db63b51efe7106d7 --- doc/filters.texi | 28 ++-- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 7538ab3273..4438386f64 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -221,6 +221,7 @@ Here is a BNF description of the filtergraph syntax: @var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] @end example +@anchor{filtergraph escaping} @section Notes on filtergraph escaping Filtergraph description composition entails several levels of @@ -20270,7 +20271,7 @@ filters in the filtergraph. @code{zmq} and @code{azmq} work as a pass-through filters. @code{zmq} must be inserted between two video filters, @code{azmq} between two -audio filters. +audio filters. Both are capable to send messages to any filter type. To enable these filters you need to install the libzmq library and headers and configure FFmpeg with @code{--enable-libzmq}. @@ -20280,7 +20281,10 @@ For more information about libzmq see: The @code{zmq} and @code{azmq} filters work as a libzmq server, which receives messages sent through a network interface defined by the -@option{bind_address} option. +@option{bind_address} (or the abbreviation "@option{b}") option. +Default value of this option is @file{tcp://localhost:}. You may +want to alter this value to your needs, but do not forget to escape any +':' signs (see @ref{filtergraph escaping}). The received message must be in the form: @example @@ -20288,7 +20292,10 @@ The received message must be in the form: @end example @var{TARGET} specifies the target of the command, usually the name of -the filter class or a specific filter instance name. +the filter class or a specific filter instance name. The default +filter instance name uses the pattern @samp{Parsed__}, +but you can override this by using the @samp{filter_name@@id} syntax +(see @ref{Filtergraph syntax}). @var{COMMAND} specifies the name of the command for the target filter. @@ -20310,14 +20317,17 @@ will send a reply to the client, adopting the format: Look at @file{tools/zmqsend} for an example of a zmq client which can be used to send commands processed by these filters. -Consider the following filtergraph generated by @command{ffplay} +Consider the following filtergraph generated by @command{ffplay}. +In this example the last overlay filter has an instance name. All other +filters will have default instance names. + @example ffplay -dumpgraph 1 -f lavfi " color=s=100x100:c=red [l]; color=s=100x100:c=blue [r]; nullsrc=s=200x100, zmq [bg]; -[bg][l] overlay [bg+l]; -[bg+l][r] overlay=x=100 " +[bg][l] overlay [bg+l]; +[bg+l][r] overlay@@my=x=100 " @end example To change the color of the left side of the video, the following @@ -20331,6 +20341,12 @@ To change the right side: echo Parsed_color_1 c pink | tools/zmqsend @end example +To change the position of the right side: +@example +echo overlay@@my x 150 | tools/zmqsend +@end example + + @c man end MULTIMEDIA FILTERS @chapter Multimedia Sources ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/unix: fix handling of EOF in case of SOCK_STREAM.
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Tue Mar 20 23:24:11 2018 +0100| [1b45e6db22d979baa410645a1d5ab575175f1eb7] | committer: Nicolas George avformat/unix: fix handling of EOF in case of SOCK_STREAM. When recv() returns 0 in case of SOCK_STREAM type, it means EOF and with this patch returns value accordingly. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1b45e6db22d979baa410645a1d5ab575175f1eb7 --- libavformat/unix.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavformat/unix.c b/libavformat/unix.c index 4f01d14a93..38016dbafe 100644 --- a/libavformat/unix.c +++ b/libavformat/unix.c @@ -111,6 +111,8 @@ static int unix_read(URLContext *h, uint8_t *buf, int size) return ret; } ret = recv(s->fd, buf, size, 0); +if (!ret && s->type == SOCK_STREAM) +return AVERROR_EOF; return ret < 0 ? ff_neterrno() : ret; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] hlsenc: Fixing HLS_TEMP_FILE usage with HLS_SECOND_LEVEL_SEGMENT_...
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Mon Feb 19 21:36:25 2018 +0100| [85e6a33bdfddfc9532dc10079368649a23c2b6c4] | committer: Steven Liu hlsenc: Fixing HLS_TEMP_FILE usage with HLS_SECOND_LEVEL_SEGMENT_... Currently using HLS_TEMP together with HLS_SECOND_LEVEL_SEGMENT_DURATION or HLS_SECOND_LEVEL_SEGMENT_SIZE gives error at end of each segment writing and the final segment file names do not contain the desired data. This patch fixes this bug by delaying the initilization of original segment filename after actual temp file renaming will skip the interfering. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=85e6a33bdfddfc9532dc10079368649a23c2b6c4 --- libavformat/hlsenc.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index cc13c94e97..ff064732a1 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -2168,13 +2168,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0) { int64_t new_start_pos; -char *old_filename = av_strdup(vs->avf->url); +char *old_filename = NULL; int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0); -if (!old_filename) { -return AVERROR(ENOMEM); -} - av_write_frame(vs->avf, NULL); /* Flush any buffered data */ new_start_pos = avio_tell(vs->avf->pb); @@ -2215,17 +2211,21 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url); -av_free(old_filename); return ret; } write_styp(vs->out); ret = flush_dynbuf(vs, _length); if (ret < 0) { -av_free(old_filename); return ret; } ff_format_io_close(s, >out); } + +old_filename = av_strdup(vs->avf->url); +if (!old_filename) { +return AVERROR(ENOMEM); +} + ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size); vs->start_pos = new_start_pos; if (ret < 0) { @@ -2316,6 +2316,12 @@ failed: if ((hls->flags & HLS_TEMP_FILE) && oc->url[0]) { hls_rename_temp_file(s, oc); +av_free(old_filename); +old_filename = av_strdup(vs->avf->url); + +if (!old_filename) { +return AVERROR(ENOMEM); +} } /* after av_write_trailer, then duration + 1 duration per packet */ ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: fix stream level metadata handling
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Mon Feb 13 07:33:48 2017 +0800| [2b9f92fcc5486361b63c4fab5a24c222dc8969ef] | committer: Steven Liu avformat/hlsenc: fix stream level metadata handling hls-encoder currenlty does not provide stream level metadata to mpegts muxer. This patch fixes track #3848 bug. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=2b9f92fcc5486361b63c4fab5a24c222dc8969ef --- libavformat/hlsenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index ad5205a..930e94b 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -450,6 +450,7 @@ static int hls_mux_init(AVFormatContext *s) avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar); st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; st->time_base = s->streams[i]->time_base; +av_dict_copy(>metadata, s->streams[i]->metadata, 0); } hls->start_pos = 0; hls->new_start = 1; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] doc/muxers/hlsenc: typo hls_flag: discont_starts => discont_start
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Thu Jan 5 13:21:13 2017 +0100| [4068f5fac7b84257b46c5050859332cd1bcdf3cc] | committer: Michael Niedermayer doc/muxers/hlsenc: typo hls_flag: discont_starts => discont_start Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4068f5fac7b84257b46c5050859332cd1bcdf3cc --- doc/muxers.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index b4a107c..351cd8c 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -567,7 +567,7 @@ and remove the @code{#EXT-X-ENDLIST} from the old segment list. Round the duration info in the playlist file segment info to integer values, instead of using floating point. -@item discont_starts +@item discont_start Add the @code{#EXT-X-DISCONTINUITY} tag to the playlist, before the first segment's information. ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] vformat/hlsenc: typo in default localtime pattern
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Thu Jan 5 19:25:38 2017 +0800| [4c63910bdbf04ce4ed80a870d676877fc031df5a] | committer: Steven Liu vformat/hlsenc: typo in default localtime pattern in get_default_pattern_localtime_fmt the default pattern contains %Y%m%d%H%I%S but the original intention was %Y%m%d%H%M%S Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4c63910bdbf04ce4ed80a870d676877fc031df5a --- libavformat/hlsenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index eac8308..920987f 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -956,7 +956,7 @@ static const char * get_default_pattern_localtime_fmt(void) struct tm *p, tmbuf; p = localtime_r(, ); // no %s support when strftime returned error or left format string unchanged -return (!strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%I%S.ts" : "-%s.ts"; +return (!strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts"; } static int hls_write_header(AVFormatContext *s) ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: bugfix in duplicate filename detection
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Thu Jan 5 07:39:00 2017 +0800| [8c9c43fc43f824366798b38177b7ca7ad028feb9] | committer: Steven Liu avformat/hlsenc: bugfix in duplicate filename detection A wrong, unitialized variable is used for testing. This patch fixes this typo. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8c9c43fc43f824366798b38177b7ca7ad028feb9 --- libavformat/hlsenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 4b1f12f..808a797 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -490,7 +490,7 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double filename = hls->avf->filename; } if (find_segment_by_filename(hls->segments, filename) -|| find_segment_by_filename(hls->old_segments, en->filename)) { +|| find_segment_by_filename(hls->old_segments, filename)) { av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename); } av_strlcpy(en->filename, filename, sizeof(en->filename)); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: size and duration in segment filenames
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Tue Jan 3 22:57:51 2017 +0800| [557c0df9a854350853ae0609a7728a4fb1ba3383] | committer: Steven Liu avformat/hlsenc: size and duration in segment filenames 1st: This patch makes it possible to put actual segment file size (measured in bytes) and/or duration (calculated in microseconds) into segment filenames. This feature is useful when post-processing live streaming access log files. New behaviour works only when -use_localtime option is set and second_level_segment_size or/and second_level_segment_duration new hls_flags are specified. %%s is the placeholder for size and %%t for duration in hls_segment_filename option. Fix sized trailing zeropadding also works eg. %%09s or %%023t. A command to test new features: ./ffmpeg -loglevel info -y -f lavfi -i color=c=red:size=640x480:r=25 -f lavfi -i sine=f=440:b=4:r=44100 -c:v mpeg2video -g 25 -acodec aac -cutoff 2 -ac 2 -ar 44100 -ab 192k -f hls -hls_time 3 -hls_list_size 5 -hls_flags second_level_segment_index+second_level_segment_size+second_level_segment_duration -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename "segment_%Y%m%d%H%M%S_%%04d_%%08s_%%013t.ts" stream.m3u8 2nd: doc/muxers: beside second_level_segment_duration and second_level_segment_size, added some more details and example to hls_segment_filename, use_localtime, use_localtime_mkdir, hls_flags. hls_flags option list reformatted to table Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=557c0df9a854350853ae0609a7728a4fb1ba3383 --- doc/muxers.texi | 71 libavformat/hlsenc.c | 180 --- 2 files changed, 230 insertions(+), 21 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index c2598b2..b4a107c 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -441,8 +441,15 @@ ffmpeg -i in.nut -hls_segment_filename 'file%03d.ts' out.m3u8 This example will produce the playlist, @file{out.m3u8}, and segment files: @file{file000.ts}, @file{file001.ts}, @file{file002.ts}, etc. +@var{filename} may contain full path or relative path specification, +but only the file name part without any path info will be contained in the m3u8 segment list. +Should a relative path be specified, the path of the created segment +files will be relative to the current working directory. +When use_localtime_mkdir is set, the whole expanded value of @var{filename} will be written into the m3u8 segment list. + + @item use_localtime -Use strftime on @var{filename} to expand the segment filename with localtime. +Use strftime() on @var{filename} to expand the segment filename with localtime. The segment number is also available in this mode, but to use it, you need to specify second_level_segment_index hls_flag and %%d will be the specifier. @example @@ -450,6 +457,8 @@ ffmpeg -i in.nut -use_localtime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out. @end example This example will produce the playlist, @file{out.m3u8}, and segment files: @file{file-20160215-1455569023.ts}, @file{file-20160215-1455569024.ts}, etc. +Note: On some systems/environments, the @code{%s} specifier is not available. See + @code{strftime()} documentation. @example ffmpeg -i in.nut -use_localtime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8 @end example @@ -457,14 +466,21 @@ This example will produce the playlist, @file{out.m3u8}, and segment files: @file{file-20160215-0001.ts}, @file{file-20160215-0002.ts}, etc. @item use_localtime_mkdir -Used together with -use_localtime, it will create up to one subdirectory which +Used together with -use_localtime, it will create all subdirectories which is expanded in @var{filename}. @example ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8 @end example This example will create a directory 201560215 (if it does not exist), and then produce the playlist, @file{out.m3u8}, and segment files: -@file{201560215/file-20160215-1455569023.ts}, @file{201560215/file-20160215-1455569024.ts}, etc. +@file{20160215/file-20160215-1455569023.ts}, @file{20160215/file-20160215-1455569024.ts}, etc. + +@example +ffmpeg -i in.nut -use_localtime 1 -use_localtime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8 +@end example +This example will create a directory hierarchy 2016/02/15 (if any of them do not exist), and then +produce the playlist, @file{out.m3u8}, and segment files: +@file{2016/02/15/file-20160215-1455569023.ts}, @file{2016/02/15/file-20160215-1455569024.ts}, etc. @item hls_key_info_file @var{key_info_file} @@ -523,7 +539,12 @@ ffmpeg -f lavfi -re -i testsrc -c:v h264 -hls_flags delete_segments \ -hls_key_info_file file.keyinfo out.m3u8 @end example -@item
[FFmpeg-cvslog] avformat/hlsenc: Duplicated segment filenames and use_localtime_mkdir
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Sun Jan 1 20:22:34 2017 +0800| [03a69bd897e49a636a7c2f044f74fb96288955d4] | committer: Bela Bodecs avformat/hlsenc: Duplicated segment filenames and use_localtime_mkdir Current implementation of finding duplicate segment filenames may fail if use_localtime_mkdir and use_localtime are in effect and segment_filename option expression contains subdirectories with date/time specifiers. This patch fixes this false behaviour. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=03a69bd897e49a636a7c2f044f74fb96288955d4 --- libavformat/hlsenc.c | 50 ++ 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 57fc9c1..591ab73 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -367,6 +367,16 @@ static int hls_mux_init(AVFormatContext *s) return 0; } +static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename) +{ +while (segment) { +if (!av_strcasecmp(segment->filename,filename)) +return segment; +segment = segment->next; +} +return (HLSSegment *) NULL; +} + /* Create a new segment and append it to the segment list */ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration, int64_t pos, int64_t size) @@ -383,6 +393,10 @@ static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double if (hls->use_localtime_mkdir) { filename = hls->avf->filename; } +if (find_segment_by_filename(hls->segments, filename) +|| find_segment_by_filename(hls->old_segments, en->filename)) { +av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename); +} av_strlcpy(en->filename, filename, sizeof(en->filename)); if(hls->has_subtitle) @@ -659,38 +673,6 @@ fail: return ret; } -static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename) -{ -/* filename may contain rel/abs path, but segments store only basename */ -char *p = NULL, *dirname = NULL, *path = NULL; -int path_size; -HLSSegment *ret_segment = NULL; -dirname = av_strdup(filename); -if (!dirname) -return NULL; -p = (char *)av_basename(dirname); // av_dirname would return . in case of no dir -*p = '\0'; // maybe empty - -while (segment) { -path_size = strlen(dirname) + strlen(segment->filename) + 1; -path = av_malloc(path_size); -if (!path) -goto end; -av_strlcpy(path, dirname, path_size); -av_strlcat(path, segment->filename, path_size); -if (!strcmp(path,filename)) { -ret_segment = segment; -av_free(path); -goto end; -} -av_free(path); -segment = segment->next; -} -end: -av_free(dirname); -return ret_segment; -} - static int hls_start(AVFormatContext *s) { HLSContext *c = s->priv_data; @@ -736,10 +718,6 @@ static int hls_start(AVFormatContext *s) } av_free(filename); } -if (find_segment_by_filename(c->segments, oc->filename) -|| find_segment_by_filename(c->old_segments, oc->filename)) { -av_log(c, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", oc->filename); -} if (c->use_localtime_mkdir) { const char *dir; char *fn_copy = av_strdup(oc->filename); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] libavformat/hlsenc: default segment name and use_localtime
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Sun Jan 1 11:00:45 2017 +0800| [8fd3e02eee87e0830fa7ab1dbb65160e5be76d20] | committer: Bela Bodecs libavformat/hlsenc: default segment name and use_localtime in hlcenc.c, in the hls_write_header() function the default format string for strftime() function contains %s specifier when use_localtime is true. This %s specifier will insert the seconds since EPOCH. But %s is not available on all system/environment. This patch check %s availabilty at runtine and alter the default format string if necessary. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8fd3e02eee87e0830fa7ab1dbb65160e5be76d20 --- libavformat/hlsenc.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index c9d8e3c..57fc9c1 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -829,13 +829,23 @@ fail: return err; } +static const char * get_default_pattern_localtime_fmt(void) +{ +char b[21]; +time_t t = time(NULL); +struct tm *p, tmbuf; +p = localtime_r(, ); +// no %s support when strftime returned error or left format string unchanged +return (!strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%I%S.ts" : "-%s.ts"; +} + static int hls_write_header(AVFormatContext *s) { HLSContext *hls = s->priv_data; int ret, i; char *p; const char *pattern = "%d.ts"; -const char *pattern_localtime_fmt = "-%s.ts"; +const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(); const char *vtt_pattern = "%d.vtt"; AVDictionary *options = NULL; int basename_size; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] libavformat/hlsenc: fix delete_segments when use_localtime_mkdir
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Thu Dec 29 12:00:20 2016 +0800| [9ec52a0a9b086d8a916a580ad594c126cd810a45] | committer: Bela Bodecs libavformat/hlsenc: fix delete_segments when use_localtime_mkdir When delete_segments hls_flag is specified, deleting old segments may fail in certain cases when use_localtime_mkdir is in effect and hls_segment_filename expression contains subdirs. This patch fixes this behaviour. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <l...@chinaffmpeg.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9ec52a0a9b086d8a916a580ad594c126cd810a45 --- libavformat/hlsenc.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index cf4d4bd..c9d8e3c 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -194,7 +194,7 @@ static int hls_delete_old_segments(HLSContext *hls) { } } -if (segment) { +if (segment && !hls->use_localtime_mkdir) { if (hls->segment_filename) { dirname = av_strdup(hls->segment_filename); } else { @@ -211,15 +211,20 @@ static int hls_delete_old_segments(HLSContext *hls) { while (segment) { av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n", segment->filename); -path_size = strlen(dirname) + strlen(segment->filename) + 1; +path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1; path = av_malloc(path_size); if (!path) { ret = AVERROR(ENOMEM); goto fail; } -av_strlcpy(path, dirname, path_size); -av_strlcat(path, segment->filename, path_size); +if (hls->use_localtime_mkdir) +av_strlcpy(path, segment->filename, path_size); +else { // segment->filename contains basename only +av_strlcpy(path, dirname, path_size); +av_strlcat(path, segment->filename, path_size); +} + if (unlink(path) < 0) { av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n", path, strerror(errno)); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] flv demuxer supports live rtmp inputs but there is no any info about it in the docs.
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Sat Dec 24 00:21:23 2016 +0100| [ce5c7260df2d66dd26a6fe9709cef66aa7139162] | committer: Michael Niedermayer flv demuxer supports live rtmp inputs but there is no any info about it in the docs. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ce5c7260df2d66dd26a6fe9709cef66aa7139162 --- doc/demuxers.texi | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 2934a1c..c12c07e 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -243,11 +243,17 @@ file subdir/file-2.wav @end example @end itemize -@section flv +@section flv, live_flv Adobe Flash Video Format demuxer. -This demuxer is used to demux FLV files and RTMP network streams. +This demuxer is used to demux FLV files and RTMP network streams. In case of live network streams, if you force format, you may use live_flv option instead of flv to survive timestamp discontinuities. + +@example +ffmpeg -f flv -i myfile.flv ... +ffmpeg -f live_flv -i rtmp:///anything/key +@end example + @table @option @item -flv_metadata @var{bool} ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] avformat/hlsenc: detecting duplicated segment filenames
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Mon Dec 26 18:14:40 2016 +0800| [e7fbd7018932aa349bf52a2bc8e1acd6da058a1b] | committer: Bela Bodecs avformat/hlsenc: detecting duplicated segment filenames ffmpeg-devel with use_localtime parameter hlsenc may produce identical filenames for different but still existing segments. It happens when hls_segment_filename contains syntacticaly correct but inadequate format parameters. Currently there is no any log message when such a situaton occurs but these cases should be avoided in most times. This patch generate warning log messages in these cases. ticketID: #6043 Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Steven Liu <lingjiujia...@gmail.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=e7fbd7018932aa349bf52a2bc8e1acd6da058a1b --- libavformat/hlsenc.c | 36 1 file changed, 36 insertions(+) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index acf3a30..e46e9b4 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -653,6 +653,38 @@ fail: return ret; } +static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename) +{ +/* filename may contain rel/abs path, but segments store only basename */ +char *p = NULL, *dirname = NULL, *path = NULL; +int path_size; +HLSSegment *ret_segment = NULL; +dirname = av_strdup(filename); +if (!dirname) +return NULL; +p = (char *)av_basename(dirname); // av_dirname would return . in case of no dir +*p = '\0'; // maybe empty + +while (segment) { +path_size = strlen(dirname) + strlen(segment->filename) + 1; +path = av_malloc(path_size); +if (!path) +goto end; +av_strlcpy(path, dirname, path_size); +av_strlcat(path, segment->filename, path_size); +if (!strcmp(path,filename)) { +ret_segment = segment; +av_free(path); +goto end; +} +av_free(path); +segment = segment->next; +} +end: +av_free(dirname); +return ret_segment; +} + static int hls_start(AVFormatContext *s) { HLSContext *c = s->priv_data; @@ -686,6 +718,10 @@ static int hls_start(AVFormatContext *s) return AVERROR(EINVAL); } +if (find_segment_by_filename(c->segments, oc->filename) +|| find_segment_by_filename(c->old_segments, oc->filename)) { +av_log(c, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", oc->filename); +} if (c->use_localtime_mkdir) { const char *dir; char *fn_copy = av_strdup(oc->filename); ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] vf_scale: eval, param0 and param1 documentation
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Wed Jan 20 15:29:13 2016 +0100| [dec23859b040e2b76f6753789dbe7b47f2ecf497] | committer: Michael Niedermayer vf_scale: eval, param0 and param1 documentation Documentation of eval, param0 and param1 parameters Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=dec23859b040e2b76f6753789dbe7b47f2ecf497 --- doc/filters.texi | 24 doc/scaler.texi |1 + 2 files changed, 25 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index d8e3317..f5f4bfc 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -9954,6 +9954,21 @@ dimension is divisible by n and adjust the value if necessary. See below for the list of accepted constants for use in the dimension expression. +@item eval +Specify when to evaluate @var{width} and @var{height} expression. It accepts the following values: + +@table @samp +@item init +Only evaluate expressions once during the filter initialization or when a command is processed. + +@item frame +Evaluate expressions for each incoming frame. + +@end table + +Default value is @samp{init}. + + @item interl Set the interlacing mode. It accepts the following values: @@ -9977,6 +9992,15 @@ Set libswscale scaling flags. See complete list of values. If not explicitly specified the filter applies the default flags. + +@item param0, param1 +Set libswscale input parameters for scaling algorithms that need them. See +@ref{sws_params,,the ffmpeg-scaler manual,ffmpeg-scaler} for the +complete documentation. If not explicitly specified the filter applies +empty parameters. + + + @item size, s Set the video size. For the syntax of this option, check the @ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}. diff --git a/doc/scaler.texi b/doc/scaler.texi index 55b2fbe..3e115cd 100644 --- a/doc/scaler.texi +++ b/doc/scaler.texi @@ -91,6 +91,7 @@ Select source range. @item dst_range Select destination range. +@anchor{sws_params} @item param0, param1 Set scaling algorithm parameters. The specified values are specific of some scaling algorithms and ignored by others. The specified values ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] vf_scale: Detecting changes of incoming frame properties and dinamically evaluate width and height expressions
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Mon Jan 18 18:44:09 2016 +0100| [868a2ed568414b80d8b083f41293c65b73bf6091] | committer: Michael Niedermayer vf_scale: Detecting changes of incoming frame properties and dinamically evaluate width and height expressions Currently scale filter accepts expressions in its width and height parameters but evaluates them only once at init and replaces them with their actual values. Later on, if any parameter of incoming frames changes - ie those were used in the original size expressions - then they new values will not have any affect for width and heigth values. They remain the same. This patch makes possible that width and height expressions be evaluated frame-by-frame basis if width/height/sar/format properties of incoming frame would change. To retain the current behaviour and not to break any earlier app, a new config parameter has been introduced. Its name is "eval" and it has two distinct values: "init" and "frame". The default value is "init". This feature is very usefull in case of DVBT mpeg-ts streams where SAR may change time-by-time from 4/3 to 16/9 and vica-versa and the size remains the same and you want to create a variable sized output with 1/1 SAR. Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Reviewed-by: Paul B Mahol <one...@gmail.com> Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=868a2ed568414b80d8b083f41293c65b73bf6091 --- libavfilter/vf_scale.c | 31 ++- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 7eabe00..ac9d4c3 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -71,6 +71,13 @@ enum var_name { VARS_NB }; +enum EvalMode { +EVAL_MODE_INIT, +EVAL_MODE_FRAME, +EVAL_MODE_NB +}; + + typedef struct ScaleContext { const AVClass *class; struct SwsContext *sws; ///< software scaler context @@ -112,6 +119,9 @@ typedef struct ScaleContext { int force_original_aspect_ratio; int nb_slices; + +int eval_mode; ///< expression evaluation mode + } ScaleContext; AVFilter ff_vf_scale2ref; @@ -494,17 +504,25 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) if( in->width != link->w || in->height != link->h - || in->format != link->format) { + || in->format != link->format + || in->sample_aspect_ratio.den != link->sample_aspect_ratio.den || in->sample_aspect_ratio.num != link->sample_aspect_ratio.num) { int ret; -snprintf(buf, sizeof(buf)-1, "%d", outlink->w); -av_opt_set(scale, "w", buf, 0); -snprintf(buf, sizeof(buf)-1, "%d", outlink->h); -av_opt_set(scale, "h", buf, 0); + +if (scale->eval_mode == EVAL_MODE_INIT) { +snprintf(buf, sizeof(buf)-1, "%d", outlink->w); +av_opt_set(scale, "w", buf, 0); +snprintf(buf, sizeof(buf)-1, "%d", outlink->h); +av_opt_set(scale, "h", buf, 0); +} link->dst->inputs[0]->format = in->format; link->dst->inputs[0]->w = in->width; link->dst->inputs[0]->h = in->height; +link->dst->inputs[0]->sample_aspect_ratio.den = in->sample_aspect_ratio.den; +link->dst->inputs[0]->sample_aspect_ratio.num = in->sample_aspect_ratio.num; + + if ((ret = config_props(outlink)) < 0) return ret; } @@ -665,6 +683,9 @@ static const AVOption scale_options[] = { { "param0", "Scaler param 0", OFFSET(param[0]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS }, { "param1", "Scaler param 1", OFFSET(param[1]), AV_OPT_TYPE_DOUBLE, { .dbl = SWS_PARAM_DEFAULT }, INT_MIN, INT_MAX, FLAGS }, { "nb_slices", "set the number of slices (debug purpose only)", OFFSET(nb_slices), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, +{ "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, + { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, + { "frame", "eval expressions during initialization and per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, { NULL } }; ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] lavf/tee: allow multiple stream specifiers in select.
ffmpeg | branch: master | Bela Bodecs <bode...@vivanet.hu> | Sat Oct 10 21:29:12 2015 +0200| [1f3a29e999b635fee913680402977eb1d51a8461] | committer: Nicolas George lavf/tee: allow multiple stream specifiers in select. It makes possible to put multiple stream specifier into the select option separated by comma. eg. select=\'a:0,v\' Signed-off-by: Bela Bodecs <bode...@vivanet.hu> Signed-off-by: Nicolas George <geo...@nsup.org> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1f3a29e999b635fee913680402977eb1d51a8461 --- doc/muxers.texi |3 ++- libavformat/tee.c | 33 +++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 91d131f..06483fa 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1272,7 +1272,8 @@ Several bitstream filters can be specified, separated by ",". @item select Select the streams that should be mapped to the slave output, specified by a stream specifier. If not specified, this defaults to -all the input streams. +all the input streams. You may use multiple stream specifiers +separated by commas (@code{,}) e.g.: @code{a:0,v} @end table @subsection Examples diff --git a/libavformat/tee.c b/libavformat/tee.c index c619eae..e9fccc1 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -47,6 +47,7 @@ static const char *const slave_opt_open = "["; static const char *const slave_opt_close = "]"; static const char *const slave_opt_delim = ":]"; /* must have the close too */ static const char *const slave_bsfs_spec_sep = "/"; +static const char *const slave_select_sep = ","; static const AVClass tee_muxer_class = { .class_name = "Tee muxer", @@ -142,6 +143,8 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) AVFormatContext *avf2 = NULL; AVStream *st, *st2; int stream_count; +int fullret; +char *subselect = NULL, *next_subselect = NULL, *first_subselect = NULL, *tmp_select = NULL; if ((ret = parse_slave_options(avf, slave, , )) < 0) return ret; @@ -172,15 +175,32 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) for (i = 0; i < avf->nb_streams; i++) { st = avf->streams[i]; if (select) { -ret = avformat_match_stream_specifier(avf, avf->streams[i], select); -if (ret < 0) { -av_log(avf, AV_LOG_ERROR, - "Invalid stream specifier '%s' for output '%s'\n", - select, slave); +tmp_select = av_strdup(select); // av_strtok is destructive so we regenerate it in each loop +if (!tmp_select) { +ret = AVERROR(ENOMEM); goto end; } +fullret = 0; +first_subselect = tmp_select; +next_subselect = NULL; +while (subselect = av_strtok(first_subselect, slave_select_sep, _subselect)) { +first_subselect = NULL; + +ret = avformat_match_stream_specifier(avf, avf->streams[i], subselect); +if (ret < 0) { +av_log(avf, AV_LOG_ERROR, + "Invalid stream specifier '%s' for output '%s'\n", + subselect, slave); +goto end; +} +if (ret != 0) { +fullret = 1; // match +break; +} +} +av_freep(_select); -if (ret == 0) { /* no match */ +if (fullret == 0) { /* no match */ tee_slave->stream_map[i] = -1; continue; } @@ -282,6 +302,7 @@ end: av_free(format); av_free(select); av_dict_free(); +av_freep(_select); return ret; } ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog