if (!fmt || must_open_file) {
/* if no file needed do not try to open one */
- if (url_fopen(pb, filename, URL_RDONLY) < 0) {
- err = AVERROR_IO;
+ if ((err=url_fopen(pb, filename, URL_RDONLY)) < 0) {
goto fail;
}
file_opened = 1;
for(probe_size= PROBE_BUF_MIN; probe_size<=PROBE_BUF_MAX && !fmt; probe_size<<=1){
int score= probe_size < PROBE_BUF_MAX ? AVPROBE_SCORE_MAX/4 : 0;
/* read probe data */
- pd->buf= av_realloc(pd->buf, probe_size);
+ pd->buf= av_realloc(pd->buf, probe_size + AVPROBE_PADDING_SIZE);
pd->buf_size = get_buffer(pb, pd->buf, probe_size);
if (url_fseek(pb, 0, SEEK_SET) < 0) {
url_fclose(pb);
}
/* XXX: suppress this hack for redirectors */
-#ifdef CONFIG_NETWORK
+#ifdef CONFIG_REDIR_DEMUXER
if (fmt == &redir_demuxer) {
err = redir_open(ic_ptr, pb);
url_fclose(pb);
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
{
+ av_init_packet(pkt);
return s->iformat->read_packet(s, pkt);
}
AVCodecParserContext *pc, AVPacket *pkt)
{
int num, den, presentation_delayed, delay, i;
+ int64_t offset;
/* handle wrapping */
if(st->cur_dts != AV_NOPTS_VALUE){
if(pkt->pts != AV_NOPTS_VALUE)
}
}
+ /* correct timestamps with byte offset if demuxers only have timestamps on packet boundaries */
+ if(pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size){
+ /* this will estimate bitrate based on this frame's duration and size */
+ offset = av_rescale(pc->offset, pkt->duration, pkt->size);
+ if(pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+ if(pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+ }
+
if(is_intra_only(st->codec))
pkt->flags |= PKT_FLAG_KEY;
AVStream *st;
int len, ret, i;
+ av_init_packet(pkt);
+
for(;;) {
/* select current input stream component */
st = s->cur_st;
/* return packet if any */
if (pkt->size) {
got_packet:
+ pkt->pos = s->cur_pkt.pos; // Isn't quite accurate but close.
pkt->duration = 0;
pkt->stream_index = st->index;
pkt->pts = st->parser->pts;
st->parser = av_parser_init(st->codec->codec_id);
if (!st->parser) {
/* no parser available : just output the raw packets */
- st->need_parsing = 0;
- }else if(st->need_parsing == 2){
+ st->need_parsing = AVSTREAM_PARSE_NONE;
+ }else if(st->need_parsing == AVSTREAM_PARSE_HEADERS){
st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
if(st->parser && (s->iformat->flags & AVFMT_GENERIC_INDEX)){
#ifdef DEBUG_SEEK
av_log(s, AV_LOG_DEBUG, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n", pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts, pos_limit, start_pos, no_change);
#endif
+ if(ts == AV_NOPTS_VALUE){
+ av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
+ return -1;
+ }
assert(ts != AV_NOPTS_VALUE);
if (target_ts <= ts) {
pos_limit = start_pos - 1;
index = av_index_search_timestamp(st, timestamp, flags);
- if(index < 0){
+ if(index < 0 || index==st->nb_index_entries-1){
int i;
AVPacket pkt;
int64_t end_time;
int64_t filesize, offset, duration;
- av_read_frame_flush(ic);
+ /* free previous packet */
+ if (ic->cur_st && ic->cur_st->parser)
+ av_free_packet(&ic->cur_pkt);
+ ic->cur_st = NULL;
+
+ /* flush packet queue */
+ flush_packet_queue(ic);
+
+ for(i=0;i<ic->nb_streams;i++) {
+ st = ic->streams[i];
+ 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) */
return ret;
}
+static int set_codec_from_probe_data(AVStream *st, AVProbeData *pd, int score)
+{
+ AVInputFormat *fmt;
+ fmt = av_probe_input_format2(pd, 1, &score);
+
+ if (fmt) {
+ if (strncmp(fmt->name, "mp3", 3) == 0)
+ st->codec->codec_id = CODEC_ID_MP3;
+ else if (strncmp(fmt->name, "ac3", 3) == 0)
+ st->codec->codec_id = CODEC_ID_AC3;
+ }
+ return !!fmt;
+}
+
/* absolute maximum size we read until we abort */
#define MAX_READ_SIZE 5000000
offset_t old_offset = url_ftell(&ic->pb);
int64_t codec_info_duration[MAX_STREAMS]={0};
int codec_info_nb_frames[MAX_STREAMS]={0};
+ AVProbeData probe_data[MAX_STREAMS];
+ int codec_identified[MAX_STREAMS]={0};
duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
if (!duration_error) return AVERROR_NOMEM;
//only for the split stuff
if (!st->parser) {
st->parser = av_parser_init(st->codec->codec_id);
- if(st->need_parsing == 2 && st->parser){
+ if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){
st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
}
last_dts[i]= AV_NOPTS_VALUE;
}
+ memset(probe_data, 0, sizeof(probe_data));
count = 0;
read_size = 0;
ppktl = &ic->packet_buffer;
break;
if(st->parser && st->parser->parser->split && !st->codec->extradata)
break;
+ if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
+ st->codec->codec_id == CODEC_ID_NONE)
+ break;
}
if (i == ic->nb_streams) {
/* NOTE: if the format has no header, then we need to read
}
if(last == AV_NOPTS_VALUE || duration_count[index]<=1)
last_dts[pkt->stream_index]= pkt->dts;
+
+ if (st->codec->codec_id == CODEC_ID_NONE) {
+ AVProbeData *pd = &(probe_data[st->index]);
+ pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size);
+ memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
+ pd->buf_size += pkt->size;
+ }
}
if(st->parser && st->parser->parser->split && !st->codec->extradata){
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
}
}
}else if(st->codec->codec_type == CODEC_TYPE_AUDIO) {
+ if (st->codec->codec_id == CODEC_ID_NONE) {
+ codec_identified[st->index] = set_codec_from_probe_data(st, &(probe_data[st->index]), 0);
+ if (codec_identified[st->index]) {
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ }
+ }
if(!st->codec->bits_per_sample)
st->codec->bits_per_sample= av_get_bits_per_sample(st->codec->codec_id);
}
}
av_estimate_timings(ic, old_offset);
+
+ for(i=0;i<ic->nb_streams;i++) {
+ st = ic->streams[i];
+ if (codec_identified[st->index]) {
+ av_read_frame_flush(ic);
+ av_seek_frame(ic, st->index, 0.0, 0);
+ url_fseek(&ic->pb, ic->data_offset, SEEK_SET);
+ }
+ }
+
#if 0
/* correct DTS for b frame streams with no timestamps */
for(i=0;i<ic->nb_streams;i++) {
#endif
av_free(duration_error);
+ for(i=0;i<MAX_STREAMS;i++){
+ av_freep(&(probe_data[i].buf));
+ }
return ret;
}
}
if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
- av_log(NULL, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64" st:%d\n", st->cur_dts, pkt->dts, st->index);
+ av_log(NULL, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts);
return -1;
}
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
- av_log(NULL, AV_LOG_ERROR, "error, pts < dts (%"PRId64" < %"PRId64")\n",
- pkt->pts, pkt->dts);
+ av_log(NULL, AV_LOG_ERROR, "error, pts < dts\n");
return -1;
}
{ "qcif", 176, 144, 0, 0 },
{ "cif", 352, 288, 0, 0 },
{ "4cif", 704, 576, 0, 0 },
+ { "qqvga", 160, 120, 0, 0 },
+ { "qvga", 320, 240, 0, 0 },
+ { "vga", 640, 480, 0, 0 },
+ { "svga", 800, 600, 0, 0 },
+ { "xga", 1024, 768, 0, 0 },
+ { "uxga", 1600,1200, 0, 0 },
+ { "qxga", 2048,1536, 0, 0 },
+ { "sxga", 1280,1024, 0, 0 },
+ { "qsxga", 2560,2048, 0, 0 },
+ { "hsxga", 5120,4096, 0, 0 },
+ { "wvga", 852, 480, 0, 0 },
+ { "wxga", 1366, 768, 0, 0 },
+ { "wsxga", 1600,1024, 0, 0 },
+ { "wuxga", 1920,1200, 0, 0 },
+ { "woxga", 2560,1600, 0, 0 },
+ { "wqsxga", 3200,2048, 0, 0 },
+ { "wquxga", 3840,2400, 0, 0 },
+ { "whsxga", 6400,4096, 0, 0 },
+ { "whuxga", 7680,4800, 0, 0 },
+ { "cga", 320, 200, 0, 0 },
+ { "ega", 640, 350, 0, 0 },
+ { "hd480", 852, 480, 0, 0 },
+ { "hd720", 1280, 720, 0, 0 },
+ { "hd1080", 1920,1080, 0, 0 },
};
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
return 0;
}
-#ifndef CONFIG_WINCE
int64_t parse_date(const char *datestr, int duration)
{
const char *p;
}
return negative ? -t : t;
}
-#endif /* CONFIG_WINCE */
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
{