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;
}
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
+ if (!(s->url = av_strdup(filename ? filename : ""))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+#if FF_API_FORMAT_FILENAME
+FF_DISABLE_DEPRECATION_WARNINGS
av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
s->probe_score = ret;
goto fail;
if ((ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0)
goto fail;
+ if ((ret = ff_id3v2_parse_priv(s, &id3v2_extra_meta)) < 0)
+ goto fail;
} else
av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");
}
continue;
}
- if (!pkt->buf) {
- AVPacket tmp = { 0 };
- ret = av_packet_ref(&tmp, pkt);
- if (ret < 0)
- return ret;
- *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;
case AV_CODEC_ID_MP1:
case AV_CODEC_ID_MP2:
case AV_CODEC_ID_MP3:
+ case AV_CODEC_ID_CODEC2:
return 1;
}
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;
}
if (st->start_time == AV_NOPTS_VALUE) {
- st->start_time = pts;
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || !(pkt->flags & AV_PKT_FLAG_DISCARD)) {
+ st->start_time = pts;
+ }
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate)
st->start_time += av_rescale_q(st->skip_samples, (AVRational){1, st->codecpar->sample_rate}, st->time_base);
}
#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;
}
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);
+ 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)
goto fail;
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;
}
int64_t pos_delta = 0;
int64_t skip = 0;
//We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
- const char *proto = avio_find_protocol_name(s->filename);
+ const char *proto = avio_find_protocol_name(s->url);
if (!proto) {
av_log(s, AV_LOG_INFO,
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) {
av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream endtime %f\n", end_time_text / (float)AV_TIME_BASE);
int ff_alloc_extradata(AVCodecParameters *par, int size)
{
- int ret;
+ av_freep(&par->extradata);
+ par->extradata_size = 0;
- if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
- par->extradata = NULL;
- par->extradata_size = 0;
+ if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
return AVERROR(EINVAL);
- }
+
par->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (par->extradata) {
- memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- par->extradata_size = size;
- ret = 0;
- } else {
- par->extradata_size = 0;
- ret = AVERROR(ENOMEM);
- }
- return ret;
+ if (!par->extradata)
+ return AVERROR(ENOMEM);
+
+ memset(par->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ par->extradata_size = size;
+
+ return 0;
}
int ff_get_extradata(AVFormatContext *s, AVCodecParameters *par, AVIOContext *pb, int size)
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;
}
if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
st->info->fps_last_dts_idx > st->info->fps_first_dts_idx &&
(pkt->dts - st->info->fps_last_dts) / 1000 >
- (st->info->fps_last_dts - st->info->fps_first_dts) /
+ (st->info->fps_last_dts - (uint64_t)st->info->fps_first_dts) /
(st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) {
av_log(ic, AV_LOG_WARNING,
"DTS discontinuity in stream %d: packet %d with DTS "
av_freep(&s->streams);
flush_packet_queue(s);
av_freep(&s->internal);
+ av_freep(&s->url);
av_free(s);
}
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++)
return st->internal->avctx->time_base;
#endif
}
+
+void ff_format_set_url(AVFormatContext *s, char *url)
+{
+ av_assert0(url);
+ av_freep(&s->url);
+ s->url = url;
+#if FF_API_FORMAT_FILENAME
+FF_DISABLE_DEPRECATION_WARNINGS
+ av_strlcpy(s->filename, url, sizeof(s->filename));
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+}