2017-12-29 15:05 GMT+08:00 Jeyapal, Karthick <kjeya...@akamai.com>: > > > On 12/28/17 5:17 PM, Karthick J wrote: >> From: Karthick Jeyapal <kjeya...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel