Message ID | 1514459988-19703-1-git-send-email-kjeyapal@akamai.com |
---|---|
State | Superseded |
Headers | show |
> On 28 Dec 2017, at 19:19, Karthick J <kjeyapal@akamai.com> wrote: > > From: Karthick Jeyapal <kjeyapal@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..1a84799 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 (!strstr(vs->codec_attr, attr)) { Is this use av_stristr? > + 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); > -- > 1.9.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
On 12/28/17 5:05 PM, 刘歧 wrote: > >> On 28 Dec 2017, at 19:19, Karthick J <kjeyapal@akamai.com> wrote: >> >> From: Karthick Jeyapal <kjeyapal@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..1a84799 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 (!strstr(vs->codec_attr, attr)) { > Is this use av_stristr? Thanks for your comments. I have sent PATCH v2 with that correction. > >> + 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); >> -- >> 1.9.1 >> >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > Regards, Karthick
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..1a84799 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 (!strstr(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);
From: Karthick Jeyapal <kjeyapal@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(-)