2017-12-29 19:58 GMT+08:00 Dixit, Vishwanath <[email protected]>:
>
>
> On 12/29/17 5:11 PM, Steven Liu wrote:
>> 2017-12-29 18:44 GMT+08:00 <[email protected]>:
>>> From: Vishwanath Dixit <[email protected]>
>>>
>>> ---
>>> 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??
>
>
>>> + 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
[email protected]
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel