X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Futils.c;h=dcc0de92550655cb35dec06a01bf757b88680282;hb=b4a1ccfc41613ae476791e539c176ac98be03a05;hp=733c6d65dc4ed4b060e654f981ca8d0dfa0a1b1f;hpb=4339c94364f8ff143d051fcace3e5801625db607;p=ffmpeg diff --git a/libavformat/utils.c b/libavformat/utils.c index 733c6d65dc4..dcc0de92550 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1332,7 +1332,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, + av_log(s, AV_LOG_DEBUG, "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%"PRId64" delay:%d onein_oneout:%d\n", presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), pkt->stream_index, pc, pkt->duration, delay, onein_oneout); @@ -1401,11 +1401,11 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, st->cur_dts = pkt->dts; if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_TRACE, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n", + av_log(s, AV_LOG_DEBUG, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n", presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts)); /* update flags */ - if (is_intra_only(st->codecpar->codec_id)) + if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA || is_intra_only(st->codecpar->codec_id)) pkt->flags |= AV_PKT_FLAG_KEY; #if FF_API_CONVERGENCE_DURATION FF_DISABLE_DEPRECATION_WARNINGS @@ -1472,6 +1472,22 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) if (!out_pkt.size) continue; + if (pkt->buf && out_pkt.data == pkt->data) { + /* reference pkt->buf only when out_pkt.data is guaranteed to point + * to data in it and not in the parser's internal buffer. */ + /* XXX: Ensure this is the case with all parsers when st->parser->flags + * is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */ + out_pkt.buf = av_buffer_ref(pkt->buf); + if (!out_pkt.buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + } else { + ret = av_packet_make_refcounted(&out_pkt); + if (ret < 0) + goto fail; + } + if (pkt->side_data) { out_pkt.side_data = pkt->side_data; out_pkt.side_data_elems = pkt->side_data_elems; @@ -1512,10 +1528,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) ret = ff_packet_list_put(&s->internal->parse_queue, &s->internal->parse_queue_end, - &out_pkt, FF_PACKETLIST_FLAG_REF_PACKET); - av_packet_unref(&out_pkt); - if (ret < 0) + &out_pkt, 0); + if (ret < 0) { + av_packet_unref(&out_pkt); goto fail; + } } /* end of the stream => close and free the parser */ @@ -2601,9 +2618,8 @@ static int has_duration(AVFormatContext *ic) static void update_stream_timings(AVFormatContext *ic) { int64_t start_time, start_time1, start_time_text, end_time, end_time1, end_time_text; - int64_t duration, duration1, filesize; + int64_t duration, duration1, duration_text, filesize; int i; - AVStream *st; AVProgram *p; start_time = INT64_MAX; @@ -2611,22 +2627,25 @@ static void update_stream_timings(AVFormatContext *ic) end_time = INT64_MIN; end_time_text = INT64_MIN; duration = INT64_MIN; + duration_text = INT64_MIN; + for (i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; + AVStream *st = ic->streams[i]; + int is_text = st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || + st->codecpar->codec_type == AVMEDIA_TYPE_DATA; if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) { start_time1 = av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); - if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { - if (start_time1 < start_time_text) - start_time_text = start_time1; - } else + if (is_text) + start_time_text = FFMIN(start_time_text, start_time1); + else start_time = FFMIN(start_time, start_time1); end_time1 = av_rescale_q_rnd(st->duration, st->time_base, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); if (end_time1 != AV_NOPTS_VALUE && (end_time1 > 0 ? start_time1 <= INT64_MAX - end_time1 : start_time1 >= INT64_MIN - end_time1)) { end_time1 += start_time1; - if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codecpar->codec_type == AVMEDIA_TYPE_DATA) + if (is_text) end_time_text = FFMAX(end_time_text, end_time1); else end_time = FFMAX(end_time, end_time1); @@ -2641,19 +2660,26 @@ static void update_stream_timings(AVFormatContext *ic) if (st->duration != AV_NOPTS_VALUE) { duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); - duration = FFMAX(duration, duration1); + if (is_text) + duration_text = FFMAX(duration_text, duration1); + else + duration = FFMAX(duration, duration1); } } - if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE)) + if (start_time == INT64_MAX || (start_time > start_time_text && start_time - (uint64_t)start_time_text < AV_TIME_BASE)) start_time = start_time_text; else if (start_time > start_time_text) av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE); - if (end_time == INT64_MIN || (end_time < end_time_text && end_time_text - (uint64_t)end_time < AV_TIME_BASE)) { + if (end_time == INT64_MIN || (end_time < end_time_text && end_time_text - (uint64_t)end_time < AV_TIME_BASE)) end_time = end_time_text; - } else if (end_time < end_time_text) { + else if (end_time < end_time_text) av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream endtime %f\n", end_time_text / (float)AV_TIME_BASE); - } + + if (duration == INT64_MIN || (duration < duration_text && duration_text - duration < AV_TIME_BASE)) + duration = duration_text; + else if (duration < duration_text) + av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream duration %f\n", duration_text / (float)AV_TIME_BASE); if (start_time != INT64_MAX) { ic->start_time = start_time; @@ -2786,6 +2812,11 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) } } + if (ic->skip_estimate_duration_from_pts) { + av_log(ic, AV_LOG_INFO, "Skipping duration calculation in estimate_timings_from_pts\n"); + goto skip_duration_calc; + } + av_opt_set(ic, "skip_changes", "1", AV_OPT_SEARCH_CHILDREN); /* estimate the end time (duration) */ /* XXX: may need to support wrapping */ @@ -2870,6 +2901,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) } } } +skip_duration_calc: fill_all_stream_timings(ic); avio_seek(ic->pb, old_offset, SEEK_SET); @@ -3429,7 +3461,7 @@ static int extract_extradata_check(AVStream *st) static int extract_extradata_init(AVStream *st) { - AVStreamInternal *i = st->internal; + AVStreamInternal *sti = st->internal; const AVBitStreamFilter *f; int ret; @@ -3442,70 +3474,66 @@ static int extract_extradata_init(AVStream *st) if (!ret) goto finish; - i->extract_extradata.pkt = av_packet_alloc(); - if (!i->extract_extradata.pkt) + sti->extract_extradata.pkt = av_packet_alloc(); + if (!sti->extract_extradata.pkt) return AVERROR(ENOMEM); - ret = av_bsf_alloc(f, &i->extract_extradata.bsf); + ret = av_bsf_alloc(f, &sti->extract_extradata.bsf); if (ret < 0) goto fail; - ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in, + ret = avcodec_parameters_copy(sti->extract_extradata.bsf->par_in, st->codecpar); if (ret < 0) goto fail; - i->extract_extradata.bsf->time_base_in = st->time_base; + sti->extract_extradata.bsf->time_base_in = st->time_base; - /* if init fails here, we assume extracting extradata is just not - * supported for this codec, so we return success */ - ret = av_bsf_init(i->extract_extradata.bsf); - if (ret < 0) { - av_bsf_free(&i->extract_extradata.bsf); - ret = 0; - } + ret = av_bsf_init(sti->extract_extradata.bsf); + if (ret < 0) + goto fail; finish: - i->extract_extradata.inited = 1; + sti->extract_extradata.inited = 1; return 0; fail: - av_bsf_free(&i->extract_extradata.bsf); - av_packet_free(&i->extract_extradata.pkt); + av_bsf_free(&sti->extract_extradata.bsf); + av_packet_free(&sti->extract_extradata.pkt); return ret; } static int extract_extradata(AVStream *st, AVPacket *pkt) { - AVStreamInternal *i = st->internal; + AVStreamInternal *sti = st->internal; AVPacket *pkt_ref; int ret; - if (!i->extract_extradata.inited) { + if (!sti->extract_extradata.inited) { ret = extract_extradata_init(st); if (ret < 0) return ret; } - if (i->extract_extradata.inited && !i->extract_extradata.bsf) + if (sti->extract_extradata.inited && !sti->extract_extradata.bsf) return 0; - pkt_ref = i->extract_extradata.pkt; + pkt_ref = sti->extract_extradata.pkt; ret = av_packet_ref(pkt_ref, pkt); if (ret < 0) return ret; - ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref); + ret = av_bsf_send_packet(sti->extract_extradata.bsf, pkt_ref); if (ret < 0) { av_packet_unref(pkt_ref); return ret; } - while (ret >= 0 && !i->avctx->extradata) { + while (ret >= 0 && !sti->avctx->extradata) { int extradata_size; uint8_t *extradata; - ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref); + ret = av_bsf_receive_packet(sti->extract_extradata.bsf, pkt_ref); if (ret < 0) { if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) return ret; @@ -3516,13 +3544,13 @@ static int extract_extradata(AVStream *st, AVPacket *pkt) &extradata_size); if (extradata) { - i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (!i->avctx->extradata) { + sti->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!sti->avctx->extradata) { av_packet_unref(pkt_ref); return AVERROR(ENOMEM); } - memcpy(i->avctx->extradata, extradata, extradata_size); - i->avctx->extradata_size = extradata_size; + memcpy(sti->avctx->extradata, extradata, extradata_size); + sti->avctx->extradata_size = extradata_size; } av_packet_unref(pkt_ref); } @@ -3837,7 +3865,7 @@ FF_ENABLE_DEPRECATION_WARNINGS break; } if (pkt->duration) { - if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { + if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { st->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->info->codec_info_duration + pkt->duration); } else st->info->codec_info_duration += pkt->duration; @@ -4537,6 +4565,7 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) return NULL; dynarray_add(&ac->programs, &ac->nb_programs, program); program->discard = AVDISCARD_NONE; + program->pmt_version = -1; } program->id = id; program->pts_wrap_reference = AV_NOPTS_VALUE; @@ -4611,6 +4640,28 @@ uint64_t ff_ntp_time(void) return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; } +uint64_t ff_get_formatted_ntp_time(uint64_t ntp_time_us) +{ + uint64_t ntp_ts, frac_part, sec; + uint32_t usec; + + //current ntp time in seconds and micro seconds + sec = ntp_time_us / 1000000; + usec = ntp_time_us % 1000000; + + //encoding in ntp timestamp format + frac_part = usec * 0xFFFFFFFFULL; + frac_part /= 1000000; + + if (sec > 0xFFFFFFFFULL) + av_log(NULL, AV_LOG_WARNING, "NTP time format roll over detected\n"); + + ntp_ts = sec << 32; + ntp_ts |= frac_part; + + return ntp_ts; +} + int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags) { const char *p; @@ -4742,6 +4793,40 @@ void av_url_split(char *proto, int proto_size, } } +int ff_mkdir_p(const char *path) +{ + int ret = 0; + char *temp = av_strdup(path); + char *pos = temp; + char tmp_ch = '\0'; + + if (!path || !temp) { + return -1; + } + + if (!av_strncasecmp(temp, "/", 1) || !av_strncasecmp(temp, "\\", 1)) { + pos++; + } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 2)) { + pos += 2; + } + + for ( ; *pos != '\0'; ++pos) { + if (*pos == '/' || *pos == '\\') { + tmp_ch = *pos; + *pos = '\0'; + ret = mkdir(temp, 0755); + *pos = tmp_ch; + } + } + + if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) { + ret = mkdir(temp, 0755); + } + + av_free(temp); + return ret; +} + char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) { int i;