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

Steven Liu lingjiujianke at gmail.com
Sat Oct 26 07:46:20 CEST 2013


在 2013-10-26,上午10:52,Steven Liu <lingjiujianke at gmail.com> 写道:

> 
> 在 2013-10-25,下午10:54,Steven Liu <lingjiujianke at gmail.com> 写道:
> 
>> 
>> 在 2013-10-25,下午9:56,Stefano Sabatini <stefasab at gmail.com> 写道:
>> 
>>> On date Friday 2013-10-25 16:01:11 +0800, Steven Liu encoded:
>>>> 
>>>> Create 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, *NO USE* "-segment_path path"
>>>> 
>>>> 
>>>> 
>>>> 
>>>> ---
>>>> libavformat/segment.c | 23 ++++++++++++++++++++---
>>>> 1 file changed, 20 insertions(+), 3 deletions(-)
>>>> 
>>>> diff --git a/libavformat/segment.c b/libavformat/segment.c
>>>> index 05e29d4..4e4765e 100644
>>>> --- a/libavformat/segment.c
>>>> +++ b/libavformat/segment.c
>>>> @@ -75,6 +75,7 @@ typedef struct {
>>>> ListType list_type;    ///< set the list type
>>>> AVIOContext *list_pb;  ///< list file put-byte context
>>>> char *time_str;        ///< segment duration specification string
>>>> +    char *path;
>>>> int64_t time;          ///< segment duration
>>>> 
>>>> char *times_str;       ///< segment times specification string
>>>> @@ -175,6 +176,7 @@ static int segment_start(AVFormatContext *s, int write_header)
>>>> SegmentContext *seg = s->priv_data;
>>>> AVFormatContext *oc = seg->avf;
>>>> int err = 0;
>>>> +    uint8_t seg_path[1024];
>>> 
>>> weird indent
>>> 
>>>> if (write_header) {
>>>>     avformat_free_context(oc);
>>>> @@ -188,7 +190,13 @@ 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,
>>>> +    /* seg_path = path + filename */
>>>> +    if (!seg->path) {
>>>> +        snprintf(seg_path, sizeof(seg_path), "%s/%s", seg->path, oc->filename);
>>>> +    } else {
>>>> +        snprintf(seg_path, sizeof(seg_path), "%s", oc->filename);
>>>> +    }
>>> 
>>> inverted logic?
>>> 
>>> You should use av_asprintf() in order to avoid arbitrary limitations
>>> on the path length.
>>> 
>>> Also I believe you should change the set_segment_filename() code
>>> instead, in order to avoid code duplication.
>>> 
>>>> +    if ((err = avio_open2(&oc->pb, seg_path, AVIO_FLAG_WRITE,
>>>>                       &s->interrupt_callback, NULL)) < 0)
>>>>     return err;
>>>> 
>>>> @@ -528,6 +536,7 @@ static int seg_write_header(AVFormatContext *s)
>>>> SegmentContext *seg = s->priv_data;
>>>> AVFormatContext *oc = NULL;
>>>> int ret;
>>>> +    uint8_t seg_path[1024];
>>>> 
>>>> seg->segment_count = 0;
>>>> if (!seg->write_header_trailer)
>>>> @@ -599,8 +608,15 @@ 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,
>>>> -                              &s->interrupt_callback, NULL)) < 0)
>>>> +
>>>> +    /* seg_path = path + filename */
>>>> +    if (!seg->path) {
>>>> +        snprintf(seg_path, sizeof(seg_path), "%s/%s", seg->path, oc->filename);
>>>> +    } else {
>>>> +        snprintf(seg_path, sizeof(seg_path), "%s", oc->filename);
>>>> +    }
>>>> +    if ((ret = avio_open2(&oc->pb, seg_path, AVIO_FLAG_WRITE,
>>>> +                          &s->interrupt_callback, NULL)) < 0)
>>>>         goto fail;
>>>> } else {
>>>>     if ((ret = open_null_ctx(&oc->pb)) < 0)
>>>> @@ -779,6 +795,7 @@ static const AVOption options[] = {
>>>> { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E },
>>>> { "segment_times",     "set segment split time points",              OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
>>>> { "segment_frames",    "set segment split frame numbers",            OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
>>>> +    { "segment_path",    "set segment save to path",            OFFSET(path),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
>>> 
>>> set segment path?
>>> Also weird indent.
>>> 
>> 
>> Okay, I will send a new patch by this suggestion.
> Hi Guys,
> 	This is the patch got Stefano suggestions.
> 
> Create 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, *NO USE* "-segment_path path".
> 
> for example:
> ./ffmpeg -i ../yedian.avi -preset ultrafast -vcodec libx264 -vprofile
> baseline -vlevel 1.0  -s 640x480 -b:v 800k -r 15  -pix_fmt yuv420p
> -acodec copy -strict -2 -f segment -segment_format mpegts -segment_time
> 10 -segment_list /usr/local/nginx/html/a.m3u8 -segment_list_flags live
> -map 0:0 -map 0:1 -flags -global_header video-%d.ts
> The file will create at current directory, and the list file will create
> at /usr/local/nginx/html/, but the list file context is
> #EXTM3U
> #EXT-X-VERSION:3
> #EXT-X-MEDIA-SEQUENCE:0
> #EXT-X-ALLOW-CACHE:NO
> #EXT-X-TARGETDURATION:17
> #EXTINF:16.680000,
> video-0.ts
> #EXTINF:16.669333,
> video-1.ts
> #EXTINF:16.682667,
> video-2.ts
> #EXTINF:16.672000,
> video-3.ts
> #EXT-X-ENDLIST
> 
> And other ways:
> ./ffmpeg -i ../yedian.avi -preset ultrafast -vcodec libx264 -vprofile
> baseline -vlevel 1.0  -s 640x480 -b:v 800k -r 15  -pix_fmt yuv420p
> -acodec copy -strict -2 -f segment -segment_format mpegts -segment_time
> 10 -segment_list /usr/local/nginx/html/a.m3u8 -segment_list_flags live
> -map 0:0 -map 0:1 -flags -global_header /usr/local/nginx/html/video-%d.ts
> 
> The list context is
> #EXTM3U
> #EXT-X-VERSION:3
> #EXT-X-MEDIA-SEQUENCE:0
> #EXT-X-ALLOW-CACHE:NO
> #EXT-X-TARGETDURATION:17
> #EXTINF:16.680000,
> /usr/local/nginx/html/video-0.ts
> #EXTINF:16.669333,
> /usr/local/nginx/html/video-1.ts
> #EXTINF:16.682667,
> /usr/local/nginx/html/video-2.ts
> #EXTINF:16.672000,
> /usr/local/nginx/html/video-3.ts
> #EXTINF:16.685333,
> #EXT-X-ENDLIST
> 
> So use this patch can create at the directory at the
> /usr/local/nginx/html, and make the list context:
> #EXTM3U
> #EXT-X-VERSION:3
> #EXT-X-MEDIA-SEQUENCE:0
> #EXT-X-ALLOW-CACHE:NO
> #EXT-X-TARGETDURATION:17
> #EXTINF:16.680000,
> video-0.ts
> #EXTINF:16.669333,
> video-1.ts
> #EXTINF:16.682667,
> video-2.ts
> #EXTINF:16.672000,
> video-3.ts
> #EXT-X-ENDLIST
> 
> Signed-off-by: Steven Liu <lingjiujianke at gmail.com>
> 
> ---
> 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;
>     } else {
> @@ -779,6 +789,7 @@ static const AVOption options[] = {
>     { "segment_time_delta","set approximation value used for the segment times", OFFSET(time_delta), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, 0, E },
>     { "segment_times",     "set segment split time points",              OFFSET(times_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
>     { "segment_frames",    "set segment split frame numbers",            OFFSET(frames_str),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
> +    { "segment_path",    "set segment file created path",            OFFSET(path),AV_OPT_TYPE_STRING,{.str = NULL},  0, 0,       E },
>     { "segment_wrap",      "set number after which the index wraps",     OFFSET(segment_idx_wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
>     { "segment_start_number", "set the sequence number of the first segment", OFFSET(segment_idx), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
> 
> --
> 1.7.12.4 (Apple Git-37)
> 

Stefano,
	Please use the attachment file.


Steven
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-add-segment_path-for-save-segment-movie-file.patch
Type: application/octet-stream
Size: 4549 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20131026/57a6f151/attachment.obj>


More information about the ffmpeg-devel mailing list