On 12/29/17 5:35 PM, Steven Liu wrote: > 2017-12-29 19:58 GMT+08:00 Dixit, Vishwanath <vdi...@akamai.com>: >> >> On 12/29/17 5:11 PM, Steven Liu wrote: >>> 2017-12-29 18:44 GMT+08:00 <vdi...@akamai.com>: >>>> From: Vishwanath Dixit <vdi...@akamai.com> >>>> >>>> --- >>>> doc/muxers.texi | 4 ++++ >>>> libavformat/dashenc.c | 2 +- >>>> libavformat/hlsenc.c | 14 +++++++++++++- >>>> libavformat/hlsplaylist.c | 5 ++++- >>>> libavformat/hlsplaylist.h | 3 ++- >>>> 5 files changed, 24 insertions(+), 4 deletions(-) >>>> >>>> diff --git a/doc/muxers.texi b/doc/muxers.texi >>>> index 93db549..8229202 100644 >>>> --- a/doc/muxers.texi >>>> +++ b/doc/muxers.texi >>>> @@ -872,6 +872,10 @@ publishing it repeatedly every after 30 segments i.e. >>>> every after 60s. >>>> @item http_persistent >>>> Use persistent HTTP connections. Applicable only for HTTP output. >>>> >>>> +@item cc_instream_id >>>> +Add @code{#EXT-X-MEDIA} tag in the master playlist with the specified >>>> instream ID. It >>>> +accepts the values in the range 1-4. >>>> + >>>> @end table >>>> >>>> @anchor{ico} >>>> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >>>> index 478a384..8797959 100644 >>>> --- a/libavformat/dashenc.c >>>> +++ b/libavformat/dashenc.c >>>> @@ -760,7 +760,7 @@ static int write_manifest(AVFormatContext *s, int >>>> final) >>>> AVStream *st = s->streams[i]; >>>> get_hls_playlist_name(playlist_file, sizeof(playlist_file), >>>> NULL, i); >>>> ff_hls_write_stream_info(st, out, st->codecpar->bit_rate, >>>> - playlist_file, NULL); >>>> + playlist_file, NULL, NULL); >>>> } >>>> avio_close(out); >>>> if (use_rename) >>>> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c >>>> index 74f66ce..e5176a8 100644 >>>> --- a/libavformat/hlsenc.c >>>> +++ b/libavformat/hlsenc.c >>>> @@ -206,6 +206,7 @@ typedef struct HLSContext { >>>> int http_persistent; >>>> AVIOContext *m3u8_out; >>>> AVIOContext *sub_m3u8_out; >>>> + int cc_instream_id; /* closed captions INSTREAM-ID */ >>>> } HLSContext; >>>> >>>> static int mkdir_p(const char *path) { >>>> @@ -1122,6 +1123,7 @@ static int create_master_playlist(AVFormatContext *s, >>>> unsigned int i, j; >>>> int m3u8_name_size, ret, bandwidth; >>>> char *m3u8_rel_name; >>>> + char cc_group[16] = {0}; >>>> >>>> input_vs->m3u8_created = 1; >>>> if (!hls->master_m3u8_created) { >>>> @@ -1148,6 +1150,14 @@ static int create_master_playlist(AVFormatContext >>>> *s, >>>> >>>> ff_hls_write_playlist_version(hls->m3u8_out, hls->version); >>>> >>>> + if (hls->cc_instream_id) { >>>> + av_strlcpy(cc_group, "group_cc", sizeof(cc_group)); >>> Why do you write "group_cc" ? maybe this can make an option be set by >>> user, and set a default string, if it can be set by user, need >>> attention with the printf, about that security. >>> >> Unlike audio rendition streams, in common usage scenarios, there will be >> only one cc rendition stream and all the video rendition streams refer to >> the same cc rendition stream. The following example shows a common use case >> where both video rendition streams (media_0.m3u8 and media_2.m3u8) are >> referring to the same closed caption rendition with group id “group_cc”. >> #EXTM3U >> #EXT-X-VERSION:3 >> >> #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="group_cc",NAME="captions",INSTREAM-ID="CC1" >> >> #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud1",NAME="audio_0",DEFAULT=YES,URI="media_1.m3u8" >> >> #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud2",NAME="audio_0",DEFAULT=YES,URI="media_3.m3u8" >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=1280x720,AUDIO="group_aud1",CLOSED-CAPTIONS="group_cc" >> media_0.m3u8 >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,AUDIO="group_aud1" >> media_1.m3u8 >> >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=1280x720,AUDIO="group_aud2",CLOSED-CAPTIONS="group_cc" >> media_2.m3u8 >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,AUDIO="group_aud2" >> media_3.m3u8 >> >> So, currently the group id name is fixed to “group_cc”. However, this >> functionality can be further extended in the future for different CC groups >> when there are different closed caption sources are present in the input. >> Please let me know your further thoughts/suggestions on this. > I think "group_cc" should be a variable, it can be set by the user, > not write to a constant by hlsenc. for example: > > #EXTM3U > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Main", \ > DEFAULT=YES,URI="low/main/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Centerfield", \ > DEFAULT=NO,URI="low/centerfield/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Dugout", \ > DEFAULT=NO,URI="low/dugout/audio-video.m3u8" > > #EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS="...",VIDEO="low" > low/main/audio-video.m3u8 > > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Main", \ > DEFAULT=YES,URI="mid/main/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Centerfield", \ > DEFAULT=NO,URI="mid/centerfield/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="mid",NAME="Dugout", \ > DEFAULT=NO,URI="mid/dugout/audio-video.m3u8" > > #EXT-X-STREAM-INF:BANDWIDTH=2560000,CODECS="...",VIDEO="mid" > mid/main/audio-video.m3u8 > > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Main", \ > DEFAULT=YES,URI="hi/main/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Centerfield", \ > DEFAULT=NO,URI="hi/centerfield/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="hi",NAME="Dugout", \ > DEFAULT=NO,URI="hi/dugout/audio-video.m3u8" > > #EXT-X-STREAM-INF:BANDWIDTH=7680000,CODECS="...",VIDEO="hi" > hi/main/audio-video.m3u8 > > > > What do you think about it?? Sorry for my delayed response. I have revamped the implementation, so that user can configure many options including the cc group name and have submitted the patch with version v2 (https://patchwork.ffmpeg.org/patch/7229/). Please review the revised patch. > >> >>>> + avio_printf(hls->m3u8_out, >>>> "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID=\"%s\"", >>>> + cc_group); >>>> + avio_printf(hls->m3u8_out, >>>> ",NAME=\"captions\",INSTREAM-ID=\"CC%d\"\n", >>>> + hls->cc_instream_id); >>>> + } >>>> + >>>> /* For audio only variant streams add #EXT-X-MEDIA tag with >>>> attributes*/ >>>> for (i = 0; i < hls->nb_varstreams; i++) { >>>> vs = &(hls->var_streams[i]); >>>> @@ -1235,7 +1245,8 @@ static int create_master_playlist(AVFormatContext *s, >>>> bandwidth += bandwidth / 10; >>>> >>>> ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, >>>> m3u8_rel_name, >>>> - aud_st ? vs->agroup : NULL); >>>> + aud_st ? vs->agroup : NULL, >>>> + vid_st ? cc_group : NULL); >>>> >>>> av_freep(&m3u8_rel_name); >>>> } >>>> @@ -2444,6 +2455,7 @@ static const AVOption options[] = { >>>> {"master_pl_name", "Create HLS master playlist with this name", >>>> OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, >>>> {"master_pl_publish_rate", "Publish master play list every after >>>> this many segment intervals", OFFSET(master_publish_rate), >>>> AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E}, >>>> {"http_persistent", "Use persistent HTTP connections", >>>> OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, >>>> + {"cc_instream_id", "Closed captions INSTREAM-ID", >>>> OFFSET(cc_instream_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 4, E}, >>>> { NULL }, >>>> }; >>>> >>>> diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c >>>> index 42f059a..8619436 100644 >>>> --- a/libavformat/hlsplaylist.c >>>> +++ b/libavformat/hlsplaylist.c >>>> @@ -36,7 +36,8 @@ void ff_hls_write_playlist_version(AVIOContext *out, int >>>> version) { >>>> } >>>> >>>> void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, >>>> - int bandwidth, char *filename, char >>>> *agroup) { >>>> + int bandwidth, char *filename, char *agroup, >>>> + char *cc_group) { >>>> if (!out || !filename) >>>> return; >>>> >>>> @@ -52,6 +53,8 @@ void ff_hls_write_stream_info(AVStream *st, AVIOContext >>>> *out, >>>> st->codecpar->height); >>>> if (agroup && strlen(agroup) > 0) >>>> avio_printf(out, ",AUDIO=\"group_%s\"", agroup); >>>> + if (cc_group && strlen(cc_group) > 0) >>>> + avio_printf(out, ",CLOSED-CAPTIONS=\"%s\"", cc_group); >>>> avio_printf(out, "\n%s\n\n", filename); >>>> } >>>> >>>> diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h >>>> index ac03550..71ccee7 100644 >>>> --- a/libavformat/hlsplaylist.h >>>> +++ b/libavformat/hlsplaylist.h >>>> @@ -38,7 +38,8 @@ typedef enum { >>>> >>>> void ff_hls_write_playlist_version(AVIOContext *out, int version); >>>> void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, >>>> - int bandwidth, char *filename, char >>>> *agroup); >>>> + int bandwidth, char *filename, char *agroup, >>>> + char *cc_group); >>>> void ff_hls_write_playlist_header(AVIOContext *out, int version, int >>>> allowcache, >>>> int target_duration, int64_t sequence, >>>> uint32_t playlist_type); >>>> -- >>>> 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