]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/utils.c
allows adding chapters with NULL title
[ffmpeg] / libavformat / utils.c
index 4936349d7d429cc43c9ca3321b22a409baaf2868..9c537f361e5404696d3701ad569e892d8f806fbf 100644 (file)
@@ -19,8 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
-#include "opt.h"
-#include "avstring.h"
+#include "libavcodec/opt.h"
+#include "libavutil/avstring.h"
 #include "riff.h"
 #include <sys/time.h>
 #include <time.h>
@@ -282,7 +282,8 @@ static AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int
         if (score > *score_max) {
             *score_max = score;
             fmt = fmt1;
-        }
+        }else if (score == *score_max)
+            fmt = NULL;
     }
     return fmt;
 }
@@ -323,7 +324,8 @@ static const AVOption options[]={
 {"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E},
 {"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D},
 {"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, 0, 0, 0, D},
-{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, INT_MAX, 0, INT_MAX, D},
+{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, 1<<20, 0, INT_MAX, D},
+{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), FF_OPT_TYPE_INT, 3041280, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
 {NULL},
 };
 
@@ -641,7 +643,8 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, AVPacket
     for(; pktl; pktl= pktl->next){
         if(pktl->pkt.stream_index != pkt->stream_index)
             continue;
-        if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE){
+        if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE
+           && !pktl->pkt.duration){
             pktl->pkt.pts= pktl->pkt.dts= st->cur_dts;
             st->cur_dts += pkt->duration;
             pktl->pkt.duration= pkt->duration;
@@ -666,7 +669,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
         if (den && num) {
             pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
 
-            if(pkt->dts == AV_NOPTS_VALUE && pkt->pts == AV_NOPTS_VALUE && st->cur_dts == 0)
+            if(st->cur_dts == 0 && pkt->duration != 0)
                 update_initial_durations(s, st, pkt);
         }
     }
@@ -702,30 +705,21 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
     /* interpolate PTS and DTS if they are not present */
     if(delay <=1){
         if (presentation_delayed) {
-            int fields= 2 + (pc ? pc->repeat_pict : 0);
-            int field_duration= pkt->duration / fields;
-            int parity= pc ? pc->parity : 0;
             /* DTS = decompression timestamp */
             /* PTS = presentation timestamp */
             if (pkt->dts == AV_NOPTS_VALUE)
-                pkt->dts = st->last_IP_pts[parity];
+                pkt->dts = st->last_IP_pts;
             update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
             if (pkt->dts == AV_NOPTS_VALUE)
                 pkt->dts = st->cur_dts;
 
             /* this is tricky: the dts must be incremented by the duration
             of the frame we are displaying, i.e. the last I- or P-frame */
-            st->cur_dts = pkt->dts;
-            for(i=0; i<fields; i++){
-                int p= (parity + i)&1;
-                if(!st->last_IP_duration[p])
-                    st->last_IP_duration[p]= field_duration;
-                st->cur_dts += st->last_IP_duration[p];
-                st->last_IP_pts[p]= pkt->pts;
-                if(pkt->pts != AV_NOPTS_VALUE)
-                    st->last_IP_pts[p] += i*field_duration;
-                st->last_IP_duration[p]= field_duration;
-            }
+            if (st->last_IP_duration == 0)
+                st->last_IP_duration = pkt->duration;
+            st->cur_dts = pkt->dts + st->last_IP_duration;
+            st->last_IP_duration  = pkt->duration;
+            st->last_IP_pts= pkt->pts;
             /* cannot compute PTS if not present (we can compute it only
             by knowing the future */
         } else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
@@ -1023,8 +1017,7 @@ static void av_read_frame_flush(AVFormatContext *s)
             av_parser_close(st->parser);
             st->parser = NULL;
         }
-        st->last_IP_pts[0] =
-        st->last_IP_pts[1] = AV_NOPTS_VALUE;
+        st->last_IP_pts = AV_NOPTS_VALUE;
         st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
     }
 }
@@ -1632,8 +1625,7 @@ static void av_estimate_timings_from_pts(AVFormatContext *ic, offset_t old_offse
     for(i=0; i<ic->nb_streams; i++){
         st= ic->streams[i];
         st->cur_dts= st->first_dts;
-        st->last_IP_pts[0] =
-        st->last_IP_pts[1] = AV_NOPTS_VALUE;
+        st->last_IP_pts = AV_NOPTS_VALUE;
     }
 }
 
@@ -1698,7 +1690,7 @@ static int has_codec_parameters(AVCodecContext *enc)
         val = 1;
         break;
     }
-    return (enc->codec_id != CODEC_ID_NONE && val != 0);
+    return enc->codec_id != CODEC_ID_NONE && val != 0;
 }
 
 static int try_decode_frame(AVStream *st, const uint8_t *data, int size)
@@ -1942,7 +1934,7 @@ int av_find_stream_info(AVFormatContext *ic)
 //                if(st->codec->codec_type == CODEC_TYPE_VIDEO)
 //                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
                 if(duration_count[index] < 2)
-                    memset(duration_error, 0, MAX_STREAMS * sizeof(*duration_error));
+                    memset(duration_error[index], 0, sizeof(*duration_error));
                 for(i=1; i<MAX_STD_TIMEBASES; i++){
                     int framerate= get_std_framerate(i);
                     int ticks= lrintf(dur*framerate/(1001*12));
@@ -1999,7 +1991,7 @@ int av_find_stream_info(AVFormatContext *ic)
         count++;
     }
 
-    // close codecs which where opened in try_decode_frame()
+    // close codecs which were opened in try_decode_frame()
     for(i=0;i<ic->nb_streams;i++) {
         st = ic->streams[i];
         if(st->codec->codec)
@@ -2153,8 +2145,14 @@ void av_close_input_stream(AVFormatContext *s)
         av_freep(&s->programs[i]->stream_index);
         av_freep(&s->programs[i]);
     }
+    av_freep(&s->programs);
     flush_packet_queue(s);
     av_freep(&s->priv_data);
+    while(s->num_chapters--) {
+        av_free(s->chapters[s->num_chapters]->title);
+        av_free(s->chapters[s->num_chapters]);
+    }
+    av_freep(&s->chapters);
     av_free(s);
 }
 
@@ -2192,8 +2190,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
 
     /* default pts setting is MPEG-like */
     av_set_pts_info(st, 33, 1, 90000);
-    st->last_IP_pts[0] =
-    st->last_IP_pts[1] = AV_NOPTS_VALUE;
+    st->last_IP_pts = AV_NOPTS_VALUE;
     for(i=0; i<MAX_REORDER_DELAY+1; i++)
         st->pts_buffer[i]= AV_NOPTS_VALUE;
 
@@ -2237,6 +2234,20 @@ void av_set_program_name(AVProgram *program, char *provider_name, char *name)
     }
 }
 
+int ff_new_chapter(AVFormatContext *s, int64_t start, int64_t end, const char *title)
+{
+    AVChapter *chapter = av_mallocz(sizeof(AVChapter));
+    if(!chapter)
+        return AVERROR(ENOMEM);
+    if (title)
+    chapter->title = av_strdup(title);
+    chapter->start = start;
+    chapter->end = end;
+
+    dynarray_add(&s->chapters, &s->num_chapters, chapter);
+
+    return 0;
+}
 
 /************************************************************/
 /* output media file */
@@ -2494,7 +2505,7 @@ int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pk
  * @param flush 1 if no further packets are available as input and all
  *              remaining packets should be output
  * @return 1 if a packet was output, 0 if no packet could be output,
- *         < 0 if an error occured
+ *         < 0 if an error occurred
  */
 static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
     if(s->oformat->interleave_packet)
@@ -2643,8 +2654,8 @@ void dump_format(AVFormatContext *ic,
             secs %= 60;
             hours = mins / 60;
             mins %= 60;
-            av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%01d", hours, mins, secs,
-                   (10 * us) / AV_TIME_BASE);
+            av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%02d", hours, mins, secs,
+                   (100 * us) / AV_TIME_BASE);
         } else {
             av_log(NULL, AV_LOG_INFO, "N/A");
         }