X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fdashdec.c;h=497e7e469cbe80a803ffa5dac952b0b384d1848b;hb=9d4829f3c9152c98b9235346fae553295683bcee;hp=0435f254122fadaaabdc686c09c5573be841dfd6;hpb=4069096dd535ee99175c2a29c1a1f59c3fc110c1;p=ffmpeg diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 0435f254122..497e7e469cb 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -122,6 +122,19 @@ struct representation { typedef struct DASHContext { const AVClass *class; char *base_url; + char *adaptionset_contenttype_val; + char *adaptionset_par_val; + char *adaptionset_lang_val; + char *adaptionset_minbw_val; + char *adaptionset_maxbw_val; + char *adaptionset_minwidth_val; + char *adaptionset_maxwidth_val; + char *adaptionset_minheight_val; + char *adaptionset_maxheight_val; + char *adaptionset_minframerate_val; + char *adaptionset_maxframerate_val; + char *adaptionset_segmentalignment_val; + char *adaptionset_bitstreamswitching_val; int n_videos; struct representation **videos; @@ -132,6 +145,7 @@ typedef struct DASHContext { uint64_t media_presentation_duration; uint64_t suggested_presentation_delay; uint64_t availability_start_time; + uint64_t availability_end_time; uint64_t publish_time; uint64_t minimum_update_period; uint64_t time_shift_buffer_depth; @@ -905,18 +919,22 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (presentation_timeoffset_val) { rep->presentation_timeoffset = (int64_t) strtoll(presentation_timeoffset_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->presentation_timeoffset = [%"PRId64"]\n", rep->presentation_timeoffset); xmlFree(presentation_timeoffset_val); } if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); xmlFree(timescale_val); } if (startnumber_val) { rep->first_seq_no = (int64_t) strtoll(startnumber_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); xmlFree(startnumber_val); } if (adaptionset_supplementalproperty_node) { @@ -974,10 +992,12 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, timescale_val = get_val_from_nodes_tab(segmentlists_tab, 2, "timescale"); if (duration_val) { rep->fragment_duration = (int64_t) strtoll(duration_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_duration = [%"PRId64"]\n", rep->fragment_duration); xmlFree(duration_val); } if (timescale_val) { rep->fragment_timescale = (int64_t) strtoll(timescale_val, NULL, 10); + av_log(s, AV_LOG_TRACE, "rep->fragment_timescale = [%"PRId64"]\n", rep->fragment_timescale); xmlFree(timescale_val); } fragmenturl_node = xmlFirstElementChild(representation_segmentlist_node); @@ -1060,12 +1080,26 @@ 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 adaptionset_baseurl_node = NULL; xmlNodePtr adaptionset_segmentlist_node = NULL; xmlNodePtr adaptionset_supplementalproperty_node = NULL; xmlNodePtr node = NULL; + c->adaptionset_contenttype_val = xmlGetProp(adaptionset_node, "contentType"); + c->adaptionset_par_val = xmlGetProp(adaptionset_node, "par"); + c->adaptionset_lang_val = xmlGetProp(adaptionset_node, "lang"); + c->adaptionset_minbw_val = xmlGetProp(adaptionset_node, "minBandwidth"); + c->adaptionset_maxbw_val = xmlGetProp(adaptionset_node, "maxBandwidth"); + c->adaptionset_minwidth_val = xmlGetProp(adaptionset_node, "minWidth"); + c->adaptionset_maxwidth_val = xmlGetProp(adaptionset_node, "maxWidth"); + c->adaptionset_minheight_val = xmlGetProp(adaptionset_node, "minHeight"); + c->adaptionset_maxheight_val = xmlGetProp(adaptionset_node, "maxHeight"); + c->adaptionset_minframerate_val = xmlGetProp(adaptionset_node, "minFrameRate"); + c->adaptionset_maxframerate_val = xmlGetProp(adaptionset_node, "maxFrameRate"); + c->adaptionset_segmentalignment_val = xmlGetProp(adaptionset_node, "segmentAlignment"); + c->adaptionset_bitstreamswitching_val = xmlGetProp(adaptionset_node, "bitstreamSwitching"); node = xmlFirstElementChild(adaptionset_node); while (node) { @@ -1191,18 +1225,28 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) if (!av_strcasecmp(attr->name, (const char *)"availabilityStartTime")) { c->availability_start_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->availability_start_time = [%"PRId64"]\n", c->availability_start_time); + } else if (!av_strcasecmp(attr->name, (const char *)"availabilityEndTime")) { + c->availability_end_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->availability_end_time = [%"PRId64"]\n", c->availability_end_time); } else if (!av_strcasecmp(attr->name, (const char *)"publishTime")) { c->publish_time = get_utc_date_time_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->publish_time = [%"PRId64"]\n", c->publish_time); } else if (!av_strcasecmp(attr->name, (const char *)"minimumUpdatePeriod")) { c->minimum_update_period = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->minimum_update_period = [%"PRId64"]\n", c->minimum_update_period); } else if (!av_strcasecmp(attr->name, (const char *)"timeShiftBufferDepth")) { c->time_shift_buffer_depth = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->time_shift_buffer_depth = [%"PRId64"]\n", c->time_shift_buffer_depth); } else if (!av_strcasecmp(attr->name, (const char *)"minBufferTime")) { c->min_buffer_time = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->min_buffer_time = [%"PRId64"]\n", c->min_buffer_time); } else if (!av_strcasecmp(attr->name, (const char *)"suggestedPresentationDelay")) { c->suggested_presentation_delay = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->suggested_presentation_delay = [%"PRId64"]\n", c->suggested_presentation_delay); } else if (!av_strcasecmp(attr->name, (const char *)"mediaPresentationDuration")) { c->media_presentation_duration = get_duration_insec(s, (const char *)val); + av_log(s, AV_LOG_TRACE, "c->media_presentation_duration = [%"PRId64"]\n", c->media_presentation_duration); } attr = attr->next; xmlFree(val); @@ -1284,8 +1328,10 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) if (c->is_live) { if (pls->n_fragments) { + av_log(s, AV_LOG_TRACE, "in n_fragments mode\n"); num = pls->first_seq_no; } else if (pls->n_timelines) { + av_log(s, AV_LOG_TRACE, "in n_timelines mode\n"); start_time_offset = get_segment_start_time_based_on_timeline(pls, 0xFFFFFFFF) - 60 * pls->fragment_timescale; // 60 seconds before end num = calc_next_seg_no_from_timelines(pls, start_time_offset); if (num == -1) @@ -1293,10 +1339,15 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, struct representation *pls) else num += pls->first_seq_no; } else if (pls->fragment_duration){ + av_log(s, AV_LOG_TRACE, "in fragment_duration mode fragment_timescale = %"PRId64", presentation_timeoffset = %"PRId64"\n", pls->fragment_timescale, pls->presentation_timeoffset); if (pls->presentation_timeoffset) { - num = pls->presentation_timeoffset * pls->fragment_timescale / pls->fragment_duration; + num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) * pls->fragment_timescale)-pls->presentation_timeoffset) / pls->fragment_duration - c->min_buffer_time; } else if (c->publish_time > 0 && !c->availability_start_time) { - num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; + if (c->min_buffer_time) { + num = pls->first_seq_no + (((c->publish_time + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration - c->min_buffer_time; + } else { + num = pls->first_seq_no + (((c->publish_time - c->time_shift_buffer_depth + pls->fragment_duration) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; + } } else { num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->suggested_presentation_delay) * pls->fragment_timescale) / pls->fragment_duration; } @@ -1313,6 +1364,7 @@ static int64_t calc_min_seg_no(AVFormatContext *s, struct representation *pls) int64_t num = 0; if (c->is_live && pls->fragment_duration) { + av_log(s, AV_LOG_TRACE, "in live mode\n"); num = pls->first_seq_no + (((get_current_time_in_sec() - c->availability_start_time) - c->time_shift_buffer_depth) * pls->fragment_timescale) / pls->fragment_duration; } else { num = pls->first_seq_no; @@ -1538,14 +1590,8 @@ static struct fragment *get_current_fragment(struct representation *pls) return seg; } -enum ReadFromURLMode { - READ_NORMAL, - READ_COMPLETE, -}; - static int read_from_url(struct representation *pls, struct fragment *seg, - uint8_t *buf, int buf_size, - enum ReadFromURLMode mode) + uint8_t *buf, int buf_size) { int ret; @@ -1553,14 +1599,7 @@ static int read_from_url(struct representation *pls, struct fragment *seg, if (seg->size >= 0) buf_size = FFMIN(buf_size, pls->cur_seg_size - pls->cur_seg_offset); - if (mode == READ_COMPLETE) { - ret = avio_read(pls->input, buf, buf_size); - if (ret < buf_size) { - av_log(pls->parent, AV_LOG_WARNING, "Could not read complete fragment.\n"); - } - } else { - ret = avio_read(pls->input, buf, buf_size); - } + ret = avio_read(pls->input, buf, buf_size); if (ret > 0) pls->cur_seg_offset += ret; @@ -1636,7 +1675,7 @@ static int update_init_section(struct representation *pls) av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size); ret = read_from_url(pls, pls->init_section, pls->init_sec_buf, - pls->init_sec_buf_size, READ_COMPLETE); + pls->init_sec_buf_size); ff_format_io_close(pls->parent, &pls->input); if (ret < 0) @@ -1707,7 +1746,7 @@ restart: ret = AVERROR_EOF; goto end; } - ret = read_from_url(v, v->cur_seg, buf, buf_size, READ_NORMAL); + ret = read_from_url(v, v->cur_seg, buf, buf_size); if (ret > 0) goto end;