Message ID | 1512041572-23671-1-git-send-email-vdixit@akamai.com |
---|---|
State | Superseded |
Headers | show |
2017-11-30 19:32 GMT+08:00 <vdixit@akamai.com>: > From: Vishwanath Dixit <vdixit@akamai.com> > > --- > libavformat/Makefile | 2 +- > libavformat/dashenc.c | 2 +- > libavformat/hlsenc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-- > libavformat/hlsplaylist.c | 5 +++- > libavformat/hlsplaylist.h | 3 ++- > libavformat/reverse.c | 1 + Remove this modify if this have nothing to do. > tests/ref/fate/source | 1 + > 7 files changed, 73 insertions(+), 6 deletions(-) > create mode 100644 libavformat/reverse.c > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index 4bffdf2..2bdb777 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -61,7 +61,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ > rtpdec_vp9.o \ > rtpdec_xiph.o > OBJS-$(CONFIG_RTPENC_CHAIN) += rtpenc_chain.o rtp.o > -OBJS-$(CONFIG_SHARED) += log2_tab.o golomb_tab.o > +OBJS-$(CONFIG_SHARED) += log2_tab.o golomb_tab.o reverse.o > OBJS-$(CONFIG_SRTP) += srtp.o > > # muxers/demuxers > diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c > index 90cd2d0..e0b1679 100644 > --- a/libavformat/dashenc.c > +++ b/libavformat/dashenc.c > @@ -754,7 +754,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 8d4b333..0702124 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -39,6 +39,7 @@ > #include "libavutil/avstring.h" > #include "libavutil/intreadwrite.h" > #include "libavutil/random_seed.h" > +#include "libavutil/reverse.h" > #include "libavutil/opt.h" > #include "libavutil/log.h" > #include "libavutil/time_internal.h" > @@ -1074,6 +1075,63 @@ static int get_relative_url(const char *master_url, const char *media_url, > return 0; > } > > +static char *get_codec_str(AVStream *vid_st, AVStream *aud_st) { > + size_t codec_str_size = 64; > + char *codec_str = av_malloc(codec_str_size); > + int video_str_len = 0; > + > + if (!codec_str) > + return NULL; > + > + if (!vid_st && !aud_st) { > + goto fail; > + } > + > + if (vid_st) { > + if (vid_st->codecpar->profile != FF_PROFILE_UNKNOWN && > + vid_st->codecpar->level != FF_LEVEL_UNKNOWN && > + vid_st->codecpar->codec_id == AV_CODEC_ID_H264) { > + snprintf(codec_str, codec_str_size, "avc1.%02x%02x%02x", > + vid_st->codecpar->profile & 0xFF, > + ff_reverse[(vid_st->codecpar->profile >> 8) & 0xFF], > + vid_st->codecpar->level); > + } else { > + goto fail; > + } > + video_str_len = strlen(codec_str); > + } > + > + if (aud_st) { > + char *audio_str = codec_str; > + if (video_str_len) { > + codec_str[video_str_len] = ','; > + video_str_len += 1; > + audio_str += video_str_len; > + codec_str_size -= video_str_len; > + } > + if (aud_st->codecpar->codec_id == AV_CODEC_ID_MP2) { > + snprintf(audio_str, codec_str_size, "mp4a.40.33"); > + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_MP3) { > + snprintf(audio_str, codec_str_size, "mp4a.40.34"); > + } else if (aud_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(audio_str, codec_str_size, "mp4a.40.2"); > + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_AC3) { > + snprintf(audio_str, codec_str_size, "mp4a.A5"); > + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_EAC3) { > + snprintf(audio_str, codec_str_size, "mp4a.A6"); > + } else { > + goto fail; > + } > + } > + > + return codec_str; > + > +fail: > + av_free(codec_str); > + return NULL; > +} > + > static int create_master_playlist(AVFormatContext *s, > VariantStream * const input_vs) > { > @@ -1084,7 +1142,7 @@ static int create_master_playlist(AVFormatContext *s, > AVDictionary *options = NULL; > unsigned int i, j; > int m3u8_name_size, ret, bandwidth; > - char *m3u8_rel_name; > + char *m3u8_rel_name, *codec_str; > > input_vs->m3u8_created = 1; > if (!hls->master_m3u8_created) { > @@ -1198,9 +1256,12 @@ static int create_master_playlist(AVFormatContext *s, > bandwidth += aud_st->codecpar->bit_rate; > bandwidth += bandwidth / 10; > > + codec_str = get_codec_str(vid_st, aud_st); > + > ff_hls_write_stream_info(vid_st, master_pb, bandwidth, m3u8_rel_name, > - aud_st ? vs->agroup : NULL); > + codec_str, aud_st ? vs->agroup : NULL); > > + av_freep(&codec_str); > av_freep(&m3u8_rel_name); > } > fail: > diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c > index 5e12682..eaf598f 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 *codec_str, > + char *agroup) { > 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 (codec_str && strlen(codec_str) > 0) > + avio_printf(out, ",CODECS=\"%s\"", codec_str); > 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 3231733..476cfc4 100644 > --- a/libavformat/hlsplaylist.h > +++ b/libavformat/hlsplaylist.h > @@ -43,7 +43,8 @@ static inline int hls_get_int_from_double(double val) > > 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 *codec_str, > + char *agroup); > void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, > int target_duration, int64_t sequence, > uint32_t playlist_type); > diff --git a/libavformat/reverse.c b/libavformat/reverse.c > new file mode 100644 > index 0000000..440bada > --- /dev/null > +++ b/libavformat/reverse.c > @@ -0,0 +1 @@ > +#include "libavutil/reverse.c" > diff --git a/tests/ref/fate/source b/tests/ref/fate/source > index 2def034..b68873b 100644 > --- a/tests/ref/fate/source > +++ b/tests/ref/fate/source > @@ -11,6 +11,7 @@ libavfilter/log2_tab.c > libavformat/file_open.c > libavformat/golomb_tab.c > libavformat/log2_tab.c > +libavformat/reverse.c > libswresample/log2_tab.c > libswscale/log2_tab.c > tools/uncoded_frame.c > -- > 1.9.1 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>On 11/30/17, 5:31 PM, "Steven Liu" <lingjiujianke@gmail.com> wrote: > > 2017-11-30 19:32 GMT+08:00 <vdixit@akamai.com>: >> From: Vishwanath Dixit <vdixit@akamai.com> >> >> --- >> libavformat/Makefile | 2 +- >> libavformat/dashenc.c | 2 +- >> libavformat/hlsenc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-- >> libavformat/hlsplaylist.c | 5 +++- >> libavformat/hlsplaylist.h | 3 ++- >> libavformat/reverse.c | 1 + > Remove this modify if this have nothing to do. This new wrapper file is needed, as the patch is using the function ff_reverse, which is defined in libavutil/reverse.c. Without this libavformat library compilation will fail with the same error as reported for libavdevice here https://trac.ffmpeg.org/ticket/6544.
diff --git a/libavformat/Makefile b/libavformat/Makefile index 4bffdf2..2bdb777 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -61,7 +61,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ rtpdec_vp9.o \ rtpdec_xiph.o OBJS-$(CONFIG_RTPENC_CHAIN) += rtpenc_chain.o rtp.o -OBJS-$(CONFIG_SHARED) += log2_tab.o golomb_tab.o +OBJS-$(CONFIG_SHARED) += log2_tab.o golomb_tab.o reverse.o OBJS-$(CONFIG_SRTP) += srtp.o # muxers/demuxers diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 90cd2d0..e0b1679 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -754,7 +754,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 8d4b333..0702124 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -39,6 +39,7 @@ #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" #include "libavutil/random_seed.h" +#include "libavutil/reverse.h" #include "libavutil/opt.h" #include "libavutil/log.h" #include "libavutil/time_internal.h" @@ -1074,6 +1075,63 @@ static int get_relative_url(const char *master_url, const char *media_url, return 0; } +static char *get_codec_str(AVStream *vid_st, AVStream *aud_st) { + size_t codec_str_size = 64; + char *codec_str = av_malloc(codec_str_size); + int video_str_len = 0; + + if (!codec_str) + return NULL; + + if (!vid_st && !aud_st) { + goto fail; + } + + if (vid_st) { + if (vid_st->codecpar->profile != FF_PROFILE_UNKNOWN && + vid_st->codecpar->level != FF_LEVEL_UNKNOWN && + vid_st->codecpar->codec_id == AV_CODEC_ID_H264) { + snprintf(codec_str, codec_str_size, "avc1.%02x%02x%02x", + vid_st->codecpar->profile & 0xFF, + ff_reverse[(vid_st->codecpar->profile >> 8) & 0xFF], + vid_st->codecpar->level); + } else { + goto fail; + } + video_str_len = strlen(codec_str); + } + + if (aud_st) { + char *audio_str = codec_str; + if (video_str_len) { + codec_str[video_str_len] = ','; + video_str_len += 1; + audio_str += video_str_len; + codec_str_size -= video_str_len; + } + if (aud_st->codecpar->codec_id == AV_CODEC_ID_MP2) { + snprintf(audio_str, codec_str_size, "mp4a.40.33"); + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_MP3) { + snprintf(audio_str, codec_str_size, "mp4a.40.34"); + } else if (aud_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(audio_str, codec_str_size, "mp4a.40.2"); + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_AC3) { + snprintf(audio_str, codec_str_size, "mp4a.A5"); + } else if (aud_st->codecpar->codec_id == AV_CODEC_ID_EAC3) { + snprintf(audio_str, codec_str_size, "mp4a.A6"); + } else { + goto fail; + } + } + + return codec_str; + +fail: + av_free(codec_str); + return NULL; +} + static int create_master_playlist(AVFormatContext *s, VariantStream * const input_vs) { @@ -1084,7 +1142,7 @@ static int create_master_playlist(AVFormatContext *s, AVDictionary *options = NULL; unsigned int i, j; int m3u8_name_size, ret, bandwidth; - char *m3u8_rel_name; + char *m3u8_rel_name, *codec_str; input_vs->m3u8_created = 1; if (!hls->master_m3u8_created) { @@ -1198,9 +1256,12 @@ static int create_master_playlist(AVFormatContext *s, bandwidth += aud_st->codecpar->bit_rate; bandwidth += bandwidth / 10; + codec_str = get_codec_str(vid_st, aud_st); + ff_hls_write_stream_info(vid_st, master_pb, bandwidth, m3u8_rel_name, - aud_st ? vs->agroup : NULL); + codec_str, aud_st ? vs->agroup : NULL); + av_freep(&codec_str); av_freep(&m3u8_rel_name); } fail: diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c index 5e12682..eaf598f 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 *codec_str, + char *agroup) { 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 (codec_str && strlen(codec_str) > 0) + avio_printf(out, ",CODECS=\"%s\"", codec_str); 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 3231733..476cfc4 100644 --- a/libavformat/hlsplaylist.h +++ b/libavformat/hlsplaylist.h @@ -43,7 +43,8 @@ static inline int hls_get_int_from_double(double val) 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 *codec_str, + char *agroup); void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type); diff --git a/libavformat/reverse.c b/libavformat/reverse.c new file mode 100644 index 0000000..440bada --- /dev/null +++ b/libavformat/reverse.c @@ -0,0 +1 @@ +#include "libavutil/reverse.c" diff --git a/tests/ref/fate/source b/tests/ref/fate/source index 2def034..b68873b 100644 --- a/tests/ref/fate/source +++ b/tests/ref/fate/source @@ -11,6 +11,7 @@ libavfilter/log2_tab.c libavformat/file_open.c libavformat/golomb_tab.c libavformat/log2_tab.c +libavformat/reverse.c libswresample/log2_tab.c libswscale/log2_tab.c tools/uncoded_frame.c
From: Vishwanath Dixit <vdixit@akamai.com> --- libavformat/Makefile | 2 +- libavformat/dashenc.c | 2 +- libavformat/hlsenc.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-- libavformat/hlsplaylist.c | 5 +++- libavformat/hlsplaylist.h | 3 ++- libavformat/reverse.c | 1 + tests/ref/fate/source | 1 + 7 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 libavformat/reverse.c