pts and dts support in parser API

Originally committed as revision 2619 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2003-12-16 11:17:06 +00:00
parent ac3d5cac7b
commit b84f2a3533
2 changed files with 50 additions and 6 deletions

View File

@ -17,7 +17,7 @@ extern "C" {
#define FFMPEG_VERSION_INT 0x000408
#define FFMPEG_VERSION "0.4.8"
#define LIBAVCODEC_BUILD 4696
#define LIBAVCODEC_BUILD 4697
#define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT
#define LIBAVCODEC_VERSION FFMPEG_VERSION
@ -1932,8 +1932,18 @@ typedef struct AVCodecParserContext {
/* video info */
int pict_type; /* XXX: put it back in AVCodecContext */
int repeat_pict; /* XXX: put it back in AVCodecContext */
int64_t pts; /* in us, if given by the codec (used by raw mpeg4) */
int64_t dts; /* in us, if given by the codec (used by raw mpeg4) */
int64_t pts; /* pts of the current frame */
int64_t dts; /* dts of the current frame */
/* private data */
int64_t last_pts;
int64_t last_dts;
#define AV_PARSER_PTS_NB 4
int cur_frame_start_index;
int64_t cur_frame_offset[AV_PARSER_PTS_NB];
int64_t cur_frame_pts[AV_PARSER_PTS_NB];
int64_t cur_frame_dts[AV_PARSER_PTS_NB];
} AVCodecParserContext;
typedef struct AVCodecParser {
@ -1955,7 +1965,8 @@ AVCodecParserContext *av_parser_init(int codec_id);
int av_parser_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size);
const uint8_t *buf, int buf_size,
int64_t pts, int64_t dts);
void av_parser_close(AVCodecParserContext *s);
extern AVCodecParser mpegvideo_parser;

View File

@ -68,23 +68,56 @@ AVCodecParserContext *av_parser_init(int codec_id)
int av_parser_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size,
int64_t pts, int64_t dts)
{
int index;
int index, i, k;
uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
if (buf_size == 0) {
/* padding is always necessary even if EOF, so we add it here */
memset(dummy_buf, 0, sizeof(dummy_buf));
buf = dummy_buf;
} else {
/* add a new packet descriptor */
k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
s->cur_frame_start_index = k;
s->cur_frame_offset[k] = s->cur_offset;
s->cur_frame_pts[k] = pts;
s->cur_frame_dts[k] = dts;
/* fill first PTS/DTS */
if (s->cur_offset == 0) {
s->last_pts = pts;
s->last_dts = dts;
}
}
/* WARNING: the returned index can be negative */
index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
/* update the file pointer */
if (*poutbuf_size) {
/* fill the data for the current frame */
s->frame_offset = s->last_frame_offset;
s->pts = s->last_pts;
s->dts = s->last_dts;
/* offset of the next frame */
s->last_frame_offset = s->cur_offset + index;
/* find the packet in which the new frame starts. It
is tricky because of MPEG video start codes
which can begin in one packet and finish in
another packet. In the worst case, an MPEG
video start code could be in 4 different
packets. */
k = s->cur_frame_start_index;
for(i = 0; i < AV_PARSER_PTS_NB; i++) {
if (s->last_frame_offset >= s->cur_frame_offset[k])
break;
k = (k - 1) & (AV_PARSER_PTS_NB - 1);
}
s->last_pts = s->cur_frame_pts[k];
s->last_dts = s->cur_frame_dts[k];
}
if (index < 0)
index = 0;