[FFmpeg-devel] [PATCH v2] avformat/hlsenc: Add CODECS attribute to master playlist
Steven Liu
lingjiujianke at gmail.com
Fri Jan 19 12:31:53 EET 2018
2017-12-29 15:05 GMT+08:00 Jeyapal, Karthick <kjeyapal at akamai.com>:
>
>
> On 12/28/17 5:17 PM, Karthick J wrote:
>> From: Karthick Jeyapal <kjeyapal at akamai.com>
>>
>> ---
>> libavformat/dashenc.c | 2 +-
>> libavformat/hlsenc.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++-
>> libavformat/hlsplaylist.c | 5 +++-
>> libavformat/hlsplaylist.h | 3 ++-
>> 4 files changed, 73 insertions(+), 4 deletions(-)
>>
>> 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..bb442f5 100644
>> --- a/libavformat/hlsenc.c
>> +++ b/libavformat/hlsenc.c
>> @@ -58,6 +58,11 @@ typedef enum {
>> HLS_START_SEQUENCE_AS_FORMATTED_DATETIME = 2, // YYYYMMDDhhmmss
>> } StartSequenceSourceType;
>>
>> +typedef enum {
>> + CODEC_ATTRIBUTE_WRITTEN = 0,
>> + CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN,
>> +} CodecAttributeStatus;
>> +
>> #define KEYSIZE 16
>> #define LINE_BUFFER_SIZE 1024
>> #define HLS_MICROSECOND_UNIT 1000000
>> @@ -142,6 +147,8 @@ typedef struct VariantStream {
>> int fmp4_init_mode;
>>
>> AVStream **streams;
>> + char codec_attr[128];
>> + CodecAttributeStatus attr_status;
>> unsigned int nb_streams;
>> int m3u8_created; /* status of media play-list creation */
>> char *agroup; /* audio group name */
>> @@ -296,6 +303,51 @@ static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSCont
>>
>> }
>>
>> +static void write_codec_attr(AVStream *st, VariantStream *vs) {
>> + int codec_strlen = strlen(vs->codec_attr);
>> + char attr[32];
>> +
>> + if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
>> + return;
>> + if (vs->attr_status == CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN)
>> + return;
>> +
>> + if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
>> + uint8_t *data = st->codecpar->extradata;
>> + if ((data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 0x1F) == 7) {
>> + snprintf(attr, sizeof(attr),
>> + "avc1.%02x%02x%02x", data[5], data[6], data[7]);
>> + } else {
>> + goto fail;
>> + }
>> + } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
>> + snprintf(attr, sizeof(attr), "mp4a.40.33");
>> + } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
>> + snprintf(attr, sizeof(attr), "mp4a.40.34");
>> + } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
>> + /* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 and 29 respectively */
>> + snprintf(attr, sizeof(attr), "mp4a.40.2");
>> + } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
>> + snprintf(attr, sizeof(attr), "ac-3");
>> + } else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
>> + snprintf(attr, sizeof(attr), "ec-3");
>> + } else {
>> + goto fail;
>> + }
>> + // Don't write the same attribute multiple times
>> + if (!av_stristr(vs->codec_attr, attr)) {
>> + snprintf(vs->codec_attr + codec_strlen,
>> + sizeof(vs->codec_attr) - codec_strlen,
>> + "%s%s", codec_strlen ? "," : "", attr);
>> + }
>> + return;
>> +
>> +fail:
>> + vs->codec_attr[0] = '\0';
>> + vs->attr_status = CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN;
>> + return;
>> +}
>> +
>> static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number)
>> {
>> const char *p;
>> @@ -1235,7 +1287,7 @@ 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, vs->codec_attr);
>>
>> av_freep(&m3u8_rel_name);
>> }
>> @@ -1764,6 +1816,19 @@ static int hls_write_header(AVFormatContext *s)
>> continue;
>> }
>> avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
>> + write_codec_attr(outer_st, vs);
>> +
>> + }
>> + /* Update the Codec Attr string for the mapped audio groups */
>> + if (vs->has_video && vs->agroup) {
>> + for (j = 0; j < hls->nb_varstreams; j++) {
>> + VariantStream *vs_agroup = &(hls->var_streams[j]);
>> + if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
>> + vs_agroup->agroup &&
>> + !av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
>> + write_codec_attr(vs_agroup->streams[0], vs);
>> + }
>> + }
>> }
>> }
>> fail:
>> diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
>> index 42f059a..99231c9 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 *codecs) {
>> if (!out || !filename)
>> return;
>>
>> @@ -50,6 +51,8 @@ void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
>> if (st && st->codecpar->width > 0 && st->codecpar->height > 0)
>> avio_printf(out, ",RESOLUTION=%dx%d", st->codecpar->width,
>> st->codecpar->height);
>> + if (codecs && strlen(codecs) > 0)
>> + avio_printf(out, ",CODECS=\"%s\"", codecs);
>> if (agroup && strlen(agroup) > 0)
>> avio_printf(out, ",AUDIO=\"group_%s\"", agroup);
>> avio_printf(out, "\n%s\n\n", filename);
>> diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
>> index ac03550..5bbdf86 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 *codecs);
>> void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache,
>> int target_duration, int64_t sequence,
>> uint32_t playlist_type);
Pushed
Thanks
Steven
More information about the ffmpeg-devel
mailing list