Commit 6a25bb5a authored by Steven Liu's avatar Steven Liu

avformat/hlsenc: add var_stream_map DEFAULT field status parameter

use a:0,agroup:aud_low,default:Yes a:1,agroup:aud_low,
    a:2,agroup:aud_high,default:Yes a:3, agroup:aud_high,
    v:0,agroup:aud_low v:1,agroup:aud_high
    create master m3u8 list.

result:
EXTM3U
EXT-X-VERSION:3
EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud_low",NAME="audio_0",DEFAULT=YES,URI="out_0.m3u8"
EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud_low",NAME="audio_1",DEFAULT=NO,URI="out_1.m3u8"
EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud_high",NAME="audio_2",DEFAULT=YES,URI="out_2.m3u8"
EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud_high",NAME="audio_3",DEFAULT=NO,URI="out_3.m3u8"
EXT-X-STREAM-INF:BANDWIDTH=1170400,RESOLUTION=640x480,CODECS="avc1.64001e,mp4a.40.2",AUDIO="group_aud_low"
out_4.m3u8
EXT-X-STREAM-INF:BANDWIDTH=3440800,RESOLUTION=640x480,CODECS="avc1.64001e,mp4a.40.2",AUDIO="group_aud_high"
out_5.m3u8
Signed-off-by: 's avatarSteven Liu <lq@chinaffmpeg.org>
parent 62e8644b
...@@ -967,6 +967,21 @@ and they are mapped to the two video only variant streams with audio group names ...@@ -967,6 +967,21 @@ and they are mapped to the two video only variant streams with audio group names
By default, a single hls variant containing all the encoded streams is created. By default, a single hls variant containing all the encoded streams is created.
@example
ffmpeg -re -i in.ts -b:a:0 32k -b:a:1 64k -b:v:0 1000k \
-map 0:a -map 0:a -map 0:v -f hls \
-var_stream_map "a:0,agroup:aud_low,default:yes a:1,agroup:aud_low v:0,agroup:aud_low" \
-master_pl_name master.m3u8 \
http://example.com/live/out_%v.m3u8
@end example
This example creates two audio only and one video only variant streams. In
addition to the #EXT-X-STREAM-INF tag for each variant stream in the master
playlist, #EXT-X-MEDIA tag is also added for the two audio only variant streams
and they are mapped to the one video only variant streams with audio group name
'aud_low', and the audio group have default stat is NO or YES.
By default, a single hls variant containing all the encoded streams is created.
@item cc_stream_map @item cc_stream_map
Map string which specifies different closed captions groups and their Map string which specifies different closed captions groups and their
attributes. The closed captions stream groups are separated by space. attributes. The closed captions stream groups are separated by space.
......
...@@ -153,6 +153,7 @@ typedef struct VariantStream { ...@@ -153,6 +153,7 @@ typedef struct VariantStream {
CodecAttributeStatus attr_status; CodecAttributeStatus attr_status;
unsigned int nb_streams; unsigned int nb_streams;
int m3u8_created; /* status of media play-list creation */ int m3u8_created; /* status of media play-list creation */
int is_default; /* default status of audio group */
char *agroup; /* audio group name */ char *agroup; /* audio group name */
char *ccgroup; /* closed caption group name */ char *ccgroup; /* closed caption group name */
char *baseurl; char *baseurl;
...@@ -228,6 +229,8 @@ typedef struct HLSContext { ...@@ -228,6 +229,8 @@ typedef struct HLSContext {
AVIOContext *sub_m3u8_out; AVIOContext *sub_m3u8_out;
int64_t timeout; int64_t timeout;
int ignore_io_errors; int ignore_io_errors;
int has_default_key; /* has DEFAULT field of var_stream_map */
int has_video_m3u8; /* has video stream m3u8 list */
} HLSContext; } HLSContext;
static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
...@@ -1258,7 +1261,7 @@ static int create_master_playlist(AVFormatContext *s, ...@@ -1258,7 +1261,7 @@ static int create_master_playlist(AVFormatContext *s,
goto fail; goto fail;
} }
ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, i, 1); ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, i, hls->has_default_key ? vs->is_default : 1);
av_freep(&m3u8_rel_name); av_freep(&m3u8_rel_name);
} }
...@@ -1336,8 +1339,15 @@ static int create_master_playlist(AVFormatContext *s, ...@@ -1336,8 +1339,15 @@ static int create_master_playlist(AVFormatContext *s,
vs->ccgroup); vs->ccgroup);
} }
ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name, if (!hls->has_default_key || !hls->has_video_m3u8) {
aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup); ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup);
} else {
if (vid_st) {
ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup);
}
}
av_freep(&m3u8_rel_name); av_freep(&m3u8_rel_name);
} }
...@@ -1819,7 +1829,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) ...@@ -1819,7 +1829,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
/** /**
* Expected format for var_stream_map string is as below: * Expected format for var_stream_map string is as below:
* "a:0,v:0 a:1,v:1" * "a:0,v:0 a:1,v:1"
* "a:0,agroup:a0 a:1,agroup:a1 v:0,agroup:a0 v:1,agroup:a1" * "a:0,agroup:a0,default:1 a:1,agroup:a1,defalut:0 v:0,agroup:a0 v:1,agroup:a1"
* This string specifies how to group the audio, video and subtitle streams * This string specifies how to group the audio, video and subtitle streams
* into different variant streams. The variant stream groups are separated * into different variant streams. The variant stream groups are separated
* by space. * by space.
...@@ -1850,6 +1860,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) ...@@ -1850,6 +1860,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
if (nb_varstreams < hls->nb_varstreams) { if (nb_varstreams < hls->nb_varstreams) {
vs = &(hls->var_streams[nb_varstreams]); vs = &(hls->var_streams[nb_varstreams]);
vs->var_stream_idx = nb_varstreams; vs->var_stream_idx = nb_varstreams;
vs->is_default = 0;
nb_varstreams++; nb_varstreams++;
} else } else
return AVERROR(EINVAL); return AVERROR(EINVAL);
...@@ -1869,7 +1880,12 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) ...@@ -1869,7 +1880,12 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
while (keyval = av_strtok(varstr, ",", &saveptr2)) { while (keyval = av_strtok(varstr, ",", &saveptr2)) {
varstr = NULL; varstr = NULL;
if (av_strstart(keyval, "agroup:", &val)) { if (av_strstart(keyval, "default:", &val)) {
vs->is_default = (!av_strncasecmp(val, "YES", strlen("YES")) ||
(!av_strncasecmp(val, "1", strlen("1"))));
hls->has_default_key = 1;
continue;
} else if (av_strstart(keyval, "agroup:", &val)) {
vs->agroup = av_strdup(val); vs->agroup = av_strdup(val);
if (!vs->agroup) if (!vs->agroup)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
...@@ -1881,6 +1897,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s) ...@@ -1881,6 +1897,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
continue; continue;
} else if (av_strstart(keyval, "v:", &val)) { } else if (av_strstart(keyval, "v:", &val)) {
codec_type = AVMEDIA_TYPE_VIDEO; codec_type = AVMEDIA_TYPE_VIDEO;
hls->has_video_m3u8 = 1;
} else if (av_strstart(keyval, "a:", &val)) { } else if (av_strstart(keyval, "a:", &val)) {
codec_type = AVMEDIA_TYPE_AUDIO; codec_type = AVMEDIA_TYPE_AUDIO;
} else if (av_strstart(keyval, "s:", &val)) { } else if (av_strstart(keyval, "s:", &val)) {
...@@ -2519,6 +2536,8 @@ static int hls_init(AVFormatContext *s) ...@@ -2519,6 +2536,8 @@ static int hls_init(AVFormatContext *s)
int vtt_basename_size = 0; int vtt_basename_size = 0;
int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1; int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
hls->has_default_key = 0;
hls->has_video_m3u8 = 0;
ret = update_variant_stream_info(s); ret = update_variant_stream_info(s);
if (ret < 0) { if (ret < 0) {
av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n", av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment