s, 0, s->format_probesize);
}
-static int add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
- AVPacketList **plast_pktl, int ref)
+int ff_packet_list_put(AVPacketList **packet_buffer,
+ AVPacketList **plast_pktl,
+ AVPacket *pkt, int flags)
{
AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
int ret;
if (!pktl)
return AVERROR(ENOMEM);
- if (ref) {
+ if (flags & FF_PACKETLIST_FLAG_REF_PACKET) {
if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) {
av_free(pktl);
return ret;
}
} else {
+ // TODO: Adapt callers in this file so the line below can use
+ // av_packet_move_ref() to effectively move the reference
+ // to the list.
pktl->pkt = *pkt;
}
continue;
}
- ret = add_to_pktbuf(&s->internal->raw_packet_buffer,
- &s->streams[i]->attached_pic,
- &s->internal->raw_packet_buffer_end, 1);
+ ret = ff_packet_list_put(&s->internal->raw_packet_buffer,
+ &s->internal->raw_packet_buffer_end,
+ &s->streams[i]->attached_pic,
+ FF_PACKETLIST_FLAG_REF_PACKET);
if (ret < 0)
return ret;
}
continue;
}
- if (!pkt->buf) {
- AVPacket tmp = { 0 };
- err = av_packet_ref(&tmp, pkt);
- if (err < 0)
- return err;
- *pkt = tmp;
- }
+ err = av_packet_make_refcounted(pkt);
+ if (err < 0)
+ return err;
if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
(pkt->flags & AV_PKT_FLAG_CORRUPT)) {
if (!pktl && st->request_probe <= 0)
return ret;
- err = add_to_pktbuf(&s->internal->raw_packet_buffer, pkt,
- &s->internal->raw_packet_buffer_end, 0);
+ err = ff_packet_list_put(&s->internal->raw_packet_buffer,
+ &s->internal->raw_packet_buffer_end,
+ pkt, 0);
if (err)
return err;
s->internal->raw_packet_buffer_remaining_size -= pkt->size;
if (st->first_dts != AV_NOPTS_VALUE ||
dts == AV_NOPTS_VALUE ||
st->cur_dts == AV_NOPTS_VALUE ||
+ st->cur_dts < INT_MIN + RELATIVE_TS_BASE ||
is_relative(dts))
return;
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);
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
#endif
}
-static void free_packet_buffer(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
+void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
{
- while (*pkt_buf) {
- AVPacketList *pktl = *pkt_buf;
- *pkt_buf = pktl->next;
+ AVPacketList *tmp = *pkt_buf;
+
+ while (tmp) {
+ AVPacketList *pktl = tmp;
+ tmp = pktl->next;
av_packet_unref(&pktl->pkt);
av_freep(&pktl);
}
+ *pkt_buf = NULL;
*pkt_buf_end = NULL;
}
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;
compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
- ret = add_to_pktbuf(&s->internal->parse_queue, &out_pkt,
- &s->internal->parse_queue_end, 1);
- av_packet_unref(&out_pkt);
- if (ret < 0)
+ ret = ff_packet_list_put(&s->internal->parse_queue,
+ &s->internal->parse_queue_end,
+ &out_pkt, 0);
+ if (ret < 0) {
+ av_packet_unref(&out_pkt);
goto fail;
+ }
}
/* end of the stream => close and free the parser */
return ret;
}
-static int read_from_packet_buffer(AVPacketList **pkt_buffer,
- AVPacketList **pkt_buffer_end,
- AVPacket *pkt)
+int ff_packet_list_get(AVPacketList **pkt_buffer,
+ AVPacketList **pkt_buffer_end,
+ AVPacket *pkt)
{
AVPacketList *pktl;
av_assert0(*pkt_buffer);
}
if (!got_packet && s->internal->parse_queue)
- ret = read_from_packet_buffer(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
+ ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
if (ret >= 0) {
AVStream *st = s->streams[pkt->stream_index];
if (!genpts) {
ret = s->internal->packet_buffer
- ? read_from_packet_buffer(&s->internal->packet_buffer,
+ ? ff_packet_list_get(&s->internal->packet_buffer,
&s->internal->packet_buffer_end, pkt)
: read_frame_internal(s, pkt);
if (ret < 0)
st = s->streams[next_pkt->stream_index];
if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL &&
next_pkt->dts != AV_NOPTS_VALUE && !eof)) {
- ret = read_from_packet_buffer(&s->internal->packet_buffer,
+ ret = ff_packet_list_get(&s->internal->packet_buffer,
&s->internal->packet_buffer_end, pkt);
goto return_packet;
}
return ret;
}
- ret = add_to_pktbuf(&s->internal->packet_buffer, pkt,
- &s->internal->packet_buffer_end, 1);
+ ret = ff_packet_list_put(&s->internal->packet_buffer,
+ &s->internal->packet_buffer_end,
+ pkt, FF_PACKETLIST_FLAG_REF_PACKET);
av_packet_unref(pkt);
if (ret < 0)
return ret;
{
if (!s->internal)
return;
- free_packet_buffer(&s->internal->parse_queue, &s->internal->parse_queue_end);
- free_packet_buffer(&s->internal->packet_buffer, &s->internal->packet_buffer_end);
- free_packet_buffer(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
+ ff_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end);
+ ff_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end);
+ ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
}
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;
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);
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 - 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;
}
}
+ 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 */
}
}
}
+skip_duration_calc:
fill_all_stream_timings(ic);
avio_seek(ic->pb, old_offset, SEEK_SET);
static int extract_extradata_init(AVStream *st)
{
- AVStreamInternal *i = st->internal;
+ AVStreamInternal *sti = st->internal;
const AVBitStreamFilter *f;
int ret;
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;
&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);
}
pkt = &pkt1;
if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
- ret = add_to_pktbuf(&ic->internal->packet_buffer, pkt,
- &ic->internal->packet_buffer_end, 0);
+ ret = ff_packet_list_put(&ic->internal->packet_buffer,
+ &ic->internal->packet_buffer_end,
+ pkt, 0);
if (ret < 0)
goto find_stream_info_err;
}
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;
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;
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;
}
}
+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;
if (s->programs[i]->id != prog_id)
continue;
- if (*endptr++ == ':') {
- int stream_idx = strtol(endptr, NULL, 0);
- return stream_idx >= 0 &&
- stream_idx < s->programs[i]->nb_stream_indexes &&
- st->index == s->programs[i]->stream_index[stream_idx];
+ if (*endptr++ == ':') { // p:<id>:....
+ if ( *endptr == 'a' || *endptr == 'v' ||
+ *endptr == 's' || *endptr == 'd') { // p:<id>:<st_type>[:<index>]
+ enum AVMediaType type;
+
+ switch (*endptr++) {
+ case 'v': type = AVMEDIA_TYPE_VIDEO; break;
+ case 'a': type = AVMEDIA_TYPE_AUDIO; break;
+ case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
+ case 'd': type = AVMEDIA_TYPE_DATA; break;
+ default: av_assert0(0);
+ }
+ if (*endptr++ == ':') { // p:<id>:<st_type>:<index>
+ int stream_idx = strtol(endptr, NULL, 0), type_counter = 0;
+ for (j = 0; j < s->programs[i]->nb_stream_indexes; j++) {
+ int stream_index = s->programs[i]->stream_index[j];
+ if (st->index == s->programs[i]->stream_index[j]) {
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+ return type_counter == stream_idx &&
+ (type == st->codecpar->codec_type ||
+ type == st->codec->codec_type);
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ return type_counter == stream_idx &&
+ type == st->codecpar->codec_type;
+#endif
+ }
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (type == s->streams[stream_index]->codecpar->codec_type ||
+ type == s->streams[stream_index]->codec->codec_type)
+ type_counter++;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ if (type == s->streams[stream_index]->codecpar->codec_type)
+ type_counter++;
+#endif
+ }
+ return 0;
+ } else { // p:<id>:<st_type>
+ for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+ if (st->index == s->programs[i]->stream_index[j]) {
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+ return type == st->codecpar->codec_type ||
+ type == st->codec->codec_type;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ return type == st->codecpar->codec_type;
+#endif
+ }
+ return 0;
+ }
+
+ } else if ( *endptr == 'm') { // p:<id>:m:<metadata_spec>
+ AVDictionaryEntry *tag;
+ char *key, *val;
+ int ret = 0;
+
+ if (*(++endptr) != ':') {
+ av_log(s, AV_LOG_ERROR, "Invalid stream specifier syntax, missing ':' sign after :m.\n");
+ return AVERROR(EINVAL);
+ }
+
+ val = strchr(++endptr, ':');
+ key = val ? av_strndup(endptr, val - endptr) : av_strdup(endptr);
+ if (!key)
+ return AVERROR(ENOMEM);
+
+ for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+ if (st->index == s->programs[i]->stream_index[j]) {
+ tag = av_dict_get(st->metadata, key, NULL, 0);
+ if (tag && (!val || !strcmp(tag->value, val + 1)))
+ ret = 1;
+
+ break;
+ }
+
+ av_freep(&key);
+ return ret;
+
+ } else { // p:<id>:<index>
+ int stream_idx = strtol(endptr, NULL, 0);
+ return stream_idx >= 0 &&
+ stream_idx < s->programs[i]->nb_stream_indexes &&
+ st->index == s->programs[i]->stream_index[stream_idx];
+ }
}
for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)