#include "id3v2.h"
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
#include "riff.h"
#include "audiointerleave.h"
#include "url.h"
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
{
- int ret= av_new_packet(pkt, size);
+ int ret;
+
+ if(s->maxsize>=0){
+ int64_t remaining= s->maxsize - avio_tell(s);
+ if(remaining < size){
+ int64_t newsize= avio_size(s);
+ if(!s->maxsize || s->maxsize<newsize)
+ s->maxsize= newsize;
+ remaining= s->maxsize - avio_tell(s);
+ }
+
+ if(s->maxsize>=0 && remaining>=0 && remaining+1 < size){
+ av_log(0, AV_LOG_ERROR, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1);
+ size= remaining+1;
+ }
+ }
+
+ ret= av_new_packet(pkt, size);
if(ret<0)
return ret;
{
AVProbeData lpd = *pd;
AVInputFormat *fmt1 = NULL, *fmt;
- int score, score_max=0;
+ int score, nodat = 0, score_max=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;
- }
+ }else
+ nodat = 1;
}
fmt = NULL;
score = 0;
if (fmt1->read_probe) {
score = fmt1->read_probe(&lpd);
- if(!score && fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
- score = 1;
+ if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
+ score = FFMAX(score, nodat ? AVPROBE_SCORE_MAX/4-1 : 1);
} else if (fmt1->extensions) {
if (av_match_ext(lpd.filename, fmt1->extensions)) {
score = 50;
#endif
/* open input file and probe the format if necessary */
-static int init_input(AVFormatContext *s, const char *filename)
+static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options)
{
int ret;
AVProbeData pd = {filename, NULL, 0};
+ if(s->iformat && !strlen(filename))
+ return 0;
+
if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
(!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
return 0;
- if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0)
+ if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
+ &s->interrupt_callback, options)) < 0)
return ret;
if (s->iformat)
return 0;
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
- if ((ret = init_input(s, filename)) < 0)
+ if ((ret = init_input(s, filename, &tmp)) < 0)
goto fail;
/* check filename in case an image number is expected */
*pden = 0;
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- if(st->time_base.num*1000LL > st->time_base.den){
+ if (st->r_frame_rate.num && !pc) {
+ *pnum = st->r_frame_rate.den;
+ *pden = st->r_frame_rate.num;
+ } 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){
delay= st->codec->has_b_frames;
presentation_delayed = 0;
- // ignore delay caused by frame threading so that the mpeg2-without-dts
- // warning will not trigger
- if (delay && st->codec->active_thread_type&FF_THREAD_FRAME)
- delay -= st->codec->thread_count-1;
-
/* XXX: need has_b_frame, but cannot get it if the codec is
not initialized */
if (delay &&
// Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
- pkt->dts= pkt->pts= AV_NOPTS_VALUE;
+ pkt->dts= AV_NOPTS_VALUE;
}
if (pkt->duration == 0) {
FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
if(pkt->dts == AV_NOPTS_VALUE)
pkt->dts= st->pts_buffer[0];
- if(st->codec->codec_id == CODEC_ID_H264){ //we skiped it above so we try here
+ if(st->codec->codec_id == CODEC_ID_H264){ // we skipped it above so we try here
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet
}
if(pkt->dts > st->cur_dts)
if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
st->parser = av_parser_init(st->codec->codec_id);
if (!st->parser) {
- av_log(s, AV_LOG_WARNING, "parser not found for codec "
+ av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
"%s, packets or times may be invalid.\n",
avcodec_get_name(st->codec->codec_id));
/* no parser available: just output the raw packets */
#if FF_API_SEEK_PUBLIC
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
- return ff_update_cur_dts(s, ref_st, timestamp);
+ ff_update_cur_dts(s, ref_st, timestamp);
}
#endif
if(stream_index == pkt.stream_index && pkt.dts > timestamp){
if(pkt.flags & AV_PKT_FLAG_KEY)
break;
- if(nonkey++ > 1000){
+ if(nonkey++ > 1000 && st->codec->codec_id != CODEC_ID_CDGRAPHICS){
av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
break;
}
static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{
- int16_t *samples;
AVCodec *codec;
- int got_picture, data_size, ret=0;
+ int got_picture, ret = 0;
AVFrame picture;
+ AVPacket pkt = *avpkt;
if(!st->codec->codec){
codec = avcodec_find_decoder(st->codec->codec_id);
return ret;
}
- if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st) ||
- (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) {
+ while (pkt.size > 0 && ret >= 0 &&
+ (!has_codec_parameters(st->codec) ||
+ !has_decode_delay_been_guessed(st) ||
+ (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
+ got_picture = 0;
+ avcodec_get_frame_defaults(&picture);
switch(st->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO:
- avcodec_get_frame_defaults(&picture);
ret = avcodec_decode_video2(st->codec, &picture,
- &got_picture, avpkt);
- if (got_picture)
- st->info->nb_decoded_frames++;
+ &got_picture, &pkt);
break;
case AVMEDIA_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);
+ ret = avcodec_decode_audio4(st->codec, &picture, &got_picture, &pkt);
break;
default:
break;
}
+ if (ret >= 0) {
+ if (got_picture)
+ st->info->nb_decoded_frames++;
+ pkt.data += ret;
+ pkt.size -= ret;
+ }
}
- fail:
return ret;
}
count = 0;
read_size = 0;
for(;;) {
- if(url_interrupt_cb()){
+ if (ff_check_interrupt(&ic->interrupt_callback)){
ret= AVERROR_EXIT;
av_log(ic, AV_LOG_DEBUG, "interrupted\n");
break;
double dts= pkt->dts * av_q2d(st->time_base);
int64_t duration= pkt->dts - last;
-// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
+// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); i++) {
int framerate= get_std_framerate(i);
double sdts= dts*framerate/(1001*12);
if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
continue;
+ if(!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j))
+ continue;
for(k=0; k<2; k++){
int n= st->info->duration_count;
double a= st->info->duration_error[k][0][j] / n;
return AVERROR(ENOSYS);
}
+#if FF_API_FORMAT_PARAMETERS
void av_close_input_stream(AVFormatContext *s)
{
flush_packet_queue(s);
s->iformat->read_close(s);
avformat_free_context(s);
}
+#endif
void avformat_free_context(AVFormatContext *s)
{
av_free(s);
}
+#if FF_API_CLOSE_INPUT_FILE
void av_close_input_file(AVFormatContext *s)
{
- AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?
+ avformat_close_input(&s);
+}
+#endif
+
+void avformat_close_input(AVFormatContext **ps)
+{
+ AVFormatContext *s = *ps;
+ AVIOContext *pb = (s->iformat && (s->iformat->flags & AVFMT_NOFILE)) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?
NULL : s->pb;
- av_close_input_stream(s);
+ flush_packet_queue(s);
+ if (s->iformat && (s->iformat->read_close))
+ s->iformat->read_close(s);
+ avformat_free_context(s);
+ *ps = NULL;
if (pb)
avio_close(pb);
}
st->probe_packets = MAX_PROBE_PACKETS;
/* default pts setting is MPEG-like */
- av_set_pts_info(st, 33, 1, 90000);
+ 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;
av_dlog(s, "compute_pkt_fields2: 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 AVERROR(EINVAL);*/
-
/* duration field */
if (pkt->duration == 0) {
compute_frame_duration(&num, &den, st, NULL, pkt);
return ret;
}
-void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
+#define CHUNK_START 0x1000
+
+int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
{
AVPacketList **next_point, *this_pktl;
+ AVStream *st= s->streams[pkt->stream_index];
+ int chunked= s->max_chunk_size || s->max_chunk_duration;
this_pktl = av_mallocz(sizeof(AVPacketList));
+ if (!this_pktl)
+ return AVERROR(ENOMEM);
this_pktl->pkt= *pkt;
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 = &(st->last_in_packet_buffer->next);
+ }else{
next_point = &s->packet_buffer;
+ }
if(*next_point){
+ if(chunked){
+ uint64_t max= av_rescale_q(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base);
+ if( st->interleaver_chunk_size + pkt->size <= s->max_chunk_size-1U
+ && st->interleaver_chunk_duration + pkt->duration <= max-1U){
+ st->interleaver_chunk_size += pkt->size;
+ st->interleaver_chunk_duration += pkt->duration;
+ goto next_non_null;
+ }else{
+ st->interleaver_chunk_size =
+ st->interleaver_chunk_duration = 0;
+ this_pktl->pkt.flags |= CHUNK_START;
+ }
+ }
+
if(compare(s, &s->packet_buffer_end->pkt, pkt)){
- while(!compare(s, &(*next_point)->pkt, pkt)){
+ while( *next_point
+ && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
+ || !compare(s, &(*next_point)->pkt, pkt))){
next_point= &(*next_point)->next;
}
- goto next_non_null;
+ if(*next_point)
+ goto next_non_null;
}else{
next_point = &(s->packet_buffer_end->next);
}
s->streams[pkt->stream_index]->last_in_packet_buffer=
*next_point= this_pktl;
+ return 0;
}
static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
AVStream *st2= s->streams[ next->stream_index];
int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts,
st->time_base);
+ if(s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))){
+ int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+ int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+ if(ts == ts2){
+ ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
+ -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
+ ts2=0;
+ }
+ comp= (ts>ts2) - (ts<ts2);
+ }
if (comp == 0)
return pkt->stream_index < next->stream_index;
AVPacketList *pktl;
int stream_count=0, noninterleaved_count=0;
int64_t delta_dts_max = 0;
- int i;
+ int i, ret;
if(pkt){
- ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+ ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+ if (ret < 0)
+ return ret;
}
for(i=0; i < s->nb_streams; i++) {
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
}
- if (s->iformat && s->iformat->priv_class)
+ if (s->oformat->priv_class)
av_opt_free(s->priv_data);
av_freep(&s->priv_data);
return ret;
return len;
}
+#if FF_API_SET_PTS_INFO
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
unsigned int pts_num, unsigned int pts_den)
+{
+ avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den);
+}
+#endif
+
+void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
+ unsigned int pts_num, unsigned int pts_den)
{
AVRational new_tb;
if(av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)){
int64_t ff_iso8601_to_unix_time(const char *datestr)
{
#if HAVE_STRPTIME
- struct tm time = {0};
- strptime(datestr, "%Y - %m - %dT%T", &time);
- return mktime(&time);
+ struct tm time1 = {0}, time2 = {0};
+ char *ret1, *ret2;
+ ret1 = strptime(datestr, "%Y - %m - %d %T", &time1);
+ ret2 = strptime(datestr, "%Y - %m - %dT%T", &time2);
+ if (ret2 && !ret1)
+ return av_timegm(&time2);
+ else
+ return av_timegm(&time1);
#else
av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert "
"the date string.\n");
}
return AVERROR_PATCHWELCOME;
}
+
+int avformat_network_init(void)
+{
+#if CONFIG_NETWORK
+ int ret;
+ ff_network_inited_globally = 1;
+ if ((ret = ff_network_init()) < 0)
+ return ret;
+ ff_tls_init();
+#endif
+ return 0;
+}
+
+int avformat_network_deinit(void)
+{
+#if CONFIG_NETWORK
+ ff_network_close();
+ ff_tls_deinit();
+#endif
+ return 0;
+}