Where can i find the v6 2/2 ? > 在 2017年11月29日,16:52,Karthick J <kjeya...@akamai.com> 写道: > > --- > libavformat/Makefile | 2 +- > libavformat/hlsenc.c | 115 +++++++------------------------------- > libavformat/hlsplaylist.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ > libavformat/hlsplaylist.h | 51 +++++++++++++++++ > 4 files changed, 211 insertions(+), 95 deletions(-) > create mode 100644 libavformat/hlsplaylist.c > create mode 100644 libavformat/hlsplaylist.h > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index b1e7b19..fd8b9f9 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -215,7 +215,7 @@ OBJS-$(CONFIG_HDS_MUXER) += hdsenc.o > OBJS-$(CONFIG_HEVC_DEMUXER) += hevcdec.o rawdec.o > OBJS-$(CONFIG_HEVC_MUXER) += rawenc.o > OBJS-$(CONFIG_HLS_DEMUXER) += hls.o > -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o > +OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o hlsplaylist.o > OBJS-$(CONFIG_HNM_DEMUXER) += hnm.o > OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o > OBJS-$(CONFIG_ICO_MUXER) += icoenc.o > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index d5c732f..f63b08d 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -46,6 +46,7 @@ > #include "avformat.h" > #include "avio_internal.h" > #include "http.h" > +#include "hlsplaylist.h" > #include "internal.h" > #include "os_support.h" > > @@ -97,13 +98,6 @@ typedef enum { > SEGMENT_TYPE_FMP4, > } SegmentType; > > -typedef enum { > - PLAYLIST_TYPE_NONE, > - PLAYLIST_TYPE_EVENT, > - PLAYLIST_TYPE_VOD, > - PLAYLIST_TYPE_NB, > -} PlaylistType; > - > typedef struct VariantStream { > unsigned number; > int64_t sequence; > @@ -1055,19 +1049,6 @@ static void hls_free_segments(HLSSegment *p) > } > } > > -static void write_m3u8_head_block(HLSContext *hls, AVIOContext *out, int > version, > - int target_duration, int64_t sequence) > -{ > - avio_printf(out, "#EXTM3U\n"); > - avio_printf(out, "#EXT-X-VERSION:%d\n", version); > - if (hls->allowcache == 0 || hls->allowcache == 1) { > - avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", hls->allowcache == 0 ? > "NO" : "YES"); > - } > - avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration); > - avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); > - av_log(hls, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", > sequence); > -} > - > static void hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc) > { > size_t len = strlen(oc->filename); > @@ -1133,8 +1114,7 @@ static int create_master_playlist(AVFormatContext *s, > goto fail; > } > > - avio_printf(master_pb, "#EXTM3U\n"); > - avio_printf(master_pb, "#EXT-X-VERSION:%d\n", hls->version); > + ff_hls_write_playlist_version(master_pb, hls->version); > > /* For variant streams with video add #EXT-X-STREAM-INF tag with > attributes*/ > for (i = 0; i < hls->nb_varstreams; i++) { > @@ -1175,18 +1155,7 @@ static int create_master_playlist(AVFormatContext *s, > bandwidth += aud_st->codecpar->bit_rate; > bandwidth += bandwidth / 10; > > - if (!bandwidth) { > - av_log(NULL, AV_LOG_WARNING, > - "Bandwidth info not available, set audio and video > bitrates\n"); > - av_freep(&m3u8_rel_name); > - continue; > - } > - > - avio_printf(master_pb, "#EXT-X-STREAM-INF:BANDWIDTH=%d", bandwidth); > - if (vid_st && vid_st->codecpar->width > 0 && > vid_st->codecpar->height > 0) > - avio_printf(master_pb, ",RESOLUTION=%dx%d", > vid_st->codecpar->width, > - vid_st->codecpar->height); > - avio_printf(master_pb, "\n%s\n\n", m3u8_rel_name); > + ff_hls_write_stream_info(vid_st, master_pb, bandwidth, > m3u8_rel_name); > > av_freep(&m3u8_rel_name); > } > @@ -1215,6 +1184,7 @@ static int hls_window(AVFormatContext *s, int last, > VariantStream *vs) > char *iv_string = NULL; > AVDictionary *options = NULL; > double prog_date_time = vs->initial_prog_date_time; > + double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? > &prog_date_time : NULL; > int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > > 0); > > hls->version = 3; > @@ -1245,12 +1215,8 @@ static int hls_window(AVFormatContext *s, int last, > VariantStream *vs) > } > > vs->discontinuity_set = 0; > - write_m3u8_head_block(hls, out, hls->version, target_duration, sequence); > - if (hls->pl_type == PLAYLIST_TYPE_EVENT) { > - avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n"); > - } else if (hls->pl_type == PLAYLIST_TYPE_VOD) { > - avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n"); > - } > + ff_hls_write_playlist_header(out, hls->version, hls->allowcache, > + target_duration, sequence, hls->pl_type); > > if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && > vs->discontinuity_set==0 ){ > avio_printf(out, "#EXT-X-DISCONTINUITY\n"); > @@ -1270,74 +1236,35 @@ static int hls_window(AVFormatContext *s, int last, > VariantStream *vs) > iv_string = en->iv_string; > } > > - if (en->discont) { > - avio_printf(out, "#EXT-X-DISCONTINUITY\n"); > - } > - > if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) > { > - avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", > vs->fmp4_init_filename); > - if (hls->flags & HLS_SINGLE_FILE) { > - avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", > en->size, en->pos); > - } > - avio_printf(out, "\n"); > + ff_hls_write_init_file(out, vs->fmp4_init_filename, > + hls->flags & HLS_SINGLE_FILE, en->size, > en->pos); > } > - if (hls->flags & HLS_ROUND_DURATIONS) > - avio_printf(out, "#EXTINF:%ld,\n", lrint(en->duration)); > - else > - avio_printf(out, "#EXTINF:%f,\n", en->duration); > - if (byterange_mode) > - avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n", > - en->size, en->pos); > - > - if (hls->flags & HLS_PROGRAM_DATE_TIME) { > - time_t tt, wrongsecs; > - int milli; > - struct tm *tm, tmpbuf; > - char buf0[128], buf1[128]; > - tt = (int64_t)prog_date_time; > - milli = av_clip(lrint(1000*(prog_date_time - tt)), 0, 999); > - tm = localtime_r(&tt, &tmpbuf); > - strftime(buf0, sizeof(buf0), "%Y-%m-%dT%H:%M:%S", tm); > - if (!strftime(buf1, sizeof(buf1), "%z", tm) || buf1[1]<'0' > ||buf1[1]>'2') { > - int tz_min, dst = tm->tm_isdst; > - tm = gmtime_r(&tt, &tmpbuf); > - tm->tm_isdst = dst; > - wrongsecs = mktime(tm); > - tz_min = (FFABS(wrongsecs - tt) + 30) / 60; > - snprintf(buf1, sizeof(buf1), > - "%c%02d%02d", > - wrongsecs <= tt ? '+' : '-', > - tz_min / 60, > - tz_min % 60); > - } > - avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, > milli, buf1); > - prog_date_time += en->duration; > - } > - if (vs->baseurl) > - avio_printf(out, "%s", vs->baseurl); > - avio_printf(out, "%s\n", en->filename); > + > + ff_hls_write_file_entry(out, en->discont, byterange_mode, > + en->duration, hls->flags & > HLS_ROUND_DURATIONS, > + en->size, en->pos, vs->baseurl, > + en->filename, prog_date_time_p); > + > } > > if (last && (hls->flags & HLS_OMIT_ENDLIST)==0) > - avio_printf(out, "#EXT-X-ENDLIST\n"); > + ff_hls_write_end_list(out); > > if( vs->vtt_m3u8_name ) { > if ((ret = s->io_open(s, &sub_out, vs->vtt_m3u8_name, > AVIO_FLAG_WRITE, &options)) < 0) > goto fail; > - write_m3u8_head_block(hls, sub_out, hls->version, target_duration, > sequence); > + ff_hls_write_playlist_header(sub_out, hls->version, hls->allowcache, > + target_duration, sequence, > PLAYLIST_TYPE_NONE); > > for (en = vs->segments; en; en = en->next) { > - avio_printf(sub_out, "#EXTINF:%f,\n", en->duration); > - if (byterange_mode) > - avio_printf(sub_out, > "#EXT-X-BYTERANGE:%"PRIi64"@%"PRIi64"\n", > - en->size, en->pos); > - if (vs->baseurl) > - avio_printf(sub_out, "%s", vs->baseurl); > - avio_printf(sub_out, "%s\n", en->sub_filename); > + ff_hls_write_file_entry(sub_out, 0, byterange_mode, > + en->duration, 0, en->size, en->pos, > + vs->baseurl, en->sub_filename, NULL); > } > > if (last) > - avio_printf(sub_out, "#EXT-X-ENDLIST\n"); > + ff_hls_write_end_list(sub_out); > > } > > diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c > new file mode 100644 > index 0000000..235e519 > --- /dev/null > +++ b/libavformat/hlsplaylist.c > @@ -0,0 +1,138 @@ > +/* > + * Apple HTTP Live Streaming segmenter > + * Copyright (c) 2012, Luca Barbato > + * Copyright (c) 2017 Akamai Technologies, Inc. > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include "config.h" > +#include <stdint.h> > + > +#include "libavutil/time_internal.h" > + > +#include "avformat.h" > +#include "hlsplaylist.h" > + > +void ff_hls_write_playlist_version(AVIOContext *out, int version) { > + if (!out) > + return; > + avio_printf(out, "#EXTM3U\n"); > + avio_printf(out, "#EXT-X-VERSION:%d\n", version); > +} > + > +void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, > + int bandwidth, char *filename) { > + if (!out || !filename) > + return; > + > + if (!bandwidth) { > + av_log(NULL, AV_LOG_WARNING, > + "Bandwidth info not available, set audio and video > bitrates\n"); > + return; > + } > + > + avio_printf(out, "#EXT-X-STREAM-INF:BANDWIDTH=%d", bandwidth); > + if (st && st->codecpar->width > 0 && st->codecpar->height > 0) > + avio_printf(out, ",RESOLUTION=%dx%d", st->codecpar->width, > + st->codecpar->height); > + avio_printf(out, "\n%s\n\n", filename); > +} > + > +void ff_hls_write_playlist_header(AVIOContext *out, int version, int > allowcache, > + int target_duration, int64_t sequence, > + uint32_t playlist_type) { > + if (!out) > + return; > + ff_hls_write_playlist_version(out, version); > + if (allowcache == 0 || allowcache == 1) { > + avio_printf(out, "#EXT-X-ALLOW-CACHE:%s\n", allowcache == 0 ? "NO" : > "YES"); > + } > + avio_printf(out, "#EXT-X-TARGETDURATION:%d\n", target_duration); > + avio_printf(out, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", sequence); > + av_log(NULL, AV_LOG_VERBOSE, "EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", > sequence); > + > + if (playlist_type == PLAYLIST_TYPE_EVENT) { > + avio_printf(out, "#EXT-X-PLAYLIST-TYPE:EVENT\n"); > + } else if (playlist_type == PLAYLIST_TYPE_VOD) { > + avio_printf(out, "#EXT-X-PLAYLIST-TYPE:VOD\n"); > + } > +} > + > +void ff_hls_write_init_file(AVIOContext *out, char *filename, > + int byterange_mode, int64_t size, int64_t pos) { > + avio_printf(out, "#EXT-X-MAP:URI=\"%s\"", filename); > + if (byterange_mode) { > + avio_printf(out, ",BYTERANGE=\"%"PRId64"@%"PRId64"\"", size, pos); > + } > + avio_printf(out, "\n"); > +} > + > +void ff_hls_write_file_entry(AVIOContext *out, int insert_discont, > + int byterange_mode, > + double duration, int round_duration, > + int64_t size, int64_t pos, //Used only if > HLS_SINGLE_FILE flag is set > + char *baseurl, //Ignored if NULL > + char *filename, double *prog_date_time) { > + if (!out || !filename) > + return; > + > + if (insert_discont) { > + avio_printf(out, "#EXT-X-DISCONTINUITY\n"); > + } > + if (round_duration) > + avio_printf(out, "#EXTINF:%ld,\n", lrint(duration)); > + else > + avio_printf(out, "#EXTINF:%f,\n", duration); > + if (byterange_mode) > + avio_printf(out, "#EXT-X-BYTERANGE:%"PRId64"@%"PRId64"\n", size, > pos); > + > + if (prog_date_time) { > + time_t tt, wrongsecs; > + int milli; > + struct tm *tm, tmpbuf; > + char buf0[128], buf1[128]; > + tt = (int64_t)*prog_date_time; > + milli = av_clip(lrint(1000*(*prog_date_time - tt)), 0, 999); > + tm = localtime_r(&tt, &tmpbuf); > + strftime(buf0, sizeof(buf0), "%Y-%m-%dT%H:%M:%S", tm); > + if (!strftime(buf1, sizeof(buf1), "%z", tm) || buf1[1]<'0' > ||buf1[1]>'2') { > + int tz_min, dst = tm->tm_isdst; > + tm = gmtime_r(&tt, &tmpbuf); > + tm->tm_isdst = dst; > + wrongsecs = mktime(tm); > + tz_min = (FFABS(wrongsecs - tt) + 30) / 60; > + snprintf(buf1, sizeof(buf1), > + "%c%02d%02d", > + wrongsecs <= tt ? '+' : '-', > + tz_min / 60, > + tz_min % 60); > + } > + avio_printf(out, "#EXT-X-PROGRAM-DATE-TIME:%s.%03d%s\n", buf0, > milli, buf1); > + *prog_date_time += duration; > + } > + if (baseurl) > + avio_printf(out, "%s", baseurl); > + avio_printf(out, "%s\n", filename); > +} > + > +void ff_hls_write_end_list (AVIOContext *out) { > + if (!out) > + return; > + avio_printf(out, "#EXT-X-ENDLIST\n"); > +} > + > diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h > new file mode 100644 > index 0000000..fd36c7e > --- /dev/null > +++ b/libavformat/hlsplaylist.h > @@ -0,0 +1,51 @@ > +/* > + * Apple HTTP Live Streaming segmenter > + * Copyright (c) 2012, Luca Barbato > + * Copyright (c) 2017 Akamai Technologies, Inc. > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#ifndef AVFORMAT_HLSPLAYLIST_H_ > +#define AVFORMAT_HLSPLAYLIST_H_ > + > +#include "libavutil/common.h" > + > +typedef enum { > + PLAYLIST_TYPE_NONE, > + PLAYLIST_TYPE_EVENT, > + PLAYLIST_TYPE_VOD, > + PLAYLIST_TYPE_NB, > +} PlaylistType; > + > +void ff_hls_write_playlist_version(AVIOContext *out, int version); > +void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, > + int bandwidth, char *filename); > +void ff_hls_write_playlist_header(AVIOContext *out, int version, int > allowcache, > + int target_duration, int64_t sequence, > + uint32_t playlist_type); > +void ff_hls_write_init_file(AVIOContext *out, char *filename, > + int byterange_mode, int64_t size, int64_t pos); > +void ff_hls_write_file_entry(AVIOContext *out, int insert_discont, > + int byterange_mode, > + double duration, int round_duration, > + int64_t size, int64_t pos, //Used only if > HLS_SINGLE_FILE flag is set > + char *baseurl, //Ignored if NULL > + char *filename, double *prog_date_time); > +void ff_hls_write_end_list (AVIOContext *out); > + > +#endif /* AVFORMAT_HLSPLAYLIST_H_ */ > -- > 1.9.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel