the new output PTS handling is now generic
authorFabrice Bellard <fabrice@bellard.org>
Mon, 21 Oct 2002 17:40:23 +0000 (17:40 +0000)
committerFabrice Bellard <fabrice@bellard.org>
Mon, 21 Oct 2002 17:40:23 +0000 (17:40 +0000)
Originally committed as revision 1058 to svn://svn.ffmpeg.org/ffmpeg/trunk

libav/avformat.h
libav/tick.h [deleted file]
libav/utils.c

index d8679d1..1fc099a 100644 (file)
@@ -84,6 +84,7 @@ typedef struct AVOutputFormat {
     enum CodecID audio_codec; /* default audio codec */
     enum CodecID video_codec; /* default video codec */
     int (*write_header)(struct AVFormatContext *);
+    /* XXX: change prototype for 64 bit pts */
     int (*write_packet)(struct AVFormatContext *, 
                         int stream_index,
                         unsigned char *buf, int size, int force_pts);
@@ -142,6 +143,8 @@ typedef struct AVStream {
     int codec_info_state;     
     int codec_info_nb_repeat_frames;
     int codec_info_nb_real_frames;
+    /* PTS generation when outputing stream */
+    AVFrac pts;
     /* ffmpeg.c private use */
     int stream_copy; /* if TRUE, just copy stream */
 } AVStream;
@@ -297,7 +300,8 @@ void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
 
 /* media file output */
 int av_write_header(AVFormatContext *s);
-int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts);
+int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
+                   int size);
 int av_write_trailer(AVFormatContext *s);
 
 void dump_format(AVFormatContext *ic,
diff --git a/libav/tick.h b/libav/tick.h
deleted file mode 100644 (file)
index e2d747e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* tick.h - Compute successive integer multiples of a rational
- * number without long-term rounding error.
- * (c)2002 by Lennert Buytenhek <buytenh@gnu.org>
- * File licensed under the GPL, see http://www.fsf.org/ for more info.
- * Dedicated to Marija Kulikova.
- */
-
-#include "avcodec.h"
-
-typedef struct Ticker {
-    int value;
-    int inrate;
-    int outrate;
-    int div;
-    int mod;
-} Ticker;
-
-extern void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate);
-
-static inline int ticker_tick(Ticker *tick, int num)
-{
-    int n = num * tick->div;
-
-    tick->value += num * tick->mod;
-#if 1
-    if (tick->value > 0) {
-        n += (tick->value / tick->inrate);
-        tick->value = tick->value % tick->inrate;
-        if (tick->value > 0) {
-            tick->value -= tick->inrate;
-            n++;
-        }
-    }
-#else
-    while (tick->value > 0) {
-        tick->value -= tick->inrate;
-        n++;
-    }
-#endif
-    return n;
-}
-
-static inline INT64 ticker_abs(Ticker *tick, int num)
-{
-    INT64 n = (INT64) num * tick->div;
-    INT64 value = (INT64) num * tick->mod;
-
-    if (value > 0) {
-        n += (value / tick->inrate);
-        value = value % tick->inrate;
-        if (value > 0) {
-            /* value -= tick->inrate; */
-            n++;
-        }
-    }
-    return n;
-}
index 89c32be..da4f632 100644 (file)
@@ -17,7 +17,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "avformat.h"
-#include "tick.h"
 #include <ctype.h>
 #ifndef CONFIG_WIN32
 #include <unistd.h>
@@ -695,25 +694,76 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
  */
 int av_write_header(AVFormatContext *s)
 {
+    int ret, i;
+    AVStream *st;
+
     s->priv_data = av_mallocz(s->oformat->priv_data_size);
     if (!s->priv_data)
         return AVERROR_NOMEM;
     /* default pts settings is MPEG like */
     av_set_pts_info(s, 33, 1, 90000);
-    return s->oformat->write_header(s);
+    ret = s->oformat->write_header(s);
+    if (ret < 0)
+        return ret;
+
+    /* init PTS generation */
+    for(i=0;i<s->nb_streams;i++) {
+        st = s->streams[i];
+
+        switch (st->codec.codec_type) {
+        case CODEC_TYPE_AUDIO:
+            av_frac_init(&st->pts, 0, 0, 
+                         (INT64)s->pts_num * st->codec.sample_rate);
+            break;
+        case CODEC_TYPE_VIDEO:
+            av_frac_init(&st->pts, 0, 0, 
+                         (INT64)s->pts_num * st->codec.frame_rate);
+            break;
+        default:
+            break;
+        }
+    }
+    return 0;
 }
 
 /**
- * write a packet to an output media file
+ * Write a packet to an output media file. The packet shall contain
+ * one audio or video frame.
  *
  * @param s media file handle
- * @param pkt packet to write
- * @param force_pts XXX: need to suppress that
+ * @param stream_index stream index
+ * @param buf buffer containing the frame data
+ * @param size size of buffer
+ * @return non zero if error.
  */
-int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
+int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
+                   int size)
 {
-    /* XXX: currently, an emulation because internal API must change */
-    return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
+    AVStream *st;
+    INT64 pts_mask;
+    int ret;
+
+    st = s->streams[stream_index];
+    pts_mask = (1LL << s->pts_wrap_bits) - 1;
+    ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, 
+                                   st->pts.val & pts_mask);
+    if (ret < 0)
+        return ret;
+
+    /* update pts */
+    switch (st->codec.codec_type) {
+    case CODEC_TYPE_AUDIO:
+        av_frac_add(&st->pts, 
+                    (INT64)s->pts_den * st->codec.frame_size);
+        break;
+    case CODEC_TYPE_VIDEO:
+        av_frac_add(&st->pts, 
+                    (INT64)s->pts_den * FRAME_RATE_BASE);
+        break;
+    default:
+        break;
+    }
+    return 0;
 }
 
 /**