]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/utils.c
Move 2 defines from mpegaudiodec.c to mpegaudiodata.h to allow compilation
[ffmpeg] / libavformat / utils.c
index e80e57966eb090a49a1599730e4eb8fbfa790f10..c91102c6ce9ea12cb0b56b9352eadb67c90f80ee 100644 (file)
@@ -19,7 +19,6 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
-#include "allformats.h"
 #include "opt.h"
 #include "avstring.h"
 #include "riff.h"
@@ -468,7 +467,7 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
 
     /* XXX: suppress this hack for redirectors */
 #ifdef CONFIG_REDIR_DEMUXER
-    if (fmt == &redir_demuxer) {
+    if (!strcmp(fmt->name, "redir")) {
         int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f);
         err = redir_open(ic_ptr, pb);
         url_fclose(pb);
@@ -648,9 +647,6 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
             pkt->dts += offset;
     }
 
-    if(is_intra_only(st->codec))
-        pkt->flags |= PKT_FLAG_KEY;
-
     /* do we have a video B frame ? */
     delay= st->codec->has_b_frames;
     presentation_delayed = 0;
@@ -727,7 +723,9 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
 //    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);
 
     /* update flags */
-    if (pc) {
+    if(is_intra_only(st->codec))
+        pkt->flags |= PKT_FLAG_KEY;
+    else if (pc) {
         pkt->flags = 0;
         /* key frame computation */
             if (pc->pict_type == FF_I_TYPE)
@@ -1639,7 +1637,7 @@ static int has_codec_parameters(AVCodecContext *enc)
         val = 1;
         break;
     }
-    return (val != 0);
+    return (enc->codec_id != CODEC_ID_NONE && val != 0);
 }
 
 static int try_decode_frame(AVStream *st, const uint8_t *data, int size)
@@ -1804,9 +1802,6 @@ int av_find_stream_info(AVFormatContext *ic)
                 break;
             if(st->parser && st->parser->parser->split && !st->codec->extradata)
                 break;
-            if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
-                st->codec->codec_id == CODEC_ID_NONE)
-                break;
             if(st->first_dts == AV_NOPTS_VALUE)
                 break;
         }
@@ -2068,6 +2063,12 @@ void av_close_input_file(AVFormatContext *s)
         av_free(st->codec);
         av_free(st);
     }
+    for(i=s->nb_programs-1; i>=0; i--) {
+        av_freep(&s->programs[i]->provider_name);
+        av_freep(&s->programs[i]->name);
+        av_freep(&s->programs[i]->stream_index);
+        av_freep(&s->programs[i]);
+    }
     flush_packet_queue(s);
     must_open_file = 1;
     if (s->iformat->flags & AVFMT_NOFILE) {
@@ -2114,6 +2115,43 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
     return st;
 }
 
+AVProgram *av_new_program(AVFormatContext *ac, int id)
+{
+    AVProgram *program=NULL;
+    int i;
+
+#ifdef DEBUG_SI
+    av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id);
+#endif
+
+    for(i=0; i<ac->nb_programs; i++)
+        if(ac->programs[i]->id == id)
+            program = ac->programs[i];
+
+    if(!program){
+        program = av_mallocz(sizeof(AVProgram));
+        if (!program)
+            return NULL;
+        dynarray_add(&ac->programs, &ac->nb_programs, program);
+        program->discard = AVDISCARD_NONE;
+    }
+    program->id = id;
+
+    return program;
+}
+
+void av_set_program_name(AVProgram *program, char *provider_name, char *name)
+{
+    assert(!provider_name == !name);
+    if(name){
+        av_free(program->provider_name);
+        av_free(program->         name);
+        program->provider_name = av_strdup(provider_name);
+        program->         name = av_strdup(         name);
+    }
+}
+
+
 /************************************************************/
 /* output media file */
 
@@ -2445,15 +2483,63 @@ fail:
     return ret;
 }
 
+void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
+{
+    int i, j;
+    AVProgram *program=NULL;
+    void *tmp;
+
+    for(i=0; i<ac->nb_programs; i++){
+        if(ac->programs[i]->id != progid)
+            continue;
+        program = ac->programs[i];
+        for(j=0; j<program->nb_stream_indexes; j++)
+            if(program->stream_index[j] == idx)
+                return;
+
+        tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1));
+        if(!tmp)
+            return;
+        program->stream_index = tmp;
+        program->stream_index[program->nb_stream_indexes++] = idx;
+        return;
+    }
+}
+
 /* "user interface" functions */
+static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
+{
+    char buf[256];
+    int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
+    AVStream *st = ic->streams[i];
+    int g = ff_gcd(st->time_base.num, st->time_base.den);
+    avcodec_string(buf, sizeof(buf), st->codec, is_output);
+    av_log(NULL, AV_LOG_INFO, "    Stream #%d.%d", index, i);
+    /* the pid is an important information, so we display it */
+    /* XXX: add a generic system */
+    if (flags & AVFMT_SHOW_IDS)
+        av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
+    if (strlen(st->language) > 0)
+        av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
+    av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
+    av_log(NULL, AV_LOG_INFO, ": %s", buf);
+    if(st->codec->codec_type == CODEC_TYPE_VIDEO){
+        if(st->r_frame_rate.den && st->r_frame_rate.num)
+            av_log(NULL, AV_LOG_INFO, ", %5.2f fps(r)", av_q2d(st->r_frame_rate));
+/*      else if(st->time_base.den && st->time_base.num)
+            av_log(NULL, AV_LOG_INFO, ", %5.2f fps(m)", 1/av_q2d(st->time_base));*/
+        else
+            av_log(NULL, AV_LOG_INFO, ", %5.2f fps(c)", 1/av_q2d(st->codec->time_base));
+    }
+    av_log(NULL, AV_LOG_INFO, "\n");
+}
 
 void dump_format(AVFormatContext *ic,
                  int index,
                  const char *url,
                  int is_output)
 {
-    int i, flags;
-    char buf[256];
+    int i;
 
     av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
             is_output ? "Output" : "Input",
@@ -2491,35 +2577,17 @@ void dump_format(AVFormatContext *ic,
         }
         av_log(NULL, AV_LOG_INFO, "\n");
     }
-    for(i=0;i<ic->nb_streams;i++) {
-        AVStream *st = ic->streams[i];
-        int g= ff_gcd(st->time_base.num, st->time_base.den);
-        avcodec_string(buf, sizeof(buf), st->codec, is_output);
-        av_log(NULL, AV_LOG_INFO, "  Stream #%d.%d", index, i);
-        /* the pid is an important information, so we display it */
-        /* XXX: add a generic system */
-        if (is_output)
-            flags = ic->oformat->flags;
-        else
-            flags = ic->iformat->flags;
-        if (flags & AVFMT_SHOW_IDS) {
-            av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
-        }
-        if (strlen(st->language) > 0) {
-            av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
-        }
-        av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
-        av_log(NULL, AV_LOG_INFO, ": %s", buf);
-        if(st->codec->codec_type == CODEC_TYPE_VIDEO){
-            if(st->r_frame_rate.den && st->r_frame_rate.num)
-                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(r)", av_q2d(st->r_frame_rate));
-/*            else if(st->time_base.den && st->time_base.num)
-                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(m)", 1/av_q2d(st->time_base));*/
-            else
-                av_log(NULL, AV_LOG_INFO, ", %5.2f fps(c)", 1/av_q2d(st->codec->time_base));
-        }
-        av_log(NULL, AV_LOG_INFO, "\n");
-    }
+    if(ic->nb_programs) {
+        int j, k;
+        for(j=0; j<ic->nb_programs; j++) {
+            av_log(NULL, AV_LOG_INFO, "  Program %d %s\n", ic->programs[j]->id,
+                   ic->programs[j]->name ? ic->programs[j]->name : "");
+            for(k=0; k<ic->programs[j]->nb_stream_indexes; k++)
+                dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output);
+         }
+    } else
+    for(i=0;i<ic->nb_streams;i++)
+        dump_stream_format(ic, i, index, is_output);
 }
 
 int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
@@ -2580,6 +2648,7 @@ int64_t parse_date(const char *datestr, int duration)
     p = datestr;
     q = NULL;
     if (!duration) {
+        /* parse the year-month-day part */
         for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
             q = small_strptime(p, date_fmt[i], &dt);
             if (q) {
@@ -2587,6 +2656,8 @@ int64_t parse_date(const char *datestr, int duration)
             }
         }
 
+        /* if the year-month-day part is missing, then take the
+         * current year-month-day time */
         if (!q) {
             if (is_utc) {
                 dt = *gmtime(&now);
@@ -2601,6 +2672,7 @@ int64_t parse_date(const char *datestr, int duration)
         if (*p == 'T' || *p == 't' || *p == ' ')
             p++;
 
+        /* parse the hour-minute-second part */
         for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
             q = small_strptime(p, time_fmt[i], &dt);
             if (q) {
@@ -2608,13 +2680,19 @@ int64_t parse_date(const char *datestr, int duration)
             }
         }
     } else {
+        /* parse datestr as a duration */
         if (p[0] == '-') {
             negative = 1;
             ++p;
         }
+        /* parse datestr as HH:MM:SS */
         q = small_strptime(p, time_fmt[0], &dt);
         if (!q) {
+            /* parse datestr as S+ */
             dt.tm_sec = strtol(p, (char **)&q, 10);
+            if (q == p)
+                /* the parsing didn't succeed */
+                return INT64_MIN;
             dt.tm_min = 0;
             dt.tm_hour = 0;
         }
@@ -2622,10 +2700,7 @@ int64_t parse_date(const char *datestr, int duration)
 
     /* Now we have all the fields that we can get */
     if (!q) {
-        if (duration)
-            return 0;
-        else
-            return now * INT64_C(1000000);
+        return INT64_MIN;
     }
 
     if (duration) {
@@ -2641,6 +2716,7 @@ int64_t parse_date(const char *datestr, int duration)
 
     t *= 1000000;
 
+    /* parse the .m... part */
     if (*q == '.') {
         int val, n;
         q++;
@@ -2829,68 +2905,58 @@ void url_split(char *proto, int proto_size,
                char *path, int path_size,
                const char *url)
 {
-    const char *p;
-    char *q;
-    int port;
+    const char *p, *ls, *at, *col, *brk, *q;
 
-    port = -1;
+    if (port_ptr)               *port_ptr = -1;
+    if (proto_size > 0)         proto[0] = 0;
+    if (authorization_size > 0) authorization[0] = 0;
+    if (hostname_size > 0)      hostname[0] = 0;
+    if (path_size > 0)          path[0] = 0;
 
-    p = url;
-    q = proto;
-    while (*p != ':' && *p != '\0') {
-        if ((q - proto) < proto_size - 1)
-            *q++ = *p;
-        p++;
-    }
-    if (proto_size > 0)
-        *q = '\0';
-    if (authorization_size > 0)
-        authorization[0] = '\0';
-    if (*p == '\0') {
-        if (proto_size > 0)
-            proto[0] = '\0';
-        if (hostname_size > 0)
-            hostname[0] = '\0';
-        p = url;
+    /* parse protocol */
+    if ((p = strchr(url, ':'))) {
+        av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
+        p++; /* skip ':' */
+        if (*p == '/') p++;
+        if (*p == '/') p++;
     } else {
-        char *at,*slash; // PETR: position of '@' character and '/' character
+        /* no protocol means plain filename */
+        av_strlcpy(path, url, path_size);
+        return;
+    }
 
-        p++;
-        if (*p == '/')
-            p++;
-        if (*p == '/')
-            p++;
-        at = strchr(p,'@'); // PETR: get the position of '@'
-        slash = strchr(p,'/');  // PETR: get position of '/' - end of hostname
-        if (at && slash && at > slash) at = NULL; // PETR: not interested in '@' behind '/'
-
-        q = at ? authorization : hostname;  // PETR: if '@' exists starting with auth.
-
-         while ((at || *p != ':') && *p != '/' && *p != '?' && *p != '\0') { // PETR:
-            if (*p == '@') {    // PETR: passed '@'
-              if (authorization_size > 0)
-                  *q = '\0';
-              q = hostname;
-              at = NULL;
-            } else if (!at) {   // PETR: hostname
-              if ((q - hostname) < hostname_size - 1)
-                  *q++ = *p;
-            } else {
-              if ((q - authorization) < authorization_size - 1)
-                *q++ = *p;
-            }
-            p++;
-        }
-        if (hostname_size > 0)
-            *q = '\0';
-        if (*p == ':') {
-            p++;
-            port = strtoul(p, (char **)&p, 10);
-        }
+    /* separate path from hostname */
+    if ((ls = strchr(p, '/'))) {
+        if ((q = strchr(ls, '?')))
+            av_strlcpy(path, ls, FFMIN(path_size, q - ls + 1));
+        else
+            av_strlcpy(path, ls, path_size);
+    } else if (!(ls = strchr(p, '?')))
+        ls = &p[strlen(p)]; // XXX
+
+    /* the rest is hostname, use that to parse auth/port */
+    if (ls != p) {
+        /* authorization (user[:pass]@hostname) */
+        if ((at = strchr(p, '@')) && at < ls) {
+            av_strlcpy(authorization, p,
+                       FFMIN(authorization_size, at + 1 - p));
+            p = at + 1; /* skip '@' */
+        }
+
+        if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
+            /* [host]:port */
+            av_strlcpy(hostname, p + 1,
+                       FFMIN(hostname_size, brk - p));
+            if (brk[1] == ':' && port_ptr)
+                *port_ptr = atoi(brk + 2);
+        } else if ((col = strchr(p, ':')) && col < ls) {
+            av_strlcpy(hostname, p,
+                       FFMIN(col + 1 - p, hostname_size));
+            if (port_ptr) *port_ptr = atoi(col + 1);
+        } else
+            av_strlcpy(hostname, p,
+                       FFMIN(ls + 1 - p, hostname_size));
     }
-    if (port_ptr)
-        *port_ptr = port;
-    av_strlcpy(path, p, path_size);
 }
 
 void av_set_pts_info(AVStream *s, int pts_wrap_bits,