• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/utils.c

Go to the documentation of this file.
00001 /*
00002  * various utility functions for use within FFmpeg
00003  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 #include "avformat.h"
00022 #include "internal.h"
00023 #include "libavcodec/opt.h"
00024 #include "metadata.h"
00025 #include "libavutil/avstring.h"
00026 #include "riff.h"
00027 #include <sys/time.h>
00028 #include <time.h>
00029 #include <strings.h>
00030 
00031 #undef NDEBUG
00032 #include <assert.h>
00033 
00039 unsigned avformat_version(void)
00040 {
00041     return LIBAVFORMAT_VERSION_INT;
00042 }
00043 
00044 /* fraction handling */
00045 
00056 static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
00057 {
00058     num += (den >> 1);
00059     if (num >= den) {
00060         val += num / den;
00061         num = num % den;
00062     }
00063     f->val = val;
00064     f->num = num;
00065     f->den = den;
00066 }
00067 
00074 static void av_frac_add(AVFrac *f, int64_t incr)
00075 {
00076     int64_t num, den;
00077 
00078     num = f->num + incr;
00079     den = f->den;
00080     if (num < 0) {
00081         f->val += num / den;
00082         num = num % den;
00083         if (num < 0) {
00084             num += den;
00085             f->val--;
00086         }
00087     } else if (num >= den) {
00088         f->val += num / den;
00089         num = num % den;
00090     }
00091     f->num = num;
00092 }
00093 
00095 AVInputFormat *first_iformat = NULL;
00097 AVOutputFormat *first_oformat = NULL;
00098 
00099 AVInputFormat  *av_iformat_next(AVInputFormat  *f)
00100 {
00101     if(f) return f->next;
00102     else  return first_iformat;
00103 }
00104 
00105 AVOutputFormat *av_oformat_next(AVOutputFormat *f)
00106 {
00107     if(f) return f->next;
00108     else  return first_oformat;
00109 }
00110 
00111 void av_register_input_format(AVInputFormat *format)
00112 {
00113     AVInputFormat **p;
00114     p = &first_iformat;
00115     while (*p != NULL) p = &(*p)->next;
00116     *p = format;
00117     format->next = NULL;
00118 }
00119 
00120 void av_register_output_format(AVOutputFormat *format)
00121 {
00122     AVOutputFormat **p;
00123     p = &first_oformat;
00124     while (*p != NULL) p = &(*p)->next;
00125     *p = format;
00126     format->next = NULL;
00127 }
00128 
00129 int match_ext(const char *filename, const char *extensions)
00130 {
00131     const char *ext, *p;
00132     char ext1[32], *q;
00133 
00134     if(!filename)
00135         return 0;
00136 
00137     ext = strrchr(filename, '.');
00138     if (ext) {
00139         ext++;
00140         p = extensions;
00141         for(;;) {
00142             q = ext1;
00143             while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
00144                 *q++ = *p++;
00145             *q = '\0';
00146             if (!strcasecmp(ext1, ext))
00147                 return 1;
00148             if (*p == '\0')
00149                 break;
00150             p++;
00151         }
00152     }
00153     return 0;
00154 }
00155 
00156 static int match_format(const char *name, const char *names)
00157 {
00158     const char *p;
00159     int len, namelen;
00160 
00161     if (!name || !names)
00162         return 0;
00163 
00164     namelen = strlen(name);
00165     while ((p = strchr(names, ','))) {
00166         len = FFMAX(p - names, namelen);
00167         if (!strncasecmp(name, names, len))
00168             return 1;
00169         names = p+1;
00170     }
00171     return !strcasecmp(name, names);
00172 }
00173 
00174 AVOutputFormat *guess_format(const char *short_name, const char *filename,
00175                              const char *mime_type)
00176 {
00177     AVOutputFormat *fmt, *fmt_found;
00178     int score_max, score;
00179 
00180     /* specific test for image sequences */
00181 #if CONFIG_IMAGE2_MUXER
00182     if (!short_name && filename &&
00183         av_filename_number_test(filename) &&
00184         av_guess_image2_codec(filename) != CODEC_ID_NONE) {
00185         return guess_format("image2", NULL, NULL);
00186     }
00187 #endif
00188     /* Find the proper file type. */
00189     fmt_found = NULL;
00190     score_max = 0;
00191     fmt = first_oformat;
00192     while (fmt != NULL) {
00193         score = 0;
00194         if (fmt->name && short_name && !strcmp(fmt->name, short_name))
00195             score += 100;
00196         if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
00197             score += 10;
00198         if (filename && fmt->extensions &&
00199             match_ext(filename, fmt->extensions)) {
00200             score += 5;
00201         }
00202         if (score > score_max) {
00203             score_max = score;
00204             fmt_found = fmt;
00205         }
00206         fmt = fmt->next;
00207     }
00208     return fmt_found;
00209 }
00210 
00211 AVOutputFormat *guess_stream_format(const char *short_name, const char *filename,
00212                              const char *mime_type)
00213 {
00214     AVOutputFormat *fmt = guess_format(short_name, filename, mime_type);
00215 
00216     if (fmt) {
00217         AVOutputFormat *stream_fmt;
00218         char stream_format_name[64];
00219 
00220         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
00221         stream_fmt = guess_format(stream_format_name, NULL, NULL);
00222 
00223         if (stream_fmt)
00224             fmt = stream_fmt;
00225     }
00226 
00227     return fmt;
00228 }
00229 
00230 enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name,
00231                             const char *filename, const char *mime_type, enum CodecType type){
00232     if(type == CODEC_TYPE_VIDEO){
00233         enum CodecID codec_id= CODEC_ID_NONE;
00234 
00235 #if CONFIG_IMAGE2_MUXER
00236         if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
00237             codec_id= av_guess_image2_codec(filename);
00238         }
00239 #endif
00240         if(codec_id == CODEC_ID_NONE)
00241             codec_id= fmt->video_codec;
00242         return codec_id;
00243     }else if(type == CODEC_TYPE_AUDIO)
00244         return fmt->audio_codec;
00245     else
00246         return CODEC_ID_NONE;
00247 }
00248 
00249 AVInputFormat *av_find_input_format(const char *short_name)
00250 {
00251     AVInputFormat *fmt;
00252     for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
00253         if (match_format(short_name, fmt->name))
00254             return fmt;
00255     }
00256     return NULL;
00257 }
00258 
00259 /* memory handling */
00260 
00261 void av_destruct_packet(AVPacket *pkt)
00262 {
00263     av_free(pkt->data);
00264     pkt->data = NULL; pkt->size = 0;
00265 }
00266 
00267 void av_init_packet(AVPacket *pkt)
00268 {
00269     pkt->pts   = AV_NOPTS_VALUE;
00270     pkt->dts   = AV_NOPTS_VALUE;
00271     pkt->pos   = -1;
00272     pkt->duration = 0;
00273     pkt->convergence_duration = 0;
00274     pkt->flags = 0;
00275     pkt->stream_index = 0;
00276     pkt->destruct= av_destruct_packet_nofree;
00277 }
00278 
00279 int av_new_packet(AVPacket *pkt, int size)
00280 {
00281     uint8_t *data;
00282     if((unsigned)size > (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
00283         return AVERROR(ENOMEM);
00284     data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
00285     if (!data)
00286         return AVERROR(ENOMEM);
00287     memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00288 
00289     av_init_packet(pkt);
00290     pkt->data = data;
00291     pkt->size = size;
00292     pkt->destruct = av_destruct_packet;
00293     return 0;
00294 }
00295 
00296 int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
00297 {
00298     int ret= av_new_packet(pkt, size);
00299 
00300     if(ret<0)
00301         return ret;
00302 
00303     pkt->pos= url_ftell(s);
00304 
00305     ret= get_buffer(s, pkt->data, size);
00306     if(ret<=0)
00307         av_free_packet(pkt);
00308     else
00309         pkt->size= ret;
00310 
00311     return ret;
00312 }
00313 
00314 int av_dup_packet(AVPacket *pkt)
00315 {
00316     if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
00317         uint8_t *data;
00318         /* We duplicate the packet and don't forget to add the padding again. */
00319         if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
00320             return AVERROR(ENOMEM);
00321         data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
00322         if (!data) {
00323             return AVERROR(ENOMEM);
00324         }
00325         memcpy(data, pkt->data, pkt->size);
00326         memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00327         pkt->data = data;
00328         pkt->destruct = av_destruct_packet;
00329     }
00330     return 0;
00331 }
00332 
00333 int av_filename_number_test(const char *filename)
00334 {
00335     char buf[1024];
00336     return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
00337 }
00338 
00339 static AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
00340 {
00341     AVInputFormat *fmt1, *fmt;
00342     int score;
00343 
00344     fmt = NULL;
00345     for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
00346         if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
00347             continue;
00348         score = 0;
00349         if (fmt1->read_probe) {
00350             score = fmt1->read_probe(pd);
00351         } else if (fmt1->extensions) {
00352             if (match_ext(pd->filename, fmt1->extensions)) {
00353                 score = 50;
00354             }
00355         }
00356         if (score > *score_max) {
00357             *score_max = score;
00358             fmt = fmt1;
00359         }else if (score == *score_max)
00360             fmt = NULL;
00361     }
00362     return fmt;
00363 }
00364 
00365 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
00366     int score=0;
00367     return av_probe_input_format2(pd, is_opened, &score);
00368 }
00369 
00370 static int set_codec_from_probe_data(AVStream *st, AVProbeData *pd, int score)
00371 {
00372     AVInputFormat *fmt;
00373     fmt = av_probe_input_format2(pd, 1, &score);
00374 
00375     if (fmt) {
00376         if (!strcmp(fmt->name, "mp3")) {
00377             st->codec->codec_id = CODEC_ID_MP3;
00378             st->codec->codec_type = CODEC_TYPE_AUDIO;
00379         } else if (!strcmp(fmt->name, "ac3")) {
00380             st->codec->codec_id = CODEC_ID_AC3;
00381             st->codec->codec_type = CODEC_TYPE_AUDIO;
00382         } else if (!strcmp(fmt->name, "mpegvideo")) {
00383             st->codec->codec_id = CODEC_ID_MPEG2VIDEO;
00384             st->codec->codec_type = CODEC_TYPE_VIDEO;
00385         } else if (!strcmp(fmt->name, "m4v")) {
00386             st->codec->codec_id = CODEC_ID_MPEG4;
00387             st->codec->codec_type = CODEC_TYPE_VIDEO;
00388         } else if (!strcmp(fmt->name, "h264")) {
00389             st->codec->codec_id = CODEC_ID_H264;
00390             st->codec->codec_type = CODEC_TYPE_VIDEO;
00391         }
00392     }
00393     return !!fmt;
00394 }
00395 
00396 /************************************************************/
00397 /* input media file */
00398 
00402 int av_open_input_stream(AVFormatContext **ic_ptr,
00403                          ByteIOContext *pb, const char *filename,
00404                          AVInputFormat *fmt, AVFormatParameters *ap)
00405 {
00406     int err;
00407     AVFormatContext *ic;
00408     AVFormatParameters default_ap;
00409 
00410     if(!ap){
00411         ap=&default_ap;
00412         memset(ap, 0, sizeof(default_ap));
00413     }
00414 
00415     if(!ap->prealloced_context)
00416         ic = avformat_alloc_context();
00417     else
00418         ic = *ic_ptr;
00419     if (!ic) {
00420         err = AVERROR(ENOMEM);
00421         goto fail;
00422     }
00423     ic->iformat = fmt;
00424     ic->pb = pb;
00425     ic->duration = AV_NOPTS_VALUE;
00426     ic->start_time = AV_NOPTS_VALUE;
00427     av_strlcpy(ic->filename, filename, sizeof(ic->filename));
00428 
00429     /* allocate private data */
00430     if (fmt->priv_data_size > 0) {
00431         ic->priv_data = av_mallocz(fmt->priv_data_size);
00432         if (!ic->priv_data) {
00433             err = AVERROR(ENOMEM);
00434             goto fail;
00435         }
00436     } else {
00437         ic->priv_data = NULL;
00438     }
00439 
00440     if (ic->iformat->read_header) {
00441         err = ic->iformat->read_header(ic, ap);
00442         if (err < 0)
00443             goto fail;
00444     }
00445 
00446     if (pb && !ic->data_offset)
00447         ic->data_offset = url_ftell(ic->pb);
00448 
00449 #if LIBAVFORMAT_VERSION_MAJOR < 53
00450     ff_metadata_demux_compat(ic);
00451 #endif
00452 
00453     *ic_ptr = ic;
00454     return 0;
00455  fail:
00456     if (ic) {
00457         int i;
00458         av_freep(&ic->priv_data);
00459         for(i=0;i<ic->nb_streams;i++) {
00460             AVStream *st = ic->streams[i];
00461             if (st) {
00462                 av_free(st->priv_data);
00463                 av_free(st->codec->extradata);
00464             }
00465             av_free(st);
00466         }
00467     }
00468     av_free(ic);
00469     *ic_ptr = NULL;
00470     return err;
00471 }
00472 
00474 #define PROBE_BUF_MIN 2048
00475 #define PROBE_BUF_MAX (1<<20)
00476 
00477 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
00478                        AVInputFormat *fmt,
00479                        int buf_size,
00480                        AVFormatParameters *ap)
00481 {
00482     int err, probe_size;
00483     AVProbeData probe_data, *pd = &probe_data;
00484     ByteIOContext *pb = NULL;
00485 
00486     pd->filename = "";
00487     if (filename)
00488         pd->filename = filename;
00489     pd->buf = NULL;
00490     pd->buf_size = 0;
00491 
00492     if (!fmt) {
00493         /* guess format if no file can be opened */
00494         fmt = av_probe_input_format(pd, 0);
00495     }
00496 
00497     /* Do not open file if the format does not need it. XXX: specific
00498        hack needed to handle RTSP/TCP */
00499     if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
00500         /* if no file needed do not try to open one */
00501         if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0) {
00502             goto fail;
00503         }
00504         if (buf_size > 0) {
00505             url_setbufsize(pb, buf_size);
00506         }
00507 
00508         for(probe_size= PROBE_BUF_MIN; probe_size<=PROBE_BUF_MAX && !fmt; probe_size<<=1){
00509             int score= probe_size < PROBE_BUF_MAX ? AVPROBE_SCORE_MAX/4 : 0;
00510             /* read probe data */
00511             pd->buf= av_realloc(pd->buf, probe_size + AVPROBE_PADDING_SIZE);
00512             pd->buf_size = get_buffer(pb, pd->buf, probe_size);
00513             memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
00514             if (url_fseek(pb, 0, SEEK_SET) < 0) {
00515                 url_fclose(pb);
00516                 if (url_fopen(&pb, filename, URL_RDONLY) < 0) {
00517                     pb = NULL;
00518                     err = AVERROR(EIO);
00519                     goto fail;
00520                 }
00521             }
00522             /* guess file format */
00523             fmt = av_probe_input_format2(pd, 1, &score);
00524         }
00525         av_freep(&pd->buf);
00526     }
00527 
00528     /* if still no format found, error */
00529     if (!fmt) {
00530         err = AVERROR_NOFMT;
00531         goto fail;
00532     }
00533 
00534     /* check filename in case an image number is expected */
00535     if (fmt->flags & AVFMT_NEEDNUMBER) {
00536         if (!av_filename_number_test(filename)) {
00537             err = AVERROR_NUMEXPECTED;
00538             goto fail;
00539         }
00540     }
00541     err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);
00542     if (err)
00543         goto fail;
00544     return 0;
00545  fail:
00546     av_freep(&pd->buf);
00547     if (pb)
00548         url_fclose(pb);
00549     *ic_ptr = NULL;
00550     return err;
00551 
00552 }
00553 
00554 /*******************************************************/
00555 
00556 static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
00557                                AVPacketList **plast_pktl){
00558     AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
00559     if (!pktl)
00560         return NULL;
00561 
00562     if (*packet_buffer)
00563         (*plast_pktl)->next = pktl;
00564     else
00565         *packet_buffer = pktl;
00566 
00567     /* add the packet in the buffered packet list */
00568     *plast_pktl = pktl;
00569     pktl->pkt= *pkt;
00570     return &pktl->pkt;
00571 }
00572 
00573 int av_read_packet(AVFormatContext *s, AVPacket *pkt)
00574 {
00575     int ret;
00576     AVStream *st;
00577 
00578     for(;;){
00579         AVPacketList *pktl = s->raw_packet_buffer;
00580 
00581         if (pktl) {
00582             *pkt = pktl->pkt;
00583             if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE){
00584                 s->raw_packet_buffer = pktl->next;
00585                 av_free(pktl);
00586                 return 0;
00587             }
00588         }
00589 
00590         av_init_packet(pkt);
00591         ret= s->iformat->read_packet(s, pkt);
00592         if (ret < 0)
00593             return ret;
00594         st= s->streams[pkt->stream_index];
00595 
00596         switch(st->codec->codec_type){
00597         case CODEC_TYPE_VIDEO:
00598             if(s->video_codec_id)   st->codec->codec_id= s->video_codec_id;
00599             break;
00600         case CODEC_TYPE_AUDIO:
00601             if(s->audio_codec_id)   st->codec->codec_id= s->audio_codec_id;
00602             break;
00603         case CODEC_TYPE_SUBTITLE:
00604             if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id;
00605             break;
00606         }
00607 
00608         if(!pktl && st->codec->codec_id!=CODEC_ID_PROBE)
00609             return ret;
00610 
00611         add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
00612 
00613         if(st->codec->codec_id == CODEC_ID_PROBE){
00614             AVProbeData *pd = &st->probe_data;
00615 
00616             pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
00617             memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
00618             pd->buf_size += pkt->size;
00619             memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
00620 
00621             if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
00622                 set_codec_from_probe_data(st, pd, 1);
00623                 if(st->codec->codec_id != CODEC_ID_PROBE){
00624                     pd->buf_size=0;
00625                     av_freep(&pd->buf);
00626                 }
00627             }
00628         }
00629     }
00630 }
00631 
00632 /**********************************************************/
00633 
00637 static int get_audio_frame_size(AVCodecContext *enc, int size)
00638 {
00639     int frame_size;
00640 
00641     if(enc->codec_id == CODEC_ID_VORBIS)
00642         return -1;
00643 
00644     if (enc->frame_size <= 1) {
00645         int bits_per_sample = av_get_bits_per_sample(enc->codec_id);
00646 
00647         if (bits_per_sample) {
00648             if (enc->channels == 0)
00649                 return -1;
00650             frame_size = (size << 3) / (bits_per_sample * enc->channels);
00651         } else {
00652             /* used for example by ADPCM codecs */
00653             if (enc->bit_rate == 0)
00654                 return -1;
00655             frame_size = (size * 8 * enc->sample_rate) / enc->bit_rate;
00656         }
00657     } else {
00658         frame_size = enc->frame_size;
00659     }
00660     return frame_size;
00661 }
00662 
00663 
00667 static void compute_frame_duration(int *pnum, int *pden, AVStream *st,
00668                                    AVCodecParserContext *pc, AVPacket *pkt)
00669 {
00670     int frame_size;
00671 
00672     *pnum = 0;
00673     *pden = 0;
00674     switch(st->codec->codec_type) {
00675     case CODEC_TYPE_VIDEO:
00676         if(st->time_base.num*1000LL > st->time_base.den){
00677             *pnum = st->time_base.num;
00678             *pden = st->time_base.den;
00679         }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){
00680             *pnum = st->codec->time_base.num;
00681             *pden = st->codec->time_base.den;
00682             if (pc && pc->repeat_pict) {
00683                 if (*pnum > INT_MAX / (1 + pc->repeat_pict))
00684                     *pden /= 1 + pc->repeat_pict;
00685                 else
00686                     *pnum *= 1 + pc->repeat_pict;
00687             }
00688         }
00689         break;
00690     case CODEC_TYPE_AUDIO:
00691         frame_size = get_audio_frame_size(st->codec, pkt->size);
00692         if (frame_size < 0)
00693             break;
00694         *pnum = frame_size;
00695         *pden = st->codec->sample_rate;
00696         break;
00697     default:
00698         break;
00699     }
00700 }
00701 
00702 static int is_intra_only(AVCodecContext *enc){
00703     if(enc->codec_type == CODEC_TYPE_AUDIO){
00704         return 1;
00705     }else if(enc->codec_type == CODEC_TYPE_VIDEO){
00706         switch(enc->codec_id){
00707         case CODEC_ID_MJPEG:
00708         case CODEC_ID_MJPEGB:
00709         case CODEC_ID_LJPEG:
00710         case CODEC_ID_RAWVIDEO:
00711         case CODEC_ID_DVVIDEO:
00712         case CODEC_ID_HUFFYUV:
00713         case CODEC_ID_FFVHUFF:
00714         case CODEC_ID_ASV1:
00715         case CODEC_ID_ASV2:
00716         case CODEC_ID_VCR1:
00717         case CODEC_ID_DNXHD:
00718         case CODEC_ID_JPEG2000:
00719             return 1;
00720         default: break;
00721         }
00722     }
00723     return 0;
00724 }
00725 
00726 static void update_initial_timestamps(AVFormatContext *s, int stream_index,
00727                                       int64_t dts, int64_t pts)
00728 {
00729     AVStream *st= s->streams[stream_index];
00730     AVPacketList *pktl= s->packet_buffer;
00731 
00732     if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE)
00733         return;
00734 
00735     st->first_dts= dts - st->cur_dts;
00736     st->cur_dts= dts;
00737 
00738     for(; pktl; pktl= pktl->next){
00739         if(pktl->pkt.stream_index != stream_index)
00740             continue;
00741         //FIXME think more about this check
00742         if(pktl->pkt.pts != AV_NOPTS_VALUE && pktl->pkt.pts == pktl->pkt.dts)
00743             pktl->pkt.pts += st->first_dts;
00744 
00745         if(pktl->pkt.dts != AV_NOPTS_VALUE)
00746             pktl->pkt.dts += st->first_dts;
00747 
00748         if(st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE)
00749             st->start_time= pktl->pkt.pts;
00750     }
00751     if (st->start_time == AV_NOPTS_VALUE)
00752         st->start_time = pts;
00753 }
00754 
00755 static void update_initial_durations(AVFormatContext *s, AVStream *st, AVPacket *pkt)
00756 {
00757     AVPacketList *pktl= s->packet_buffer;
00758     int64_t cur_dts= 0;
00759 
00760     if(st->first_dts != AV_NOPTS_VALUE){
00761         cur_dts= st->first_dts;
00762         for(; pktl; pktl= pktl->next){
00763             if(pktl->pkt.stream_index == pkt->stream_index){
00764                 if(pktl->pkt.pts != pktl->pkt.dts || pktl->pkt.dts != AV_NOPTS_VALUE || pktl->pkt.duration)
00765                     break;
00766                 cur_dts -= pkt->duration;
00767             }
00768         }
00769         pktl= s->packet_buffer;
00770         st->first_dts = cur_dts;
00771     }else if(st->cur_dts)
00772         return;
00773 
00774     for(; pktl; pktl= pktl->next){
00775         if(pktl->pkt.stream_index != pkt->stream_index)
00776             continue;
00777         if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE
00778            && !pktl->pkt.duration){
00779             pktl->pkt.dts= cur_dts;
00780             if(!st->codec->has_b_frames)
00781                 pktl->pkt.pts= cur_dts;
00782             cur_dts += pkt->duration;
00783             pktl->pkt.duration= pkt->duration;
00784         }else
00785             break;
00786     }
00787     if(st->first_dts == AV_NOPTS_VALUE)
00788         st->cur_dts= cur_dts;
00789 }
00790 
00791 static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
00792                                AVCodecParserContext *pc, AVPacket *pkt)
00793 {
00794     int num, den, presentation_delayed, delay, i;
00795     int64_t offset;
00796 
00797     /* do we have a video B-frame ? */
00798     delay= st->codec->has_b_frames;
00799     presentation_delayed = 0;
00800     /* XXX: need has_b_frame, but cannot get it if the codec is
00801         not initialized */
00802     if (delay &&
00803         pc && pc->pict_type != FF_B_TYPE)
00804         presentation_delayed = 1;
00805 
00806     if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63
00807        /*&& pkt->dts-(1LL<<st->pts_wrap_bits) < pkt->pts*/){
00808         pkt->dts -= 1LL<<st->pts_wrap_bits;
00809     }
00810 
00811     // some mpeg2 in mpeg-ps lack dts (issue171 / input_file.mpg)
00812     // we take the conservative approach and discard both
00813     // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
00814     if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
00815         av_log(s, AV_LOG_WARNING, "invalid dts/pts combination\n");
00816         pkt->dts= pkt->pts= AV_NOPTS_VALUE;
00817     }
00818 
00819     if (pkt->duration == 0) {
00820         compute_frame_duration(&num, &den, st, pc, pkt);
00821         if (den && num) {
00822             pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
00823 
00824             if(pkt->duration != 0 && s->packet_buffer)
00825                 update_initial_durations(s, st, pkt);
00826         }
00827     }
00828 
00829     /* correct timestamps with byte offset if demuxers only have timestamps
00830        on packet boundaries */
00831     if(pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size){
00832         /* this will estimate bitrate based on this frame's duration and size */
00833         offset = av_rescale(pc->offset, pkt->duration, pkt->size);
00834         if(pkt->pts != AV_NOPTS_VALUE)
00835             pkt->pts += offset;
00836         if(pkt->dts != AV_NOPTS_VALUE)
00837             pkt->dts += offset;
00838     }
00839 
00840     if (pc && pc->dts_sync_point >= 0) {
00841         // we have synchronization info from the parser
00842         int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num;
00843         if (den > 0) {
00844             int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den;
00845             if (pkt->dts != AV_NOPTS_VALUE) {
00846                 // got DTS from the stream, update reference timestamp
00847                 st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den;
00848                 pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
00849             } else if (st->reference_dts != AV_NOPTS_VALUE) {
00850                 // compute DTS based on reference timestamp
00851                 pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den;
00852                 pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
00853             }
00854             if (pc->dts_sync_point > 0)
00855                 st->reference_dts = pkt->dts; // new reference
00856         }
00857     }
00858 
00859     /* This may be redundant, but it should not hurt. */
00860     if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
00861         presentation_delayed = 1;
00862 
00863 //    av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc);
00864     /* interpolate PTS and DTS if they are not present */
00865     //We skip H264 currently because delay and has_b_frames are not reliably set
00866     if((delay==0 || (delay==1 && pc)) && st->codec->codec_id != CODEC_ID_H264){
00867         if (presentation_delayed) {
00868             /* DTS = decompression timestamp */
00869             /* PTS = presentation timestamp */
00870             if (pkt->dts == AV_NOPTS_VALUE)
00871                 pkt->dts = st->last_IP_pts;
00872             update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
00873             if (pkt->dts == AV_NOPTS_VALUE)
00874                 pkt->dts = st->cur_dts;
00875 
00876             /* this is tricky: the dts must be incremented by the duration
00877             of the frame we are displaying, i.e. the last I- or P-frame */
00878             if (st->last_IP_duration == 0)
00879                 st->last_IP_duration = pkt->duration;
00880             if(pkt->dts != AV_NOPTS_VALUE)
00881                 st->cur_dts = pkt->dts + st->last_IP_duration;
00882             st->last_IP_duration  = pkt->duration;
00883             st->last_IP_pts= pkt->pts;
00884             /* cannot compute PTS if not present (we can compute it only
00885             by knowing the future */
00886         } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
00887             if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
00888                 int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts);
00889                 int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
00890                 if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
00891                     pkt->pts += pkt->duration;
00892     //                av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
00893                 }
00894             }
00895 
00896             /* presentation is not delayed : PTS and DTS are the same */
00897             if(pkt->pts == AV_NOPTS_VALUE)
00898                 pkt->pts = pkt->dts;
00899             update_initial_timestamps(s, pkt->stream_index, pkt->pts, pkt->pts);
00900             if(pkt->pts == AV_NOPTS_VALUE)
00901                 pkt->pts = st->cur_dts;
00902             pkt->dts = pkt->pts;
00903             if(pkt->pts != AV_NOPTS_VALUE)
00904                 st->cur_dts = pkt->pts + pkt->duration;
00905         }
00906     }
00907 
00908     if(pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){
00909         st->pts_buffer[0]= pkt->pts;
00910         for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
00911             FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
00912         if(pkt->dts == AV_NOPTS_VALUE)
00913             pkt->dts= st->pts_buffer[0];
00914         if(st->codec->codec_id == CODEC_ID_H264){ //we skiped it above so we try here
00915             update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet
00916         }
00917         if(pkt->dts > st->cur_dts)
00918             st->cur_dts = pkt->dts;
00919     }
00920 
00921 //    av_log(NULL, AV_LOG_ERROR, "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts);
00922 
00923     /* update flags */
00924     if(is_intra_only(st->codec))
00925         pkt->flags |= PKT_FLAG_KEY;
00926     else if (pc) {
00927         pkt->flags = 0;
00928         /* keyframe computation */
00929         if (pc->key_frame == 1)
00930             pkt->flags |= PKT_FLAG_KEY;
00931         else if (pc->key_frame == -1 && pc->pict_type == FF_I_TYPE)
00932             pkt->flags |= PKT_FLAG_KEY;
00933     }
00934     if (pc)
00935         pkt->convergence_duration = pc->convergence_duration;
00936 }
00937 
00938 void av_destruct_packet_nofree(AVPacket *pkt)
00939 {
00940     pkt->data = NULL; pkt->size = 0;
00941 }
00942 
00943 static int av_read_frame_internal(AVFormatContext *s, AVPacket *pkt)
00944 {
00945     AVStream *st;
00946     int len, ret, i;
00947 
00948     av_init_packet(pkt);
00949 
00950     for(;;) {
00951         /* select current input stream component */
00952         st = s->cur_st;
00953         if (st) {
00954             if (!st->need_parsing || !st->parser) {
00955                 /* no parsing needed: we just output the packet as is */
00956                 /* raw data support */
00957                 *pkt = st->cur_pkt; st->cur_pkt.data= NULL;
00958                 compute_pkt_fields(s, st, NULL, pkt);
00959                 s->cur_st = NULL;
00960                 break;
00961             } else if (st->cur_len > 0 && st->discard < AVDISCARD_ALL) {
00962                 len = av_parser_parse(st->parser, st->codec, &pkt->data, &pkt->size,
00963                                       st->cur_ptr, st->cur_len,
00964                                       st->cur_pkt.pts, st->cur_pkt.dts);
00965                 st->cur_pkt.pts = AV_NOPTS_VALUE;
00966                 st->cur_pkt.dts = AV_NOPTS_VALUE;
00967                 /* increment read pointer */
00968                 st->cur_ptr += len;
00969                 st->cur_len -= len;
00970 
00971                 /* return packet if any */
00972                 if (pkt->size) {
00973                     pkt->pos = st->cur_pkt.pos;              // Isn't quite accurate but close.
00974                 got_packet:
00975                     pkt->duration = 0;
00976                     pkt->stream_index = st->index;
00977                     pkt->pts = st->parser->pts;
00978                     pkt->dts = st->parser->dts;
00979                     pkt->destruct = av_destruct_packet_nofree;
00980                     compute_pkt_fields(s, st, st->parser, pkt);
00981 
00982                     if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & PKT_FLAG_KEY){
00983                         ff_reduce_index(s, st->index);
00984                         av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
00985                                            0, 0, AVINDEX_KEYFRAME);
00986                     }
00987 
00988                     break;
00989                 }
00990             } else {
00991                 /* free packet */
00992                 av_free_packet(&st->cur_pkt);
00993                 s->cur_st = NULL;
00994             }
00995         } else {
00996             AVPacket cur_pkt;
00997             /* read next packet */
00998             ret = av_read_packet(s, &cur_pkt);
00999             if (ret < 0) {
01000                 if (ret == AVERROR(EAGAIN))
01001                     return ret;
01002                 /* return the last frames, if any */
01003                 for(i = 0; i < s->nb_streams; i++) {
01004                     st = s->streams[i];
01005                     if (st->parser && st->need_parsing) {
01006                         av_parser_parse(st->parser, st->codec,
01007                                         &pkt->data, &pkt->size,
01008                                         NULL, 0,
01009                                         AV_NOPTS_VALUE, AV_NOPTS_VALUE);
01010                         if (pkt->size)
01011                             goto got_packet;
01012                     }
01013                 }
01014                 /* no more packets: really terminate parsing */
01015                 return ret;
01016             }
01017             st = s->streams[cur_pkt.stream_index];
01018             st->cur_pkt= cur_pkt;
01019 
01020             if(st->cur_pkt.pts != AV_NOPTS_VALUE &&
01021                st->cur_pkt.dts != AV_NOPTS_VALUE &&
01022                st->cur_pkt.pts < st->cur_pkt.dts){
01023                 av_log(s, AV_LOG_WARNING, "Invalid timestamps stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n",
01024                     st->cur_pkt.stream_index,
01025                     st->cur_pkt.pts,
01026                     st->cur_pkt.dts,
01027                     st->cur_pkt.size);
01028 //                av_free_packet(&st->cur_pkt);
01029 //                return -1;
01030             }
01031 
01032             if(s->debug & FF_FDEBUG_TS)
01033                 av_log(s, AV_LOG_DEBUG, "av_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d,  flags=%d\n",
01034                     st->cur_pkt.stream_index,
01035                     st->cur_pkt.pts,
01036                     st->cur_pkt.dts,
01037                     st->cur_pkt.size,
01038                     st->cur_pkt.flags);
01039 
01040             s->cur_st = st;
01041             st->cur_ptr = st->cur_pkt.data;
01042             st->cur_len = st->cur_pkt.size;
01043             if (st->need_parsing && !st->parser) {
01044                 st->parser = av_parser_init(st->codec->codec_id);
01045                 if (!st->parser) {
01046                     /* no parser available: just output the raw packets */
01047                     st->need_parsing = AVSTREAM_PARSE_NONE;
01048                 }else if(st->need_parsing == AVSTREAM_PARSE_HEADERS){
01049                     st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
01050                 }
01051                 if(st->parser && (s->iformat->flags & AVFMT_GENERIC_INDEX)){
01052                     st->parser->next_frame_offset=
01053                     st->parser->cur_offset= st->cur_pkt.pos;
01054                 }
01055             }
01056         }
01057     }
01058     if(s->debug & FF_FDEBUG_TS)
01059         av_log(s, AV_LOG_DEBUG, "av_read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, flags=%d\n",
01060             pkt->stream_index,
01061             pkt->pts,
01062             pkt->dts,
01063             pkt->size,
01064             pkt->flags);
01065 
01066     return 0;
01067 }
01068 
01069 int av_read_frame(AVFormatContext *s, AVPacket *pkt)
01070 {
01071     AVPacketList *pktl;
01072     int eof=0;
01073     const int genpts= s->flags & AVFMT_FLAG_GENPTS;
01074 
01075     for(;;){
01076         pktl = s->packet_buffer;
01077         if (pktl) {
01078             AVPacket *next_pkt= &pktl->pkt;
01079 
01080             if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
01081                 while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
01082                     if(   pktl->pkt.stream_index == next_pkt->stream_index
01083                        && next_pkt->dts < pktl->pkt.dts
01084                        && pktl->pkt.pts != pktl->pkt.dts //not b frame
01085                        /*&& pktl->pkt.dts != AV_NOPTS_VALUE*/){
01086                         next_pkt->pts= pktl->pkt.dts;
01087                     }
01088                     pktl= pktl->next;
01089                 }
01090                 pktl = s->packet_buffer;
01091             }
01092 
01093             if(   next_pkt->pts != AV_NOPTS_VALUE
01094                || next_pkt->dts == AV_NOPTS_VALUE
01095                || !genpts || eof){
01096                 /* read packet from packet buffer, if there is data */
01097                 *pkt = *next_pkt;
01098                 s->packet_buffer = pktl->next;
01099                 av_free(pktl);
01100                 return 0;
01101             }
01102         }
01103         if(genpts){
01104             int ret= av_read_frame_internal(s, pkt);
01105             if(ret<0){
01106                 if(pktl && ret != AVERROR(EAGAIN)){
01107                     eof=1;
01108                     continue;
01109                 }else
01110                     return ret;
01111             }
01112 
01113             if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
01114                                            &s->packet_buffer_end)) < 0)
01115                 return AVERROR(ENOMEM);
01116         }else{
01117             assert(!s->packet_buffer);
01118             return av_read_frame_internal(s, pkt);
01119         }
01120     }
01121 }
01122 
01123 /* XXX: suppress the packet queue */
01124 static void flush_packet_queue(AVFormatContext *s)
01125 {
01126     AVPacketList *pktl;
01127 
01128     for(;;) {
01129         pktl = s->packet_buffer;
01130         if (!pktl)
01131             break;
01132         s->packet_buffer = pktl->next;
01133         av_free_packet(&pktl->pkt);
01134         av_free(pktl);
01135     }
01136 }
01137 
01138 /*******************************************************/
01139 /* seek support */
01140 
01141 int av_find_default_stream_index(AVFormatContext *s)
01142 {
01143     int first_audio_index = -1;
01144     int i;
01145     AVStream *st;
01146 
01147     if (s->nb_streams <= 0)
01148         return -1;
01149     for(i = 0; i < s->nb_streams; i++) {
01150         st = s->streams[i];
01151         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
01152             return i;
01153         }
01154         if (first_audio_index < 0 && st->codec->codec_type == CODEC_TYPE_AUDIO)
01155             first_audio_index = i;
01156     }
01157     return first_audio_index >= 0 ? first_audio_index : 0;
01158 }
01159 
01163 static void av_read_frame_flush(AVFormatContext *s)
01164 {
01165     AVStream *st;
01166     int i;
01167 
01168     flush_packet_queue(s);
01169 
01170     s->cur_st = NULL;
01171 
01172     /* for each stream, reset read state */
01173     for(i = 0; i < s->nb_streams; i++) {
01174         st = s->streams[i];
01175 
01176         if (st->parser) {
01177             av_parser_close(st->parser);
01178             st->parser = NULL;
01179             av_free_packet(&st->cur_pkt);
01180         }
01181         st->last_IP_pts = AV_NOPTS_VALUE;
01182         st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
01183         st->reference_dts = AV_NOPTS_VALUE;
01184         /* fail safe */
01185         st->cur_ptr = NULL;
01186         st->cur_len = 0;
01187     }
01188 }
01189 
01190 void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){
01191     int i;
01192 
01193     for(i = 0; i < s->nb_streams; i++) {
01194         AVStream *st = s->streams[i];
01195 
01196         st->cur_dts = av_rescale(timestamp,
01197                                  st->time_base.den * (int64_t)ref_st->time_base.num,
01198                                  st->time_base.num * (int64_t)ref_st->time_base.den);
01199     }
01200 }
01201 
01202 void ff_reduce_index(AVFormatContext *s, int stream_index)
01203 {
01204     AVStream *st= s->streams[stream_index];
01205     unsigned int max_entries= s->max_index_size / sizeof(AVIndexEntry);
01206 
01207     if((unsigned)st->nb_index_entries >= max_entries){
01208         int i;
01209         for(i=0; 2*i<st->nb_index_entries; i++)
01210             st->index_entries[i]= st->index_entries[2*i];
01211         st->nb_index_entries= i;
01212     }
01213 }
01214 
01215 int av_add_index_entry(AVStream *st,
01216                             int64_t pos, int64_t timestamp, int size, int distance, int flags)
01217 {
01218     AVIndexEntry *entries, *ie;
01219     int index;
01220 
01221     if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
01222         return -1;
01223 
01224     entries = av_fast_realloc(st->index_entries,
01225                               &st->index_entries_allocated_size,
01226                               (st->nb_index_entries + 1) *
01227                               sizeof(AVIndexEntry));
01228     if(!entries)
01229         return -1;
01230 
01231     st->index_entries= entries;
01232 
01233     index= av_index_search_timestamp(st, timestamp, AVSEEK_FLAG_ANY);
01234 
01235     if(index<0){
01236         index= st->nb_index_entries++;
01237         ie= &entries[index];
01238         assert(index==0 || ie[-1].timestamp < timestamp);
01239     }else{
01240         ie= &entries[index];
01241         if(ie->timestamp != timestamp){
01242             if(ie->timestamp <= timestamp)
01243                 return -1;
01244             memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(st->nb_index_entries - index));
01245             st->nb_index_entries++;
01246         }else if(ie->pos == pos && distance < ie->min_distance) //do not reduce the distance
01247             distance= ie->min_distance;
01248     }
01249 
01250     ie->pos = pos;
01251     ie->timestamp = timestamp;
01252     ie->min_distance= distance;
01253     ie->size= size;
01254     ie->flags = flags;
01255 
01256     return index;
01257 }
01258 
01259 int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp,
01260                               int flags)
01261 {
01262     AVIndexEntry *entries= st->index_entries;
01263     int nb_entries= st->nb_index_entries;
01264     int a, b, m;
01265     int64_t timestamp;
01266 
01267     a = - 1;
01268     b = nb_entries;
01269 
01270     while (b - a > 1) {
01271         m = (a + b) >> 1;
01272         timestamp = entries[m].timestamp;
01273         if(timestamp >= wanted_timestamp)
01274             b = m;
01275         if(timestamp <= wanted_timestamp)
01276             a = m;
01277     }
01278     m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
01279 
01280     if(!(flags & AVSEEK_FLAG_ANY)){
01281         while(m>=0 && m<nb_entries && !(entries[m].flags & AVINDEX_KEYFRAME)){
01282             m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
01283         }
01284     }
01285 
01286     if(m == nb_entries)
01287         return -1;
01288     return  m;
01289 }
01290 
01291 #define DEBUG_SEEK
01292 
01293 int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
01294     AVInputFormat *avif= s->iformat;
01295     int64_t pos_min, pos_max, pos, pos_limit;
01296     int64_t ts_min, ts_max, ts;
01297     int index;
01298     AVStream *st;
01299 
01300     if (stream_index < 0)
01301         return -1;
01302 
01303 #ifdef DEBUG_SEEK
01304     av_log(s, AV_LOG_DEBUG, "read_seek: %d %"PRId64"\n", stream_index, target_ts);
01305 #endif
01306 
01307     ts_max=
01308     ts_min= AV_NOPTS_VALUE;
01309     pos_limit= -1; //gcc falsely says it may be uninitialized
01310 
01311     st= s->streams[stream_index];
01312     if(st->index_entries){
01313         AVIndexEntry *e;
01314 
01315         index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non-keyframe entries in index case, especially read_timestamp()
01316         index= FFMAX(index, 0);
01317         e= &st->index_entries[index];
01318 
01319         if(e->timestamp <= target_ts || e->pos == e->min_distance){
01320             pos_min= e->pos;
01321             ts_min= e->timestamp;
01322 #ifdef DEBUG_SEEK
01323         av_log(s, AV_LOG_DEBUG, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",
01324                pos_min,ts_min);
01325 #endif
01326         }else{
01327             assert(index==0);
01328         }
01329 
01330         index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD);
01331         assert(index < st->nb_index_entries);
01332         if(index >= 0){
01333             e= &st->index_entries[index];
01334             assert(e->timestamp >= target_ts);
01335             pos_max= e->pos;
01336             ts_max= e->timestamp;
01337             pos_limit= pos_max - e->min_distance;
01338 #ifdef DEBUG_SEEK
01339         av_log(s, AV_LOG_DEBUG, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",
01340                pos_max,pos_limit, ts_max);
01341 #endif
01342         }
01343     }
01344 
01345     pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp);
01346     if(pos<0)
01347         return -1;
01348 
01349     /* do the seek */
01350     url_fseek(s->pb, pos, SEEK_SET);
01351 
01352     av_update_cur_dts(s, st, ts);
01353 
01354     return 0;
01355 }
01356 
01357 int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){
01358     int64_t pos, ts;
01359     int64_t start_pos, filesize;
01360     int no_change;
01361 
01362 #ifdef DEBUG_SEEK
01363     av_log(s, AV_LOG_DEBUG, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
01364 #endif
01365 
01366     if(ts_min == AV_NOPTS_VALUE){
01367         pos_min = s->data_offset;
01368         ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
01369         if (ts_min == AV_NOPTS_VALUE)
01370             return -1;
01371     }
01372 
01373     if(ts_max == AV_NOPTS_VALUE){
01374         int step= 1024;
01375         filesize = url_fsize(s->pb);
01376         pos_max = filesize - 1;
01377         do{
01378             pos_max -= step;
01379             ts_max = read_timestamp(s, stream_index, &pos_max, pos_max + step);
01380             step += step;
01381         }while(ts_max == AV_NOPTS_VALUE && pos_max >= step);
01382         if (ts_max == AV_NOPTS_VALUE)
01383             return -1;
01384 
01385         for(;;){
01386             int64_t tmp_pos= pos_max + 1;
01387             int64_t tmp_ts= read_timestamp(s, stream_index, &tmp_pos, INT64_MAX);
01388             if(tmp_ts == AV_NOPTS_VALUE)
01389                 break;
01390             ts_max= tmp_ts;
01391             pos_max= tmp_pos;
01392             if(tmp_pos >= filesize)
01393                 break;
01394         }
01395         pos_limit= pos_max;
01396     }
01397 
01398     if(ts_min > ts_max){
01399         return -1;
01400     }else if(ts_min == ts_max){
01401         pos_limit= pos_min;
01402     }
01403 
01404     no_change=0;
01405     while (pos_min < pos_limit) {
01406 #ifdef DEBUG_SEEK
01407         av_log(s, AV_LOG_DEBUG, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",
01408                pos_min, pos_max,
01409                ts_min, ts_max);
01410 #endif
01411         assert(pos_limit <= pos_max);
01412 
01413         if(no_change==0){
01414             int64_t approximate_keyframe_distance= pos_max - pos_limit;
01415             // interpolate position (better than dichotomy)
01416             pos = av_rescale(target_ts - ts_min, pos_max - pos_min, ts_max - ts_min)
01417                 + pos_min - approximate_keyframe_distance;
01418         }else if(no_change==1){
01419             // bisection, if interpolation failed to change min or max pos last time
01420             pos = (pos_min + pos_limit)>>1;
01421         }else{
01422             /* linear search if bisection failed, can only happen if there
01423                are very few or no keyframes between min/max */
01424             pos=pos_min;
01425         }
01426         if(pos <= pos_min)
01427             pos= pos_min + 1;
01428         else if(pos > pos_limit)
01429             pos= pos_limit;
01430         start_pos= pos;
01431 
01432         ts = read_timestamp(s, stream_index, &pos, INT64_MAX); //may pass pos_limit instead of -1
01433         if(pos == pos_max)
01434             no_change++;
01435         else
01436             no_change=0;
01437 #ifdef DEBUG_SEEK
01438 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);
01439 #endif
01440         if(ts == AV_NOPTS_VALUE){
01441             av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
01442             return -1;
01443         }
01444         assert(ts != AV_NOPTS_VALUE);
01445         if (target_ts <= ts) {
01446             pos_limit = start_pos - 1;
01447             pos_max = pos;
01448             ts_max = ts;
01449         }
01450         if (target_ts >= ts) {
01451             pos_min = pos;
01452             ts_min = ts;
01453         }
01454     }
01455 
01456     pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
01457     ts  = (flags & AVSEEK_FLAG_BACKWARD) ?  ts_min :  ts_max;
01458 #ifdef DEBUG_SEEK
01459     pos_min = pos;
01460     ts_min = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
01461     pos_min++;
01462     ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
01463     av_log(s, AV_LOG_DEBUG, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
01464            pos, ts_min, target_ts, ts_max);
01465 #endif
01466     *ts_ret= ts;
01467     return pos;
01468 }
01469 
01470 static int av_seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){
01471     int64_t pos_min, pos_max;
01472 #if 0
01473     AVStream *st;
01474 
01475     if (stream_index < 0)
01476         return -1;
01477 
01478     st= s->streams[stream_index];
01479 #endif
01480 
01481     pos_min = s->data_offset;
01482     pos_max = url_fsize(s->pb) - 1;
01483 
01484     if     (pos < pos_min) pos= pos_min;
01485     else if(pos > pos_max) pos= pos_max;
01486 
01487     url_fseek(s->pb, pos, SEEK_SET);
01488 
01489 #if 0
01490     av_update_cur_dts(s, st, ts);
01491 #endif
01492     return 0;
01493 }
01494 
01495 static int av_seek_frame_generic(AVFormatContext *s,
01496                                  int stream_index, int64_t timestamp, int flags)
01497 {
01498     int index, ret;
01499     AVStream *st;
01500     AVIndexEntry *ie;
01501 
01502     st = s->streams[stream_index];
01503 
01504     index = av_index_search_timestamp(st, timestamp, flags);
01505 
01506     if(index < 0 || index==st->nb_index_entries-1){
01507         int i;
01508         AVPacket pkt;
01509 
01510         if(st->nb_index_entries){
01511             assert(st->index_entries);
01512             ie= &st->index_entries[st->nb_index_entries-1];
01513             if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0)
01514                 return ret;
01515             av_update_cur_dts(s, st, ie->timestamp);
01516         }else{
01517             if ((ret = url_fseek(s->pb, 0, SEEK_SET)) < 0)
01518                 return ret;
01519         }
01520         for(i=0;; i++) {
01521             int ret = av_read_frame(s, &pkt);
01522             if(ret<0)
01523                 break;
01524             av_free_packet(&pkt);
01525             if(stream_index == pkt.stream_index){
01526                 if((pkt.flags & PKT_FLAG_KEY) && pkt.dts > timestamp)
01527                     break;
01528             }
01529         }
01530         index = av_index_search_timestamp(st, timestamp, flags);
01531     }
01532     if (index < 0)
01533         return -1;
01534 
01535     av_read_frame_flush(s);
01536     if (s->iformat->read_seek){
01537         if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
01538             return 0;
01539     }
01540     ie = &st->index_entries[index];
01541     if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0)
01542         return ret;
01543     av_update_cur_dts(s, st, ie->timestamp);
01544 
01545     return 0;
01546 }
01547 
01548 int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
01549 {
01550     int ret;
01551     AVStream *st;
01552 
01553     av_read_frame_flush(s);
01554 
01555     if(flags & AVSEEK_FLAG_BYTE)
01556         return av_seek_frame_byte(s, stream_index, timestamp, flags);
01557 
01558     if(stream_index < 0){
01559         stream_index= av_find_default_stream_index(s);
01560         if(stream_index < 0)
01561             return -1;
01562 
01563         st= s->streams[stream_index];
01564        /* timestamp for default must be expressed in AV_TIME_BASE units */
01565         timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
01566     }
01567 
01568     /* first, we try the format specific seek */
01569     if (s->iformat->read_seek)
01570         ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
01571     else
01572         ret = -1;
01573     if (ret >= 0) {
01574         return 0;
01575     }
01576 
01577     if(s->iformat->read_timestamp)
01578         return av_seek_frame_binary(s, stream_index, timestamp, flags);
01579     else
01580         return av_seek_frame_generic(s, stream_index, timestamp, flags);
01581 }
01582 
01583 /*******************************************************/
01584 
01590 static int av_has_duration(AVFormatContext *ic)
01591 {
01592     int i;
01593     AVStream *st;
01594 
01595     for(i = 0;i < ic->nb_streams; i++) {
01596         st = ic->streams[i];
01597         if (st->duration != AV_NOPTS_VALUE)
01598             return 1;
01599     }
01600     return 0;
01601 }
01602 
01608 static void av_update_stream_timings(AVFormatContext *ic)
01609 {
01610     int64_t start_time, start_time1, end_time, end_time1;
01611     int64_t duration, duration1;
01612     int i;
01613     AVStream *st;
01614 
01615     start_time = INT64_MAX;
01616     end_time = INT64_MIN;
01617     duration = INT64_MIN;
01618     for(i = 0;i < ic->nb_streams; i++) {
01619         st = ic->streams[i];
01620         if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
01621             start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
01622             if (start_time1 < start_time)
01623                 start_time = start_time1;
01624             if (st->duration != AV_NOPTS_VALUE) {
01625                 end_time1 = start_time1
01626                           + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
01627                 if (end_time1 > end_time)
01628                     end_time = end_time1;
01629             }
01630         }
01631         if (st->duration != AV_NOPTS_VALUE) {
01632             duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
01633             if (duration1 > duration)
01634                 duration = duration1;
01635         }
01636     }
01637     if (start_time != INT64_MAX) {
01638         ic->start_time = start_time;
01639         if (end_time != INT64_MIN) {
01640             if (end_time - start_time > duration)
01641                 duration = end_time - start_time;
01642         }
01643     }
01644     if (duration != INT64_MIN) {
01645         ic->duration = duration;
01646         if (ic->file_size > 0) {
01647             /* compute the bitrate */
01648             ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
01649                 (double)ic->duration;
01650         }
01651     }
01652 }
01653 
01654 static void fill_all_stream_timings(AVFormatContext *ic)
01655 {
01656     int i;
01657     AVStream *st;
01658 
01659     av_update_stream_timings(ic);
01660     for(i = 0;i < ic->nb_streams; i++) {
01661         st = ic->streams[i];
01662         if (st->start_time == AV_NOPTS_VALUE) {
01663             if(ic->start_time != AV_NOPTS_VALUE)
01664                 st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base);
01665             if(ic->duration != AV_NOPTS_VALUE)
01666                 st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base);
01667         }
01668     }
01669 }
01670 
01671 static void av_estimate_timings_from_bit_rate(AVFormatContext *ic)
01672 {
01673     int64_t filesize, duration;
01674     int bit_rate, i;
01675     AVStream *st;
01676 
01677     /* if bit_rate is already set, we believe it */
01678     if (ic->bit_rate == 0) {
01679         bit_rate = 0;
01680         for(i=0;i<ic->nb_streams;i++) {
01681             st = ic->streams[i];
01682             bit_rate += st->codec->bit_rate;
01683         }
01684         ic->bit_rate = bit_rate;
01685     }
01686 
01687     /* if duration is already set, we believe it */
01688     if (ic->duration == AV_NOPTS_VALUE &&
01689         ic->bit_rate != 0 &&
01690         ic->file_size != 0)  {
01691         filesize = ic->file_size;
01692         if (filesize > 0) {
01693             for(i = 0; i < ic->nb_streams; i++) {
01694                 st = ic->streams[i];
01695                 duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num);
01696                 if (st->duration == AV_NOPTS_VALUE)
01697                     st->duration = duration;
01698             }
01699         }
01700     }
01701 }
01702 
01703 #define DURATION_MAX_READ_SIZE 250000
01704 
01705 /* only usable for MPEG-PS streams */
01706 static void av_estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
01707 {
01708     AVPacket pkt1, *pkt = &pkt1;
01709     AVStream *st;
01710     int read_size, i, ret;
01711     int64_t end_time;
01712     int64_t filesize, offset, duration;
01713 
01714     ic->cur_st = NULL;
01715 
01716     /* flush packet queue */
01717     flush_packet_queue(ic);
01718 
01719     for(i=0;i<ic->nb_streams;i++) {
01720         st = ic->streams[i];
01721         if (st->parser) {
01722             av_parser_close(st->parser);
01723             st->parser= NULL;
01724             av_free_packet(&st->cur_pkt);
01725         }
01726     }
01727 
01728     /* we read the first packets to get the first PTS (not fully
01729        accurate, but it is enough now) */
01730     url_fseek(ic->pb, 0, SEEK_SET);
01731     read_size = 0;
01732     for(;;) {
01733         if (read_size >= DURATION_MAX_READ_SIZE)
01734             break;
01735         /* if all info is available, we can stop */
01736         for(i = 0;i < ic->nb_streams; i++) {
01737             st = ic->streams[i];
01738             if (st->start_time == AV_NOPTS_VALUE)
01739                 break;
01740         }
01741         if (i == ic->nb_streams)
01742             break;
01743 
01744         ret = av_read_packet(ic, pkt);
01745         if (ret != 0)
01746             break;
01747         read_size += pkt->size;
01748         st = ic->streams[pkt->stream_index];
01749         if (pkt->pts != AV_NOPTS_VALUE) {
01750             if (st->start_time == AV_NOPTS_VALUE)
01751                 st->start_time = pkt->pts;
01752         }
01753         av_free_packet(pkt);
01754     }
01755 
01756     /* estimate the end time (duration) */
01757     /* XXX: may need to support wrapping */
01758     filesize = ic->file_size;
01759     offset = filesize - DURATION_MAX_READ_SIZE;
01760     if (offset < 0)
01761         offset = 0;
01762 
01763     url_fseek(ic->pb, offset, SEEK_SET);
01764     read_size = 0;
01765     for(;;) {
01766         if (read_size >= DURATION_MAX_READ_SIZE)
01767             break;
01768 
01769         ret = av_read_packet(ic, pkt);
01770         if (ret != 0)
01771             break;
01772         read_size += pkt->size;
01773         st = ic->streams[pkt->stream_index];
01774         if (pkt->pts != AV_NOPTS_VALUE &&
01775             st->start_time != AV_NOPTS_VALUE) {
01776             end_time = pkt->pts;
01777             duration = end_time - st->start_time;
01778             if (duration > 0) {
01779                 if (st->duration == AV_NOPTS_VALUE ||
01780                     st->duration < duration)
01781                     st->duration = duration;
01782             }
01783         }
01784         av_free_packet(pkt);
01785     }
01786 
01787     fill_all_stream_timings(ic);
01788 
01789     url_fseek(ic->pb, old_offset, SEEK_SET);
01790     for(i=0; i<ic->nb_streams; i++){
01791         st= ic->streams[i];
01792         st->cur_dts= st->first_dts;
01793         st->last_IP_pts = AV_NOPTS_VALUE;
01794     }
01795 }
01796 
01797 static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
01798 {
01799     int64_t file_size;
01800 
01801     /* get the file size, if possible */
01802     if (ic->iformat->flags & AVFMT_NOFILE) {
01803         file_size = 0;
01804     } else {
01805         file_size = url_fsize(ic->pb);
01806         if (file_size < 0)
01807             file_size = 0;
01808     }
01809     ic->file_size = file_size;
01810 
01811     if ((!strcmp(ic->iformat->name, "mpeg") ||
01812          !strcmp(ic->iformat->name, "mpegts")) &&
01813         file_size && !url_is_streamed(ic->pb)) {
01814         /* get accurate estimate from the PTSes */
01815         av_estimate_timings_from_pts(ic, old_offset);
01816     } else if (av_has_duration(ic)) {
01817         /* at least one component has timings - we use them for all
01818            the components */
01819         fill_all_stream_timings(ic);
01820     } else {
01821         /* less precise: use bitrate info */
01822         av_estimate_timings_from_bit_rate(ic);
01823     }
01824     av_update_stream_timings(ic);
01825 
01826 #if 0
01827     {
01828         int i;
01829         AVStream *st;
01830         for(i = 0;i < ic->nb_streams; i++) {
01831             st = ic->streams[i];
01832         printf("%d: start_time: %0.3f duration: %0.3f\n",
01833                i, (double)st->start_time / AV_TIME_BASE,
01834                (double)st->duration / AV_TIME_BASE);
01835         }
01836         printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",
01837                (double)ic->start_time / AV_TIME_BASE,
01838                (double)ic->duration / AV_TIME_BASE,
01839                ic->bit_rate / 1000);
01840     }
01841 #endif
01842 }
01843 
01844 static int has_codec_parameters(AVCodecContext *enc)
01845 {
01846     int val;
01847     switch(enc->codec_type) {
01848     case CODEC_TYPE_AUDIO:
01849         val = enc->sample_rate && enc->channels && enc->sample_fmt != SAMPLE_FMT_NONE;
01850         if(!enc->frame_size &&
01851            (enc->codec_id == CODEC_ID_VORBIS ||
01852             enc->codec_id == CODEC_ID_AAC))
01853             return 0;
01854         break;
01855     case CODEC_TYPE_VIDEO:
01856         val = enc->width && enc->pix_fmt != PIX_FMT_NONE;
01857         break;
01858     default:
01859         val = 1;
01860         break;
01861     }
01862     return enc->codec_id != CODEC_ID_NONE && val != 0;
01863 }
01864 
01865 static int try_decode_frame(AVStream *st, const uint8_t *data, int size)
01866 {
01867     int16_t *samples;
01868     AVCodec *codec;
01869     int got_picture, data_size, ret=0;
01870     AVFrame picture;
01871 
01872   if(!st->codec->codec){
01873     codec = avcodec_find_decoder(st->codec->codec_id);
01874     if (!codec)
01875         return -1;
01876     ret = avcodec_open(st->codec, codec);
01877     if (ret < 0)
01878         return ret;
01879   }
01880 
01881   if(!has_codec_parameters(st->codec)){
01882     switch(st->codec->codec_type) {
01883     case CODEC_TYPE_VIDEO:
01884         ret = avcodec_decode_video(st->codec, &picture,
01885                                    &got_picture, data, size);
01886         break;
01887     case CODEC_TYPE_AUDIO:
01888         data_size = FFMAX(size, AVCODEC_MAX_AUDIO_FRAME_SIZE);
01889         samples = av_malloc(data_size);
01890         if (!samples)
01891             goto fail;
01892         ret = avcodec_decode_audio2(st->codec, samples,
01893                                     &data_size, data, size);
01894         av_free(samples);
01895         break;
01896     default:
01897         break;
01898     }
01899   }
01900  fail:
01901     return ret;
01902 }
01903 
01904 unsigned int codec_get_tag(const AVCodecTag *tags, int id)
01905 {
01906     while (tags->id != CODEC_ID_NONE) {
01907         if (tags->id == id)
01908             return tags->tag;
01909         tags++;
01910     }
01911     return 0;
01912 }
01913 
01914 enum CodecID codec_get_id(const AVCodecTag *tags, unsigned int tag)
01915 {
01916     int i;
01917     for(i=0; tags[i].id != CODEC_ID_NONE;i++) {
01918         if(tag == tags[i].tag)
01919             return tags[i].id;
01920     }
01921     for(i=0; tags[i].id != CODEC_ID_NONE; i++) {
01922         if(   toupper((tag >> 0)&0xFF) == toupper((tags[i].tag >> 0)&0xFF)
01923            && toupper((tag >> 8)&0xFF) == toupper((tags[i].tag >> 8)&0xFF)
01924            && toupper((tag >>16)&0xFF) == toupper((tags[i].tag >>16)&0xFF)
01925            && toupper((tag >>24)&0xFF) == toupper((tags[i].tag >>24)&0xFF))
01926             return tags[i].id;
01927     }
01928     return CODEC_ID_NONE;
01929 }
01930 
01931 unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum CodecID id)
01932 {
01933     int i;
01934     for(i=0; tags && tags[i]; i++){
01935         int tag= codec_get_tag(tags[i], id);
01936         if(tag) return tag;
01937     }
01938     return 0;
01939 }
01940 
01941 enum CodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag)
01942 {
01943     int i;
01944     for(i=0; tags && tags[i]; i++){
01945         enum CodecID id= codec_get_id(tags[i], tag);
01946         if(id!=CODEC_ID_NONE) return id;
01947     }
01948     return CODEC_ID_NONE;
01949 }
01950 
01951 static void compute_chapters_end(AVFormatContext *s)
01952 {
01953     unsigned int i;
01954 
01955     for (i=0; i+1<s->nb_chapters; i++)
01956         if (s->chapters[i]->end == AV_NOPTS_VALUE) {
01957             assert(s->chapters[i]->start <= s->chapters[i+1]->start);
01958             assert(!av_cmp_q(s->chapters[i]->time_base, s->chapters[i+1]->time_base));
01959             s->chapters[i]->end = s->chapters[i+1]->start;
01960         }
01961 
01962     if (s->nb_chapters && s->chapters[i]->end == AV_NOPTS_VALUE) {
01963         assert(s->start_time != AV_NOPTS_VALUE);
01964         assert(s->duration > 0);
01965         s->chapters[i]->end = av_rescale_q(s->start_time + s->duration,
01966                                            AV_TIME_BASE_Q,
01967                                            s->chapters[i]->time_base);
01968     }
01969 }
01970 
01971 /* absolute maximum size we read until we abort */
01972 #define MAX_READ_SIZE        5000000
01973 
01974 #define MAX_STD_TIMEBASES (60*12+5)
01975 static int get_std_framerate(int i){
01976     if(i<60*12) return i*1001;
01977     else        return ((const int[]){24,30,60,12,15})[i-60*12]*1000*12;
01978 }
01979 
01980 /*
01981  * Is the time base unreliable.
01982  * This is a heuristic to balance between quick acceptance of the values in
01983  * the headers vs. some extra checks.
01984  * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps.
01985  * MPEG-2 commonly misuses field repeat flags to store different framerates.
01986  * And there are "variable" fps files this needs to detect as well.
01987  */
01988 static int tb_unreliable(AVCodecContext *c){
01989     if(   c->time_base.den >= 101L*c->time_base.num
01990        || c->time_base.den <    5L*c->time_base.num
01991 /*       || c->codec_tag == AV_RL32("DIVX")
01992        || c->codec_tag == AV_RL32("XVID")*/
01993        || c->codec_id == CODEC_ID_MPEG2VIDEO
01994        || c->codec_id == CODEC_ID_H264
01995        )
01996         return 1;
01997     return 0;
01998 }
01999 
02000 int av_find_stream_info(AVFormatContext *ic)
02001 {
02002     int i, count, ret, read_size, j;
02003     AVStream *st;
02004     AVPacket pkt1, *pkt;
02005     int64_t last_dts[MAX_STREAMS];
02006     int64_t duration_gcd[MAX_STREAMS]={0};
02007     int duration_count[MAX_STREAMS]={0};
02008     double (*duration_error)[MAX_STD_TIMEBASES];
02009     int64_t old_offset = url_ftell(ic->pb);
02010     int64_t codec_info_duration[MAX_STREAMS]={0};
02011     int codec_info_nb_frames[MAX_STREAMS]={0};
02012 
02013     duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
02014     if (!duration_error) return AVERROR(ENOMEM);
02015 
02016     for(i=0;i<ic->nb_streams;i++) {
02017         st = ic->streams[i];
02018         if(st->codec->codec_type == CODEC_TYPE_VIDEO){
02019 /*            if(!st->time_base.num)
02020                 st->time_base= */
02021             if(!st->codec->time_base.num)
02022                 st->codec->time_base= st->time_base;
02023         }
02024         //only for the split stuff
02025         if (!st->parser) {
02026             st->parser = av_parser_init(st->codec->codec_id);
02027             if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){
02028                 st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
02029             }
02030         }
02031     }
02032 
02033     for(i=0;i<MAX_STREAMS;i++){
02034         last_dts[i]= AV_NOPTS_VALUE;
02035     }
02036 
02037     count = 0;
02038     read_size = 0;
02039     for(;;) {
02040         if(url_interrupt_cb()){
02041             ret= AVERROR(EINTR);
02042             break;
02043         }
02044 
02045         /* check if one codec still needs to be handled */
02046         for(i=0;i<ic->nb_streams;i++) {
02047             st = ic->streams[i];
02048             if (!has_codec_parameters(st->codec))
02049                 break;
02050             /* variable fps and no guess at the real fps */
02051             if(   tb_unreliable(st->codec)
02052                && duration_count[i]<20 && st->codec->codec_type == CODEC_TYPE_VIDEO)
02053                 break;
02054             if(st->parser && st->parser->parser->split && !st->codec->extradata)
02055                 break;
02056             if(st->first_dts == AV_NOPTS_VALUE)
02057                 break;
02058         }
02059         if (i == ic->nb_streams) {
02060             /* NOTE: if the format has no header, then we need to read
02061                some packets to get most of the streams, so we cannot
02062                stop here */
02063             if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
02064                 /* if we found the info for all the codecs, we can stop */
02065                 ret = count;
02066                 break;
02067             }
02068         }
02069         /* we did not get all the codec info, but we read too much data */
02070         if (read_size >= MAX_READ_SIZE) {
02071             ret = count;
02072             break;
02073         }
02074 
02075         /* NOTE: a new stream can be added there if no header in file
02076            (AVFMTCTX_NOHEADER) */
02077         ret = av_read_frame_internal(ic, &pkt1);
02078         if (ret < 0) {
02079             /* EOF or error */
02080             ret = -1; /* we could not have all the codec parameters before EOF */
02081             for(i=0;i<ic->nb_streams;i++) {
02082                 st = ic->streams[i];
02083                 if (!has_codec_parameters(st->codec)){
02084                     char buf[256];
02085                     avcodec_string(buf, sizeof(buf), st->codec, 0);
02086                     av_log(ic, AV_LOG_INFO, "Could not find codec parameters (%s)\n", buf);
02087                 } else {
02088                     ret = 0;
02089                 }
02090             }
02091             break;
02092         }
02093 
02094         pkt= add_to_pktbuf(&ic->packet_buffer, &pkt1, &ic->packet_buffer_end);
02095         if(av_dup_packet(pkt) < 0) {
02096             av_free(duration_error);
02097             return AVERROR(ENOMEM);
02098         }
02099 
02100         read_size += pkt->size;
02101 
02102         st = ic->streams[pkt->stream_index];
02103         if(codec_info_nb_frames[st->index]>1)
02104             codec_info_duration[st->index] += pkt->duration;
02105         if (pkt->duration != 0)
02106             codec_info_nb_frames[st->index]++;
02107 
02108         {
02109             int index= pkt->stream_index;
02110             int64_t last= last_dts[index];
02111             int64_t duration= pkt->dts - last;
02112 
02113             if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
02114                 double dur= duration * av_q2d(st->time_base);
02115 
02116 //                if(st->codec->codec_type == CODEC_TYPE_VIDEO)
02117 //                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
02118                 if(duration_count[index] < 2)
02119                     memset(duration_error[index], 0, sizeof(*duration_error));
02120                 for(i=1; i<MAX_STD_TIMEBASES; i++){
02121                     int framerate= get_std_framerate(i);
02122                     int ticks= lrintf(dur*framerate/(1001*12));
02123                     double error= dur - ticks*1001*12/(double)framerate;
02124                     duration_error[index][i] += error*error;
02125                 }
02126                 duration_count[index]++;
02127                 // ignore the first 4 values, they might have some random jitter
02128                 if (duration_count[index] > 3)
02129                     duration_gcd[index] = av_gcd(duration_gcd[index], duration);
02130             }
02131             if(last == AV_NOPTS_VALUE || duration_count[index]<=1)
02132                 last_dts[pkt->stream_index]= pkt->dts;
02133         }
02134         if(st->parser && st->parser->parser->split && !st->codec->extradata){
02135             int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
02136             if(i){
02137                 st->codec->extradata_size= i;
02138                 st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
02139                 memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);
02140                 memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
02141             }
02142         }
02143 
02144         /* if still no information, we try to open the codec and to
02145            decompress the frame. We try to avoid that in most cases as
02146            it takes longer and uses more memory. For MPEG-4, we need to
02147            decompress for QuickTime. */
02148         if (!has_codec_parameters(st->codec) /*&&
02149             (st->codec->codec_id == CODEC_ID_FLV1 ||
02150              st->codec->codec_id == CODEC_ID_H264 ||
02151              st->codec->codec_id == CODEC_ID_H263 ||
02152              st->codec->codec_id == CODEC_ID_H261 ||
02153              st->codec->codec_id == CODEC_ID_VORBIS ||
02154              st->codec->codec_id == CODEC_ID_MJPEG ||
02155              st->codec->codec_id == CODEC_ID_PNG ||
02156              st->codec->codec_id == CODEC_ID_PAM ||
02157              st->codec->codec_id == CODEC_ID_PGM ||
02158              st->codec->codec_id == CODEC_ID_PGMYUV ||
02159              st->codec->codec_id == CODEC_ID_PBM ||
02160              st->codec->codec_id == CODEC_ID_PPM ||
02161              st->codec->codec_id == CODEC_ID_SHORTEN ||
02162              (st->codec->codec_id == CODEC_ID_MPEG4 && !st->need_parsing))*/)
02163             try_decode_frame(st, pkt->data, pkt->size);
02164 
02165         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) {
02166             break;
02167         }
02168         count++;
02169     }
02170 
02171     // close codecs which were opened in try_decode_frame()
02172     for(i=0;i<ic->nb_streams;i++) {
02173         st = ic->streams[i];
02174         if(st->codec->codec)
02175             avcodec_close(st->codec);
02176     }
02177     for(i=0;i<ic->nb_streams;i++) {
02178         st = ic->streams[i];
02179         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
02180             if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
02181                 st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
02182 
02183             // the check for tb_unreliable() is not completely correct, since this is not about handling
02184             // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
02185             // ipmovie.c produces.
02186             if (tb_unreliable(st->codec) && duration_count[i] > 15 && duration_gcd[i] > 1)
02187                 av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * duration_gcd[i], INT_MAX);
02188             if(duration_count[i]
02189                && tb_unreliable(st->codec) /*&&
02190                //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
02191                st->time_base.num*duration_sum[i]/duration_count[i]*101LL > st->time_base.den*/){
02192                 int num = 0;
02193                 double best_error= 2*av_q2d(st->time_base);
02194                 best_error= best_error*best_error*duration_count[i]*1000*12*30;
02195 
02196                 for(j=1; j<MAX_STD_TIMEBASES; j++){
02197                     double error= duration_error[i][j] * get_std_framerate(j);
02198 //                    if(st->codec->codec_type == CODEC_TYPE_VIDEO)
02199 //                        av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
02200                     if(error < best_error){
02201                         best_error= error;
02202                         num = get_std_framerate(j);
02203                     }
02204                 }
02205                 // do not increase frame rate by more than 1 % in order to match a standard rate.
02206                 if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))
02207                     av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);
02208             }
02209 
02210             if (!st->r_frame_rate.num){
02211                 if(    st->codec->time_base.den * (int64_t)st->time_base.num
02212                     <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){
02213                     st->r_frame_rate.num = st->codec->time_base.den;
02214                     st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame;
02215                 }else{
02216                     st->r_frame_rate.num = st->time_base.den;
02217                     st->r_frame_rate.den = st->time_base.num;
02218                 }
02219             }
02220         }else if(st->codec->codec_type == CODEC_TYPE_AUDIO) {
02221             if(!st->codec->bits_per_coded_sample)
02222                 st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);
02223         }
02224     }
02225 
02226     av_estimate_timings(ic, old_offset);
02227 
02228     compute_chapters_end(ic);
02229 
02230 #if 0
02231     /* correct DTS for B-frame streams with no timestamps */
02232     for(i=0;i<ic->nb_streams;i++) {
02233         st = ic->streams[i];
02234         if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
02235             if(b-frames){
02236                 ppktl = &ic->packet_buffer;
02237                 while(ppkt1){
02238                     if(ppkt1->stream_index != i)
02239                         continue;
02240                     if(ppkt1->pkt->dts < 0)
02241                         break;
02242                     if(ppkt1->pkt->pts != AV_NOPTS_VALUE)
02243                         break;
02244                     ppkt1->pkt->dts -= delta;
02245                     ppkt1= ppkt1->next;
02246                 }
02247                 if(ppkt1)
02248                     continue;
02249                 st->cur_dts -= delta;
02250             }
02251         }
02252     }
02253 #endif
02254 
02255     av_free(duration_error);
02256 
02257     return ret;
02258 }
02259 
02260 /*******************************************************/
02261 
02262 int av_read_play(AVFormatContext *s)
02263 {
02264     if (s->iformat->read_play)
02265         return s->iformat->read_play(s);
02266     if (s->pb)
02267         return av_url_read_fpause(s->pb, 0);
02268     return AVERROR(ENOSYS);
02269 }
02270 
02271 int av_read_pause(AVFormatContext *s)
02272 {
02273     if (s->iformat->read_pause)
02274         return s->iformat->read_pause(s);
02275     if (s->pb)
02276         return av_url_read_fpause(s->pb, 1);
02277     return AVERROR(ENOSYS);
02278 }
02279 
02280 void av_close_input_stream(AVFormatContext *s)
02281 {
02282     int i;
02283     AVStream *st;
02284 
02285     if (s->iformat->read_close)
02286         s->iformat->read_close(s);
02287     for(i=0;i<s->nb_streams;i++) {
02288         /* free all data in a stream component */
02289         st = s->streams[i];
02290         if (st->parser) {
02291             av_parser_close(st->parser);
02292             av_free_packet(&st->cur_pkt);
02293         }
02294         av_metadata_free(&st->metadata);
02295         av_free(st->index_entries);
02296         av_free(st->codec->extradata);
02297         av_free(st->codec);
02298 #if LIBAVFORMAT_VERSION_INT < (53<<16)
02299         av_free(st->filename);
02300 #endif
02301         av_free(st->priv_data);
02302         av_free(st);
02303     }
02304     for(i=s->nb_programs-1; i>=0; i--) {
02305 #if LIBAVFORMAT_VERSION_INT < (53<<16)
02306         av_freep(&s->programs[i]->provider_name);
02307         av_freep(&s->programs[i]->name);
02308 #endif
02309         av_metadata_free(&s->programs[i]->metadata);
02310         av_freep(&s->programs[i]->stream_index);
02311         av_freep(&s->programs[i]);
02312     }
02313     av_freep(&s->programs);
02314     flush_packet_queue(s);
02315     av_freep(&s->priv_data);
02316     while(s->nb_chapters--) {
02317 #if LIBAVFORMAT_VERSION_INT < (53<<16)
02318         av_free(s->chapters[s->nb_chapters]->title);
02319 #endif
02320         av_metadata_free(&s->chapters[s->nb_chapters]->metadata);
02321         av_free(s->chapters[s->nb_chapters]);
02322     }
02323     av_freep(&s->chapters);
02324     av_metadata_free(&s->metadata);
02325     av_free(s);
02326 }
02327 
02328 void av_close_input_file(AVFormatContext *s)
02329 {
02330     ByteIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb;
02331     av_close_input_stream(s);
02332     if (pb)
02333         url_fclose(pb);
02334 }
02335 
02336 AVStream *av_new_stream(AVFormatContext *s, int id)
02337 {
02338     AVStream *st;
02339     int i;
02340 
02341     if (s->nb_streams >= MAX_STREAMS)
02342         return NULL;
02343 
02344     st = av_mallocz(sizeof(AVStream));
02345     if (!st)
02346         return NULL;
02347 
02348     st->codec= avcodec_alloc_context();
02349     if (s->iformat) {
02350         /* no default bitrate if decoding */
02351         st->codec->bit_rate = 0;
02352     }
02353     st->index = s->nb_streams;
02354     st->id = id;
02355     st->start_time = AV_NOPTS_VALUE;
02356     st->duration = AV_NOPTS_VALUE;
02357         /* we set the current DTS to 0 so that formats without any timestamps
02358            but durations get some timestamps, formats with some unknown
02359            timestamps have their first few packets buffered and the
02360            timestamps corrected before they are returned to the user */
02361     st->cur_dts = 0;
02362     st->first_dts = AV_NOPTS_VALUE;
02363 
02364     /* default pts setting is MPEG-like */
02365     av_set_pts_info(st, 33, 1, 90000);
02366     st->last_IP_pts = AV_NOPTS_VALUE;
02367     for(i=0; i<MAX_REORDER_DELAY+1; i++)
02368         st->pts_buffer[i]= AV_NOPTS_VALUE;
02369     st->reference_dts = AV_NOPTS_VALUE;
02370 
02371     st->sample_aspect_ratio = (AVRational){0,1};
02372 
02373     s->streams[s->nb_streams++] = st;
02374     return st;
02375 }
02376 
02377 AVProgram *av_new_program(AVFormatContext *ac, int id)
02378 {
02379     AVProgram *program=NULL;
02380     int i;
02381 
02382 #ifdef DEBUG_SI
02383     av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id);
02384 #endif
02385 
02386     for(i=0; i<ac->nb_programs; i++)
02387         if(ac->programs[i]->id == id)
02388             program = ac->programs[i];
02389 
02390     if(!program){
02391         program = av_mallocz(sizeof(AVProgram));
02392         if (!program)
02393             return NULL;
02394         dynarray_add(&ac->programs, &ac->nb_programs, program);
02395         program->discard = AVDISCARD_NONE;
02396     }
02397     program->id = id;
02398 
02399     return program;
02400 }
02401 
02402 AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
02403 {
02404     AVChapter *chapter = NULL;
02405     int i;
02406 
02407     for(i=0; i<s->nb_chapters; i++)
02408         if(s->chapters[i]->id == id)
02409             chapter = s->chapters[i];
02410 
02411     if(!chapter){
02412         chapter= av_mallocz(sizeof(AVChapter));
02413         if(!chapter)
02414             return NULL;
02415         dynarray_add(&s->chapters, &s->nb_chapters, chapter);
02416     }
02417 #if LIBAVFORMAT_VERSION_INT < (53<<16)
02418     av_free(chapter->title);
02419 #endif
02420     av_metadata_set(&chapter->metadata, "title", title);
02421     chapter->id    = id;
02422     chapter->time_base= time_base;
02423     chapter->start = start;
02424     chapter->end   = end;
02425 
02426     return chapter;
02427 }
02428 
02429 /************************************************************/
02430 /* output media file */
02431 
02432 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
02433 {
02434     int ret;
02435 
02436     if (s->oformat->priv_data_size > 0) {
02437         s->priv_data = av_mallocz(s->oformat->priv_data_size);
02438         if (!s->priv_data)
02439             return AVERROR(ENOMEM);
02440     } else
02441         s->priv_data = NULL;
02442 
02443     if (s->oformat->set_parameters) {
02444         ret = s->oformat->set_parameters(s, ap);
02445         if (ret < 0)
02446             return ret;
02447     }
02448     return 0;
02449 }
02450 
02451 int av_write_header(AVFormatContext *s)
02452 {
02453     int ret, i;
02454     AVStream *st;
02455 
02456     // some sanity checks
02457     for(i=0;i<s->nb_streams;i++) {
02458         st = s->streams[i];
02459 
02460         switch (st->codec->codec_type) {
02461         case CODEC_TYPE_AUDIO:
02462             if(st->codec->sample_rate<=0){
02463                 av_log(s, AV_LOG_ERROR, "sample rate not set\n");
02464                 return -1;
02465             }
02466             if(!st->codec->block_align)
02467                 st->codec->block_align = st->codec->channels *
02468                     av_get_bits_per_sample(st->codec->codec_id) >> 3;
02469             break;
02470         case CODEC_TYPE_VIDEO:
02471             if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
02472                 av_log(s, AV_LOG_ERROR, "time base not set\n");
02473                 return -1;
02474             }
02475             if(st->codec->width<=0 || st->codec->height<=0){
02476                 av_log(s, AV_LOG_ERROR, "dimensions not set\n");
02477                 return -1;
02478             }
02479             if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
02480                 av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
02481                 return -1;
02482             }
02483             break;
02484         }
02485 
02486         if(s->oformat->codec_tag){
02487             if(st->codec->codec_tag){
02488                 //FIXME
02489                 //check that tag + id is in the table
02490                 //if neither is in the table -> OK
02491                 //if tag is in the table with another id -> FAIL
02492                 //if id is in the table with another tag -> FAIL unless strict < ?
02493             }else
02494                 st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
02495         }
02496 
02497         if(s->oformat->flags & AVFMT_GLOBALHEADER &&
02498             !(st->codec->flags & CODEC_FLAG_GLOBAL_HEADER))
02499           av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers but container format requires global headers\n", i);
02500     }
02501 
02502     if (!s->priv_data && s->oformat->priv_data_size > 0) {
02503         s->priv_data = av_mallocz(s->oformat->priv_data_size);
02504         if (!s->priv_data)
02505             return AVERROR(ENOMEM);
02506     }
02507 
02508 #if LIBAVFORMAT_VERSION_MAJOR < 53
02509     ff_metadata_mux_compat(s);
02510 #endif
02511 
02512     if(s->oformat->write_header){
02513         ret = s->oformat->write_header(s);
02514         if (ret < 0)
02515             return ret;
02516     }
02517 
02518     /* init PTS generation */
02519     for(i=0;i<s->nb_streams;i++) {
02520         int64_t den = AV_NOPTS_VALUE;
02521         st = s->streams[i];
02522 
02523         switch (st->codec->codec_type) {
02524         case CODEC_TYPE_AUDIO:
02525             den = (int64_t)st->time_base.num * st->codec->sample_rate;
02526             break;
02527         case CODEC_TYPE_VIDEO:
02528             den = (int64_t)st->time_base.num * st->codec->time_base.den;
02529             break;
02530         default:
02531             break;
02532         }
02533         if (den != AV_NOPTS_VALUE) {
02534             if (den <= 0)
02535                 return AVERROR_INVALIDDATA;
02536             av_frac_init(&st->pts, 0, 0, den);
02537         }
02538     }
02539     return 0;
02540 }
02541 
02542 //FIXME merge with compute_pkt_fields
02543 static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){
02544     int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
02545     int num, den, frame_size, i;
02546 
02547 //    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);
02548 
02549 /*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
02550         return -1;*/
02551 
02552     /* duration field */
02553     if (pkt->duration == 0) {
02554         compute_frame_duration(&num, &den, st, NULL, pkt);
02555         if (den && num) {
02556             pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num);
02557         }
02558     }
02559 
02560     if(pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay==0)
02561         pkt->pts= pkt->dts;
02562 
02563     //XXX/FIXME this is a temporary hack until all encoders output pts
02564     if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){
02565         pkt->dts=
02566 //        pkt->pts= st->cur_dts;
02567         pkt->pts= st->pts.val;
02568     }
02569 
02570     //calculate dts from pts
02571     if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){
02572         st->pts_buffer[0]= pkt->pts;
02573         for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
02574             st->pts_buffer[i]= (i-delay-1) * pkt->duration;
02575         for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
02576             FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
02577 
02578         pkt->dts= st->pts_buffer[0];
02579     }
02580 
02581     if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
02582         av_log(st->codec, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts);
02583         return -1;
02584     }
02585     if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
02586         av_log(st->codec, AV_LOG_ERROR, "error, pts < dts\n");
02587         return -1;
02588     }
02589 
02590 //    av_log(NULL, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts);
02591     st->cur_dts= pkt->dts;
02592     st->pts.val= pkt->dts;
02593 
02594     /* update pts */
02595     switch (st->codec->codec_type) {
02596     case CODEC_TYPE_AUDIO:
02597         frame_size = get_audio_frame_size(st->codec, pkt->size);
02598 
02599         /* HACK/FIXME, we skip the initial 0 size packets as they are most
02600            likely equal to the encoder delay, but it would be better if we
02601            had the real timestamps from the encoder */
02602         if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
02603             av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
02604         }
02605         break;
02606     case CODEC_TYPE_VIDEO:
02607         av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
02608         break;
02609     default:
02610         break;
02611     }
02612     return 0;
02613 }
02614 
02615 int av_write_frame(AVFormatContext *s, AVPacket *pkt)
02616 {
02617     int ret = compute_pkt_fields2(s->streams[pkt->stream_index], pkt);
02618 
02619     if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
02620         return ret;
02621 
02622     ret= s->oformat->write_packet(s, pkt);
02623     if(!ret)
02624         ret= url_ferror(s->pb);
02625     return ret;
02626 }
02627 
02628 void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
02629                               int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
02630 {
02631     AVPacketList **next_point, *this_pktl;
02632 
02633     this_pktl = av_mallocz(sizeof(AVPacketList));
02634     this_pktl->pkt= *pkt;
02635     if(pkt->destruct == av_destruct_packet)
02636         pkt->destruct= NULL; // not shared -> must keep original from being freed
02637     else
02638         av_dup_packet(&this_pktl->pkt);  //shared -> must dup
02639 
02640     next_point = &s->packet_buffer;
02641     while(*next_point){
02642         if(compare(s, &(*next_point)->pkt, pkt))
02643             break;
02644         next_point= &(*next_point)->next;
02645     }
02646     this_pktl->next= *next_point;
02647     *next_point= this_pktl;
02648 }
02649 
02650 int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
02651 {
02652     AVStream *st = s->streams[ pkt ->stream_index];
02653     AVStream *st2= s->streams[ next->stream_index];
02654     int64_t left = st2->time_base.num * (int64_t)st ->time_base.den;
02655     int64_t right= st ->time_base.num * (int64_t)st2->time_base.den;
02656 
02657     if (pkt->dts == AV_NOPTS_VALUE)
02658         return 0;
02659 
02660     return next->dts * left > pkt->dts * right; //FIXME this can overflow
02661 }
02662 
02663 int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
02664     AVPacketList *pktl;
02665     int stream_count=0;
02666     int streams[MAX_STREAMS];
02667 
02668     if(pkt){
02669         ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
02670     }
02671 
02672     memset(streams, 0, sizeof(streams));
02673     pktl= s->packet_buffer;
02674     while(pktl){
02675 //av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts);
02676         if(streams[ pktl->pkt.stream_index ] == 0)
02677             stream_count++;
02678         streams[ pktl->pkt.stream_index ]++;
02679         pktl= pktl->next;
02680     }
02681 
02682     if(stream_count && (s->nb_streams == stream_count || flush)){
02683         pktl= s->packet_buffer;
02684         *out= pktl->pkt;
02685 
02686         s->packet_buffer= pktl->next;
02687         av_freep(&pktl);
02688         return 1;
02689     }else{
02690         av_init_packet(out);
02691         return 0;
02692     }
02693 }
02694 
02704 static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
02705     if(s->oformat->interleave_packet)
02706         return s->oformat->interleave_packet(s, out, in, flush);
02707     else
02708         return av_interleave_packet_per_dts(s, out, in, flush);
02709 }
02710 
02711 int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
02712     AVStream *st= s->streams[ pkt->stream_index];
02713 
02714     //FIXME/XXX/HACK drop zero sized packets
02715     if(st->codec->codec_type == CODEC_TYPE_AUDIO && pkt->size==0)
02716         return 0;
02717 
02718 //av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts);
02719     if(compute_pkt_fields2(st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
02720         return -1;
02721 
02722     if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
02723         return -1;
02724 
02725     for(;;){
02726         AVPacket opkt;
02727         int ret= av_interleave_packet(s, &opkt, pkt, 0);
02728         if(ret<=0) //FIXME cleanup needed for ret<0 ?
02729             return ret;
02730 
02731         ret= s->oformat->write_packet(s, &opkt);
02732 
02733         av_free_packet(&opkt);
02734         pkt= NULL;
02735 
02736         if(ret<0)
02737             return ret;
02738         if(url_ferror(s->pb))
02739             return url_ferror(s->pb);
02740     }
02741 }
02742 
02743 int av_write_trailer(AVFormatContext *s)
02744 {
02745     int ret, i;
02746 
02747     for(;;){
02748         AVPacket pkt;
02749         ret= av_interleave_packet(s, &pkt, NULL, 1);
02750         if(ret<0) //FIXME cleanup needed for ret<0 ?
02751             goto fail;
02752         if(!ret)
02753             break;
02754 
02755         ret= s->oformat->write_packet(s, &pkt);
02756 
02757         av_free_packet(&pkt);
02758 
02759         if(ret<0)
02760             goto fail;
02761         if(url_ferror(s->pb))
02762             goto fail;
02763     }
02764 
02765     if(s->oformat->write_trailer)
02766         ret = s->oformat->write_trailer(s);
02767 fail:
02768     if(ret == 0)
02769        ret=url_ferror(s->pb);
02770     for(i=0;i<s->nb_streams;i++)
02771         av_freep(&s->streams[i]->priv_data);
02772     av_freep(&s->priv_data);
02773     return ret;
02774 }
02775 
02776 void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
02777 {
02778     int i, j;
02779     AVProgram *program=NULL;
02780     void *tmp;
02781 
02782     for(i=0; i<ac->nb_programs; i++){
02783         if(ac->programs[i]->id != progid)
02784             continue;
02785         program = ac->programs[i];
02786         for(j=0; j<program->nb_stream_indexes; j++)
02787             if(program->stream_index[j] == idx)
02788                 return;
02789 
02790         tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1));
02791         if(!tmp)
02792             return;
02793         program->stream_index = tmp;
02794         program->stream_index[program->nb_stream_indexes++] = idx;
02795         return;
02796     }
02797 }
02798 
02799 static void print_fps(double d, const char *postfix){
02800     uint64_t v= lrintf(d*100);
02801     if     (v% 100      ) av_log(NULL, AV_LOG_INFO, ", %3.2f %s", d, postfix);
02802     else if(v%(100*1000)) av_log(NULL, AV_LOG_INFO, ", %1.0f %s", d, postfix);
02803     else                  av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d/1000, postfix);
02804 }
02805 
02806 /* "user interface" functions */
02807 static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
02808 {
02809     char buf[256];
02810     int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
02811     AVStream *st = ic->streams[i];
02812     int g = av_gcd(st->time_base.num, st->time_base.den);
02813     AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
02814     avcodec_string(buf, sizeof(buf), st->codec, is_output);
02815     av_log(NULL, AV_LOG_INFO, "    Stream #%d.%d", index, i);
02816     /* the pid is an important information, so we display it */
02817     /* XXX: add a generic system */
02818     if (flags & AVFMT_SHOW_IDS)
02819         av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
02820     if (lang)
02821         av_log(NULL, AV_LOG_INFO, "(%s)", lang->value);
02822     av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
02823     av_log(NULL, AV_LOG_INFO, ": %s", buf);
02824     if (st->sample_aspect_ratio.num && // default
02825         av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) {
02826         AVRational display_aspect_ratio;
02827         av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
02828                   st->codec->width*st->sample_aspect_ratio.num,
02829                   st->codec->height*st->sample_aspect_ratio.den,
02830                   1024*1024);
02831         av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d",
02832                  st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
02833                  display_aspect_ratio.num, display_aspect_ratio.den);
02834     }
02835     if(st->codec->codec_type == CODEC_TYPE_VIDEO){
02836         if(st->r_frame_rate.den && st->r_frame_rate.num)
02837             print_fps(av_q2d(st->r_frame_rate), "tbr");
02838         if(st->time_base.den && st->time_base.num)
02839             print_fps(1/av_q2d(st->time_base), "tbn");
02840         if(st->codec->time_base.den && st->codec->time_base.num)
02841             print_fps(1/av_q2d(st->codec->time_base), "tbc");
02842     }
02843     av_log(NULL, AV_LOG_INFO, "\n");
02844 }
02845 
02846 void dump_format(AVFormatContext *ic,
02847                  int index,
02848                  const char *url,
02849                  int is_output)
02850 {
02851     int i;
02852 
02853     av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
02854             is_output ? "Output" : "Input",
02855             index,
02856             is_output ? ic->oformat->name : ic->iformat->name,
02857             is_output ? "to" : "from", url);
02858     if (!is_output) {
02859         av_log(NULL, AV_LOG_INFO, "  Duration: ");
02860         if (ic->duration != AV_NOPTS_VALUE) {
02861             int hours, mins, secs, us;
02862             secs = ic->duration / AV_TIME_BASE;
02863             us = ic->duration % AV_TIME_BASE;
02864             mins = secs / 60;
02865             secs %= 60;
02866             hours = mins / 60;
02867             mins %= 60;
02868             av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%02d", hours, mins, secs,
02869                    (100 * us) / AV_TIME_BASE);
02870         } else {
02871             av_log(NULL, AV_LOG_INFO, "N/A");
02872         }
02873         if (ic->start_time != AV_NOPTS_VALUE) {
02874             int secs, us;
02875             av_log(NULL, AV_LOG_INFO, ", start: ");
02876             secs = ic->start_time / AV_TIME_BASE;
02877             us = ic->start_time % AV_TIME_BASE;
02878             av_log(NULL, AV_LOG_INFO, "%d.%06d",
02879                    secs, (int)av_rescale(us, 1000000, AV_TIME_BASE));
02880         }
02881         av_log(NULL, AV_LOG_INFO, ", bitrate: ");
02882         if (ic->bit_rate) {
02883             av_log(NULL, AV_LOG_INFO,"%d kb/s", ic->bit_rate / 1000);
02884         } else {
02885             av_log(NULL, AV_LOG_INFO, "N/A");
02886         }
02887         av_log(NULL, AV_LOG_INFO, "\n");
02888     }
02889     if(ic->nb_programs) {
02890         int j, k;
02891         for(j=0; j<ic->nb_programs; j++) {
02892             AVMetadataTag *name = av_metadata_get(ic->programs[j]->metadata,
02893                                                   "name", NULL, 0);
02894             av_log(NULL, AV_LOG_INFO, "  Program %d %s\n", ic->programs[j]->id,
02895                    name ? name->value : "");
02896             for(k=0; k<ic->programs[j]->nb_stream_indexes; k++)
02897                 dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output);
02898          }
02899     } else
02900     for(i=0;i<ic->nb_streams;i++)
02901         dump_stream_format(ic, i, index, is_output);
02902 }
02903 
02904 #if LIBAVFORMAT_VERSION_MAJOR < 53
02905 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
02906 {
02907     return av_parse_video_frame_size(width_ptr, height_ptr, str);
02908 }
02909 
02910 int parse_frame_rate(int *frame_rate_num, int *frame_rate_den, const char *arg)
02911 {
02912     AVRational frame_rate;
02913     int ret = av_parse_video_frame_rate(&frame_rate, arg);
02914     *frame_rate_num= frame_rate.num;
02915     *frame_rate_den= frame_rate.den;
02916     return ret;
02917 }
02918 #endif
02919 
02920 int64_t av_gettime(void)
02921 {
02922     struct timeval tv;
02923     gettimeofday(&tv,NULL);
02924     return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
02925 }
02926 
02927 int64_t parse_date(const char *datestr, int duration)
02928 {
02929     const char *p;
02930     int64_t t;
02931     struct tm dt;
02932     int i;
02933     static const char * const date_fmt[] = {
02934         "%Y-%m-%d",
02935         "%Y%m%d",
02936     };
02937     static const char * const time_fmt[] = {
02938         "%H:%M:%S",
02939         "%H%M%S",
02940     };
02941     const char *q;
02942     int is_utc, len;
02943     char lastch;
02944     int negative = 0;
02945 
02946 #undef time
02947     time_t now = time(0);
02948 
02949     len = strlen(datestr);
02950     if (len > 0)
02951         lastch = datestr[len - 1];
02952     else
02953         lastch = '\0';
02954     is_utc = (lastch == 'z' || lastch == 'Z');
02955 
02956     memset(&dt, 0, sizeof(dt));
02957 
02958     p = datestr;
02959     q = NULL;
02960     if (!duration) {
02961         if (!strncasecmp(datestr, "now", len))
02962             return (int64_t) now * 1000000;
02963 
02964         /* parse the year-month-day part */
02965         for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
02966             q = small_strptime(p, date_fmt[i], &dt);
02967             if (q) {
02968                 break;
02969             }
02970         }
02971 
02972         /* if the year-month-day part is missing, then take the
02973          * current year-month-day time */
02974         if (!q) {
02975             if (is_utc) {
02976                 dt = *gmtime(&now);
02977             } else {
02978                 dt = *localtime(&now);
02979             }
02980             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
02981         } else {
02982             p = q;
02983         }
02984 
02985         if (*p == 'T' || *p == 't' || *p == ' ')
02986             p++;
02987 
02988         /* parse the hour-minute-second part */
02989         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
02990             q = small_strptime(p, time_fmt[i], &dt);
02991             if (q) {
02992                 break;
02993             }
02994         }
02995     } else {
02996         /* parse datestr as a duration */
02997         if (p[0] == '-') {
02998             negative = 1;
02999             ++p;
03000         }
03001         /* parse datestr as HH:MM:SS */
03002         q = small_strptime(p, time_fmt[0], &dt);
03003         if (!q) {
03004             /* parse datestr as S+ */
03005             dt.tm_sec = strtol(p, (char **)&q, 10);
03006             if (q == p)
03007                 /* the parsing didn't succeed */
03008                 return INT64_MIN;
03009             dt.tm_min = 0;
03010             dt.tm_hour = 0;
03011         }
03012     }
03013 
03014     /* Now we have all the fields that we can get */
03015     if (!q) {
03016         return INT64_MIN;
03017     }
03018 
03019     if (duration) {
03020         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
03021     } else {
03022         dt.tm_isdst = -1;       /* unknown */
03023         if (is_utc) {
03024             t = mktimegm(&dt);
03025         } else {
03026             t = mktime(&dt);
03027         }
03028     }
03029 
03030     t *= 1000000;
03031 
03032     /* parse the .m... part */
03033     if (*q == '.') {
03034         int val, n;
03035         q++;
03036         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
03037             if (!isdigit(*q))
03038                 break;
03039             val += n * (*q - '0');
03040         }
03041         t += val;
03042     }
03043     return negative ? -t : t;
03044 }
03045 
03046 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
03047 {
03048     const char *p;
03049     char tag[128], *q;
03050 
03051     p = info;
03052     if (*p == '?')
03053         p++;
03054     for(;;) {
03055         q = tag;
03056         while (*p != '\0' && *p != '=' && *p != '&') {
03057             if ((q - tag) < sizeof(tag) - 1)
03058                 *q++ = *p;
03059             p++;
03060         }
03061         *q = '\0';
03062         q = arg;
03063         if (*p == '=') {
03064             p++;
03065             while (*p != '&' && *p != '\0') {
03066                 if ((q - arg) < arg_size - 1) {
03067                     if (*p == '+')
03068                         *q++ = ' ';
03069                     else
03070                         *q++ = *p;
03071                 }
03072                 p++;
03073             }
03074             *q = '\0';
03075         }
03076         if (!strcmp(tag, tag1))
03077             return 1;
03078         if (*p != '&')
03079             break;
03080         p++;
03081     }
03082     return 0;
03083 }
03084 
03085 int av_get_frame_filename(char *buf, int buf_size,
03086                           const char *path, int number)
03087 {
03088     const char *p;
03089     char *q, buf1[20], c;
03090     int nd, len, percentd_found;
03091 
03092     q = buf;
03093     p = path;
03094     percentd_found = 0;
03095     for(;;) {
03096         c = *p++;
03097         if (c == '\0')
03098             break;
03099         if (c == '%') {
03100             do {
03101                 nd = 0;
03102                 while (isdigit(*p)) {
03103                     nd = nd * 10 + *p++ - '0';
03104                 }
03105                 c = *p++;
03106             } while (isdigit(c));
03107 
03108             switch(c) {
03109             case '%':
03110                 goto addchar;
03111             case 'd':
03112                 if (percentd_found)
03113                     goto fail;
03114                 percentd_found = 1;
03115                 snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
03116                 len = strlen(buf1);
03117                 if ((q - buf + len) > buf_size - 1)
03118                     goto fail;
03119                 memcpy(q, buf1, len);
03120                 q += len;
03121                 break;
03122             default:
03123                 goto fail;
03124             }
03125         } else {
03126         addchar:
03127             if ((q - buf) < buf_size - 1)
03128                 *q++ = c;
03129         }
03130     }
03131     if (!percentd_found)
03132         goto fail;
03133     *q = '\0';
03134     return 0;
03135  fail:
03136     *q = '\0';
03137     return -1;
03138 }
03139 
03140 static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size)
03141 {
03142     int len, i, j, c;
03143 #define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
03144 
03145     for(i=0;i<size;i+=16) {
03146         len = size - i;
03147         if (len > 16)
03148             len = 16;
03149         PRINT("%08x ", i);
03150         for(j=0;j<16;j++) {
03151             if (j < len)
03152                 PRINT(" %02x", buf[i+j]);
03153             else
03154                 PRINT("   ");
03155         }
03156         PRINT(" ");
03157         for(j=0;j<len;j++) {
03158             c = buf[i+j];
03159             if (c < ' ' || c > '~')
03160                 c = '.';
03161             PRINT("%c", c);
03162         }
03163         PRINT("\n");
03164     }
03165 #undef PRINT
03166 }
03167 
03168 void av_hex_dump(FILE *f, uint8_t *buf, int size)
03169 {
03170     hex_dump_internal(NULL, f, 0, buf, size);
03171 }
03172 
03173 void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size)
03174 {
03175     hex_dump_internal(avcl, NULL, level, buf, size);
03176 }
03177 
03178  //FIXME needs to know the time_base
03179 static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
03180 {
03181 #define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
03182     PRINT("stream #%d:\n", pkt->stream_index);
03183     PRINT("  keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
03184     PRINT("  duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
03185     /* DTS is _always_ valid after av_read_frame() */
03186     PRINT("  dts=");
03187     if (pkt->dts == AV_NOPTS_VALUE)
03188         PRINT("N/A");
03189     else
03190         PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE);
03191     /* PTS may not be known if B-frames are present. */
03192     PRINT("  pts=");
03193     if (pkt->pts == AV_NOPTS_VALUE)
03194         PRINT("N/A");
03195     else
03196         PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE);
03197     PRINT("\n");
03198     PRINT("  size=%d\n", pkt->size);
03199 #undef PRINT
03200     if (dump_payload)
03201         av_hex_dump(f, pkt->data, pkt->size);
03202 }
03203 
03204 void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
03205 {
03206     pkt_dump_internal(NULL, f, 0, pkt, dump_payload);
03207 }
03208 
03209 void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
03210 {
03211     pkt_dump_internal(avcl, NULL, level, pkt, dump_payload);
03212 }
03213 
03214 void url_split(char *proto, int proto_size,
03215                char *authorization, int authorization_size,
03216                char *hostname, int hostname_size,
03217                int *port_ptr,
03218                char *path, int path_size,
03219                const char *url)
03220 {
03221     const char *p, *ls, *at, *col, *brk;
03222 
03223     if (port_ptr)               *port_ptr = -1;
03224     if (proto_size > 0)         proto[0] = 0;
03225     if (authorization_size > 0) authorization[0] = 0;
03226     if (hostname_size > 0)      hostname[0] = 0;
03227     if (path_size > 0)          path[0] = 0;
03228 
03229     /* parse protocol */
03230     if ((p = strchr(url, ':'))) {
03231         av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
03232         p++; /* skip ':' */
03233         if (*p == '/') p++;
03234         if (*p == '/') p++;
03235     } else {
03236         /* no protocol means plain filename */
03237         av_strlcpy(path, url, path_size);
03238         return;
03239     }
03240 
03241     /* separate path from hostname */
03242     ls = strchr(p, '/');
03243     if(!ls)
03244         ls = strchr(p, '?');
03245     if(ls)
03246         av_strlcpy(path, ls, path_size);
03247     else
03248         ls = &p[strlen(p)]; // XXX
03249 
03250     /* the rest is hostname, use that to parse auth/port */
03251     if (ls != p) {
03252         /* authorization (user[:pass]@hostname) */
03253         if ((at = strchr(p, '@')) && at < ls) {
03254             av_strlcpy(authorization, p,
03255                        FFMIN(authorization_size, at + 1 - p));
03256             p = at + 1; /* skip '@' */
03257         }
03258 
03259         if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
03260             /* [host]:port */
03261             av_strlcpy(hostname, p + 1,
03262                        FFMIN(hostname_size, brk - p));
03263             if (brk[1] == ':' && port_ptr)
03264                 *port_ptr = atoi(brk + 2);
03265         } else if ((col = strchr(p, ':')) && col < ls) {
03266             av_strlcpy(hostname, p,
03267                        FFMIN(col + 1 - p, hostname_size));
03268             if (port_ptr) *port_ptr = atoi(col + 1);
03269         } else
03270             av_strlcpy(hostname, p,
03271                        FFMIN(ls + 1 - p, hostname_size));
03272     }
03273 }
03274 
03275 char *ff_data_to_hex(char *buff, const uint8_t *src, int s)
03276 {
03277     int i;
03278     static const char hex_table[16] = { '0', '1', '2', '3',
03279                                         '4', '5', '6', '7',
03280                                         '8', '9', 'A', 'B',
03281                                         'C', 'D', 'E', 'F' };
03282 
03283     for(i = 0; i < s; i++) {
03284         buff[i * 2]     = hex_table[src[i] >> 4];
03285         buff[i * 2 + 1] = hex_table[src[i] & 0xF];
03286     }
03287 
03288     return buff;
03289 }
03290 
03291 void av_set_pts_info(AVStream *s, int pts_wrap_bits,
03292                      unsigned int pts_num, unsigned int pts_den)
03293 {
03294     unsigned int gcd= av_gcd(pts_num, pts_den);
03295     s->pts_wrap_bits = pts_wrap_bits;
03296     s->time_base.num = pts_num/gcd;
03297     s->time_base.den = pts_den/gcd;
03298 
03299     if(gcd>1)
03300         av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, gcd);
03301 }

Generated on Sat Feb 16 2013 09:23:14 for ffmpeg by  doxygen 1.7.1