From patchwork Tue Dec 19 06:09:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dixit, Vishwanath" X-Patchwork-Id: 6861 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.79.195 with SMTP id r64csp1171488jad; Mon, 18 Dec 2017 22:09:54 -0800 (PST) X-Google-Smtp-Source: ACJfBosA93g4sWyJASptKOpcHH+4v0EGsAo/LRbMvzIWClnnHSBwvg4AcxSHgUuawL/Lfz+zcwbw X-Received: by 10.223.150.20 with SMTP id b20mr3302921wra.5.1513663794452; Mon, 18 Dec 2017 22:09:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513663794; cv=none; d=google.com; s=arc-20160816; b=FMC/sElvs4RM1G6JjF7Ufgoh1pJ6wy8b1yI/K51x76bI5dMTrFB8sGulYVyIRR28V0 rp6SOiNkV3B5rMApjVl8HpZ1No5K5rFzAmmS5ihL4LQJP8FN45E9QsLLnWuAILlxQxj0 sFAXjgnkMH0j122Afbu8N8EAh0TIyH8xpD8MzucnU2/LkriYwIHZcg2iaNFEkDDD3OWA BjQHSm7xSkeJlj9IyDu2Ar5Od0b9xvp7TwK6Ao5DRID7FuGko5xkHOZa4wf2384LFca6 +5Q8uSl/pEl98yIWY0/RhE+QUXhv90KuKXylNpVrlMd/4wIIZGmeCw1HL4zj0s65MKZu oV1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:feedback-id:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to :arc-authentication-results; bh=n7xFfK5rXwJciTWbyz6PqXk4H/WaxEoJtM3EaB1mt7s=; b=LRQB5A6zzFNtwO2gP5tt5vYNm9YwTvS8cXfAN3MQ7YjeiDcXWTAPVDmaQO8nriGH4/ 9eioJVKn9gOjwxEg9Jo0prMuvdP0e6HbX6RQHtb20YNT4xfV2fCWqlAWXvTZire8KUJR 5lu1RDjWJatngKCjvvoUJEfnGoYgrZiAZg2/f8RWex0EyI8xzHLkYz3jemCBzYnlw17M M7O9xgVJKwfrUpe5cTX9ioal7aEAPz+3h3SmqKOt/ayS3BM0/OeRPTawMn5tCAp0u/ZK dI9ftD+oFuHmkBq87oJjGdyRHmpnGyphxgUkffc8iut9/x3/gFCoLTSI/eZb2ZGZjvDI qZAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@smtpservice.net header.s=m78bu0.a1-4.dyn header.b=JCl/4cYS; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=akamai.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o36si6157485wrf.523.2017.12.18.22.09.54; Mon, 18 Dec 2017 22:09:54 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@smtpservice.net header.s=m78bu0.a1-4.dyn header.b=JCl/4cYS; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=akamai.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C65F0689C95; Tue, 19 Dec 2017 08:09:42 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from a2i831.smtp2go.com (a2i831.smtp2go.com [103.47.207.63]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C0284688312 for ; Tue, 19 Dec 2017 08:09:36 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpservice.net; s=m78bu0.a1-4.dyn; x=1513664692; h=Feedback-ID: X-Smtpcorp-Track:Message-Id:Date:Subject:To:From:Reply-To:Sender: List-Unsubscribe; bh=LMjb12rz6nyxVmmTaMKBzt9hg70QaneGOxCJXvZJLHA=; b=JCl/4cYS mS+3IUng2ESn5VuXRmNS5xiMvXKLrjnRJfZ+VmbcupU8eVQTNnPGqPk5yuK6b6x3PlGD8Zs9tLudI XFVhvt1PGSl9xAQgC4KtPv7PfczqczUQM3wXFOwRQfR4yJMFEOhznqjhWArG8J2+dHfA+XRzWoUTR r6Hb0SjPJ/bLhghEP+9HwkHLc3UaRo9iYHKsx/padSaunZEq/rLMN6nZFCkNJHJrOK839H8acrWfh Frnk4vqAs6CT4Yhcz2MA0vCxXUNpcB/RBxecp5yXyz4opfYeiVJoIh5S5Vol/yzMp7agh3BEgLEvi ySGEZRMjmySqINH+Ljfn9efvEQ==; From: vdixit@akamai.com To: ffmpeg-devel@ffmpeg.org Date: Tue, 19 Dec 2017 11:39:40 +0530 Message-Id: <1513663780-1982-1-git-send-email-vdixit@akamai.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1513601594-27964-1-git-send-email-vdixit@akamai.com> References: <1513601594-27964-1-git-send-email-vdixit@akamai.com> X-Smtpcorp-Track: 1-RU60DIIcPzOg.OO0pbcBlr Feedback-ID: 337386m:337386asVRLGB:337386sWHzhDJFpp:SMTPCORP X-Report-Abuse: Please forward a copy of this message, including all headers, to Subject: [FFmpeg-devel] [PATCH v8 3/3] avformat/hlsenc:addition of CODECS attribute in the master playlist X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Vishwanath Dixit MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Vishwanath Dixit --- 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 diff --git a/libavformat/Makefile b/libavformat/Makefile index cb70eac..1072ff9 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 f363418..016ada3 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 53dc835..d66b88b 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" @@ -1082,6 +1083,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) { @@ -1091,7 +1149,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) { @@ -1204,9 +1262,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, hls->m3u8_out, 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 42f059a..b1b1ec6 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 a3ce26c..e807c6e 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