# HG changeset patch # User bellard # Date 1071573426 0 # Node ID f5af91b8be17b3e0a55bf696a546ca202e48f6c5 # Parent 2d11403fde4e00c904734a069301b72d7775efe3 pts and dts support in parser API diff -r 2d11403fde4e -r f5af91b8be17 avcodec.h --- a/avcodec.h Tue Dec 16 01:17:58 2003 +0000 +++ b/avcodec.h Tue Dec 16 11:17:06 2003 +0000 @@ -17,7 +17,7 @@ #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 @@ /* 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 @@ 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; diff -r 2d11403fde4e -r f5af91b8be17 parser.c --- a/parser.c Tue Dec 16 01:17:58 2003 +0000 +++ b/parser.c Tue Dec 16 11:17:06 2003 +0000 @@ -68,23 +68,56 @@ 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;