Browse Source

Add timestamp computation if values are exported by decoder.

Patch by Ivan Schreter, schreter gmx net

Originally committed as revision 17574 to svn://svn.ffmpeg.org/ffmpeg/trunk
tags/v0.5
Ivan Schreter Carl Eugen Hoyos 17 years ago
parent
commit
27ca0a79c9
4 changed files with 78 additions and 3 deletions
  1. +42
    -1
      libavcodec/avcodec.h
  2. +3
    -0
      libavcodec/parser.c
  3. +12
    -2
      libavformat/avformat.h
  4. +21
    -0
      libavformat/utils.c

+ 42
- 1
libavcodec/avcodec.h View File

@@ -30,7 +30,7 @@
#include "libavutil/avutil.h" #include "libavutil/avutil.h"


#define LIBAVCODEC_VERSION_MAJOR 52 #define LIBAVCODEC_VERSION_MAJOR 52
#define LIBAVCODEC_VERSION_MINOR 18
#define LIBAVCODEC_VERSION_MINOR 19
#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_MICRO 0


#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -3147,6 +3147,47 @@ typedef struct AVCodecParserContext {
* subtitles are correctly displayed after seeking. * subtitles are correctly displayed after seeking.
*/ */
int64_t convergence_duration; int64_t convergence_duration;

// Timestamp generation support:
/**
* Synchronization point for start of timestamp generation.
*
* Set to >0 for sync point, 0 for no sync point and <0 for undefined
* (default).
*
* For example, this corresponds to presence of H.264 buffering period
* SEI message.
*/
int dts_sync_point;

/**
* Offset of the current timestamp against last timestamp sync point in
* units of AVCodecContext.time_base.
*
* Set to INT_MIN when dts_sync_point unused. Otherwise, it must
* contain a valid timestamp offset.
*
* Note that the timestamp of sync point has usually a nonzero
* dts_ref_dts_delta, which refers to the previous sync point. Offset of
* the next frame after timestamp sync point will be usually 1.
*
* For example, this corresponds to H.264 cpb_removal_delay.
*/
int dts_ref_dts_delta;

/**
* Presentation delay of current frame in units of AVCodecContext.time_base.
*
* Set to INT_MIN when dts_sync_point unused. Otherwise, it must
* contain valid non-negative timestamp delta (presentation time of a frame
* must not lie in the past).
*
* This delay represents the difference between decoding and presentation
* time of the frame.
*
* For example, this corresponds to H.264 dpb_output_delay.
*/
int pts_dts_delta;
} AVCodecParserContext; } AVCodecParserContext;


typedef struct AVCodecParser { typedef struct AVCodecParser {


+ 3
- 0
libavcodec/parser.c View File

@@ -75,6 +75,9 @@ AVCodecParserContext *av_parser_init(int codec_id)
s->pict_type = FF_I_TYPE; s->pict_type = FF_I_TYPE;
s->key_frame = -1; s->key_frame = -1;
s->convergence_duration = AV_NOPTS_VALUE; s->convergence_duration = AV_NOPTS_VALUE;
s->dts_sync_point = INT_MIN;
s->dts_ref_dts_delta = INT_MIN;
s->pts_dts_delta = INT_MIN;
return s; return s;
} }




+ 12
- 2
libavformat/avformat.h View File

@@ -22,8 +22,8 @@
#define AVFORMAT_AVFORMAT_H #define AVFORMAT_AVFORMAT_H


#define LIBAVFORMAT_VERSION_MAJOR 52 #define LIBAVFORMAT_VERSION_MAJOR 52
#define LIBAVFORMAT_VERSION_MINOR 29
#define LIBAVFORMAT_VERSION_MICRO 2
#define LIBAVFORMAT_VERSION_MINOR 30
#define LIBAVFORMAT_VERSION_MICRO 0


#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
@@ -494,6 +494,16 @@ typedef struct AVStream {
const uint8_t *cur_ptr; const uint8_t *cur_ptr;
int cur_len; int cur_len;
AVPacket cur_pkt; AVPacket cur_pkt;

// Timestamp generation support:
/**
* Timestamp corresponding to the last dts sync point.
*
* Initialized when AVCodecParserContext.dts_sync_point >= 0 and
* a DTS is received from the underlying container. Otherwise set to
* AV_NOPTS_VALUE by default.
*/
int64_t reference_dts;
} AVStream; } AVStream;


#define AV_PROGRAM_RUNNING 1 #define AV_PROGRAM_RUNNING 1


+ 21
- 0
libavformat/utils.c View File

@@ -834,6 +834,25 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
pkt->dts += offset; pkt->dts += offset;
} }


if (pc && pc->dts_sync_point >= 0) {
// we have synchronization info from the parser
int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num;
if (den > 0) {
int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den;
if (pkt->dts != AV_NOPTS_VALUE) {
// got DTS from the stream, update reference timestamp
st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den;
pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
} else if (st->reference_dts != AV_NOPTS_VALUE) {
// compute DTS based on reference timestamp
pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den;
pkt->pts = pkt->dts + pc->pts_dts_delta * num / den;
}
if (pc->dts_sync_point > 0)
st->reference_dts = pkt->dts; // new reference
}
}

/* This may be redundant, but it should not hurt. */ /* This may be redundant, but it should not hurt. */
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts) if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
presentation_delayed = 1; presentation_delayed = 1;
@@ -1157,6 +1176,7 @@ static void av_read_frame_flush(AVFormatContext *s)
} }
st->last_IP_pts = AV_NOPTS_VALUE; st->last_IP_pts = AV_NOPTS_VALUE;
st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
st->reference_dts = AV_NOPTS_VALUE;
/* fail safe */ /* fail safe */
st->cur_ptr = NULL; st->cur_ptr = NULL;
st->cur_len = 0; st->cur_len = 0;
@@ -2332,6 +2352,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id)
st->last_IP_pts = AV_NOPTS_VALUE; st->last_IP_pts = AV_NOPTS_VALUE;
for(i=0; i<MAX_REORDER_DELAY+1; i++) for(i=0; i<MAX_REORDER_DELAY+1; i++)
st->pts_buffer[i]= AV_NOPTS_VALUE; st->pts_buffer[i]= AV_NOPTS_VALUE;
st->reference_dts = AV_NOPTS_VALUE;


st->sample_aspect_ratio = (AVRational){0,1}; st->sample_aspect_ratio = (AVRational){0,1};




Loading…
Cancel
Save