[FFmpeg-devel] [PATCH] add segment_path for save segment movie
Steven Liu
lingjiujianke at gmail.com
Sat Oct 26 04:52:32 CEST 2013
在 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)
More information about the ffmpeg-devel
mailing list