diff options
author | Fabrice Bellard <fabrice@bellard.org> | 2002-10-21 17:40:23 +0000 |
---|---|---|
committer | Fabrice Bellard <fabrice@bellard.org> | 2002-10-21 17:40:23 +0000 |
commit | 1e51d801d349154fc73fdd99ec0fc1bf8a6f4e05 (patch) | |
tree | 21906788216b2afc76ee4041711f799cae0a803d | |
parent | 6b10e6e48c970476db90f7efc80a1f79629ff452 (diff) | |
download | ffmpeg-1e51d801d349154fc73fdd99ec0fc1bf8a6f4e05.tar.gz |
the new output PTS handling is now generic
Originally committed as revision 1058 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libav/avformat.h | 6 | ||||
-rw-r--r-- | libav/tick.h | 57 | ||||
-rw-r--r-- | libav/utils.c | 66 |
3 files changed, 63 insertions, 66 deletions
diff --git a/libav/avformat.h b/libav/avformat.h index d8679d164d..1fc099a145 100644 --- a/libav/avformat.h +++ b/libav/avformat.h @@ -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 index e2d747e336..0000000000 --- a/libav/tick.h +++ /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; -} diff --git a/libav/utils.c b/libav/utils.c index 89c32be03a..da4f6329fe 100644 --- a/libav/utils.c +++ b/libav/utils.c @@ -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; } /** |