summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-rw-r--r--demux/demux_mkv.c87
1 files changed, 40 insertions, 47 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index ec98bc81a9..b0e7ed0ac2 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -129,7 +129,6 @@ typedef struct mkv_track {
int realmedia;
int64_t rv_kf_base;
int rv_kf_pts;
- double rv_pts; /* previous video timestamp */
double ra_pts; /* previous audio timestamp */
/** realaudio descrambling */
@@ -1940,49 +1939,43 @@ static int demux_mkv_read_block_lacing(bstr *buffer, int *laces,
#define SKIP_BITS(n) buffer<<=n
#define SHOW_BITS(n) ((buffer)>>(32-(n)))
-static double real_fix_timestamp(unsigned char *buf, unsigned int timestamp, unsigned int format, int64_t *kf_base, int *kf_pts, double *pts){
- double v_pts;
- unsigned char *s = buf + 1 + (*buf+1)*8;
- uint32_t buffer= (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3];
- unsigned int kf=timestamp;
-
- if(format==MP_FOURCC('R','V','3','0') || format==MP_FOURCC('R','V','4','0')){
- int pict_type;
- if(format==MP_FOURCC('R','V','3','0')){
- SKIP_BITS(3);
- pict_type= SHOW_BITS(2);
- SKIP_BITS(2 + 7);
- }else{
- SKIP_BITS(1);
- pict_type= SHOW_BITS(2);
- SKIP_BITS(2 + 7 + 3);
- }
- kf= SHOW_BITS(13); // kf= 2*SHOW_BITS(12);
-// if(pict_type==0)
- if(pict_type<=1){
- // I frame, sync timestamps:
- *kf_base=(int64_t)timestamp-kf;
- mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: base=%08"PRIX64"\n",*kf_base);
- kf=timestamp;
+static int64_t real_fix_timestamp(unsigned char *buf, int len, int64_t timestamp,
+ unsigned int format, int64_t *kf_base,
+ int *kf_pts)
+{
+ if (format != MP_FOURCC('R', 'V', '3', '0') &&
+ format != MP_FOURCC('R', 'V', '4', '0'))
+ return timestamp;
+
+ if (len < 1) // invalid packet
+ return timestamp;
+
+ int offset = 1 + (buf[0] + 1) * 8;
+ if (offset + 4 > len) // invalid packet
+ return timestamp;
+
+ int hdr = AV_RB32(buf + offset);
+ int pict_type, pts;
+ if (format == MP_FOURCC('R', 'V', '3', '0')) {
+ pict_type = (hdr >> 27) & 3;
+ pts = (hdr >> 7) & 0x1FFF;
+ } else {
+ pict_type = (hdr >> 29) & 3;
+ pts = (hdr >> 6) & 0x1FFF;
+ }
+
+ if (pict_type != 3) {
+ *kf_base = timestamp;
+ *kf_pts = pts;
} else {
- // P/B frame, merge timestamps:
- int64_t tmp=(int64_t)timestamp-*kf_base;
- kf|=tmp&(~0x1fff); // combine with packet timestamp
- if(kf<tmp-4096) kf+=8192; else // workaround wrap-around problems
- if(kf>tmp+4096) kf-=8192;
- kf+=*kf_base;
- }
- if(pict_type != 3){ // P || I frame -> swap timestamps
- unsigned int tmp=kf;
- kf=*kf_pts;
- *kf_pts=tmp;
-// if(kf<=tmp) kf=0;
- }
- }
- v_pts=kf*0.001f;
-// if(pts && (v_pts<*pts || !kf)) v_pts=*pts+frametime;
- if(pts) *pts=v_pts;
- return v_pts;
+ if (pict_type != 3) {
+ timestamp = *kf_base + ((pts - *kf_pts) & 0x1FFF);
+ } else {
+ timestamp = *kf_base - ((*kf_pts - pts) & 0x1FFF);
+ }
+ }
+
+ return timestamp;
}
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
@@ -1990,19 +1983,19 @@ static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
demux_packet_t *dp;
- uint32_t timestamp = mkv_d->last_pts * 1000;
+ int64_t timestamp = mkv_d->last_pts * 1000;
dp = new_demux_packet_from(data.start, data.len);
if (mkv_d->v_skip_to_keyframe) {
dp->pts = mkv_d->last_pts;
track->rv_kf_base = 0;
- track->rv_kf_pts = timestamp;
+ track->rv_kf_pts = 0;
} else {
dp->pts =
- real_fix_timestamp(dp->buffer, timestamp,
+ real_fix_timestamp(dp->buffer, dp->len, timestamp,
track->stream->video->bih->biCompression,
- &track->rv_kf_base, &track->rv_kf_pts, NULL);
+ &track->rv_kf_base, &track->rv_kf_pts) * 0.001;
}
dp->pos = mkv_d->last_filepos;
dp->keyframe = keyframe;