[FFmpeg-devel] [PATCH] resend: add segment_path for save segment movie

Stefano Sabatini stefasab at gmail.com
Mon Oct 28 10:26:57 CET 2013


[resending since I sent it privately]

In date Sunday 2013-10-27 22:55:57 +0800, Steven Liu wrote:
> Create video file in segment_path, and *DO NOT WANT* write the path into the
> list file, use "-segment_path path" can do it. If *WANT* write the path into the list, 
> *DO NOT USE* "-segment_path path".
[...]
> ---
> libavformat/segment.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index 05e29d4..c0e3ca5 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -76,6 +76,8 @@ typedef struct {
>     AVIOContext *list_pb;  ///< list file put-byte context
>     char *time_str;        ///< segment duration specification string
>     int64_t time;          ///< segment duration
> +  char *path;            ///< parent path for segment create
> +  char *seg_file_path;   ///< segment file create full path
> 
>     char *times_str;       ///< segment times specification string
>     int64_t *times;        ///< list of segment interval specification
> @@ -167,6 +169,14 @@ static int set_segment_filename(AVFormatContext *s)
>         return AVERROR(EINVAL);
>     }
>     av_strlcpy(seg->cur_entry.filename, oc->filename, sizeof(seg->cur_entry.filename));
> +
> +  /* If no -segment_path option, use the oc->filename */
> +  if (!seg->path) {
> +      seg->seg_file_path = av_asprintf("%s", oc->filename);
> +  } else {
> +      seg->seg_file_path = av_asprintf("%s/%s", seg->path, oc->filename);
> +  }
> +
>     return 0;
> }
> 
> @@ -188,7 +198,7 @@ static int segment_start(AVFormatContext *s, int write_header)
>     if ((err = set_segment_filename(s)) < 0)
>         return err;
> 
> -   if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
> +  if ((err = avio_open2(&oc->pb, seg->seg_file_path, AVIO_FLAG_WRITE,
>                           &s->interrupt_callback, NULL)) < 0)
>         return err;
> 
> @@ -599,7 +609,7 @@ static int seg_write_header(AVFormatContext *s)
>         goto fail;
> 
>     if (seg->write_header_trailer) {
> -        if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
> +       if ((ret = avio_open2(&oc->pb, seg->seg_file_path, AVIO_FLAG_WRITE,
>                               &s->interrupt_callback, NULL)) < 0)
>             goto fail;

I don't think this approach is correct. Indeed we should distinguish
the filename where the file is written (oc->filename) from the
filename which is displayed on the output list file.

Note that your approach won't work for example on Windows, where "/"
is not recognized as a file separator.

I see two solutions.

1. we *always* print on the list file the segment file basename (the
   filename stripped of the prefix path), as it is done in hlsenc.c

2. we allow to specify a pattern for the name of the file written on
   the list file (probably overkill), or at least allow to specify a
   prefix.

What do you think is good enough for you?


More information about the ffmpeg-devel mailing list