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)
}
/* 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;
+ --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);
pd->buf_size += 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);
/* 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;
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;
/* fail safe */
st->cur_ptr = NULL;
st->cur_len = 0;
+
+ st->probe_packets = MAX_PROBE_PACKETS;
}
}
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_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)
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);
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
- next_point = &s->packet_buffer;
- while(*next_point){
- if(compare(s, &(*next_point)->pkt, pkt))
- break;
- next_point= &(*next_point)->next;
+ 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{
} else
for(i=0;i<ic->nb_streams;i++)
dump_stream_format(ic, i, index, is_output);
+ if (ic->metadata) {
+ AVMetadataTag *tag=NULL;
+ av_log(NULL, AV_LOG_INFO, " Metadata\n");
+ while((tag=av_metadata_get(ic->metadata, "", tag, AV_METADATA_IGNORE_SUFFIX))) {
+ av_log(NULL, AV_LOG_INFO, " %-16s: %s\n", tag->key, tag->value);
+ }
+ }
+
}
#if LIBAVFORMAT_VERSION_MAJOR < 53
}
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;
}