changeset 468:60f897e8dd2d libavformat

pass AVPacket into av_write_frame() fixes the random dts/pts during encoding asf preroll fix no more initial zero frames for b frame encoding mpeg-es dts during demuxing fixed .ffm timestamp scale fixed, ffm is still broken though
author michael
date Sat, 29 May 2004 02:06:32 +0000
parents 40069a91d1a0
children 6a4cc19e8d9b
files amr.c asf-enc.c au.c audio.c avformat.h avienc.c crc.c dv.c ffm.c flvenc.c gif.c img.c movenc.c mp3.c mpeg.c mpegtsenc.c mpjpeg.c nut.c ogg.c raw.c rm.c rtp.c swf.c utils.c wav.c yuv4mpeg.c
diffstat 26 files changed, 209 insertions(+), 144 deletions(-) [+]
line wrap: on
line diff
--- a/amr.c	Tue May 25 23:06:00 2004 +0000
+++ b/amr.c	Sat May 29 02:06:32 2004 +0000
@@ -51,10 +51,9 @@
     return 0;
 }
 
-static int amr_write_packet(AVFormatContext *s, int stream_index_ptr,
-                           uint8_t *buf, int size, int force_pts)
+static int amr_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    put_buffer(&s->pb, buf, size);
+    put_buffer(&s->pb, pkt->data, pkt->size);
     put_flush_packet(&s->pb);
     return 0;
 }
--- a/asf-enc.c	Tue May 25 23:06:00 2004 +0000
+++ b/asf-enc.c	Sat May 29 02:06:32 2004 +0000
@@ -310,7 +310,7 @@
     put_le64(pb, asf->nb_packets); /* number of packets */
     put_le64(pb, asf->duration); /* end time stamp (in 100ns units) */
     put_le64(pb, asf->duration); /* duration (in 100ns units) */
-    put_le32(pb, 0); /* start time stamp */
+    put_le32(pb, preroll_time); /* start time stamp */
     put_le32(pb, 0); /* ??? */
     put_le32(pb, asf->is_streamed ? 1 : 0); /* ??? */
     put_le32(pb, asf->packet_size); /* packet size */
@@ -686,17 +686,17 @@
     stream->seq++;
 }
 
-static int asf_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t timestamp)
+static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ASFContext *asf = s->priv_data;
     ASFStream *stream;
     int64_t duration;
     AVCodecContext *codec;
 
-    codec = &s->streams[stream_index]->codec;
-    stream = &asf->streams[stream_index];
+    codec = &s->streams[pkt->stream_index]->codec;
+    stream = &asf->streams[pkt->stream_index];
 
+    //XXX /FIXME use duration from AVPacket
     if (codec->codec_type == CODEC_TYPE_AUDIO) {
         duration = (codec->frame_number * codec->frame_size * int64_t_C(10000000)) /
             codec->sample_rate;
@@ -706,7 +706,7 @@
     if (duration > asf->duration)
         asf->duration = duration;
 
-    put_frame(s, stream, timestamp, buf, size);
+    put_frame(s, stream, pkt->pts, pkt->data, pkt->size);
     return 0;
 }
 
--- a/au.c	Tue May 25 23:06:00 2004 +0000
+++ b/au.c	Sat May 29 02:06:32 2004 +0000
@@ -72,11 +72,10 @@
     return 0;
 }
 
-static int au_write_packet(AVFormatContext *s, int stream_index_ptr,
-                           const uint8_t *buf, int size, int64_t pts)
+static int au_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ByteIOContext *pb = &s->pb;
-    put_buffer(pb, buf, size);
+    put_buffer(pb, pkt->data, pkt->size);
     return 0;
 }
 
--- a/audio.c	Tue May 25 23:06:00 2004 +0000
+++ b/audio.c	Sat May 29 02:06:32 2004 +0000
@@ -164,11 +164,12 @@
     }
 }
 
-static int audio_write_packet(AVFormatContext *s1, int stream_index,
-                              const uint8_t *buf, int size, int64_t pts)
+static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     AudioData *s = s1->priv_data;
     int len, ret;
+    int size= pkt->size;
+    uint8_t *buf= pkt->data;
 
     while (size > 0) {
         len = AUDIO_BLOCK_SIZE - s->buffer_ptr;
--- a/avformat.h	Tue May 25 23:06:00 2004 +0000
+++ b/avformat.h	Sat May 29 02:06:32 2004 +0000
@@ -5,7 +5,7 @@
 extern "C" {
 #endif
 
-#define LIBAVFORMAT_BUILD       4614
+#define LIBAVFORMAT_BUILD       4615
 
 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT
 #define LIBAVFORMAT_VERSION     FFMPEG_VERSION
@@ -131,9 +131,7 @@
     enum CodecID audio_codec; /* default audio codec */
     enum CodecID video_codec; /* default video codec */
     int (*write_header)(struct AVFormatContext *);
-    int (*write_packet)(struct AVFormatContext *, 
-                        int stream_index,
-                        const uint8_t *buf, int size, int64_t pts);
+    int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
     int (*write_trailer)(struct AVFormatContext *);
     /* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER */
     int flags;
@@ -558,8 +556,8 @@
 /* media file output */
 int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
 int av_write_header(AVFormatContext *s);
-int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
-                   int size);
+int av_write_frame(AVFormatContext *s, AVPacket *pkt);
+
 int av_write_trailer(AVFormatContext *s);
 
 void dump_format(AVFormatContext *ic,
--- a/avienc.c	Tue May 25 23:06:00 2004 +0000
+++ b/avienc.c	Sat May 29 02:06:32 2004 +0000
@@ -607,14 +607,15 @@
     return 0;
 }
 
-static int avi_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t pts)
+static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     AVIContext *avi = s->priv_data;
     ByteIOContext *pb = &s->pb;
     unsigned char tag[5];
-    unsigned int flags;
+    unsigned int flags=0;
     AVCodecContext *enc;
+    const int stream_index= pkt->stream_index;
+    int size= pkt->size;
 
     if (url_ftell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE) { 
         avi_write_ix(s);
@@ -629,11 +630,11 @@
     
     enc = &s->streams[stream_index]->codec;
     avi_stream2fourcc(&tag[0], stream_index, enc->codec_type);
+    if(pkt->flags&PKT_FLAG_KEY)
+        flags = 0x10;
     if (enc->codec_type == CODEC_TYPE_AUDIO) {
        avi->audio_strm_length[stream_index] += size;
-       flags = 0x10;
-    } else
-       flags = enc->coded_frame->key_frame ? 0x10 : 0x00;
+    }
 
     if (!url_is_streamed(&s->pb)) {
         AVIIndex* idx = &avi->indexes[stream_index];
@@ -657,7 +658,7 @@
     
     put_buffer(pb, tag, 4);
     put_le32(pb, size);
-    put_buffer(pb, buf, size);
+    put_buffer(pb, pkt->data, size);
     if (size & 1)
         put_byte(pb, 0);
 
--- a/crc.c	Tue May 25 23:06:00 2004 +0000
+++ b/crc.c	Sat May 29 02:06:32 2004 +0000
@@ -71,12 +71,10 @@
     return 0;
 }
 
-static int crc_write_packet(struct AVFormatContext *s, 
-                            int stream_index,
-                            const uint8_t *buf, int size, int64_t pts)
+static int crc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
     CRCState *crc = s->priv_data;
-    crc->crcval = update_adler32(crc->crcval, buf, size);
+    crc->crcval = update_adler32(crc->crcval, pkt->data, pkt->size);
     return 0;
 }
 
--- a/dv.c	Tue May 25 23:06:00 2004 +0000
+++ b/dv.c	Sat May 29 02:06:32 2004 +0000
@@ -888,15 +888,13 @@
     return 0;
 }
 
-static int dv_write_packet(struct AVFormatContext *s, 
-                           int stream_index,
-                           const uint8_t *buf, int size, int64_t pts)
+static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
     uint8_t* frame;
     int fsize;
    
-    fsize = dv_assemble_frame((DVMuxContext *)s->priv_data, s->streams[stream_index],
-                              buf, size, &frame);
+    fsize = dv_assemble_frame((DVMuxContext *)s->priv_data, s->streams[pkt->stream_index],
+                              pkt->data, pkt->size, &frame);
     if (fsize > 0) {
         put_buffer(&s->pb, frame, fsize); 
         put_flush_packet(&s->pb);
--- a/ffm.c	Tue May 25 23:06:00 2004 +0000
+++ b/ffm.c	Sat May 29 02:06:32 2004 +0000
@@ -222,15 +222,16 @@
     return -1;
 }
 
-static int ffm_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t force_pts)
+static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVStream *st = s->streams[stream_index];
+    AVStream *st = s->streams[pkt->stream_index];
     FFMStream *fst = st->priv_data;
     int64_t pts;
     uint8_t header[FRAME_HEADER_SIZE];
     int duration;
+    int size= pkt->size;
 
+    //XXX/FIXME use duration from pkt
     if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
         duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0);
     } else {
@@ -239,9 +240,9 @@
 
     pts = fst->pts;
     /* packet size & key_frame */
-    header[0] = stream_index;
+    header[0] = pkt->stream_index;
     header[1] = 0;
-    if (st->codec.coded_frame->key_frame) //if st->codec.coded_frame==NULL then there is a bug somewhere else
+    if (pkt->flags & PKT_FLAG_KEY)
         header[1] |= FLAG_KEY_FRAME;
     header[2] = (size >> 16) & 0xff;
     header[3] = (size >> 8) & 0xff;
@@ -250,7 +251,7 @@
     header[6] = (duration >> 8) & 0xff;
     header[7] = duration & 0xff;
     ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1);
-    ffm_write_data(s, buf, size, pts, 0);
+    ffm_write_data(s, pkt->data, size, pts, 0);
 
     fst->pts += duration;
     return 0;
@@ -467,6 +468,9 @@
         fst = av_mallocz(sizeof(FFMStream));
         if (!fst)
             goto fail;
+            
+        av_set_pts_info(st, 64, 1, 1000000);
+            
         st->priv_data = fst;
 
         codec = &st->codec;
--- a/flvenc.c	Tue May 25 23:06:00 2004 +0000
+++ b/flvenc.c	Sat May 29 02:06:32 2004 +0000
@@ -239,18 +239,19 @@
     return 0;
 }
 
-static int flv_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t timestamp)
+static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ByteIOContext *pb = &s->pb;
-    AVCodecContext *enc = &s->streams[stream_index]->codec;
+    AVCodecContext *enc = &s->streams[pkt->stream_index]->codec;
     FLVContext *flv = s->priv_data;
     FLVFrame *frame = av_malloc(sizeof(FLVFrame));
+    int size= pkt->size;
+    uint8_t *buf= pkt->data;
 
     frame->next = 0;
     frame->size = size;
     frame->data = av_malloc(size);
-    frame->timestamp = timestamp;
+    frame->timestamp = pkt->pts;
     frame->reserved= flv->reserved;
     memcpy(frame->data,buf,size);
     
@@ -259,7 +260,7 @@
     if (enc->codec_type == CODEC_TYPE_VIDEO) {
         frame->type = 9;
         frame->flags = 2; // choose h263
-        frame->flags |= enc->coded_frame->key_frame ? 0x10 : 0x20; // add keyframe indicator
+        frame->flags |= pkt->flags & PKT_FLAG_KEY ? 0x10 : 0x20; // add keyframe indicator
         //frame->timestamp = ( ( flv->frameCount * (int64_t)FRAME_RATE_BASE * (int64_t)1000 ) / (int64_t)enc->frame_rate );
         //printf("%08x %f %f\n",frame->timestamp,(double)enc->frame_rate/(double)FRAME_RATE_BASE,1000*(double)FRAME_RATE_BASE/(double)enc->frame_rate);
         flv->hasVideo = 1;
@@ -306,7 +307,7 @@
 
         assert(size);
         if ( flv->initDelay == -1 ) {
-            flv->initDelay = timestamp;
+            flv->initDelay = pkt->pts;
         }
 
         frame->type = 8;
--- a/gif.c	Tue May 25 23:06:00 2004 +0000
+++ b/gif.c	Sat May 29 02:06:32 2004 +0000
@@ -364,14 +364,13 @@
     return 0;
 }
 
-static int gif_write_packet(AVFormatContext *s, int stream_index, 
-                            const uint8_t *buf, int size, int64_t pts)
+static int gif_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVCodecContext *codec = &s->streams[stream_index]->codec;
+    AVCodecContext *codec = &s->streams[pkt->stream_index]->codec;
     if (codec->codec_type == CODEC_TYPE_AUDIO)
         return 0; /* just ignore audio */
     else
-        return gif_write_video(s, codec, buf, size);
+        return gif_write_video(s, codec, pkt->data, pkt->size);
 }
 
 static int gif_write_trailer(AVFormatContext *s)
--- a/img.c	Tue May 25 23:06:00 2004 +0000
+++ b/img.c	Sat May 29 02:06:32 2004 +0000
@@ -300,11 +300,10 @@
     return 0;
 }
 
-static int img_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t pts)
+static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     VideoData *img = s->priv_data;
-    AVStream *st = s->streams[stream_index];
+    AVStream *st = s->streams[pkt->stream_index];
     ByteIOContext pb1, *pb;
     AVPicture *picture;
     int width, height, ret;
@@ -314,7 +313,7 @@
     width = st->codec.width;
     height = st->codec.height;
     
-    picture = (AVPicture *)buf;
+    picture = (AVPicture *)pkt->data;
 
     if (!img->is_pipe) {
         if (get_frame_filename(filename, sizeof(filename), 
--- a/movenc.c	Tue May 25 23:06:00 2004 +0000
+++ b/movenc.c	Sat May 29 02:06:32 2004 +0000
@@ -950,15 +950,15 @@
     return 0;
 }
 
-static int mov_write_packet(AVFormatContext *s, int stream_index,
-                            const uint8_t *buf, int size, int64_t pts)
+static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MOVContext *mov = s->priv_data;
     ByteIOContext *pb = &s->pb;
-    AVCodecContext *enc = &s->streams[stream_index]->codec;
-    MOVTrack* trk = &mov->tracks[stream_index];
+    AVCodecContext *enc = &s->streams[pkt->stream_index]->codec;
+    MOVTrack* trk = &mov->tracks[pkt->stream_index];
     int cl, id;
     unsigned int samplesInChunk = 0;
+    int size= pkt->size;
 
     if (url_is_streamed(&s->pb)) return 0; /* Can't handle that */
     if (!size) return 0; /* Discard 0 sized packets */
@@ -974,7 +974,7 @@
             int len = 0;
 
             while (len < size && samplesInChunk < 100) {
-                len += packed_size[(buf[len] >> 3) & 0x0F];
+                len += packed_size[(pkt->data[len] >> 3) & 0x0F];
                 samplesInChunk++;
             }
         }
@@ -1021,8 +1021,8 @@
     trk->cluster[cl][id].size = size;
     trk->cluster[cl][id].entries = samplesInChunk;
     if(enc->codec_type == CODEC_TYPE_VIDEO) {
-        trk->cluster[cl][id].key_frame = enc->coded_frame->key_frame;
-        if(enc->coded_frame->pict_type == FF_I_TYPE)
+        trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
+        if(trk->cluster[cl][id].key_frame)
             trk->hasKeyframes = 1;
     }
     trk->enc = enc;
@@ -1030,7 +1030,7 @@
     trk->sampleCount += samplesInChunk;
     trk->mdat_size += size;
 
-    put_buffer(pb, buf, size);
+    put_buffer(pb, pkt->data, size);
 
     put_flush_packet(pb);
     return 0;
--- a/mp3.c	Tue May 25 23:06:00 2004 +0000
+++ b/mp3.c	Sat May 29 02:06:32 2004 +0000
@@ -324,10 +324,9 @@
     return 0;
 }
 
-static int mp3_write_packet(struct AVFormatContext *s, int stream_index,
-			    const uint8_t *buf, int size, int64_t pts)
+static int mp3_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
-    put_buffer(&s->pb, buf, size);
+    put_buffer(&s->pb, pkt->data, pkt->size);
     put_flush_packet(&s->pb);
     return 0;
 }
--- a/mpeg.c	Tue May 25 23:06:00 2004 +0000
+++ b/mpeg.c	Sat May 29 02:06:32 2004 +0000
@@ -912,17 +912,22 @@
 }    
 
 
-static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,
-                                 const uint8_t *buf, int size, 
-                                 int64_t timestamp)
+static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
 {
     MpegMuxContext *s = ctx->priv_data;
+    int stream_index= pkt->stream_index;
+    int size= pkt->size;
+    uint8_t *buf= pkt->data;
     AVStream *st = ctx->streams[stream_index];
     StreamInfo *stream = st->priv_data;
     int64_t pts, dts, new_start_pts, new_start_dts;
     int len, avail_size;
     
-    compute_pts_dts(st, &pts, &dts, timestamp);
+    //XXX/FIXME this is and always was broken
+//    compute_pts_dts(st, &pts, &dts, pkt->pts);
+
+    pts= pkt->pts;
+    dts= pkt->dts;
 
     if(s->is_svcd) {
         /* offset pts and dts slightly into the future to be able
--- a/mpegtsenc.c	Tue May 25 23:06:00 2004 +0000
+++ b/mpegtsenc.c	Sat May 29 02:06:32 2004 +0000
@@ -549,10 +549,11 @@
     put_flush_packet(&s->pb);
 }
 
-static int mpegts_write_packet(AVFormatContext *s, int stream_index,
-                               const uint8_t *buf, int size, int64_t pts1)
+static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVStream *st = s->streams[stream_index];
+    AVStream *st = s->streams[pkt->stream_index];
+    int size= pkt->size;
+    uint8_t *buf= pkt->data;
     MpegTSWriteStream *ts_st = st->priv_data;
     int len;
 
@@ -565,7 +566,7 @@
         size -= len;
         ts_st->payload_index += len;
         if (ts_st->payload_pts == AV_NOPTS_VALUE)
-            ts_st->payload_pts = pts1;
+            ts_st->payload_pts = pkt->pts;
         if (ts_st->payload_index >= DEFAULT_PES_PAYLOAD_SIZE) {
             mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
                              ts_st->payload_pts);
--- a/mpjpeg.c	Tue May 25 23:06:00 2004 +0000
+++ b/mpjpeg.c	Sat May 29 02:06:32 2004 +0000
@@ -33,14 +33,13 @@
     return 0;
 }
 
-static int mpjpeg_write_packet(AVFormatContext *s, int stream_index, 
-                               const uint8_t *buf, int size, int64_t pts)
+static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     uint8_t buf1[256];
 
     snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n");
     put_buffer(&s->pb, buf1, strlen(buf1));
-    put_buffer(&s->pb, buf, size);
+    put_buffer(&s->pb, pkt->data, pkt->size);
 
     snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG);
     put_buffer(&s->pb, buf1, strlen(buf1));
@@ -75,10 +74,9 @@
     return 0;
 }
 
-static int single_jpeg_write_packet(AVFormatContext *s, int stream_index,
-                                    const uint8_t *buf, int size, int64_t pts)
+static int single_jpeg_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    put_buffer(&s->pb, buf, size);
+    put_buffer(&s->pb, pkt->data, pkt->size);
     put_flush_packet(&s->pb);
     return 1; /* no more data can be sent */
 }
--- a/nut.c	Tue May 25 23:06:00 2004 +0000
+++ b/nut.c	Sat May 29 02:06:32 2004 +0000
@@ -691,25 +691,22 @@
     return  ((lsb - delta)&mask) + delta;
 }
 
-static int nut_write_packet(AVFormatContext *s, int stream_index, 
-			    const uint8_t *buf, int size, int64_t pts)
+static int nut_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     NUTContext *nut = s->priv_data;
-    StreamContext *stream= &nut->stream[stream_index];
+    StreamContext *stream= &nut->stream[pkt->stream_index];
     ByteIOContext *bc = &s->pb;
     int key_frame = 0, full_pts=0;
     AVCodecContext *enc;
     int64_t coded_pts;
     int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb, time_delta;
     const int64_t frame_start= url_ftell(bc);
+    int64_t pts= pkt->pts;
+    int size= pkt->size;
+    int stream_index= pkt->stream_index;
 
-    if (stream_index > s->nb_streams)
-	return 1;
-        
     enc = &s->streams[stream_index]->codec;
-    key_frame = enc->coded_frame->key_frame;
-    if(enc->coded_frame->pts != AV_NOPTS_VALUE)
-        pts= av_rescale(enc->coded_frame->pts, stream->rate_num, stream->rate_den*(int64_t)AV_TIME_BASE); //FIXME XXX HACK
+    key_frame = !!(pkt->flags & PKT_FLAG_KEY);
     
     frame_type=0;
     if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE)
@@ -808,7 +805,7 @@
         assert(frame_type > 1);
     }
     
-    put_buffer(bc, buf, size);
+    put_buffer(bc, pkt->data, size);
 
     update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);
     
--- a/ogg.c	Tue May 25 23:06:00 2004 +0000
+++ b/ogg.c	Sat May 29 02:06:32 2004 +0000
@@ -62,16 +62,15 @@
     return 0 ;
 }
 
-static int ogg_write_packet(AVFormatContext *avfcontext,
-			    int stream_index,
-			    const uint8_t *buf, int size, int64_t pts)
+static int ogg_write_packet(AVFormatContext *avfcontext, AVPacket *pkt)
 {
     OggContext *context = avfcontext->priv_data ;
-    AVCodecContext *avctx= &avfcontext->streams[stream_index]->codec;
+    AVCodecContext *avctx= &avfcontext->streams[pkt->stream_index]->codec;
     ogg_packet *op= &context->op;
     ogg_page og ;
+    int64_t pts;
 
-    pts= av_rescale(pts, avctx->sample_rate, AV_TIME_BASE);
+    pts= av_rescale(pkt->pts, avctx->sample_rate, AV_TIME_BASE);
 
 //    av_log(avfcontext, AV_LOG_DEBUG, "M%d\n", size);
 
@@ -86,8 +85,8 @@
 	context->header_handled = 1 ;
     }
 
-    op->packet = (uint8_t*) buf;
-    op->bytes  = size;
+    op->packet = (uint8_t*) pkt->data;
+    op->bytes  = pkt->size;
     op->b_o_s  = op->packetno == 0;
     op->granulepos= pts;
 
--- a/raw.c	Tue May 25 23:06:00 2004 +0000
+++ b/raw.c	Sat May 29 02:06:32 2004 +0000
@@ -25,10 +25,9 @@
     return 0;
 }
 
-static int raw_write_packet(struct AVFormatContext *s, int stream_index,
-			    const uint8_t *buf, int size, int64_t pts)
+static int raw_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
-    put_buffer(&s->pb, buf, size);
+    put_buffer(&s->pb, pkt->data, pkt->size);
     put_flush_packet(&s->pb);
     return 0;
 }
@@ -551,9 +550,7 @@
 #endif //CONFIG_ENCODERS
 
 #ifdef CONFIG_ENCODERS
-static int null_write_packet(struct AVFormatContext *s, 
-                             int stream_index,
-                             const uint8_t *buf, int size, int64_t pts)
+static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt)
 {
     return 0;
 }
--- a/rm.c	Tue May 25 23:06:00 2004 +0000
+++ b/rm.c	Sat May 29 02:06:32 2004 +0000
@@ -389,14 +389,13 @@
     return 0;
 }
 
-static int rm_write_packet(AVFormatContext *s, int stream_index, 
-                           const uint8_t *buf, int size, int64_t pts)
+static int rm_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    if (s->streams[stream_index]->codec.codec_type == 
+    if (s->streams[pkt->stream_index]->codec.codec_type == 
         CODEC_TYPE_AUDIO)
-        return rm_write_audio(s, buf, size);
+        return rm_write_audio(s, pkt->data, pkt->size);
     else
-        return rm_write_video(s, buf, size);
+        return rm_write_video(s, pkt->data, pkt->size);
 }
         
 static int rm_write_trailer(AVFormatContext *s)
--- a/rtp.c	Tue May 25 23:06:00 2004 +0000
+++ b/rtp.c	Sat May 29 02:06:32 2004 +0000
@@ -669,16 +669,17 @@
 }
 
 /* write an RTP packet. 'buf1' must contain a single specific frame. */
-static int rtp_write_packet(AVFormatContext *s1, int stream_index,
-                            const uint8_t *buf1, int size, int64_t pts)
+static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     RTPDemuxContext *s = s1->priv_data;
     AVStream *st = s1->streams[0];
     int rtcp_bytes;
     int64_t ntp_time;
+    int size= pkt->size;
+    uint8_t *buf1= pkt->data;
     
 #ifdef DEBUG
-    printf("%d: write len=%d\n", stream_index, size);
+    printf("%d: write len=%d\n", pkt->stream_index, size);
 #endif
 
     /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */
@@ -687,7 +688,7 @@
     if (s->first_packet || rtcp_bytes >= 28) {
         /* compute NTP time */
         /* XXX: 90 kHz timestamp hardcoded */
-        ntp_time = (pts << 28) / 5625;
+        ntp_time = (pkt->pts << 28) / 5625;
         rtcp_send_sr(s1, ntp_time); 
         s->last_octet_count = s->octet_count;
         s->first_packet = 0;
--- a/swf.c	Tue May 25 23:06:00 2004 +0000
+++ b/swf.c	Sat May 29 02:06:32 2004 +0000
@@ -700,14 +700,13 @@
     return 0;
 }
 
-static int swf_write_packet(AVFormatContext *s, int stream_index, 
-                           const uint8_t *buf, int size, int64_t pts)
+static int swf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVCodecContext *codec = &s->streams[stream_index]->codec;
+    AVCodecContext *codec = &s->streams[pkt->stream_index]->codec;
     if (codec->codec_type == CODEC_TYPE_AUDIO)
-        return swf_write_audio(s, codec, buf, size);
+        return swf_write_audio(s, codec, pkt->data, pkt->size);
     else
-        return swf_write_video(s, codec, buf, size);
+        return swf_write_video(s, codec, pkt->data, pkt->size);
 }
 
 static int swf_write_trailer(AVFormatContext *s)
--- a/utils.c	Tue May 25 23:06:00 2004 +0000
+++ b/utils.c	Sat May 29 02:06:32 2004 +0000
@@ -569,10 +569,12 @@
     int num, den, presentation_delayed;
 
     /* handle wrapping */
-    if(pkt->pts != AV_NOPTS_VALUE)
-        pkt->pts= lsb2full(pkt->pts, st->cur_dts, st->pts_wrap_bits);
-    if(pkt->dts != AV_NOPTS_VALUE)
-        pkt->dts= lsb2full(pkt->dts, st->cur_dts, st->pts_wrap_bits);
+    if(st->cur_dts != AV_NOPTS_VALUE){
+        if(pkt->pts != AV_NOPTS_VALUE)
+            pkt->pts= lsb2full(pkt->pts, st->cur_dts, st->pts_wrap_bits);
+        if(pkt->dts != AV_NOPTS_VALUE)
+            pkt->dts= lsb2full(pkt->dts, st->cur_dts, st->pts_wrap_bits);
+    }
     
     if (pkt->duration == 0) {
         compute_frame_duration(&num, &den, s, st, pc, pkt);
@@ -596,7 +598,13 @@
         if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
             presentation_delayed = 1;
     }
+    
+    if(st->cur_dts == AV_NOPTS_VALUE){
+        if(presentation_delayed) st->cur_dts = -pkt->duration;
+        else                     st->cur_dts = 0;
+    }
 
+//    av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%lld, dts:%lld cur_dts:%lld\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts);
     /* interpolate PTS and DTS if they are not present */
     if (presentation_delayed) {
         /* DTS = decompression time stamp */
@@ -637,6 +645,7 @@
         }
         st->cur_dts += pkt->duration;
     }
+//    av_log(NULL, AV_LOG_DEBUG, "OUTdelayed:%d pts:%lld, dts:%lld cur_dts:%lld\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts);
     
     /* update flags */
     if (pc) {
@@ -1672,6 +1681,30 @@
     }
 
     av_estimate_timings(ic);
+#if 0
+    /* correct DTS for b frame streams with no timestamps */
+    for(i=0;i<ic->nb_streams;i++) {
+        st = ic->streams[i];
+        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
+            if(b-frames){
+                ppktl = &ic->packet_buffer;
+                while(ppkt1){
+                    if(ppkt1->stream_index != i)
+                        continue;
+                    if(ppkt1->pkt->dts < 0)
+                        break;
+                    if(ppkt1->pkt->pts != AV_NOPTS_VALUE)
+                        break;
+                    ppkt1->pkt->dts -= delta;
+                    ppkt1= ppkt1->next;
+                }
+                if(ppkt1)
+                    continue;
+                st->cur_dts -= delta;
+            }
+        }
+    }
+#endif
     return ret;
 }
 
@@ -1764,6 +1797,7 @@
     st->id = id;
     st->start_time = AV_NOPTS_VALUE;
     st->duration = AV_NOPTS_VALUE;
+    st->cur_dts = AV_NOPTS_VALUE;
 
     /* default pts settings is MPEG like */
     av_set_pts_info(st, 33, 1, 90000);
@@ -1836,27 +1870,68 @@
  * one audio or video frame.
  *
  * @param s media file handle
- * @param stream_index stream index
- * @param buf buffer containing the frame data
- * @param size size of buffer
+ * @param pkt the packet, which contains the stream_index, buf/buf_size, dts/pts, ...
  * @return < 0 if error, = 0 if OK, 1 if end of stream wanted.
  */
-int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, 
-                   int size)
+int av_write_frame(AVFormatContext *s, AVPacket *pkt)
 {
     AVStream *st;
     int64_t pts_mask;
     int ret, frame_size;
+    int b_frames;
 
-    st = s->streams[stream_index];
-    pts_mask = (1LL << st->pts_wrap_bits) - 1;
+    if(pkt->stream_index<0)
+        return -1;
+    st = s->streams[pkt->stream_index];
+
+    b_frames = FFMAX(st->codec.has_b_frames, st->codec.max_b_frames);
+
+  //  av_log(s, AV_LOG_DEBUG, "av_write_frame: pts:%lld dts:%lld cur_dts:%lld b:%d size:%d\n", pkt->pts, pkt->dts, st->cur_dts, b_frames, pkt->size);
+    
+/*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
+        return -1;*/
+            
+    if(pkt->pts != AV_NOPTS_VALUE)
+        pkt->pts = av_rescale(pkt->pts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
+    if(pkt->dts != AV_NOPTS_VALUE)
+        pkt->dts = av_rescale(pkt->dts, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
+
+    /* duration field */
+    pkt->duration = av_rescale(pkt->duration, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num);
 
-    /* HACK/FIXME we skip all zero size audio packets so a encoder can pass pts by outputing zero size packets */
-    if(st->codec.codec_type==CODEC_TYPE_AUDIO && size==0)
-        ret = 0;
-    else
-        ret = s->oformat->write_packet(s, stream_index, buf, size, 
-                                       st->pts.val & pts_mask);
+    //XXX/FIXME this is a temporary hack until all encoders output pts
+    if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !b_frames){
+        pkt->dts=
+//        pkt->pts= st->cur_dts;
+        pkt->pts= st->pts.val;
+    }
+
+    //calculate dts from pts    
+    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE){
+        if(b_frames){
+            if(st->last_IP_pts == AV_NOPTS_VALUE){
+                st->last_IP_pts= -av_rescale(1, 
+                    st->codec.frame_rate_base*(int64_t)st->time_base.den, 
+                    st->codec.frame_rate     *(int64_t)st->time_base.num);
+            }
+            if(st->last_IP_pts < pkt->pts){
+                pkt->dts= st->last_IP_pts;
+                st->last_IP_pts= pkt->pts;
+            }else
+                pkt->dts= pkt->pts;
+        }else
+            pkt->dts= pkt->pts;
+    }
+    
+//    av_log(s, AV_LOG_DEBUG, "av_write_frame: pts2:%lld dts2:%lld\n", pkt->pts, pkt->dts);
+    st->cur_dts= pkt->dts;
+    st->pts.val= pkt->dts;
+
+    pts_mask = (2LL << (st->pts_wrap_bits-1)) - 1;
+    pkt->pts &= pts_mask;
+    pkt->dts &= pts_mask;
+    
+    ret = s->oformat->write_packet(s, pkt);
     
     if (ret < 0)
         return ret;
@@ -1864,11 +1939,11 @@
     /* update pts */
     switch (st->codec.codec_type) {
     case CODEC_TYPE_AUDIO:
-        frame_size = get_audio_frame_size(&st->codec, size);
+        frame_size = get_audio_frame_size(&st->codec, pkt->size);
 
         /* HACK/FIXME, we skip the initial 0-size packets as they are most likely equal to the encoder delay,
            but it would be better if we had the real timestamps from the encoder */
-        if (frame_size >= 0 && (size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
+        if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
             av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
         }
         break;
--- a/wav.c	Tue May 25 23:06:00 2004 +0000
+++ b/wav.c	Sat May 29 02:06:32 2004 +0000
@@ -203,11 +203,10 @@
     return 0;
 }
 
-static int wav_write_packet(AVFormatContext *s, int stream_index_ptr,
-                            const uint8_t *buf, int size, int64_t pts)
+static int wav_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ByteIOContext *pb = &s->pb;
-    put_buffer(pb, buf, size);
+    put_buffer(pb, pkt->data, pkt->size);
     return 0;
 }
 
--- a/yuv4mpeg.c	Tue May 25 23:06:00 2004 +0000
+++ b/yuv4mpeg.c	Sat May 29 02:06:32 2004 +0000
@@ -58,10 +58,9 @@
     return n;
 }
 
-static int yuv4_write_packet(AVFormatContext *s, int stream_index,
-                             const uint8_t *buf, int size, int64_t pts)
+static int yuv4_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    AVStream *st = s->streams[stream_index];
+    AVStream *st = s->streams[pkt->stream_index];
     ByteIOContext *pb = &s->pb;
     AVPicture *picture;
     int* first_pkt = s->priv_data;
@@ -71,7 +70,7 @@
     char buf1[20];
     uint8_t *ptr, *ptr1, *ptr2;
 
-    picture = (AVPicture *)buf;
+    picture = (AVPicture *)pkt->data;
 
     /* for the first packet we have to output the header as well */
     if (*first_pkt) {