diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2004-05-29 02:06:32 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-05-29 02:06:32 +0000 |
commit | e928649b0bf6c8c7b87eb09d5e393a70387b10e9 (patch) | |
tree | 3f065adcb0e5c14127d01162d7cc8a0d934c073f /libavformat | |
parent | a7b2871cd1401ce7be59b153eed3f25565b0bb23 (diff) | |
download | ffmpeg-e928649b0bf6c8c7b87eb09d5e393a70387b10e9.tar.gz |
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
Originally committed as revision 3168 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/amr.c | 5 | ||||
-rw-r--r-- | libavformat/asf-enc.c | 12 | ||||
-rw-r--r-- | libavformat/au.c | 5 | ||||
-rw-r--r-- | libavformat/audio.c | 5 | ||||
-rw-r--r-- | libavformat/avformat.h | 10 | ||||
-rw-r--r-- | libavformat/avienc.c | 15 | ||||
-rw-r--r-- | libavformat/crc.c | 6 | ||||
-rw-r--r-- | libavformat/dv.c | 8 | ||||
-rw-r--r-- | libavformat/ffm.c | 16 | ||||
-rw-r--r-- | libavformat/flvenc.c | 13 | ||||
-rw-r--r-- | libavformat/gif.c | 7 | ||||
-rw-r--r-- | libavformat/img.c | 7 | ||||
-rw-r--r-- | libavformat/movenc.c | 16 | ||||
-rw-r--r-- | libavformat/mp3.c | 5 | ||||
-rw-r--r-- | libavformat/mpeg.c | 13 | ||||
-rw-r--r-- | libavformat/mpegtsenc.c | 9 | ||||
-rw-r--r-- | libavformat/mpjpeg.c | 10 | ||||
-rw-r--r-- | libavformat/nut.c | 17 | ||||
-rw-r--r-- | libavformat/ogg.c | 13 | ||||
-rw-r--r-- | libavformat/raw.c | 9 | ||||
-rw-r--r-- | libavformat/rm.c | 9 | ||||
-rw-r--r-- | libavformat/rtp.c | 9 | ||||
-rw-r--r-- | libavformat/swf.c | 9 | ||||
-rw-r--r-- | libavformat/utils.c | 113 | ||||
-rw-r--r-- | libavformat/wav.c | 5 | ||||
-rw-r--r-- | libavformat/yuv4mpeg.c | 7 |
26 files changed, 209 insertions, 144 deletions
diff --git a/libavformat/amr.c b/libavformat/amr.c index 67a7748bda..760eb995ae 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -51,10 +51,9 @@ static int amr_write_header(AVFormatContext *s) 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; } diff --git a/libavformat/asf-enc.c b/libavformat/asf-enc.c index 3dcf43e862..9e87909858 100644 --- a/libavformat/asf-enc.c +++ b/libavformat/asf-enc.c @@ -310,7 +310,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data 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 @@ static void put_frame( 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 @@ static int asf_write_packet(AVFormatContext *s, int stream_index, 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; } diff --git a/libavformat/au.c b/libavformat/au.c index c9837f7c76..5515c3257b 100644 --- a/libavformat/au.c +++ b/libavformat/au.c @@ -72,11 +72,10 @@ static int au_write_header(AVFormatContext *s) 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; } diff --git a/libavformat/audio.c b/libavformat/audio.c index 00f705c372..e3e5888e9b 100644 --- a/libavformat/audio.c +++ b/libavformat/audio.c @@ -164,11 +164,12 @@ static int audio_write_header(AVFormatContext *s1) } } -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; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 966d2fd096..ae1f9fe69d 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -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 @@ typedef struct AVOutputFormat { 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 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts /* 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, diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 7b3857fd3d..86f0e83446 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -607,14 +607,15 @@ static int avi_write_idx1(AVFormatContext *s) 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 @@ static int avi_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int avi_write_packet(AVFormatContext *s, int stream_index, 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); diff --git a/libavformat/crc.c b/libavformat/crc.c index 1b8d6a4df3..ee915debc5 100644 --- a/libavformat/crc.c +++ b/libavformat/crc.c @@ -71,12 +71,10 @@ static int crc_write_header(struct AVFormatContext *s) 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; } diff --git a/libavformat/dv.c b/libavformat/dv.c index ec87068a9f..8b029eb0e2 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -888,15 +888,13 @@ static int dv_write_header(AVFormatContext *s) 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); diff --git a/libavformat/ffm.c b/libavformat/ffm.c index 651abaa8f2..fca46b170f 100644 --- a/libavformat/ffm.c +++ b/libavformat/ffm.c @@ -222,15 +222,16 @@ static int ffm_write_header(AVFormatContext *s) 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 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) fst = av_mallocz(sizeof(FFMStream)); if (!fst) goto fail; + + av_set_pts_info(st, 64, 1, 1000000); + st->priv_data = fst; codec = &st->codec; diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index a44ebd966d..aa1308ce2d 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -239,18 +239,19 @@ static int flv_write_trailer(AVFormatContext *s) 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 @@ static int flv_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int flv_write_packet(AVFormatContext *s, int stream_index, assert(size); if ( flv->initDelay == -1 ) { - flv->initDelay = timestamp; + flv->initDelay = pkt->pts; } frame->type = 8; diff --git a/libavformat/gif.c b/libavformat/gif.c index 7867913da2..3a5f041e61 100644 --- a/libavformat/gif.c +++ b/libavformat/gif.c @@ -364,14 +364,13 @@ static int gif_write_video(AVFormatContext *s, 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) diff --git a/libavformat/img.c b/libavformat/img.c index 9c47d38626..468cb6e2f0 100644 --- a/libavformat/img.c +++ b/libavformat/img.c @@ -300,11 +300,10 @@ static int img_write_header(AVFormatContext *s) 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 @@ static int img_write_packet(AVFormatContext *s, int stream_index, 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), diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 0e3fb6a9de..0315d18b69 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -950,15 +950,15 @@ static int mov_write_header(AVFormatContext *s) 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 @@ static int mov_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int mov_write_packet(AVFormatContext *s, int stream_index, 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 @@ static int mov_write_packet(AVFormatContext *s, int stream_index, trk->sampleCount += samplesInChunk; trk->mdat_size += size; - put_buffer(pb, buf, size); + put_buffer(pb, pkt->data, size); put_flush_packet(pb); return 0; diff --git a/libavformat/mp3.c b/libavformat/mp3.c index 0da8a400e9..bb6deb2f3a 100644 --- a/libavformat/mp3.c +++ b/libavformat/mp3.c @@ -324,10 +324,9 @@ static int mp3_write_header(struct AVFormatContext *s) 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; } diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index e0060584c6..ffe19ea6ec 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -912,17 +912,22 @@ static int64_t update_scr(AVFormatContext *ctx,int stream_index,int64_t pts) } -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 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 7a20f8525a..fbbb83db03 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -549,10 +549,11 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, 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 @@ static int mpegts_write_packet(AVFormatContext *s, int stream_index, 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); diff --git a/libavformat/mpjpeg.c b/libavformat/mpjpeg.c index 434e519d50..da61c0726a 100644 --- a/libavformat/mpjpeg.c +++ b/libavformat/mpjpeg.c @@ -33,14 +33,13 @@ static int mpjpeg_write_header(AVFormatContext *s) 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 @@ static int single_jpeg_write_header(AVFormatContext *s) 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 */ } diff --git a/libavformat/nut.c b/libavformat/nut.c index cb327675fb..22999ec975 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -691,25 +691,22 @@ static int64_t lsb2full(StreamContext *stream, int64_t lsb){ 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 @@ static int nut_write_packet(AVFormatContext *s, int stream_index, 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); diff --git a/libavformat/ogg.c b/libavformat/ogg.c index 82354c6cdd..3d90868a02 100644 --- a/libavformat/ogg.c +++ b/libavformat/ogg.c @@ -62,16 +62,15 @@ static int ogg_write_header(AVFormatContext *avfcontext) 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 @@ static int ogg_write_packet(AVFormatContext *avfcontext, 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; diff --git a/libavformat/raw.c b/libavformat/raw.c index 1c65f3aaad..fbdbb7aa1c 100644 --- a/libavformat/raw.c +++ b/libavformat/raw.c @@ -25,10 +25,9 @@ static int raw_write_header(struct AVFormatContext *s) 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 @@ AVOutputFormat rawvideo_oformat = { #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; } diff --git a/libavformat/rm.c b/libavformat/rm.c index 7942337541..828921822c 100644 --- a/libavformat/rm.c +++ b/libavformat/rm.c @@ -389,14 +389,13 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size) 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) diff --git a/libavformat/rtp.c b/libavformat/rtp.c index 5d4884d8f7..31e4a21dc1 100644 --- a/libavformat/rtp.c +++ b/libavformat/rtp.c @@ -669,16 +669,17 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1, } /* 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 @@ static int rtp_write_packet(AVFormatContext *s1, int stream_index, 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; diff --git a/libavformat/swf.c b/libavformat/swf.c index 3f5ddd1678..798c9b1ee3 100644 --- a/libavformat/swf.c +++ b/libavformat/swf.c @@ -700,14 +700,13 @@ static int swf_write_audio(AVFormatContext *s, 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) diff --git a/libavformat/utils.c b/libavformat/utils.c index b60367c090..3232f0276f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -569,10 +569,12 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, 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 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, 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 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, } 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 @@ int av_find_stream_info(AVFormatContext *ic) } 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 @@ AVStream *av_new_stream(AVFormatContext *s, int id) 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 @@ int av_write_header(AVFormatContext *s) * 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]; - /* 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); + 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); + + //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 @@ int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, /* 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; diff --git a/libavformat/wav.c b/libavformat/wav.c index 495ae0f969..1d18098339 100644 --- a/libavformat/wav.c +++ b/libavformat/wav.c @@ -203,11 +203,10 @@ static int wav_write_header(AVFormatContext *s) 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; } diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c index 1520b34635..1a18ad03ea 100644 --- a/libavformat/yuv4mpeg.c +++ b/libavformat/yuv4mpeg.c @@ -58,10 +58,9 @@ static int yuv4_generate_header(AVFormatContext *s, char* buf) 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 @@ static int yuv4_write_packet(AVFormatContext *s, int stream_index, 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) { |