#include "audiointerleave.h"
#include "avformat.h"
-#include "avio_internal.h"
#include "id3v2.h"
#include "internal.h"
#include "metadata.h"
(av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0);
}
-AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened,
- int *score_max)
-{
- AVProbeData lpd = *pd;
- AVInputFormat *fmt1 = NULL, *fmt;
- int score, id3 = 0;
-
- if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
- int id3len = ff_id3v2_tag_len(lpd.buf);
- if (lpd.buf_size > id3len + 16) {
- lpd.buf += id3len;
- lpd.buf_size -= id3len;
- }
- id3 = 1;
- }
-
- fmt = NULL;
- while ((fmt1 = av_iformat_next(fmt1))) {
- if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
- continue;
- score = 0;
- if (fmt1->read_probe) {
- score = fmt1->read_probe(&lpd);
- } else if (fmt1->extensions) {
- if (av_match_ext(lpd.filename, fmt1->extensions))
- score = AVPROBE_SCORE_EXTENSION;
- }
- if (score > *score_max) {
- *score_max = score;
- fmt = fmt1;
- } else if (score == *score_max)
- fmt = NULL;
- }
-
- // A hack for files with huge id3v2 tags -- try to guess by file extension.
- if (!fmt && is_opened && *score_max < AVPROBE_SCORE_EXTENSION / 2) {
- while ((fmt = av_iformat_next(fmt)))
- if (fmt->extensions &&
- av_match_ext(lpd.filename, fmt->extensions)) {
- *score_max = AVPROBE_SCORE_EXTENSION / 2;
- break;
- }
- }
-
- if (!fmt && id3 && *score_max < AVPROBE_SCORE_EXTENSION / 2 - 1) {
- while ((fmt = av_iformat_next(fmt)))
- if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) {
- *score_max = AVPROBE_SCORE_EXTENSION / 2 - 1;
- break;
- }
- }
-
- return fmt;
-}
-
-AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened)
-{
- int score = 0;
- return av_probe_input_format2(pd, is_opened, &score);
-}
-
static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st,
AVProbeData *pd, int score)
{
/************************************************************/
/* input media file */
-/** size of probe buffer, for guessing file type from file contents */
-#define PROBE_BUF_MIN 2048
-#define PROBE_BUF_MAX (1 << 20)
-
-int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
- const char *filename, void *logctx,
- unsigned int offset, unsigned int max_probe_size)
-{
- AVProbeData pd = { filename ? filename : "" };
- uint8_t *buf = NULL;
- int ret = 0, probe_size;
-
- if (!max_probe_size)
- max_probe_size = PROBE_BUF_MAX;
- else if (max_probe_size > PROBE_BUF_MAX)
- max_probe_size = PROBE_BUF_MAX;
- else if (max_probe_size < PROBE_BUF_MIN)
- return AVERROR(EINVAL);
-
- if (offset >= max_probe_size)
- return AVERROR(EINVAL);
- avio_skip(pb, offset);
- max_probe_size -= offset;
-
- for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt;
- probe_size = FFMIN(probe_size << 1,
- FFMAX(max_probe_size, probe_size + 1))) {
- int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX / 4 : 0;
-
- /* Read probe data. */
- if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0)
- return ret;
- if ((ret = avio_read(pb, buf + pd.buf_size,
- probe_size - pd.buf_size)) < 0) {
- /* Fail if error was not end of file, otherwise, lower score. */
- if (ret != AVERROR_EOF) {
- av_free(buf);
- return ret;
- }
- score = 0;
- ret = 0; /* error was end of file, nothing read */
- }
- pd.buf_size += ret;
- pd.buf = buf;
-
- memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);
-
- /* Guess file format. */
- *fmt = av_probe_input_format2(&pd, 1, &score);
- if (*fmt) {
- /* This can only be true in the last iteration. */
- if (score <= AVPROBE_SCORE_MAX / 4) {
- av_log(logctx, AV_LOG_WARNING,
- "Format detected only with low score of %d, "
- "misdetection possible!\n", score);
- } else
- av_log(logctx, AV_LOG_DEBUG,
- "Probed with size=%d and score=%d\n", probe_size, score);
- }
- }
-
- if (!*fmt) {
- av_free(buf);
- return AVERROR_INVALIDDATA;
- }
-
- /* Rewind. Reuse probe buffer to avoid seeking. */
- if ((ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0)
- av_free(buf);
-
- return ret;
-}
-
/* Open input file and probe the format if necessary. */
static int init_input(AVFormatContext *s, const char *filename,
AVDictionary **options)
if (!copy.buf)
return AVERROR(ENOMEM);
- add_to_pktbuf(&s->raw_packet_buffer, ©,
- &s->raw_packet_buffer_end);
+ add_to_pktbuf(&s->internal->raw_packet_buffer, ©,
+ &s->internal->raw_packet_buffer_end);
}
return 0;
}
if ((ret = queue_attached_pictures(s)) < 0)
goto fail;
- if (s->pb && !s->data_offset)
- s->data_offset = avio_tell(s->pb);
+ if (s->pb && !s->internal->data_offset)
+ s->internal->data_offset = avio_tell(s->pb);
- s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+ s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
if (options) {
av_dict_free(options);
AVStream *st;
for (;;) {
- AVPacketList *pktl = s->raw_packet_buffer;
+ AVPacketList *pktl = s->internal->raw_packet_buffer;
if (pktl) {
*pkt = pktl->pkt;
st = s->streams[pkt->stream_index];
if (st->codec->codec_id != AV_CODEC_ID_PROBE ||
!st->probe_packets ||
- s->raw_packet_buffer_remaining_size < pkt->size) {
+ s->internal->raw_packet_buffer_remaining_size < pkt->size) {
AVProbeData *pd;
if (st->probe_packets)
if ((err = probe_codec(s, st, NULL)) < 0)
pd = &st->probe_data;
av_freep(&pd->buf);
pd->buf_size = 0;
- s->raw_packet_buffer = pktl->next;
- s->raw_packet_buffer_remaining_size += pkt->size;
+ s->internal->raw_packet_buffer = pktl->next;
+ s->internal->raw_packet_buffer_remaining_size += pkt->size;
av_free(pktl);
return 0;
}
!st->probe_packets))
return ret;
- add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
- s->raw_packet_buffer_remaining_size -= pkt->size;
+ add_to_pktbuf(&s->internal->raw_packet_buffer, pkt,
+ &s->internal->raw_packet_buffer_end);
+ s->internal->raw_packet_buffer_remaining_size -= pkt->size;
if ((err = probe_codec(s, st, pkt)) < 0)
return err;
/**********************************************************/
-/**
- * Get the number of samples of an audio frame. Return -1 on error.
- */
-int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux)
-{
- int frame_size;
-
- /* give frame_size priority if demuxing */
- if (!mux && enc->frame_size > 1)
- return enc->frame_size;
-
- if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0)
- return frame_size;
-
- /* Fall back on using frame_size if muxing. */
- if (enc->frame_size > 1)
- return enc->frame_size;
-
- return -1;
-}
-
/**
* Return the frame duration in seconds. Return 0 if not available.
*/
-void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
+void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
AVCodecParserContext *pc, AVPacket *pkt)
{
+ AVRational codec_framerate = s->iformat ? st->codec->framerate :
+ av_inv_q(st->codec->time_base);
int frame_size;
*pnum = 0;
} else if (st->time_base.num * 1000LL > st->time_base.den) {
*pnum = st->time_base.num;
*pden = st->time_base.den;
- } else if (st->codec->time_base.num * 1000LL > st->codec->time_base.den) {
- *pnum = st->codec->time_base.num;
- *pden = st->codec->time_base.den;
+ } else if (codec_framerate.den * 1000LL > codec_framerate.num) {
+ *pnum = codec_framerate.den;
+ *pden = codec_framerate.num;
if (pc && pc->repeat_pict) {
if (*pnum > INT_MAX / (1 + pc->repeat_pict))
*pden /= 1 + pc->repeat_pict;
}
break;
case AVMEDIA_TYPE_AUDIO:
- frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 0);
+ frame_size = av_get_audio_frame_duration(st->codec, pkt->size);
if (frame_size <= 0 || st->codec->sample_rate <= 0)
break;
*pnum = frame_size;
int64_t dts, int64_t pts)
{
AVStream *st = s->streams[stream_index];
- AVPacketList *pktl = s->packet_buffer;
+ AVPacketList *pktl = s->internal->packet_buffer;
if (st->first_dts != AV_NOPTS_VALUE ||
dts == AV_NOPTS_VALUE ||
static void update_initial_durations(AVFormatContext *s, AVStream *st,
int stream_index, int duration)
{
- AVPacketList *pktl = s->packet_buffer;
+ AVPacketList *pktl = s->internal->packet_buffer;
int64_t cur_dts = 0;
if (st->first_dts != AV_NOPTS_VALUE) {
cur_dts -= duration;
}
}
- pktl = s->packet_buffer;
+ pktl = s->internal->packet_buffer;
st->first_dts = cur_dts;
} else if (st->cur_dts)
return;
if (delay == 1 && pkt->dts == pkt->pts &&
pkt->dts != AV_NOPTS_VALUE && presentation_delayed) {
av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n");
- pkt->dts = pkt->pts = AV_NOPTS_VALUE;
+ pkt->dts = AV_NOPTS_VALUE;
}
if (pkt->duration == 0 && st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
- ff_compute_frame_duration(&num, &den, st, pc, pkt);
+ ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
if (den && num) {
pkt->duration = av_rescale_rnd(1, num * (int64_t) st->time_base.den,
den * (int64_t) st->time_base.num,
AV_ROUND_DOWN);
- if (pkt->duration != 0 && s->packet_buffer)
+ if (pkt->duration != 0 && s->internal->packet_buffer)
update_initial_durations(s, st, pkt->stream_index,
pkt->duration);
}
st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
int duration = pkt->duration;
if (!duration && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- ff_compute_frame_duration(&num, &den, st, pc, pkt);
+ ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
if (den && num) {
duration = av_rescale_rnd(1,
num * (int64_t) st->time_base.den,
den * (int64_t) st->time_base.num,
AV_ROUND_DOWN);
- if (duration != 0 && s->packet_buffer)
+ if (duration != 0 && s->internal->packet_buffer)
update_initial_durations(s, st, pkt->stream_index,
duration);
}
if ((ret = av_dup_packet(&out_pkt)) < 0)
goto fail;
- if (!add_to_pktbuf(&s->parse_queue, &out_pkt, &s->parse_queue_end)) {
+ if (!add_to_pktbuf(&s->internal->parse_queue, &out_pkt, &s->internal->parse_queue_end)) {
av_free_packet(&out_pkt);
ret = AVERROR(ENOMEM);
goto fail;
static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
{
int ret = 0, i, got_packet = 0;
+ AVDictionary *metadata = NULL;
av_init_packet(pkt);
- while (!got_packet && !s->parse_queue) {
+ while (!got_packet && !s->internal->parse_queue) {
AVStream *st;
AVPacket cur_pkt;
}
}
- if (!got_packet && s->parse_queue)
- ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt);
+ if (!got_packet && s->internal->parse_queue)
+ ret = read_from_packet_buffer(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt);
+
+ av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
+ if (metadata) {
+ s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+ av_dict_copy(&s->metadata, metadata, 0);
+ av_dict_free(&metadata);
+ av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+ }
if (s->debug & FF_FDEBUG_TS)
av_log(s, AV_LOG_DEBUG,
int eof = 0;
if (!genpts)
- return s->packet_buffer
- ? read_from_packet_buffer(&s->packet_buffer,
- &s->packet_buffer_end, pkt)
+ return s->internal->packet_buffer
+ ? read_from_packet_buffer(&s->internal->packet_buffer,
+ &s->internal->packet_buffer_end, pkt)
: read_frame_internal(s, pkt);
for (;;) {
int ret;
- AVPacketList *pktl = s->packet_buffer;
+ AVPacketList *pktl = s->internal->packet_buffer;
if (pktl) {
AVPacket *next_pkt = &pktl->pkt;
}
pktl = pktl->next;
}
- pktl = s->packet_buffer;
+ pktl = s->internal->packet_buffer;
}
/* read packet from packet buffer, if there is data */
if (!(next_pkt->pts == AV_NOPTS_VALUE &&
next_pkt->dts != AV_NOPTS_VALUE && !eof))
- return read_from_packet_buffer(&s->packet_buffer,
- &s->packet_buffer_end, pkt);
+ return read_from_packet_buffer(&s->internal->packet_buffer,
+ &s->internal->packet_buffer_end, pkt);
}
ret = read_frame_internal(s, pkt);
return ret;
}
- if (av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
- &s->packet_buffer_end)) < 0)
+ if (av_dup_packet(add_to_pktbuf(&s->internal->packet_buffer, pkt,
+ &s->internal->packet_buffer_end)) < 0)
return AVERROR(ENOMEM);
}
}
/* XXX: suppress the packet queue */
static void flush_packet_queue(AVFormatContext *s)
{
- free_packet_buffer(&s->parse_queue, &s->parse_queue_end);
- free_packet_buffer(&s->packet_buffer, &s->packet_buffer_end);
- free_packet_buffer(&s->raw_packet_buffer, &s->raw_packet_buffer_end);
+ 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);
- s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+ s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
}
/*******************************************************/
av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
if (ts_min == AV_NOPTS_VALUE) {
- pos_min = s->data_offset;
+ pos_min = s->internal->data_offset;
ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
if (ts_min == AV_NOPTS_VALUE)
return -1;
{
int64_t pos_min, pos_max;
- pos_min = s->data_offset;
+ pos_min = s->internal->data_offset;
pos_max = avio_size(s->pb) - 1;
if (pos < pos_min)
return ret;
ff_update_cur_dts(s, st, ie->timestamp);
} else {
- if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)
+ if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
return ret;
}
for (;;) {
!st->codec->extradata)
break;
if (st->first_dts == AV_NOPTS_VALUE &&
+ st->codec_info_nb_frames < ic->max_ts_probe &&
(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
break;
if (ic->flags & AVFMT_FLAG_NOBUFFER) {
pkt = &pkt1;
} else {
- pkt = add_to_pktbuf(&ic->packet_buffer, &pkt1,
- &ic->packet_buffer_end);
+ pkt = add_to_pktbuf(&ic->internal->packet_buffer, &pkt1,
+ &ic->internal->packet_buffer_end);
if ((ret = av_dup_packet(pkt)) < 0)
goto find_stream_info_err;
}
AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached\n",
ic->max_analyze_duration);
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
break;
}
}
int i = st->parser->parser->split(st->codec, pkt->data, pkt->size);
if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
st->codec->extradata_size = i;
- st->codec->extradata = av_malloc(st->codec->extradata_size +
- FF_INPUT_BUFFER_PADDING_SIZE);
+ st->codec->extradata = av_mallocz(st->codec->extradata_size +
+ FF_INPUT_BUFFER_PADDING_SIZE);
if (!st->codec->extradata)
return AVERROR(ENOMEM);
memcpy(st->codec->extradata, pkt->data,
st->codec->extradata_size);
- memset(st->codec->extradata + i, 0,
- FF_INPUT_BUFFER_PADDING_SIZE);
}
}
try_decode_frame(st, pkt,
(options && i < orig_nb_streams) ? &options[i] : NULL);
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
+
st->codec_info_nb_frames++;
count++;
}
int i, j;
AVStream *st;
+ if (!s)
+ return;
+
av_opt_free(s);
if (s->iformat && s->iformat->priv_class && s->priv_data)
av_opt_free(s->priv_data);
avio_close(pb);
}
-AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
+AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
{
AVStream *st;
int i;
}
st->codec = avcodec_alloc_context3(c);
- if (s->iformat)
+ if (!st->codec) {
+ av_free(st->info);
+ av_free(st);
+ return NULL;
+ }
+ if (s->iformat) {
/* no default bitrate if decoding */
st->codec->bit_rate = 0;
+
+ /* default pts setting is MPEG-like */
+ avpriv_set_pts_info(st, 33, 1, 90000);
+ }
+
st->index = s->nb_streams;
st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE;
st->first_dts = AV_NOPTS_VALUE;
st->probe_packets = MAX_PROBE_PACKETS;
- /* default pts setting is MPEG-like */
- avpriv_set_pts_info(st, 33, 1, 90000);
st->last_IP_pts = AV_NOPTS_VALUE;
for (i = 0; i < MAX_REORDER_DELAY + 1; i++)
st->pts_buffer[i] = AV_NOPTS_VALUE;
#endif
}
-int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id,
+int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
int std_compliance)
{
if (ofmt) {
}
return NULL;
}
+
+uint8_t *ff_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type,
+ int size)
+{
+ AVPacketSideData *sd, *tmp;
+ int i;
+ uint8_t *data = av_malloc(size);
+
+ if (!data)
+ return NULL;
+
+ for (i = 0; i < st->nb_side_data; i++) {
+ sd = &st->side_data[i];
+
+ if (sd->type == type) {
+ av_freep(&sd->data);
+ sd->data = data;
+ sd->size = size;
+ return sd->data;
+ }
+ }
+
+ tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp));
+ if (!tmp) {
+ av_freep(&data);
+ return NULL;
+ }
+
+ st->side_data = tmp;
+ st->nb_side_data++;
+
+ sd = &st->side_data[st->nb_side_data - 1];
+ sd->type = type;
+ sd->data = data;
+ sd->size = size;
+ return data;
+}