From patchwork Thu Aug 31 07:32:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steven Liu X-Patchwork-Id: 4914 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.15.201 with SMTP id 70csp1331599jao; Thu, 31 Aug 2017 00:33:20 -0700 (PDT) X-Google-Smtp-Source: ADKCNb7Lp7vqsAFQbKRhgdQ9YBVLRb34cH0UHvZUzIf3xN4dHT/uezP8cbz3njbREo6riRKx75/h X-Received: by 10.28.141.196 with SMTP id p187mr3164529wmd.115.1504164800585; Thu, 31 Aug 2017 00:33:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504164800; cv=none; d=google.com; s=arc-20160816; b=0331zltFNj1xvMuYw47kWkFqNb92V05nrj0msQvtGhVw10AS6efvC4J3pUA0SBmppb kNwwYymNOrMQ9f8Xs8A7Wndghl6MC8Z+HXt4XrTZW2WF3NzHx+DBmMUfqv1sP1rqVMMs KuS57JL9AuWV4u7NCxrMdurDi8OrQRybLOJdbsD5pAGtJN74PkKaobLCtFphz1NvYzwt 3SC2c8bqoYnFrN6kL9fM4eCuChAW7iLswfAl61mdDstFK8F4HmIHjtM1kCoieqrWXVlO oR+LJbNx1j4NukY0OnwjEvPHphauzYf11iaB1669M5uLZWO7XNoNJjf/hG1U1G0hZ5Yr UXzQ== 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:message-id:date:to:from :delivered-to:arc-authentication-results; bh=NtjTPybiy9pXTUUMTFKV4B/h7BY4UaRlfeMWzxcAgts=; b=EkIW/DwfWqPtawf4RQ8BGcd/NnlEIISYVzbb/2ei4WcDy/xSJiSP9XPBncxC6y+zY3 I+PWqJTbVvynateABgUfnAUK9K+prEA0iYyGhUfBfoYsh/vdjqzveKC5Af180WazHwCn LYH2+Z6oNiAPZBVCWvMPqar/usc+6v6xf/efa3WDLhCTsdr90NZDFu/4z3DkSC1P5B40 MiqUbsLSBAaJBI8G7gi958koxUIPVL0sygKNomr4xd1IQfYYD2WOqU9wQ8H0TYVfcWyd P3/I4CFNT4fco+/JDZ/rCGu0vzT83dm42jhtxOvwu9cP+Yk2KInMA8Lwae997ZsHjjUt 6qdw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l28si5950709wre.449.2017.08.31.00.33.19; Thu, 31 Aug 2017 00:33:20 -0700 (PDT) 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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F3A5468A175; Thu, 31 Aug 2017 10:33:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from smtpbg65.qq.com (smtpbg65.qq.com [103.7.28.233]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 64AD568A05F for ; Thu, 31 Aug 2017 10:33:05 +0300 (EEST) X-QQ-mid: bizesmtp14t1504164769t0rz9p2k Received: from localhost (unknown [47.90.47.25]) by esmtp4.qq.com (ESMTP) with id ; Thu, 31 Aug 2017 15:32:48 +0800 (CST) X-QQ-SSF: 01900000000000F0FH50 X-QQ-FEAT: HqsAE+iGIGg+FHIsitfVhCDHxe9jnf+Tsq0NYPhJ6FCDipb567Ksrp5PNP4jO KWhj+crBUx7i/db6eGOHqOc7oav1QQgVUQrdq/n0djPeZFqA5IHSrmFRoDpwL9G2kXYyL65 HztpF3J3CyKQ9XfJ55P+HQ64mh7TWxFb519huw5K7vS6UmDv7shgTfjBSLQqmsYFDZItMEk VX+clsucmTEhgJf4VZLAheT4dmd9j0Dxr0QlhXGqo9+Behgqs9XXJyfRRIjnk930hj+uySQ n8J4+P63ciVIUE X-QQ-GoodBg: 0 From: Steven Liu To: ffmpeg-devel@ffmpeg.org Date: Thu, 31 Aug 2017 15:32:40 +0800 Message-Id: <20170831073240.28174-1-lq@chinaffmpeg.org> X-Mailer: git-send-email 2.10.1.382.ga23ca1b.dirty X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:chinaffmpeg.org:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 Subject: [FFmpeg-devel] [PATCH] avformat/dashcomm: move reused API to common file and header file 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: Steven Liu , Steven Liu MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" move from dashenc, move DASHTmplId and dash_fill_tmpl_params to dashcomm.c, they will be used by dash demuxer and dash muxer. Suggested-by: Timo Rothenpieler Signed-off-by: Steven Liu --- libavformat/Makefile | 2 +- libavformat/dashcomm.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ libavformat/dashcomm.h | 39 ++++++++++++++ libavformat/dashenc.c | 124 +------------------------------------------- 4 files changed, 177 insertions(+), 124 deletions(-) create mode 100644 libavformat/dashcomm.c create mode 100644 libavformat/dashcomm.h diff --git a/libavformat/Makefile b/libavformat/Makefile index 36f5839aa8..4388c038a4 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -132,7 +132,7 @@ OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.o OBJS-$(CONFIG_CRC_MUXER) += crcenc.o OBJS-$(CONFIG_DATA_DEMUXER) += rawdec.o OBJS-$(CONFIG_DATA_MUXER) += rawenc.o -OBJS-$(CONFIG_DASH_MUXER) += dashenc.o +OBJS-$(CONFIG_DASH_MUXER) += dashcomm.o dashenc.o OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o OBJS-$(CONFIG_DCSTR_DEMUXER) += dcstr.o diff --git a/libavformat/dashcomm.c b/libavformat/dashcomm.c new file mode 100644 index 0000000000..4e09500b88 --- /dev/null +++ b/libavformat/dashcomm.c @@ -0,0 +1,136 @@ +#include "config.h" +#if HAVE_UNISTD_H +#include +#endif + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" +#include "libavutil/opt.h" +#include "libavutil/rational.h" +#include "libavutil/time_internal.h" + +#include "avc.h" +#include "avformat.h" +#include "avio_internal.h" +#include "internal.h" +#include "isom.h" +#include "os_support.h" +#include "url.h" +#include "dashcomm.h" + +static DASHTmplId dash_read_tmpl_id(const char *identifier, char *format_tag, + size_t format_tag_size, const char **ptr) { + const char *next_ptr; + DASHTmplId id_type = DASH_TMPL_ID_UNDEFINED; + + if (av_strstart(identifier, "$$", &next_ptr)) { + id_type = DASH_TMPL_ID_ESCAPE; + *ptr = next_ptr; + } else if (av_strstart(identifier, "$RepresentationID$", &next_ptr)) { + id_type = DASH_TMPL_ID_REP_ID; + // default to basic format, as $RepresentationID$ identifiers + // are not allowed to have custom format-tags. + av_strlcpy(format_tag, "%d", format_tag_size); + *ptr = next_ptr; + } else { // the following identifiers may have an explicit format_tag + if (av_strstart(identifier, "$Number", &next_ptr)) + id_type = DASH_TMPL_ID_NUMBER; + else if (av_strstart(identifier, "$Bandwidth", &next_ptr)) + id_type = DASH_TMPL_ID_BANDWIDTH; + else if (av_strstart(identifier, "$Time", &next_ptr)) + id_type = DASH_TMPL_ID_TIME; + else + id_type = DASH_TMPL_ID_UNDEFINED; + + // next parse the dash format-tag and generate a c-string format tag + // (next_ptr now points at the first '%' at the beginning of the format-tag) + if (id_type != DASH_TMPL_ID_UNDEFINED) { + const char *number_format = (id_type == DASH_TMPL_ID_TIME) ? PRId64 : "d"; + if (next_ptr[0] == '$') { // no dash format-tag + snprintf(format_tag, format_tag_size, "%%%s", number_format); + *ptr = &next_ptr[1]; + } else { + const char *width_ptr; + // only tolerate single-digit width-field (i.e. up to 9-digit width) + if (av_strstart(next_ptr, "%0", &width_ptr) && + av_isdigit(width_ptr[0]) && + av_strstart(&width_ptr[1], "d$", &next_ptr)) { + // yes, we're using a format tag to build format_tag. + snprintf(format_tag, format_tag_size, "%s%c%s", "%0", width_ptr[0], number_format); + *ptr = next_ptr; + } else { + av_log(NULL, AV_LOG_WARNING, "Failed to parse format-tag beginning with %s. Expected either a " + "closing '$' character or a format-string like '%%0[width]d', " + "where width must be a single digit\n", next_ptr); + id_type = DASH_TMPL_ID_UNDEFINED; + } + } + } + } + return id_type; +} + +void dash_fill_tmpl_params(char *dst, size_t buffer_size, + const char *template, int rep_id, + int number, int bit_rate, + int64_t time) { + int dst_pos = 0; + const char *t_cur = template; + while (dst_pos < buffer_size - 1 && *t_cur) { + char format_tag[7]; // May be "%d", "%0Xd", or "%0Xlld" (for $Time$), where X is in [0-9] + int n = 0; + DASHTmplId id_type; + const char *t_next = strchr(t_cur, '$'); // copy over everything up to the first '$' character + if (t_next) { + int num_copy_bytes = FFMIN(t_next - t_cur, buffer_size - dst_pos - 1); + av_strlcpy(&dst[dst_pos], t_cur, num_copy_bytes + 1); + // advance + dst_pos += num_copy_bytes; + t_cur = t_next; + } else { // no more DASH identifiers to substitute - just copy the rest over and break + av_strlcpy(&dst[dst_pos], t_cur, buffer_size - dst_pos); + break; + } + + if (dst_pos >= buffer_size - 1 || !*t_cur) + break; + + // t_cur is now pointing to a '$' character + id_type = dash_read_tmpl_id(t_cur, format_tag, sizeof(format_tag), &t_next); + switch (id_type) { + case DASH_TMPL_ID_ESCAPE: + av_strlcpy(&dst[dst_pos], "$", 2); + n = 1; + break; + case DASH_TMPL_ID_REP_ID: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, rep_id); + break; + case DASH_TMPL_ID_NUMBER: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, number); + break; + case DASH_TMPL_ID_BANDWIDTH: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, bit_rate); + break; + case DASH_TMPL_ID_TIME: + n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, time); + break; + case DASH_TMPL_ID_UNDEFINED: + // copy over one byte and advance + av_strlcpy(&dst[dst_pos], t_cur, 2); + n = 1; + t_next = &t_cur[1]; + break; + } + // t_next points just past the processed identifier + // n is the number of bytes that were attempted to be written to dst + // (may have failed to write all because buffer_size). + + // advance + dst_pos += FFMIN(n, buffer_size - dst_pos - 1); + t_cur = t_next; + } +} + + diff --git a/libavformat/dashcomm.h b/libavformat/dashcomm.h new file mode 100644 index 0000000000..941f7fded1 --- /dev/null +++ b/libavformat/dashcomm.h @@ -0,0 +1,39 @@ +/* + * MPEG-DASH ISO BMFF segmenter + * Copyright (c) 2014 Martin Storsjo + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_DASHCOMM_H +#define AVFORMAT_DASHCOMM_H +#include "avformat.h" + +// See ISO/IEC 23009-1:2014 5.3.9.4.4 +typedef enum { + DASH_TMPL_ID_UNDEFINED = -1, + DASH_TMPL_ID_ESCAPE, + DASH_TMPL_ID_REP_ID, + DASH_TMPL_ID_NUMBER, + DASH_TMPL_ID_BANDWIDTH, + DASH_TMPL_ID_TIME, +} DASHTmplId; + + +void dash_fill_tmpl_params(char *dst, size_t buffer_size, const char *template, int rep_id, int number, int bit_rate, int64_t time); + +#endif /* AVFORMAT_DASHCOMM_H */ diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index bdb332c71a..c6ea19462f 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -39,16 +39,7 @@ #include "isom.h" #include "os_support.h" #include "url.h" - -// See ISO/IEC 23009-1:2014 5.3.9.4.4 -typedef enum { - DASH_TMPL_ID_UNDEFINED = -1, - DASH_TMPL_ID_ESCAPE, - DASH_TMPL_ID_REP_ID, - DASH_TMPL_ID_NUMBER, - DASH_TMPL_ID_BANDWIDTH, - DASH_TMPL_ID_TIME, -} DASHTmplId; +#include "dashcomm.h" typedef struct Segment { char file[1024]; @@ -259,119 +250,6 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, DASHContext } } -static DASHTmplId dash_read_tmpl_id(const char *identifier, char *format_tag, - size_t format_tag_size, const char **ptr) { - const char *next_ptr; - DASHTmplId id_type = DASH_TMPL_ID_UNDEFINED; - - if (av_strstart(identifier, "$$", &next_ptr)) { - id_type = DASH_TMPL_ID_ESCAPE; - *ptr = next_ptr; - } else if (av_strstart(identifier, "$RepresentationID$", &next_ptr)) { - id_type = DASH_TMPL_ID_REP_ID; - // default to basic format, as $RepresentationID$ identifiers - // are not allowed to have custom format-tags. - av_strlcpy(format_tag, "%d", format_tag_size); - *ptr = next_ptr; - } else { // the following identifiers may have an explicit format_tag - if (av_strstart(identifier, "$Number", &next_ptr)) - id_type = DASH_TMPL_ID_NUMBER; - else if (av_strstart(identifier, "$Bandwidth", &next_ptr)) - id_type = DASH_TMPL_ID_BANDWIDTH; - else if (av_strstart(identifier, "$Time", &next_ptr)) - id_type = DASH_TMPL_ID_TIME; - else - id_type = DASH_TMPL_ID_UNDEFINED; - - // next parse the dash format-tag and generate a c-string format tag - // (next_ptr now points at the first '%' at the beginning of the format-tag) - if (id_type != DASH_TMPL_ID_UNDEFINED) { - const char *number_format = (id_type == DASH_TMPL_ID_TIME) ? PRId64 : "d"; - if (next_ptr[0] == '$') { // no dash format-tag - snprintf(format_tag, format_tag_size, "%%%s", number_format); - *ptr = &next_ptr[1]; - } else { - const char *width_ptr; - // only tolerate single-digit width-field (i.e. up to 9-digit width) - if (av_strstart(next_ptr, "%0", &width_ptr) && - av_isdigit(width_ptr[0]) && - av_strstart(&width_ptr[1], "d$", &next_ptr)) { - // yes, we're using a format tag to build format_tag. - snprintf(format_tag, format_tag_size, "%s%c%s", "%0", width_ptr[0], number_format); - *ptr = next_ptr; - } else { - av_log(NULL, AV_LOG_WARNING, "Failed to parse format-tag beginning with %s. Expected either a " - "closing '$' character or a format-string like '%%0[width]d', " - "where width must be a single digit\n", next_ptr); - id_type = DASH_TMPL_ID_UNDEFINED; - } - } - } - } - return id_type; -} - -static void dash_fill_tmpl_params(char *dst, size_t buffer_size, - const char *template, int rep_id, - int number, int bit_rate, - int64_t time) { - int dst_pos = 0; - const char *t_cur = template; - while (dst_pos < buffer_size - 1 && *t_cur) { - char format_tag[7]; // May be "%d", "%0Xd", or "%0Xlld" (for $Time$), where X is in [0-9] - int n = 0; - DASHTmplId id_type; - const char *t_next = strchr(t_cur, '$'); // copy over everything up to the first '$' character - if (t_next) { - int num_copy_bytes = FFMIN(t_next - t_cur, buffer_size - dst_pos - 1); - av_strlcpy(&dst[dst_pos], t_cur, num_copy_bytes + 1); - // advance - dst_pos += num_copy_bytes; - t_cur = t_next; - } else { // no more DASH identifiers to substitute - just copy the rest over and break - av_strlcpy(&dst[dst_pos], t_cur, buffer_size - dst_pos); - break; - } - - if (dst_pos >= buffer_size - 1 || !*t_cur) - break; - - // t_cur is now pointing to a '$' character - id_type = dash_read_tmpl_id(t_cur, format_tag, sizeof(format_tag), &t_next); - switch (id_type) { - case DASH_TMPL_ID_ESCAPE: - av_strlcpy(&dst[dst_pos], "$", 2); - n = 1; - break; - case DASH_TMPL_ID_REP_ID: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, rep_id); - break; - case DASH_TMPL_ID_NUMBER: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, number); - break; - case DASH_TMPL_ID_BANDWIDTH: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, bit_rate); - break; - case DASH_TMPL_ID_TIME: - n = snprintf(&dst[dst_pos], buffer_size - dst_pos, format_tag, time); - break; - case DASH_TMPL_ID_UNDEFINED: - // copy over one byte and advance - av_strlcpy(&dst[dst_pos], t_cur, 2); - n = 1; - t_next = &t_cur[1]; - break; - } - // t_next points just past the processed identifier - // n is the number of bytes that were attempted to be written to dst - // (may have failed to write all because buffer_size). - - // advance - dst_pos += FFMIN(n, buffer_size - dst_pos - 1); - t_cur = t_next; - } -} - static char *xmlescape(const char *str) { int outlen = strlen(str)*3/2 + 6; char *out = av_realloc(NULL, outlen + 1);