mirror of https://git.ffmpeg.org/ffmpeg.git
the new output PTS handling is now generic
Originally committed as revision 1058 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6b10e6e48c
commit
1e51d801d3
|
@ -84,6 +84,7 @@ typedef struct AVOutputFormat {
|
||||||
enum CodecID audio_codec; /* default audio codec */
|
enum CodecID audio_codec; /* default audio codec */
|
||||||
enum CodecID video_codec; /* default video codec */
|
enum CodecID video_codec; /* default video codec */
|
||||||
int (*write_header)(struct AVFormatContext *);
|
int (*write_header)(struct AVFormatContext *);
|
||||||
|
/* XXX: change prototype for 64 bit pts */
|
||||||
int (*write_packet)(struct AVFormatContext *,
|
int (*write_packet)(struct AVFormatContext *,
|
||||||
int stream_index,
|
int stream_index,
|
||||||
unsigned char *buf, int size, int force_pts);
|
unsigned char *buf, int size, int force_pts);
|
||||||
|
@ -142,6 +143,8 @@ typedef struct AVStream {
|
||||||
int codec_info_state;
|
int codec_info_state;
|
||||||
int codec_info_nb_repeat_frames;
|
int codec_info_nb_repeat_frames;
|
||||||
int codec_info_nb_real_frames;
|
int codec_info_nb_real_frames;
|
||||||
|
/* PTS generation when outputing stream */
|
||||||
|
AVFrac pts;
|
||||||
/* ffmpeg.c private use */
|
/* ffmpeg.c private use */
|
||||||
int stream_copy; /* if TRUE, just copy stream */
|
int stream_copy; /* if TRUE, just copy stream */
|
||||||
} AVStream;
|
} AVStream;
|
||||||
|
@ -297,7 +300,8 @@ void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits,
|
||||||
|
|
||||||
/* media file output */
|
/* media file output */
|
||||||
int av_write_header(AVFormatContext *s);
|
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);
|
int av_write_trailer(AVFormatContext *s);
|
||||||
|
|
||||||
void dump_format(AVFormatContext *ic,
|
void dump_format(AVFormatContext *ic,
|
||||||
|
|
57
libav/tick.h
57
libav/tick.h
|
@ -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;
|
|
||||||
}
|
|
|
@ -17,7 +17,6 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
#include "tick.h"
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifndef CONFIG_WIN32
|
#ifndef CONFIG_WIN32
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -695,25 +694,76 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
|
||||||
*/
|
*/
|
||||||
int av_write_header(AVFormatContext *s)
|
int av_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
|
int ret, i;
|
||||||
|
AVStream *st;
|
||||||
|
|
||||||
s->priv_data = av_mallocz(s->oformat->priv_data_size);
|
s->priv_data = av_mallocz(s->oformat->priv_data_size);
|
||||||
if (!s->priv_data)
|
if (!s->priv_data)
|
||||||
return AVERROR_NOMEM;
|
return AVERROR_NOMEM;
|
||||||
/* default pts settings is MPEG like */
|
/* default pts settings is MPEG like */
|
||||||
av_set_pts_info(s, 33, 1, 90000);
|
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 s media file handle
|
||||||
* @param pkt packet to write
|
* @param stream_index stream index
|
||||||
* @param force_pts XXX: need to suppress that
|
* @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 */
|
AVStream *st;
|
||||||
return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue