In particular, should fix trac ticket #1842.
Stefano Sabatini authored on 2012/12/20 22:20:19... | ... |
@@ -545,8 +545,10 @@ the specified @var{segment_time}. |
545 | 545 |
Default value is @code{cache}. |
546 | 546 |
|
547 | 547 |
@item segment_list_size @var{size} |
548 |
-Overwrite the listfile once it reaches @var{size} entries. If 0 |
|
549 |
-the listfile is never overwritten. Default value is 0. |
|
548 |
+Update the list file so that it contains at most the last @var{size} |
|
549 |
+segments. If 0 the list file will contain all the segments. Default |
|
550 |
+value is 0. |
|
551 |
+ |
|
550 | 552 |
@item segment_list type @var{type} |
551 | 553 |
Specify the format for the segment list file. |
552 | 554 |
|
... | ... |
@@ -95,6 +95,9 @@ typedef struct { |
95 | 95 |
int reference_stream_index; |
96 | 96 |
|
97 | 97 |
SegmentListEntry cur_entry; |
98 |
+ SegmentListEntry *segment_list_entries; |
|
99 |
+ SegmentListEntry *segment_list_entries_end; |
|
100 |
+ |
|
98 | 101 |
int is_first_pkt; ///< tells if it is the first packet in the segment |
99 | 102 |
} SegmentContext; |
100 | 103 |
|
... | ... |
@@ -211,15 +214,19 @@ static int segment_list_open(AVFormatContext *s) |
211 | 211 |
return ret; |
212 | 212 |
seg->list_max_segment_time = 0; |
213 | 213 |
|
214 |
- if (seg->list_type == LIST_TYPE_M3U8) { |
|
214 |
+ if (seg->list_type == LIST_TYPE_M3U8 && seg->segment_list_entries) { |
|
215 |
+ SegmentListEntry *entry; |
|
216 |
+ double max_duration = 0; |
|
217 |
+ |
|
215 | 218 |
avio_printf(seg->list_pb, "#EXTM3U\n"); |
216 | 219 |
avio_printf(seg->list_pb, "#EXT-X-VERSION:3\n"); |
217 |
- avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_idx); |
|
220 |
+ avio_printf(seg->list_pb, "#EXT-X-MEDIA-SEQUENCE:%d\n", seg->segment_list_entries->index); |
|
218 | 221 |
avio_printf(seg->list_pb, "#EXT-X-ALLOWCACHE:%d\n", |
219 | 222 |
!!(seg->list_flags & SEGMENT_LIST_FLAG_CACHE)); |
220 |
- if (seg->list_flags & SEGMENT_LIST_FLAG_LIVE) |
|
221 |
- avio_printf(seg->list_pb, |
|
222 |
- "#EXT-X-TARGETDURATION:%"PRId64"\n", seg->time / 1000000); |
|
223 |
+ |
|
224 |
+ for (entry = seg->segment_list_entries; entry; entry = entry->next) |
|
225 |
+ max_duration = FFMAX(max_duration, entry->end_time - entry->start_time); |
|
226 |
+ avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%"PRId64"\n", (int64_t)ceil(max_duration)); |
|
223 | 227 |
} |
224 | 228 |
|
225 | 229 |
return ret; |
... | ... |
@@ -228,14 +235,6 @@ static int segment_list_open(AVFormatContext *s) |
228 | 228 |
static void segment_list_close(AVFormatContext *s) |
229 | 229 |
{ |
230 | 230 |
SegmentContext *seg = s->priv_data; |
231 |
- |
|
232 |
- if (seg->list_type == LIST_TYPE_M3U8) { |
|
233 |
- if (!(seg->list_flags & SEGMENT_LIST_FLAG_LIVE)) |
|
234 |
- avio_printf(seg->list_pb, "#EXT-X-TARGETDURATION:%d\n", |
|
235 |
- (int)ceil(seg->list_max_segment_time)); |
|
236 |
- avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); |
|
237 |
- } |
|
238 |
- |
|
239 | 231 |
avio_close(seg->list_pb); |
240 | 232 |
} |
241 | 233 |
|
... | ... |
@@ -276,15 +275,40 @@ static int segment_end(AVFormatContext *s, int write_trailer) |
276 | 276 |
oc->filename); |
277 | 277 |
|
278 | 278 |
if (seg->list) { |
279 |
- if (seg->list_size && !(seg->segment_count % seg->list_size)) { |
|
279 |
+ if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) { |
|
280 |
+ SegmentListEntry *entry = av_mallocz(sizeof(*entry)); |
|
281 |
+ if (!entry) { |
|
282 |
+ ret = AVERROR(ENOMEM); |
|
283 |
+ goto end; |
|
284 |
+ } |
|
285 |
+ |
|
286 |
+ /* append new element */ |
|
287 |
+ memcpy(entry, &seg->cur_entry, sizeof(*entry)); |
|
288 |
+ if (!seg->segment_list_entries) |
|
289 |
+ seg->segment_list_entries = seg->segment_list_entries_end = entry; |
|
290 |
+ else |
|
291 |
+ seg->segment_list_entries_end->next = entry; |
|
292 |
+ seg->segment_list_entries_end = entry; |
|
293 |
+ |
|
294 |
+ /* drop first item */ |
|
295 |
+ if (seg->list_size && seg->segment_count > seg->list_size) { |
|
296 |
+ entry = seg->segment_list_entries; |
|
297 |
+ seg->segment_list_entries = seg->segment_list_entries->next; |
|
298 |
+ av_freep(&entry); |
|
299 |
+ } |
|
300 |
+ |
|
280 | 301 |
segment_list_close(s); |
281 | 302 |
if ((ret = segment_list_open(s)) < 0) |
282 | 303 |
goto end; |
304 |
+ for (entry = seg->segment_list_entries; entry; entry = entry->next) |
|
305 |
+ segment_list_print_entry(seg->list_pb, seg->list_type, entry); |
|
306 |
+ if (seg->list_type == LIST_TYPE_M3U8) |
|
307 |
+ avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); |
|
308 |
+ } else { |
|
309 |
+ segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry); |
|
310 |
+ seg->list_max_segment_time = |
|
311 |
+ FFMAX(seg->cur_entry.end_time - seg->cur_entry.start_time, seg->list_max_segment_time); |
|
283 | 312 |
} |
284 |
- |
|
285 |
- segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry); |
|
286 |
- seg->list_max_segment_time = |
|
287 |
- FFMAX(seg->cur_entry.end_time - seg->cur_entry.start_time, seg->list_max_segment_time); |
|
288 | 313 |
avio_flush(seg->list_pb); |
289 | 314 |
} |
290 | 315 |
|
... | ... |
@@ -694,6 +718,8 @@ static int seg_write_trailer(struct AVFormatContext *s) |
694 | 694 |
{ |
695 | 695 |
SegmentContext *seg = s->priv_data; |
696 | 696 |
AVFormatContext *oc = seg->avf; |
697 |
+ SegmentListEntry *cur, *next; |
|
698 |
+ |
|
697 | 699 |
int ret; |
698 | 700 |
if (!seg->write_header_trailer) { |
699 | 701 |
if ((ret = segment_end(s, 0)) < 0) |
... | ... |
@@ -712,6 +738,13 @@ fail: |
712 | 712 |
av_freep(&seg->times); |
713 | 713 |
av_freep(&seg->frames); |
714 | 714 |
|
715 |
+ cur = seg->segment_list_entries; |
|
716 |
+ while (cur) { |
|
717 |
+ next = cur->next; |
|
718 |
+ av_free(cur); |
|
719 |
+ cur = next; |
|
720 |
+ } |
|
721 |
+ |
|
715 | 722 |
avformat_free_context(oc); |
716 | 723 |
return ret; |
717 | 724 |
} |
... | ... |
@@ -31,7 +31,7 @@ |
31 | 31 |
|
32 | 32 |
#define LIBAVFORMAT_VERSION_MAJOR 54 |
33 | 33 |
#define LIBAVFORMAT_VERSION_MINOR 61 |
34 |
-#define LIBAVFORMAT_VERSION_MICRO 100 |
|
34 |
+#define LIBAVFORMAT_VERSION_MICRO 101 |
|
35 | 35 |
|
36 | 36 |
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ |
37 | 37 |
LIBAVFORMAT_VERSION_MINOR, \ |