From patchwork Thu Jun 11 04:43:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: rcombs X-Patchwork-Id: 20275 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 1CC59448CDE for ; Thu, 11 Jun 2020 07:43:44 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F20AD68B474; Thu, 11 Jun 2020 07:43:43 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from so254-54.mailgun.net (so254-54.mailgun.net [198.61.254.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D287268AFF5 for ; Thu, 11 Jun 2020 07:43:37 +0300 (EEST) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=rcombs.me; q=dns/txt; s=mx; t=1591850620; h=Content-Transfer-Encoding: MIME-Version: Message-Id: Date: Subject: To: From: Sender; bh=uKvdsNlY8mkgfoZqaoGfwJexq24lmDAZcor2VbEzWHc=; b=TEHqTwYswKMj2aebtvJh7l1V+qNxtWvGbbRc9AIBZ+O5N2Ju8Gyq/Bu9ffDnCIJJjp5RErLW 4CVXOvTypI0QWL3rWKWL4C35ZOP+XjfFBkzRSKhAO/BkEW2zHb+2AghMCgysG3R5C5eowQJv u4PEnrAYVzIspH5cnoEBKnhGIfs= X-Mailgun-Sending-Ip: 198.61.254.54 X-Mailgun-Sid: WyJiZDU1MSIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICJiMGJhIl0= Received: from rcombs-mbp.localdomain ( [24.14.135.13]) by smtp-out-n12.prod.us-west-2.postgun.com with SMTP id 5ee1b666f3deea03f39781e5 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 11 Jun 2020 04:43:18 GMT From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Jun 2020 23:43:08 -0500 Message-Id: <20200611044312.38981-1-rcombs@rcombs.me> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/5] lavf/dashdec: fix 'adaption' typo 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavformat/dashdec.c | 96 +++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 1bd070c7cb..c94ce2caca 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,7 +148,7 @@ typedef struct DASHContext { uint64_t period_start; /* AdaptationSet Attribute */ - char *adaptionset_lang; + char *adaptationset_lang; int is_live; AVIOInterruptCB *interrupt_callback; @@ -822,16 +822,16 @@ end: static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, - xmlNodePtr adaptionset_node, + xmlNodePtr adaptationset_node, xmlNodePtr mpd_baseurl_node, xmlNodePtr period_baseurl_node, xmlNodePtr period_segmenttemplate_node, xmlNodePtr period_segmentlist_node, xmlNodePtr fragment_template_node, xmlNodePtr content_component_node, - xmlNodePtr adaptionset_baseurl_node, - xmlNodePtr adaptionset_segmentlist_node, - xmlNodePtr adaptionset_supplementalproperty_node) + xmlNodePtr adaptationset_baseurl_node, + xmlNodePtr adaptationset_segmentlist_node, + xmlNodePtr adaptationset_supplementalproperty_node) { int32_t ret = 0; int32_t subtitle_rep_idx = 0; @@ -866,9 +866,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, // try get information from contentComponen if (type == AVMEDIA_TYPE_UNKNOWN) type = get_content_type(content_component_node); - // try get information from adaption set + // try get information from adaptation set if (type == AVMEDIA_TYPE_UNKNOWN) - type = get_content_type(adaptionset_node); + type = get_content_type(adaptationset_node); if (type == AVMEDIA_TYPE_UNKNOWN) { av_log(s, AV_LOG_VERBOSE, "Parsing '%s' - skipp not supported representation type\n", url); } else if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) { @@ -878,8 +878,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ret = AVERROR(ENOMEM); goto end; } - if (c->adaptionset_lang) { - rep->lang = av_strdup(c->adaptionset_lang); + if (c->adaptationset_lang) { + rep->lang = av_strdup(c->adaptationset_lang); if (!rep->lang) { av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); av_freep(&rep); @@ -894,7 +894,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[0] = mpd_baseurl_node; baseurl_nodes[1] = period_baseurl_node; - baseurl_nodes[2] = adaptionset_baseurl_node; + baseurl_nodes[2] = adaptationset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4); @@ -907,7 +907,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; - fragment_templates_tab[1] = adaptionset_segmentlist_node; + fragment_templates_tab[1] = adaptationset_segmentlist_node; fragment_templates_tab[2] = fragment_template_node; fragment_templates_tab[3] = period_segmenttemplate_node; fragment_templates_tab[4] = period_segmentlist_node; @@ -964,11 +964,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); xmlFree(startnumber_val); } - if (adaptionset_supplementalproperty_node) { - if (!av_strcasecmp(xmlGetProp(adaptionset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) { - val = xmlGetProp(adaptionset_supplementalproperty_node,"value"); + if (adaptationset_supplementalproperty_node) { + if (!av_strcasecmp(xmlGetProp(adaptationset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) { + val = xmlGetProp(adaptationset_supplementalproperty_node,"value"); if (!val) { - av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptionset_supplementalproperty_node\n"); + av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptationset_supplementalproperty_node\n"); } else { rep->last_seq_no =(int64_t) strtoll(val, NULL, 10) - 1; xmlFree(val); @@ -981,7 +981,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (!fragment_timeline_node) fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); + fragment_timeline_node = find_child_node_by_name(adaptationset_segmentlist_node, "SegmentTimeline"); if (!fragment_timeline_node) fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); if (fragment_timeline_node) { @@ -1013,7 +1013,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, // http://www-itec.uni-klu.ac.at/dash/ddash/mpdGenerator.php?fragmentlength=15&type=full xmlNodePtr fragmenturl_node = NULL; segmentlists_tab[0] = representation_segmentlist_node; - segmentlists_tab[1] = adaptionset_segmentlist_node; + segmentlists_tab[1] = adaptationset_segmentlist_node; segmentlists_tab[2] = period_segmentlist_node; duration_val = get_val_from_nodes_tab(segmentlists_tab, 3, "duration"); @@ -1052,7 +1052,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (!fragment_timeline_node) fragment_timeline_node = find_child_node_by_name(fragment_template_node, "SegmentTimeline"); if (!fragment_timeline_node) - fragment_timeline_node = find_child_node_by_name(adaptionset_segmentlist_node, "SegmentTimeline"); + fragment_timeline_node = find_child_node_by_name(adaptationset_segmentlist_node, "SegmentTimeline"); if (!fragment_timeline_node) fragment_timeline_node = find_child_node_by_name(period_segmentlist_node, "SegmentTimeline"); if (fragment_timeline_node) { @@ -1118,21 +1118,21 @@ end: return ret; } -static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptionset_node) +static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptationset_node) { DASHContext *c = s->priv_data; - if (!adaptionset_node) { - av_log(s, AV_LOG_WARNING, "Cannot get AdaptionSet\n"); + if (!adaptationset_node) { + av_log(s, AV_LOG_WARNING, "Cannot get AdaptationSet\n"); return AVERROR(EINVAL); } - c->adaptionset_lang = xmlGetProp(adaptionset_node, "lang"); + c->adaptationset_lang = xmlGetProp(adaptationset_node, "lang"); return 0; } static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, - xmlNodePtr adaptionset_node, + xmlNodePtr adaptationset_node, xmlNodePtr mpd_baseurl_node, xmlNodePtr period_baseurl_node, xmlNodePtr period_segmenttemplate_node, @@ -1142,39 +1142,39 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, DASHContext *c = s->priv_data; xmlNodePtr fragment_template_node = NULL; xmlNodePtr content_component_node = NULL; - xmlNodePtr adaptionset_baseurl_node = NULL; - xmlNodePtr adaptionset_segmentlist_node = NULL; - xmlNodePtr adaptionset_supplementalproperty_node = NULL; + xmlNodePtr adaptationset_baseurl_node = NULL; + xmlNodePtr adaptationset_segmentlist_node = NULL; + xmlNodePtr adaptationset_supplementalproperty_node = NULL; xmlNodePtr node = NULL; - ret = parse_manifest_adaptationset_attr(s, adaptionset_node); + ret = parse_manifest_adaptationset_attr(s, adaptationset_node); if (ret < 0) return ret; - node = xmlFirstElementChild(adaptionset_node); + node = xmlFirstElementChild(adaptationset_node); while (node) { if (!av_strcasecmp(node->name, (const char *)"SegmentTemplate")) { fragment_template_node = node; } else if (!av_strcasecmp(node->name, (const char *)"ContentComponent")) { content_component_node = node; } else if (!av_strcasecmp(node->name, (const char *)"BaseURL")) { - adaptionset_baseurl_node = node; + adaptationset_baseurl_node = node; } else if (!av_strcasecmp(node->name, (const char *)"SegmentList")) { - adaptionset_segmentlist_node = node; + adaptationset_segmentlist_node = node; } else if (!av_strcasecmp(node->name, (const char *)"SupplementalProperty")) { - adaptionset_supplementalproperty_node = node; + adaptationset_supplementalproperty_node = node; } else if (!av_strcasecmp(node->name, (const char *)"Representation")) { ret = parse_manifest_representation(s, url, node, - adaptionset_node, + adaptationset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node, fragment_template_node, content_component_node, - adaptionset_baseurl_node, - adaptionset_segmentlist_node, - adaptionset_supplementalproperty_node); + adaptationset_baseurl_node, + adaptationset_segmentlist_node, + adaptationset_supplementalproperty_node); if (ret < 0) goto err; } @@ -1182,7 +1182,7 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, } err: - av_freep(&c->adaptionset_lang); + av_freep(&c->adaptationset_lang); return ret; } @@ -1233,7 +1233,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) xmlNodePtr period_baseurl_node = NULL; xmlNodePtr period_segmenttemplate_node = NULL; xmlNodePtr period_segmentlist_node = NULL; - xmlNodePtr adaptionset_node = NULL; + xmlNodePtr adaptationset_node = NULL; xmlAttrPtr attr = NULL; char *val = NULL; uint32_t period_duration_sec = 0; @@ -1374,18 +1374,18 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) goto cleanup; } - adaptionset_node = xmlFirstElementChild(period_node); - while (adaptionset_node) { - if (!av_strcasecmp(adaptionset_node->name, (const char *)"BaseURL")) { - period_baseurl_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentTemplate")) { - period_segmenttemplate_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"SegmentList")) { - period_segmentlist_node = adaptionset_node; - } else if (!av_strcasecmp(adaptionset_node->name, (const char *)"AdaptationSet")) { - parse_manifest_adaptationset(s, url, adaptionset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node); + adaptationset_node = xmlFirstElementChild(period_node); + while (adaptationset_node) { + if (!av_strcasecmp(adaptationset_node->name, (const char *)"BaseURL")) { + period_baseurl_node = adaptationset_node; + } else if (!av_strcasecmp(adaptationset_node->name, (const char *)"SegmentTemplate")) { + period_segmenttemplate_node = adaptationset_node; + } else if (!av_strcasecmp(adaptationset_node->name, (const char *)"SegmentList")) { + period_segmentlist_node = adaptationset_node; + } else if (!av_strcasecmp(adaptationset_node->name, (const char *)"AdaptationSet")) { + parse_manifest_adaptationset(s, url, adaptationset_node, mpd_baseurl_node, period_baseurl_node, period_segmenttemplate_node, period_segmentlist_node); } - adaptionset_node = xmlNextElementSibling(adaptionset_node); + adaptationset_node = xmlNextElementSibling(adaptationset_node); } cleanup: /*free the document */ From patchwork Thu Jun 11 04:43:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: rcombs X-Patchwork-Id: 20277 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id F04CF448CDE for ; Thu, 11 Jun 2020 07:43:46 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D172B68B485; Thu, 11 Jun 2020 07:43:46 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from so254-54.mailgun.net (so254-54.mailgun.net [198.61.254.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2F76C68B4E8 for ; Thu, 11 Jun 2020 07:43:40 +0300 (EEST) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=rcombs.me; q=dns/txt; s=mx; t=1591850623; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: To: From: Sender; bh=SewwJPq9ihPqkVAul5FWiklPr9ZCB3CmTPvYXdvygPY=; b=hILKBxLMGMNU0My0BFZLoZbxL82wfRc4UUBMF9+oqj8BNZEM2BneiHdvxsMe6kHwLVucHIuR kEajJjXmRMxyt3jcF5Ip69OpgwzkzlGM0rKcDLEhm3bm1v0fmYC0EtUcXWxmJlonPL/nhzWB ffkKBRoUwczQLy6MlSruLC4AgXY= X-Mailgun-Sending-Ip: 198.61.254.54 X-Mailgun-Sid: WyJiZDU1MSIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICJiMGJhIl0= Received: from rcombs-mbp.localdomain ( [24.14.135.13]) by smtp-out-n12.prod.us-west-2.postgun.com with SMTP id 5ee1b667117610c7ffd62c7c (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 11 Jun 2020 04:43:19 GMT From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Jun 2020 23:43:09 -0500 Message-Id: <20200611044312.38981-2-rcombs@rcombs.me> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200611044312.38981-1-rcombs@rcombs.me> References: <20200611044312.38981-1-rcombs@rcombs.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/5] lavc: add avpriv_h264_get_profile 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/h264_parse.c | 21 +++++++++++++++++---- libavcodec/h264_parse.h | 2 ++ libavcodec/version.h | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 352ffea948..3069579926 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -528,18 +528,31 @@ int ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps, */ int ff_h264_get_profile(const SPS *sps) { - int profile = sps->profile_idc; + return avpriv_h264_get_profile(sps->profile_idc, sps->constraint_set_flags); +} + +/** + * Compute profile from profile_idc and constraint_set?_flags. + * + * @param profile_idc profile_idc field from SPS + * @param constraint_set_flags constraint_set_flags field from SPS + * + * @return profile as defined by FF_PROFILE_H264_* + */ +int avpriv_h264_get_profile(int profile_idc, int constraint_set_flags) +{ + int profile = profile_idc; - switch (sps->profile_idc) { + switch (profile_idc) { case FF_PROFILE_H264_BASELINE: // constraint_set1_flag set to 1 - profile |= (sps->constraint_set_flags & 1 << 1) ? FF_PROFILE_H264_CONSTRAINED : 0; + profile |= (constraint_set_flags & 1 << 1) ? FF_PROFILE_H264_CONSTRAINED : 0; break; case FF_PROFILE_H264_HIGH_10: case FF_PROFILE_H264_HIGH_422: case FF_PROFILE_H264_HIGH_444_PREDICTIVE: // constraint_set3_flag set to 1 - profile |= (sps->constraint_set_flags & 1 << 3) ? FF_PROFILE_H264_INTRA : 0; + profile |= (constraint_set_flags & 1 << 3) ? FF_PROFILE_H264_INTRA : 0; break; } diff --git a/libavcodec/h264_parse.h b/libavcodec/h264_parse.h index 4d01620125..a1462ad8fd 100644 --- a/libavcodec/h264_parse.h +++ b/libavcodec/h264_parse.h @@ -90,4 +90,6 @@ int ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps, */ int ff_h264_get_profile(const SPS *sps); +int avpriv_h264_get_profile(int profile_idc, int constraint_set_flags); + #endif /* AVCODEC_H264_PARSE_H */ diff --git a/libavcodec/version.h b/libavcodec/version.h index 60c0f2460d..03593026b3 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 92 +#define LIBAVCODEC_VERSION_MINOR 93 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From patchwork Thu Jun 11 04:43:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: rcombs X-Patchwork-Id: 20273 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 4810C448CDE for ; Thu, 11 Jun 2020 07:43:38 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 25AD268B11E; Thu, 11 Jun 2020 07:43:38 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from so254-54.mailgun.net (so254-54.mailgun.net [198.61.254.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C9B0268AD72 for ; Thu, 11 Jun 2020 07:43:31 +0300 (EEST) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=rcombs.me; q=dns/txt; s=mx; t=1591850614; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: To: From: Sender; bh=wI50wvJdHK24Y+JQZqhD/SqLhsYqEO5UcYs/tpa6amI=; b=ISAObKatwRF0L9PgE0dwj3gYpRBO+ZmOrzV9xtpb/BvzbZJm81OEV2O+yFOSGXuwCOhg8GfL MfuxfHYMiXlli+al8SdC968Z2qWh6nvoCifTcq98QqTsHvfUKB/r0b5f+HrjGioqiDaGB14N SYgOPKaepfRJfgCTG14jn5TBuIk= X-Mailgun-Sending-Ip: 198.61.254.54 X-Mailgun-Sid: WyJiZDU1MSIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICJiMGJhIl0= Received: from rcombs-mbp.localdomain ( [24.14.135.13]) by smtp-out-n12.prod.us-west-2.postgun.com with SMTP id 5ee1b6676f2ee827da09e928 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 11 Jun 2020 04:43:19 GMT From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Jun 2020 23:43:10 -0500 Message-Id: <20200611044312.38981-3-rcombs@rcombs.me> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200611044312.38981-1-rcombs@rcombs.me> References: <20200611044312.38981-1-rcombs@rcombs.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/5] lavc/h264dec: loosen new-extradata check 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- libavcodec/h264dec.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 6270ea80df..0d7492cfad 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -988,6 +988,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, AVFrame *pict = data; int buf_index; int ret; + const uint8_t *new_extra; + int new_extra_size; h->flags = avctx->flags; h->setup_finished = 0; @@ -999,13 +1001,10 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0) return send_next_delayed_frame(h, pict, got_frame, 0); - if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { - int side_size; - uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); - if (is_extra(side, side_size)) - ff_h264_decode_extradata(side, side_size, - &h->ps, &h->is_avc, &h->nal_length_size, - avctx->err_recognition, avctx); + if ((new_extra = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &new_extra_size))) { + ff_h264_decode_extradata(new_extra, new_extra_size, + &h->ps, &h->is_avc, &h->nal_length_size, + avctx->err_recognition, avctx); } if (h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC) { if (is_extra(buf, buf_size)) From patchwork Thu Jun 11 04:43:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: rcombs X-Patchwork-Id: 20274 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 5447D448CDE for ; Thu, 11 Jun 2020 07:43:39 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4106D68B3FD; Thu, 11 Jun 2020 07:43:39 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from so254-54.mailgun.net (so254-54.mailgun.net [198.61.254.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8C4B168AD72 for ; Thu, 11 Jun 2020 07:43:32 +0300 (EEST) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=rcombs.me; q=dns/txt; s=mx; t=1591850614; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: To: From: Sender; bh=3ylldiNFiV6t+Np1KIa0+ANtdKwVBfmw5i0MfTcOfC8=; b=A7MVPXAV3FMYL2uSoOIqTlIHZtzWVQU4QLPRCMQFIICiM0HU8uhwfTwNe0G5+WUKQBAOiRWC 8nxLyMR2d4pV783EznOx/1AyYSYM7bTh5A+edGFJx2eObyoBySZElz20Xdm64EDpaW2Y4zmL 34c7FVnxo6VRnnDNxaDYH9mfXpU= X-Mailgun-Sending-Ip: 198.61.254.54 X-Mailgun-Sid: WyJiZDU1MSIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICJiMGJhIl0= Received: from rcombs-mbp.localdomain ( [24.14.135.13]) by smtp-out-n12.prod.us-west-2.postgun.com with SMTP id 5ee1b6684c9690533a296542 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 11 Jun 2020 04:43:20 GMT From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Jun 2020 23:43:11 -0500 Message-Id: <20200611044312.38981-4-rcombs@rcombs.me> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200611044312.38981-1-rcombs@rcombs.me> References: <20200611044312.38981-1-rcombs@rcombs.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/5] lavf/dashdec: improve memory handling 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" - Fixes a couple leaks - Adds an av_freep equivalent for libxml buffers - Avoids some redundant copying --- libavformat/dashdec.c | 44 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index c94ce2caca..378c892b87 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -147,9 +147,6 @@ typedef struct DASHContext { uint64_t period_duration; uint64_t period_start; - /* AdaptationSet Attribute */ - char *adaptationset_lang; - int is_live; AVIOInterruptCB *interrupt_callback; char *allowed_extensions; @@ -162,6 +159,15 @@ typedef struct DASHContext { } DASHContext; +static void xml_freep(void* arg) +{ + void *val; + + memcpy(&val, arg, sizeof(val)); + memcpy(arg, &(void *){ NULL }, sizeof(val)); + xmlFree(val); +} + static int ishttp(char *url) { const char *proto_name = avio_find_protocol_name(url); @@ -362,6 +368,8 @@ static void free_representation(struct representation *pls) avformat_close_input(&pls->ctx); } + xml_freep(&pls->lang); + av_freep(&pls->url_template); av_freep(&pls); } @@ -878,15 +886,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ret = AVERROR(ENOMEM); goto end; } - if (c->adaptationset_lang) { - rep->lang = av_strdup(c->adaptationset_lang); - if (!rep->lang) { - av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); - av_freep(&rep); - ret = AVERROR(ENOMEM); - goto end; - } - } + + rep->lang = xmlGetProp(adaptationset_node, "lang"); + rep->parent = s; representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL"); @@ -965,7 +967,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlFree(startnumber_val); } if (adaptationset_supplementalproperty_node) { - if (!av_strcasecmp(xmlGetProp(adaptationset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number")) { + char *schemeIdUri = xmlGetProp(adaptationset_supplementalproperty_node, "schemeIdUri"); + if (!av_strcasecmp(schemeIdUri, "http://dashif.org/guidelines/last-segment-number")) { val = xmlGetProp(adaptationset_supplementalproperty_node,"value"); if (!val) { av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptationset_supplementalproperty_node\n"); @@ -974,6 +977,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlFree(val); } } + xmlFree(schemeIdUri); } fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); @@ -1120,13 +1124,10 @@ end: static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptationset_node) { - DASHContext *c = s->priv_data; - if (!adaptationset_node) { av_log(s, AV_LOG_WARNING, "Cannot get AdaptationSet\n"); return AVERROR(EINVAL); } - c->adaptationset_lang = xmlGetProp(adaptationset_node, "lang"); return 0; } @@ -1139,7 +1140,6 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, xmlNodePtr period_segmentlist_node) { int ret = 0; - DASHContext *c = s->priv_data; xmlNodePtr fragment_template_node = NULL; xmlNodePtr content_component_node = NULL; xmlNodePtr adaptationset_baseurl_node = NULL; @@ -1182,7 +1182,6 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, } err: - av_freep(&c->adaptationset_lang); return ret; } @@ -2157,6 +2156,10 @@ static int dash_read_header(AVFormatContext *s) av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); if (rep->id[0]) av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); + if (rep->lang) { + av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); + xml_freep(&rep->lang); + } } for (i = 0; i < c->n_audios; i++) { rep = c->audios[i]; @@ -2168,7 +2171,7 @@ static int dash_read_header(AVFormatContext *s) av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); if (rep->lang) { av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); - av_freep(&rep->lang); + xml_freep(&rep->lang); } } for (i = 0; i < c->n_subtitles; i++) { @@ -2179,7 +2182,7 @@ static int dash_read_header(AVFormatContext *s) av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); if (rep->lang) { av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); - av_freep(&rep->lang); + xml_freep(&rep->lang); } } } @@ -2282,6 +2285,7 @@ static int dash_close(AVFormatContext *s) DASHContext *c = s->priv_data; free_audio_list(c); free_video_list(c); + free_subtitle_list(c); av_dict_free(&c->avio_opts); av_freep(&c->base_url); return 0; From patchwork Thu Jun 11 04:43:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: rcombs X-Patchwork-Id: 20276 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 12E3B448CDE for ; Thu, 11 Jun 2020 07:43:45 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0514968B3E4; Thu, 11 Jun 2020 07:43:45 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from so254-54.mailgun.net (so254-54.mailgun.net [198.61.254.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 202EB68B396 for ; Thu, 11 Jun 2020 07:43:37 +0300 (EEST) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=rcombs.me; q=dns/txt; s=mx; t=1591850620; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-Id: Date: Subject: To: From: Sender; bh=MqsSMmlkIhWv+YGdi8IVFCRLBwRi0fmI9764KT7fBAw=; b=wyEyMvBlZB2e1iVjZhzahOn7kDu7kofZsdoGAi6S8nUKDChahhrSNJGfEJ4cBmu+g1vPdRDY SA3hfOKvtzaJpjRRBasqYt8ysySf7pyRmixdnztrfdDuqvQNUJyVOfJJXYpsKqRYpGLGOysL cua8+7A+TS+kqvWcYOivoi163J8= X-Mailgun-Sending-Ip: 198.61.254.54 X-Mailgun-Sid: WyJiZDU1MSIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICJiMGJhIl0= Received: from rcombs-mbp.localdomain ( [24.14.135.13]) by smtp-out-n12.prod.us-west-2.postgun.com with SMTP id 5ee1b6684c9690533a29659d (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 11 Jun 2020 04:43:20 GMT From: rcombs To: ffmpeg-devel@ffmpeg.org Date: Wed, 10 Jun 2020 23:43:12 -0500 Message-Id: <20200611044312.38981-5-rcombs@rcombs.me> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200611044312.38981-1-rcombs@rcombs.me> References: <20200611044312.38981-1-rcombs@rcombs.me> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/5] lavf/dashdec: don't require opening all playlists during read_header 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This improves startup performance massively when the consumer doesn't make a call to avformat_find_stream_info(). Also makes the requirement that each rendition only have 1 stream more clear (this is required by DASH), and generally improves error handling. --- libavformat/dashdec.c | 283 +++++++++++++++++++++++++++++++++++++++--- libavformat/version.h | 2 +- 2 files changed, 265 insertions(+), 20 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 378c892b87..b04a2596a9 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -27,6 +27,11 @@ #include "internal.h" #include "avio_internal.h" #include "dash.h" +#include "isom.h" + +#if CONFIG_H264PARSE +#include "libavcodec/h264_parse.h" +#endif #define INITIAL_BUFFER_SIZE 32768 #define MAX_MANIFEST_SIZE 50 * 1024 @@ -112,6 +117,14 @@ struct representation { int64_t cur_seg_size; struct fragment *cur_seg; + /* Media parameters */ + char *mimeType; + char *codecs; + char *audioSamplingRate; + char *sar; + char *width; + char *height; + /* Currently active Media Initialization Section */ struct fragment *init_section; uint8_t *init_sec_buf; @@ -120,6 +133,12 @@ struct representation { uint32_t init_sec_buf_read_offset; int64_t cur_timestamp; int is_restart_needed; + + int streams_initialized; + int open_failed; + + char *new_extradata; + int new_extradata_size; }; typedef struct DASHContext { @@ -152,6 +171,7 @@ typedef struct DASHContext { char *allowed_extensions; AVDictionary *avio_opts; int max_url_size; + int open_all; /* Flags for init section*/ int is_init_section_common_video; @@ -369,6 +389,11 @@ static void free_representation(struct representation *pls) } xml_freep(&pls->lang); + xml_freep(&pls->mimeType); + xml_freep(&pls->codecs); + xml_freep(&pls->audioSamplingRate); + xml_freep(&pls->width); + xml_freep(&pls->height); av_freep(&pls->url_template); av_freep(&pls); @@ -888,6 +913,16 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, } rep->lang = xmlGetProp(adaptationset_node, "lang"); +#define GET_VALUE(name) \ + if (!(rep->name = xmlGetProp(node, #name))) \ + rep->name = xmlGetProp(adaptationset_node, #name) + + GET_VALUE(mimeType); + GET_VALUE(codecs); + GET_VALUE(audioSamplingRate); + GET_VALUE(sar); + GET_VALUE(width); + GET_VALUE(height); rep->parent = s; representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); @@ -1905,7 +1940,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation ff_const59 AVInputFormat *in_fmt = NULL; AVDictionary *in_fmt_opts = NULL; uint8_t *avio_ctx_buffer = NULL; - int ret = 0, i; + int ret = 0; if (pls->ctx) { close_demux_for_component(pls); @@ -1969,12 +2004,14 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation av_dict_free(&in_fmt_opts); if (ret < 0) goto fail; + if (pls->ctx->nb_streams < 1) { + ret = AVERROR_INVALIDDATA; + goto fail; + } if (pls->n_fragments) { #if FF_API_R_FRAME_RATE - if (pls->framerate.den) { - for (i = 0; i < pls->ctx->nb_streams; i++) - pls->ctx->streams[i]->r_frame_rate = pls->framerate; - } + if (pls->framerate.den) + pls->ctx->streams[0]->r_frame_rate = pls->framerate; #endif ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) @@ -1985,10 +2022,157 @@ fail: return ret; } +static int parse_codecs(AVFormatContext *s, AVCodecParameters *params, const struct representation *pls) +{ + if (pls->mimeType && !strcmp(pls->mimeType, "text/vtt")) { + params->codec_id = AV_CODEC_ID_WEBVTT; + return 1; + } else if (pls->mimeType && !strcmp(pls->mimeType, "application/ttml+xml")) { + params->codec_id = AV_CODEC_ID_TTML; + return 1; + } else if (!pls->codecs) { + return 0; + } else if (!strncmp(pls->codecs, "avc1.", 5) || + !strncmp(pls->codecs, "avc3.", 5)) { + int len = strlen(pls->codecs); + + params->codec_id = AV_CODEC_ID_H264; + + if (len >= 11) { + char buf[3] = {0}; + char *end = NULL; + int profile_idc, level_idc; + + memcpy(buf, pls->codecs + 5, 2); + profile_idc = strtoul(buf, &end, 16); + if (end == &buf[2]) { +#if CONFIG_H264PARSE + int constraint_set_flags; + memcpy(buf, pls->codecs + 7, 2); + constraint_set_flags = strtoul(buf, &end, 16); + if (end != &buf[2]) // If this isn't a hex byte, assume no constraints + constraint_set_flags = 0; + + params->profile = avpriv_h264_get_profile(profile_idc, constraint_set_flags); +#else + params->profile = profile_idc; +#endif + } + + memcpy(buf, pls->codecs + 9, 2); + level_idc = strtoul(buf, &end, 16); + if (end == &buf[2]) + params->level = level_idc; + } + return 1; + } else if (!strncmp(pls->codecs, "hev1.", 5) || + !strncmp(pls->codecs, "hvc1.", 5)) { + unsigned profile_space = 0; + unsigned profile_idc, compat_flags; + char tier[2]; + unsigned level_idc; + unsigned extra_flags[6]; + char *str = pls->codecs + 5; + int count; + + params->codec_id = AV_CODEC_ID_H264; + + if (*str == 'A' || *str == 'B' || *str == 'C') + profile_space = (*str++) - 'A' + 1; + + if ((count = sscanf(str, "%d.%x.%[LH]%d.%x.%x.%x.%x.%x.%x", + &profile_idc, &compat_flags, tier, &level_idc, + &extra_flags[0], &extra_flags[1], &extra_flags[2], + &extra_flags[4], &extra_flags[5], &extra_flags[6])) >= 4) { + params->profile = profile_idc; + params->level = level_idc; + } + + return 1; + } else if (!strncmp(pls->codecs, "mp4a.", 5)) { + int count; + unsigned oui, aot; + + if ((count = sscanf(pls->codecs + 5, "%x.%d", &oui, &aot)) < 1) + return 0; + + if (!(params->codec_id = ff_codec_get_id(ff_mp4_obj_type, oui))) + return 0; + + if (count == 2 && params->codec_id == AV_CODEC_ID_AAC && aot > 0) + params->profile = aot - 1; + + return 1; + } else if (!strcmp(pls->codecs, "ac-3")) { + params->codec_id = AV_CODEC_ID_AC3; + return 1; + } else if (!strcmp(pls->codecs, "ec-3")) { + params->codec_id = AV_CODEC_ID_EAC3; + return 1; + } else if (!strcmp(pls->codecs, "mlpa")) { + params->codec_id = AV_CODEC_ID_TRUEHD; + return 1; + } else if (!strcmp(pls->codecs, "dtsc")) { + params->codec_id = AV_CODEC_ID_DTS; + params->profile = FF_PROFILE_DTS; + return 1; + } else if (!strcmp(pls->codecs, "dtsh")) { + params->codec_id = AV_CODEC_ID_DTS; + params->profile = FF_PROFILE_DTS_HD_HRA; // Can't distinguish HRA from MA here + return 1; + } else if (!strcmp(pls->codecs, "dtse")) { + params->codec_id = AV_CODEC_ID_DTS; + params->profile = FF_PROFILE_DTS_EXPRESS; + return 1; + } else if (!strcmp(pls->codecs, "dtsl")) { + params->codec_id = AV_CODEC_ID_DTS; + params->profile = FF_PROFILE_DTS_HD_MA; // No-core stream + return 1; + } else if (!strncmp(pls->codecs, "mhm1.", 5)) { + params->codec_id = AV_CODEC_ID_MPEGH_3D_AUDIO; // There's also a profile here but we can't express it yet + return 1; + } else if (!strcmp(pls->codecs, "vp8") || + !strncmp(pls->codecs, "vp8.", 4)) { + params->codec_id = AV_CODEC_ID_VP8; // Optional profile not parsed + return 1; + } else if (!strcmp(pls->codecs, "vp9") || + !strncmp(pls->codecs, "vp9.", 4)) { + params->codec_id = AV_CODEC_ID_VP8; // Optional profile not parsed + return 1; + } else if (!strncmp(pls->codecs, "av01.", 5)) { + params->codec_id = AV_CODEC_ID_AV1; // Profile/level data not parsed + return 1; + } else { + return 0; + } +} + +static int update_parameters(struct representation *pls, AVStream *st, int extern_extradata) +{ + int ret; + AVStream *ist = pls->ctx->streams[0]; + if ((ret = avcodec_parameters_copy(st->codecpar, ist->codecpar)) < 0) + return ret; + + avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + st->internal->need_context_update = 1; + + if (extern_extradata && st->codecpar->extradata) { + pls->new_extradata = st->codecpar->extradata; + pls->new_extradata_size = st->codecpar->extradata_size; + st->codecpar->extradata = NULL; + st->codecpar->extradata_size = 0; + } + + return 0; +} + static int open_demux_for_component(AVFormatContext *s, struct representation *pls) { + DASHContext *c = s->priv_data; int ret = 0; - int i; + int gotFullParams = 0; + AVCodecParameters *params = NULL; pls->parent = s; pls->cur_seq_no = calc_cur_seg_no(s, pls); @@ -1997,24 +2181,60 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p pls->last_seq_no = calc_max_seg_no(pls, s->priv_data); } - ret = reopen_demux_for_component(s, pls); - if (ret < 0) { - goto fail; + if (!c->open_all) { + if (!(params = avcodec_parameters_alloc())) { + ret = AVERROR(ENOMEM); + goto fail; + } + params->codec_type = pls->type; + if (parse_codecs(s, params, pls)) { + if (pls->type == AVMEDIA_TYPE_VIDEO) { + if (pls->width) + params->width = atoi(pls->width); + if (pls->height) + params->height = atoi(pls->height); + if (pls->sar) + av_parse_ratio_quiet(¶ms->sample_aspect_ratio, pls->sar, 1001000); + gotFullParams = (pls->width > 0) && (pls->height > 0); + } else if (pls->type == AVMEDIA_TYPE_AUDIO) { + if (pls->audioSamplingRate) + params->sample_rate = atoi(pls->audioSamplingRate); + gotFullParams = (params->sample_rate > 0); + } else if (pls->type == AVMEDIA_TYPE_SUBTITLE) { + gotFullParams = 1; + } + } } - for (i = 0; i < pls->ctx->nb_streams; i++) { + + if (gotFullParams) { AVStream *st = avformat_new_stream(s, NULL); - AVStream *ist = pls->ctx->streams[i]; if (!st) { ret = AVERROR(ENOMEM); goto fail; } - st->id = i; - avcodec_parameters_copy(st->codecpar, ist->codecpar); - avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); + st->id = 0; + avcodec_parameters_copy(st->codecpar, params); + } else { + AVStream *st; + ret = reopen_demux_for_component(s, pls); + if (ret < 0) { + goto fail; + } + if (!(st = avformat_new_stream(s, NULL))) { + ret = AVERROR(ENOMEM); + goto fail; + } + st->id = 0; + if ((ret = update_parameters(pls, st, 0)) < 0) + goto fail; + + pls->streams_initialized = 1; } - return 0; + ret = 0; + fail: + avcodec_parameters_free(¶ms); return ret; } @@ -2200,15 +2420,24 @@ static void recheck_discard_flags(AVFormatContext *s, struct representation **p, struct representation *pls = p[i]; int needed = !pls->assoc_stream || pls->assoc_stream->discard < AVDISCARD_ALL; - if (needed && !pls->ctx) { + if (needed && !pls->ctx && !pls->open_failed) { pls->cur_seg_offset = 0; pls->init_sec_buf_read_offset = 0; /* Catch up */ for (j = 0; j < n; j++) { pls->cur_seq_no = FFMAX(pls->cur_seq_no, p[j]->cur_seq_no); } - reopen_demux_for_component(s, pls); - av_log(s, AV_LOG_INFO, "Now receiving stream_index %d\n", pls->stream_index); + if (reopen_demux_for_component(s, pls) >= 0) { + av_log(s, AV_LOG_INFO, "Now receiving stream_index %d\n", pls->stream_index); + + if (!pls->streams_initialized) { + AVStream *st = s->streams[pls->stream_index]; + update_parameters(pls, st, 1); + pls->streams_initialized = 1; + } + } else { + pls->open_failed = 1; + } } else if (!needed && pls->ctx) { close_demux_for_component(pls); ff_format_io_close(pls->parent, &pls->input); @@ -2267,7 +2496,20 @@ static int dash_read_packet(AVFormatContext *s, AVPacket *pkt) /* If we got a packet, return it */ cur->cur_timestamp = av_rescale(pkt->pts, (int64_t)cur->ctx->streams[0]->time_base.num * 90000, cur->ctx->streams[0]->time_base.den); pkt->stream_index = cur->stream_index; - return 0; + + if (cur->new_extradata) { + ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, + cur->new_extradata, cur->new_extradata_size); + if (ret >= 0) { + cur->new_extradata = NULL; + cur->new_extradata_size = 0; + } + } + + if (ret >= 0) + return 0; + else + av_packet_unref(pkt); } if (cur->is_restart_needed) { cur->cur_seg_offset = 0; @@ -2409,6 +2651,9 @@ static const AVOption dash_options[] = { OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, {.str = "aac,m4a,m4s,m4v,mov,mp4,webm,ts"}, INT_MIN, INT_MAX, FLAGS}, + {"open_all", "Whether to read all variant headers during startup", + OFFSET(open_all), AV_OPT_TYPE_BOOL, {.i64 = 0}, + 0, 1, FLAGS}, {NULL} }; diff --git a/libavformat/version.h b/libavformat/version.h index 59151a71a0..ea2ccb400c 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 #define LIBAVFORMAT_VERSION_MINOR 46 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MICRO 102 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \