]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/utils.c
librtmp: append the correct field to the string
[ffmpeg] / libavformat / utils.c
index 698fcfec01978049bf7f8d4fb7929d376d2462a5..3ea0ebd9d6bda11432c341470ce66da6eb8e7beb 100644 (file)
@@ -453,33 +453,14 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
 
 /**********************************************************/
 
-/**
- * Get the number of samples of an audio frame. Return -1 on error.
- */
-int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux)
-{
-    int frame_size;
-
-    /* give frame_size priority if demuxing */
-    if (!mux && enc->frame_size > 1)
-        return enc->frame_size;
-
-    if ((frame_size = av_get_audio_frame_duration(enc, size)) > 0)
-        return frame_size;
-
-    /* Fall back on using frame_size if muxing. */
-    if (enc->frame_size > 1)
-        return enc->frame_size;
-
-    return -1;
-}
-
 /**
  * Return the frame duration in seconds. Return 0 if not available.
  */
-void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
+void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
                                AVCodecParserContext *pc, AVPacket *pkt)
 {
+    AVRational codec_framerate = s->iformat ? st->codec->framerate :
+                                              av_inv_q(st->codec->time_base);
     int frame_size;
 
     *pnum = 0;
@@ -492,9 +473,9 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
         } else if (st->time_base.num * 1000LL > st->time_base.den) {
             *pnum = st->time_base.num;
             *pden = st->time_base.den;
-        } else if (st->codec->time_base.num * 1000LL > st->codec->time_base.den) {
-            *pnum = st->codec->time_base.num;
-            *pden = st->codec->time_base.den;
+        } else if (codec_framerate.den * 1000LL > codec_framerate.num) {
+            *pnum = codec_framerate.den;
+            *pden = codec_framerate.num;
             if (pc && pc->repeat_pict) {
                 if (*pnum > INT_MAX / (1 + pc->repeat_pict))
                     *pden /= 1 + pc->repeat_pict;
@@ -509,7 +490,7 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st,
         }
         break;
     case AVMEDIA_TYPE_AUDIO:
-        frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 0);
+        frame_size = av_get_audio_frame_duration(st->codec, pkt->size);
         if (frame_size <= 0 || st->codec->sample_rate <= 0)
             break;
         *pnum = frame_size;
@@ -637,11 +618,11 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
     if (delay == 1 && pkt->dts == pkt->pts &&
         pkt->dts != AV_NOPTS_VALUE && presentation_delayed) {
         av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n");
-        pkt->dts = pkt->pts = AV_NOPTS_VALUE;
+        pkt->dts = AV_NOPTS_VALUE;
     }
 
     if (pkt->duration == 0 && st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
-        ff_compute_frame_duration(&num, &den, st, pc, pkt);
+        ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
         if (den && num) {
             pkt->duration = av_rescale_rnd(1, num * (int64_t) st->time_base.den,
                                            den * (int64_t) st->time_base.num,
@@ -704,7 +685,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
                    st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             int duration = pkt->duration;
             if (!duration && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-                ff_compute_frame_duration(&num, &den, st, pc, pkt);
+                ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
                 if (den && num) {
                     duration = av_rescale_rnd(1,
                                               num * (int64_t) st->time_base.den,
@@ -892,6 +873,7 @@ static int read_from_packet_buffer(AVPacketList **pkt_buffer,
 static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
 {
     int ret = 0, i, got_packet = 0;
+    AVDictionary *metadata = NULL;
 
     av_init_packet(pkt);
 
@@ -967,6 +949,14 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
     if (!got_packet && s->parse_queue)
         ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt);
 
+    av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
+    if (metadata) {
+        s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+        av_dict_copy(&s->metadata, metadata, 0);
+        av_dict_free(&metadata);
+        av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+    }
+
     if (s->debug & FF_FDEBUG_TS)
         av_log(s, AV_LOG_DEBUG,
                "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", "
@@ -2120,6 +2110,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                 !st->codec->extradata)
                 break;
             if (st->first_dts == AV_NOPTS_VALUE &&
+                st->codec_info_nb_frames < ic->max_ts_probe &&
                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
                  st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
                 break;
@@ -2239,6 +2230,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
                              AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
                 av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached\n",
                        ic->max_analyze_duration);
+                if (ic->flags & AVFMT_FLAG_NOBUFFER)
+                    av_packet_unref(pkt);
                 break;
             }
         }
@@ -2267,6 +2260,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
         try_decode_frame(st, pkt,
                          (options && i < orig_nb_streams) ? &options[i] : NULL);
 
+        if (ic->flags & AVFMT_FLAG_NOBUFFER)
+            av_packet_unref(pkt);
+
         st->codec_info_nb_frames++;
         count++;
     }
@@ -2438,6 +2434,9 @@ void avformat_free_context(AVFormatContext *s)
     int i, j;
     AVStream *st;
 
+    if (!s)
+        return;
+
     av_opt_free(s);
     if (s->iformat && s->iformat->priv_class && s->priv_data)
         av_opt_free(s->priv_data);