return LIBAVFORMAT_VERSION_INT;
}
+const char *avformat_configuration(void)
+{
+ return FFMPEG_CONFIGURATION;
+}
+
+const char *avformat_license(void)
+{
+#define LICENSE_PREFIX "libavformat license: "
+ return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
/* fraction handling */
/**
format->next = NULL;
}
+#if LIBAVFORMAT_VERSION_MAJOR < 53
int match_ext(const char *filename, const char *extensions)
+{
+ return av_match_ext(filename, extensions);
+}
+#endif
+
+int av_match_ext(const char *filename, const char *extensions)
{
const char *ext, *p;
char ext1[32], *q;
return !strcasecmp(name, names);
}
+#if LIBAVFORMAT_VERSION_MAJOR < 53
AVOutputFormat *guess_format(const char *short_name, const char *filename,
const char *mime_type)
+{
+ return av_guess_format(short_name, filename, mime_type);
+}
+#endif
+
+AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
+ const char *mime_type)
{
AVOutputFormat *fmt, *fmt_found;
int score_max, score;
if (!short_name && filename &&
av_filename_number_test(filename) &&
av_guess_image2_codec(filename) != CODEC_ID_NONE) {
- return guess_format("image2", NULL, NULL);
+ return av_guess_format("image2", NULL, NULL);
}
#endif
/* Find the proper file type. */
if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
score += 10;
if (filename && fmt->extensions &&
- match_ext(filename, fmt->extensions)) {
+ av_match_ext(filename, fmt->extensions)) {
score += 5;
}
if (score > score_max) {
return fmt_found;
}
+#if LIBAVFORMAT_VERSION_MAJOR < 53
AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
const char *mime_type)
{
- AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
+ AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
if (fmt) {
AVOutputFormat *stream_fmt;
char stream_format_name[64];
snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
- stream_fmt = guess_format(stream_format_name, NULL, NULL);
+ stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
if (stream_fmt)
fmt = stream_fmt;
return fmt;
}
+#endif
enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
const char *filename, const char *mime_type, enum CodecType type){
if (fmt1->read_probe) {
score = fmt1->read_probe(pd);
} else if (fmt1->extensions) {
- if (match_ext(pd->filename, fmt1->extensions)) {
+ if (av_match_ext(pd->filename, fmt1->extensions)) {
score = 50;
}
}
return av_probe_input_format2(pd, is_opened, &score);
}
-static int set_codec_from_probe_data(AVStream *st, AVProbeData *pd, int score)
+static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score)
{
AVInputFormat *fmt;
fmt = av_probe_input_format2(pd, 1, &score);
if (fmt) {
+ av_log(s, AV_LOG_DEBUG, "Probe with size=%d, packets=%d detected %s with score=%d\n",
+ pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets, fmt->name, score);
if (!strcmp(fmt->name, "mp3")) {
st->codec->codec_id = CODEC_ID_MP3;
st->codec->codec_type = CODEC_TYPE_AUDIO;
} else if (!strcmp(fmt->name, "ac3")) {
st->codec->codec_id = CODEC_ID_AC3;
st->codec->codec_type = CODEC_TYPE_AUDIO;
+ } else if (!strcmp(fmt->name, "eac3")) {
+ st->codec->codec_id = CODEC_ID_EAC3;
+ st->codec->codec_type = CODEC_TYPE_AUDIO;
} else if (!strcmp(fmt->name, "mpegvideo")) {
st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
st->codec->codec_type = CODEC_TYPE_VIDEO;
} else if (!strcmp(fmt->name, "h264")) {
st->codec->codec_id = CODEC_ID_H264;
st->codec->codec_type = CODEC_TYPE_VIDEO;
+ } else if (!strcmp(fmt->name, "dts")) {
+ st->codec->codec_id = CODEC_ID_DTS;
+ st->codec->codec_type = CODEC_TYPE_AUDIO;
}
}
return !!fmt;
ff_metadata_demux_compat(ic);
#endif
+ ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+
*ic_ptr = ic;
return 0;
fail:
int err, probe_size;
AVProbeData probe_data, *pd = &probe_data;
ByteIOContext *pb = NULL;
+ void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL;
pd->filename = "";
if (filename)
/* read probe data */
pd->buf= av_realloc(pd->buf, probe_size + AVPROBE_PADDING_SIZE);
pd->buf_size = get_buffer(pb, pd->buf, probe_size);
+
+ if ((int)pd->buf_size < 0) {
+ err = pd->buf_size;
+ goto fail;
+ }
+
memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
if (url_fseek(pb, 0, SEEK_SET) < 0) {
url_fclose(pb);
}
/* guess file format */
fmt = av_probe_input_format2(pd, 1, &score);
+ if(fmt){
+ if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration
+ 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);
+ }
}
av_freep(&pd->buf);
}
av_freep(&pd->buf);
if (pb)
url_fclose(pb);
+ if (ap && ap->prealloced_context)
+ av_free(*ic_ptr);
*ic_ptr = NULL;
return err;
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
{
- int ret;
+ int ret, i;
AVStream *st;
for(;;){
if (pktl) {
*pkt = pktl->pkt;
- if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE){
+ if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
+ !s->streams[pkt->stream_index]->probe_packets ||
+ s->raw_packet_buffer_remaining_size < pkt->size){
+ AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data;
+ av_freep(&pd->buf);
+ pd->buf_size = 0;
s->raw_packet_buffer = pktl->next;
+ s->raw_packet_buffer_remaining_size += pkt->size;
av_free(pktl);
return 0;
}
av_init_packet(pkt);
ret= s->iformat->read_packet(s, pkt);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ if (!pktl || ret == AVERROR(EAGAIN))
+ return ret;
+ for (i = 0; i < s->nb_streams; i++)
+ s->streams[i]->probe_packets = 0;
+ continue;
+ }
st= s->streams[pkt->stream_index];
switch(st->codec->codec_type){
break;
}
- if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
+ if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE ||
+ !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;
if(st->codec->codec_id == CODEC_ID_PROBE){
AVProbeData *pd = &st->probe_data;
+ av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
+ --st->probe_packets;
pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
- set_codec_from_probe_data(st, pd, 1);
+ set_codec_from_probe_data(s, st, pd, 1);
if(st->codec->codec_id != CODEC_ID_PROBE){
pd->buf_size=0;
av_freep(&pd->buf);
+ av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
}
}
}
/* used for example by ADPCM codecs */
if (enc->bit_rate == 0)
return -1;
- frame_size = (size * 8 * enc->sample_rate) / enc->bit_rate;
+ frame_size = ((int64_t)size * 8 * enc->sample_rate) / enc->bit_rate;
}
} else {
frame_size = enc->frame_size;
int num, den, presentation_delayed, delay, i;
int64_t offset;
+ if (st->codec->codec_id != CODEC_ID_H264 && pc && pc->pict_type == FF_B_TYPE)
+ //FIXME Set low_delay = 0 when has_b_frames = 1
+ st->codec->has_b_frames = 1;
+
/* do we have a video B-frame ? */
delay= st->codec->has_b_frames;
presentation_delayed = 0;
pkt->pts = st->parser->pts;
pkt->dts = st->parser->dts;
pkt->pos = st->parser->pos;
- pkt->destruct = av_destruct_packet_nofree;
+ pkt->destruct = NULL;
compute_pkt_fields(s, st, st->parser, pkt);
if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & PKT_FLAG_KEY){
}
if(s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, flags=%d\n",
+ av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
st->cur_pkt.stream_index,
st->cur_pkt.pts,
st->cur_pkt.dts,
st->cur_pkt.size,
+ st->cur_pkt.duration,
st->cur_pkt.flags);
s->cur_st = st;
}
}
if(s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, flags=%d\n",
+ av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
pkt->stream_index,
pkt->pts,
pkt->dts,
pkt->size,
+ pkt->duration,
pkt->flags);
return 0;
av_free_packet(&pktl->pkt);
av_free(pktl);
}
+ while(s->raw_packet_buffer){
+ pktl = s->raw_packet_buffer;
+ s->raw_packet_buffer = pktl->next;
+ av_free_packet(&pktl->pkt);
+ av_free(pktl);
+ }
+ s->packet_buffer_end=
+ s->raw_packet_buffer_end= NULL;
+ s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
}
/*******************************************************/
/**
* Flush the frame reader.
*/
-static void av_read_frame_flush(AVFormatContext *s)
+void av_read_frame_flush(AVFormatContext *s)
{
AVStream *st;
- int i;
+ int i, j;
flush_packet_queue(s);
/* fail safe */
st->cur_ptr = NULL;
st->cur_len = 0;
+
+ st->probe_packets = MAX_PROBE_PACKETS;
+
+ for(j=0; j<MAX_REORDER_DELAY+1; j++)
+ st->pts_buffer[j]= AV_NOPTS_VALUE;
}
}
int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
int64_t ts_min, ts_max, ts;
int index;
+ int64_t ret;
AVStream *st;
if (stream_index < 0)
return -1;
/* do the seek */
- url_fseek(s->pb, pos, SEEK_SET);
+ if ((ret = url_fseek(s->pb, pos, SEEK_SET)) < 0)
+ return ret;
av_update_cur_dts(s, st, ts);
static int av_seek_frame_generic(AVFormatContext *s,
int stream_index, int64_t timestamp, int flags)
{
- int index, ret;
+ int index;
+ int64_t ret;
AVStream *st;
AVIndexEntry *ie;
AVPacket pkt1, *pkt = &pkt1;
AVStream *st;
int read_size, i, ret;
- int64_t end_time;
+ int64_t end_time, start_time[MAX_STREAMS];
int64_t filesize, offset, duration;
ic->cur_st = NULL;
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
+ if(st->start_time != AV_NOPTS_VALUE){
+ start_time[i]= st->start_time;
+ }else if(st->first_dts != AV_NOPTS_VALUE){
+ start_time[i]= st->first_dts;
+ }else
+ av_log(st->codec, AV_LOG_WARNING, "start time is not set in av_estimate_timings_from_pts\n");
+
if (st->parser) {
av_parser_close(st->parser);
st->parser= NULL;
}
}
- /* we read the first packets to get the first PTS (not fully
- accurate, but it is enough now) */
- url_fseek(ic->pb, 0, SEEK_SET);
- read_size = 0;
- for(;;) {
- if (read_size >= DURATION_MAX_READ_SIZE)
- break;
- /* if all info is available, we can stop */
- for(i = 0;i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->start_time == AV_NOPTS_VALUE)
- break;
- }
- if (i == ic->nb_streams)
- break;
-
- do{
- ret = av_read_packet(ic, pkt);
- }while(ret == AVERROR(EAGAIN));
- if (ret != 0)
- break;
- read_size += pkt->size;
- st = ic->streams[pkt->stream_index];
- if (pkt->pts != AV_NOPTS_VALUE) {
- if (st->start_time == AV_NOPTS_VALUE)
- st->start_time = pkt->pts;
- }
- av_free_packet(pkt);
- }
-
/* estimate the end time (duration) */
/* XXX: may need to support wrapping */
filesize = ic->file_size;
read_size += pkt->size;
st = ic->streams[pkt->stream_index];
if (pkt->pts != AV_NOPTS_VALUE &&
- st->start_time != AV_NOPTS_VALUE) {
+ start_time[pkt->stream_index] != AV_NOPTS_VALUE) {
end_time = pkt->pts;
- duration = end_time - st->start_time;
+ duration = end_time - start_time[pkt->stream_index];
if (duration > 0) {
if (st->duration == AV_NOPTS_VALUE ||
st->duration < duration)
the components */
fill_all_stream_timings(ic);
} else {
+ av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n");
/* less precise: use bitrate info */
av_estimate_timings_from_bit_rate(ic);
}
val = enc->sample_rate && enc->channels && enc->sample_fmt != SAMPLE_FMT_NONE;
if(!enc->frame_size &&
(enc->codec_id == CODEC_ID_VORBIS ||
- enc->codec_id == CODEC_ID_AAC))
+ enc->codec_id == CODEC_ID_AAC ||
+ enc->codec_id == CODEC_ID_MP3 ||
+ enc->codec_id == CODEC_ID_SPEEX))
return 0;
break;
case CODEC_TYPE_VIDEO:
int got_picture, data_size, ret=0;
AVFrame picture;
- if(!st->codec->codec){
- codec = avcodec_find_decoder(st->codec->codec_id);
- if (!codec)
- return -1;
- ret = avcodec_open(st->codec, codec);
- if (ret < 0)
- return ret;
- }
+ if(!st->codec->codec){
+ codec = avcodec_find_decoder(st->codec->codec_id);
+ if (!codec)
+ return -1;
+ ret = avcodec_open(st->codec, codec);
+ if (ret < 0)
+ return ret;
+ }
- if(!has_codec_parameters(st->codec)){
- switch(st->codec->codec_type) {
- case CODEC_TYPE_VIDEO:
- ret = avcodec_decode_video2(st->codec, &picture,
- &got_picture, avpkt);
- break;
- case CODEC_TYPE_AUDIO:
- data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
- samples = av_malloc(data_size);
- if (!samples)
- goto fail;
- ret = avcodec_decode_audio3(st->codec, samples,
- &data_size, avpkt);
- av_free(samples);
- break;
- default:
- break;
+ if(!has_codec_parameters(st->codec)){
+ switch(st->codec->codec_type) {
+ case CODEC_TYPE_VIDEO:
+ avcodec_get_frame_defaults(&picture);
+ ret = avcodec_decode_video2(st->codec, &picture,
+ &got_picture, avpkt);
+ break;
+ case CODEC_TYPE_AUDIO:
+ data_size = FFMAX(avpkt->size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
+ samples = av_malloc(data_size);
+ if (!samples)
+ goto fail;
+ ret = avcodec_decode_audio3(st->codec, samples,
+ &data_size, avpkt);
+ av_free(samples);
+ break;
+ default:
+ break;
+ }
}
- }
fail:
return ret;
}
-unsigned int codec_get_tag(const AVCodecTag *tags, int id)
+unsigned int ff_codec_get_tag(const AVCodecTag *tags, int id)
{
while (tags->id != CODEC_ID_NONE) {
if (tags->id == id)
return 0;
}
-enum CodecID codec_get_id(const AVCodecTag *tags, unsigned int tag)
+enum CodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
{
int i;
for(i=0; tags[i].id != CODEC_ID_NONE;i++) {
{
int i;
for(i=0; tags && tags[i]; i++){
- int tag= codec_get_tag(tags[i], id);
+ int tag= ff_codec_get_tag(tags[i], id);
if(tag) return tag;
}
return 0;
{
int i;
for(i=0; tags && tags[i]; i++){
- enum CodecID id= codec_get_id(tags[i], tag);
+ enum CodecID id= ff_codec_get_id(tags[i], tag);
if(id!=CODEC_ID_NONE) return id;
}
return CODEC_ID_NONE;
}
}
-/* absolute maximum size we read until we abort */
-#define MAX_READ_SIZE 5000000
-
#define MAX_STD_TIMEBASES (60*12+5)
static int get_std_framerate(int i){
if(i<60*12) return i*1001;
for(;;) {
if(url_interrupt_cb()){
ret= AVERROR(EINTR);
+ av_log(ic, AV_LOG_DEBUG, "interrupted\n");
break;
}
if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
/* if we found the info for all the codecs, we can stop */
ret = count;
+ av_log(ic, AV_LOG_DEBUG, "All info found\n");
break;
}
}
/* we did not get all the codec info, but we read too much data */
- if (read_size >= MAX_READ_SIZE) {
+ if (read_size >= ic->probesize) {
ret = count;
+ av_log(ic, AV_LOG_WARNING, "MAX_READ_SIZE:%d reached\n", ic->probesize);
break;
}
if (!has_codec_parameters(st->codec)){
char buf[256];
avcodec_string(buf, sizeof(buf), st->codec, 0);
- av_log(ic, AV_LOG_INFO, "Could not find codec parameters (%s)\n", buf);
+ av_log(ic, AV_LOG_WARNING, "Could not find codec parameters (%s)\n", buf);
} else {
ret = 0;
}
st = ic->streams[pkt->stream_index];
if(codec_info_nb_frames[st->index]>1) {
- if (st->time_base.den > 0 && av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration)
+ if (st->time_base.den > 0 && av_rescale_q(codec_info_duration[st->index], st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration){
+ av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
break;
+ }
codec_info_duration[st->index] += pkt->duration;
}
if (pkt->duration != 0)
decompress the frame. We try to avoid that in most cases as
it takes longer and uses more memory. For MPEG-4, we need to
decompress for QuickTime. */
- if (!has_codec_parameters(st->codec) /*&&
- (st->codec->codec_id == CODEC_ID_FLV1 ||
- st->codec->codec_id == CODEC_ID_H264 ||
- st->codec->codec_id == CODEC_ID_H263 ||
- st->codec->codec_id == CODEC_ID_H261 ||
- st->codec->codec_id == CODEC_ID_VORBIS ||
- st->codec->codec_id == CODEC_ID_MJPEG ||
- st->codec->codec_id == CODEC_ID_PNG ||
- st->codec->codec_id == CODEC_ID_PAM ||
- st->codec->codec_id == CODEC_ID_PGM ||
- st->codec->codec_id == CODEC_ID_PGMYUV ||
- st->codec->codec_id == CODEC_ID_PBM ||
- st->codec->codec_id == CODEC_ID_PPM ||
- st->codec->codec_id == CODEC_ID_SHORTEN ||
- (st->codec->codec_id == CODEC_ID_MPEG4 && !st->need_parsing))*/)
+ if (!has_codec_parameters(st->codec))
try_decode_frame(st, pkt);
count++;
}
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
+ if(codec_info_nb_frames[i]>2)
+ av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
+ (codec_info_nb_frames[i]-2)*(int64_t)st->time_base.den,
+ codec_info_duration[i] *(int64_t)st->time_base.num, 60000);
if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
timestamps corrected before they are returned to the user */
st->cur_dts = 0;
st->first_dts = AV_NOPTS_VALUE;
+ st->probe_packets = MAX_PROBE_PACKETS;
/* default pts setting is MPEG-like */
av_set_pts_info(st, 33, 1, 90000);
AVStream *st;
// some sanity checks
+ if (s->nb_streams == 0) {
+ av_log(s, AV_LOG_ERROR, "no streams\n");
+ return -1;
+ }
+
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
}
//FIXME merge with compute_pkt_fields
-static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){
+static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
int num, den, frame_size, i;
-// av_log(st->codec, AV_LOG_DEBUG, "av_write_frame: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n", pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
+// av_log(s, AV_LOG_DEBUG, "av_write_frame: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n", pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
/* if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
return -1;*/
}
if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
- av_log(st->codec, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts);
+ av_log(s, AV_LOG_ERROR,
+ "st:%d error, non monotone timestamps %"PRId64" >= %"PRId64"\n",
+ st->index, st->cur_dts, pkt->dts);
return -1;
}
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
- av_log(st->codec, AV_LOG_ERROR, "error, pts < dts\n");
+ av_log(s, AV_LOG_ERROR, "st:%d error, pts < dts\n", st->index);
return -1;
}
-// av_log(NULL, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts);
+// av_log(s, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts);
st->cur_dts= pkt->dts;
st->pts.val= pkt->dts;
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
{
- int ret = compute_pkt_fields2(s->streams[pkt->stream_index], pkt);
+ int ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
return ret;
this_pktl = av_mallocz(sizeof(AVPacketList));
this_pktl->pkt= *pkt;
- if(pkt->destruct == av_destruct_packet)
- pkt->destruct= NULL; // not shared -> must keep original from being freed
- else
- av_dup_packet(&this_pktl->pkt); //shared -> must dup
-
- next_point = &s->packet_buffer;
- while(*next_point){
- if(compare(s, &(*next_point)->pkt, pkt))
- break;
- next_point= &(*next_point)->next;
+ pkt->destruct= NULL; // do not free original but only the copy
+ av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory
+
+ if(s->streams[pkt->stream_index]->last_in_packet_buffer){
+ next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);
+ }else
+ next_point = &s->packet_buffer;
+
+ if(*next_point){
+ if(compare(s, &s->packet_buffer_end->pkt, pkt)){
+ while(!compare(s, &(*next_point)->pkt, pkt)){
+ next_point= &(*next_point)->next;
+ }
+ goto next_non_null;
+ }else{
+ next_point = &(s->packet_buffer_end->next);
+ }
}
+ assert(!*next_point);
+
+ s->packet_buffer_end= this_pktl;
+next_non_null:
+
this_pktl->next= *next_point;
+
+ s->streams[pkt->stream_index]->last_in_packet_buffer=
*next_point= this_pktl;
}
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
AVPacketList *pktl;
int stream_count=0;
- int streams[MAX_STREAMS];
+ int i;
if(pkt){
ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
}
- memset(streams, 0, sizeof(streams));
- pktl= s->packet_buffer;
- while(pktl){
-//av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts);
- if(streams[ pktl->pkt.stream_index ] == 0)
- stream_count++;
- streams[ pktl->pkt.stream_index ]++;
- pktl= pktl->next;
- }
+ for(i=0; i < s->nb_streams; i++)
+ stream_count+= !!s->streams[i]->last_in_packet_buffer;
if(stream_count && (s->nb_streams == stream_count || flush)){
pktl= s->packet_buffer;
*out= pktl->pkt;
s->packet_buffer= pktl->next;
+ if(!s->packet_buffer)
+ s->packet_buffer_end= NULL;
+
+ if(s->streams[out->stream_index]->last_in_packet_buffer == pktl)
+ s->streams[out->stream_index]->last_in_packet_buffer= NULL;
av_freep(&pktl);
return 1;
}else{
return 0;
//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts);
- if(compute_pkt_fields2(st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ if(compute_pkt_fields2(s, st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
return -1;
if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
AVProgram *program=NULL;
void *tmp;
+ if (idx >= ac->nb_streams) {
+ av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx);
+ return;
+ }
+
for(i=0; i<ac->nb_programs; i++){
if(ac->programs[i]->id != progid)
continue;
else av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d/1000, postfix);
}
+static void dump_metadata(void *ctx, AVMetadata *m, const char *indent)
+{
+ if(m && !(m->count == 1 && av_metadata_get(m, "language", NULL, 0))){
+ AVMetadataTag *tag=NULL;
+
+ av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
+ while((tag=av_metadata_get(m, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ if(strcmp("language", tag->key))
+ av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tag->value);
+ }
+ }
+}
+
/* "user interface" functions */
static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
{
display_aspect_ratio.num, display_aspect_ratio.den);
}
if(st->codec->codec_type == CODEC_TYPE_VIDEO){
+ if(st->avg_frame_rate.den && st->avg_frame_rate.num)
+ print_fps(av_q2d(st->avg_frame_rate), "fps");
if(st->r_frame_rate.den && st->r_frame_rate.num)
print_fps(av_q2d(st->r_frame_rate), "tbr");
if(st->time_base.den && st->time_base.num)
print_fps(1/av_q2d(st->codec->time_base), "tbc");
}
av_log(NULL, AV_LOG_INFO, "\n");
+ dump_metadata(NULL, st->metadata, " ");
}
void dump_format(AVFormatContext *ic,
int is_output)
{
int i;
+ uint8_t *printed = av_mallocz(ic->nb_streams);
+ if (ic->nb_streams && !printed)
+ return;
av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
is_output ? "Output" : "Input",
index,
is_output ? ic->oformat->name : ic->iformat->name,
is_output ? "to" : "from", url);
+ dump_metadata(NULL, ic->metadata, " ");
if (!is_output) {
av_log(NULL, AV_LOG_INFO, " Duration: ");
if (ic->duration != AV_NOPTS_VALUE) {
av_log(NULL, AV_LOG_INFO, "\n");
}
if(ic->nb_programs) {
- int j, k;
+ int j, k, total = 0;
for(j=0; j<ic->nb_programs; j++) {
AVMetadataTag *name = av_metadata_get(ic->programs[j]->metadata,
"name", NULL, 0);
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
name ? name->value : "");
- for(k=0; k<ic->programs[j]->nb_stream_indexes; k++)
+ dump_metadata(NULL, ic->programs[j]->metadata, " ");
+ for(k=0; k<ic->programs[j]->nb_stream_indexes; k++) {
dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output);
- }
- } else
+ printed[ic->programs[j]->stream_index[k]] = 1;
+ }
+ total += ic->programs[j]->nb_stream_indexes;
+ }
+ if (total < ic->nb_streams)
+ av_log(NULL, AV_LOG_INFO, " No Program\n");
+ }
for(i=0;i<ic->nb_streams;i++)
- dump_stream_format(ic, i, index, is_output);
+ if (!printed[i])
+ dump_stream_format(ic, i, index, is_output);
+
+ av_free(printed);
}
#if LIBAVFORMAT_VERSION_MAJOR < 53
static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size)
{
int len, i, j, c;
+#undef fprintf
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
for(i=0;i<size;i+=16) {
//FIXME needs to know the time_base
static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
{
+#undef fprintf
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
PRINT("stream #%d:\n", pkt->stream_index);
PRINT(" keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
}
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
- int pts_num, int pts_den)
+ unsigned int pts_num, unsigned int pts_den)
{
- unsigned int gcd= av_gcd(pts_num, pts_den);
s->pts_wrap_bits = pts_wrap_bits;
- s->time_base.num = pts_num/gcd;
- s->time_base.den = pts_den/gcd;
- if(gcd>1)
- av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, gcd);
+ if(av_reduce(&s->time_base.num, &s->time_base.den, pts_num, pts_den, INT_MAX)){
+ if(s->time_base.num != pts_num)
+ av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, pts_num/s->time_base.num);
+ }else
+ av_log(NULL, AV_LOG_WARNING, "st:%d has too large timebase, reducing\n", s->index);
+
+ if(!s->time_base.num || !s->time_base.den)
+ s->time_base.num= s->time_base.den= 0;
}