diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/demuxers/demux_real.c | 101 | ||||
-rw-r--r-- | src/libreal/xine_real_video_decoder.c | 2 |
2 files changed, 33 insertions, 70 deletions
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c index 8e95f28ca..3b3aea6db 100644 --- a/src/demuxers/demux_real.c +++ b/src/demuxers/demux_real.c @@ -160,11 +160,6 @@ typedef struct { int send_newpts; int buf_flag_seek; - uint32_t last_ts; - uint32_t next_ts; - int last_seq; - int next_seq; - int fragment_size; /* video sub-demux */ int fragment_count; uint32_t *fragment_tab; @@ -1000,72 +995,43 @@ static void check_newpts (demux_real_t *this, int64_t pts, int video, int previe this->last_pts[video] = pts; } -static uint32_t real_fix_timestamp (demux_real_t *this, uint8_t *hdr, uint32_t ts_in) { - int pict_type; - int seq; - uint32_t ts_out; - - switch(this->video_stream->buf_type) { +static uint32_t real_get_reordered_pts (demux_real_t *this, uint8_t *hdr, uint32_t dts) { + int pict_type; /* I1/I2/P/B-frame */ + uint32_t t, pts; + /* lower 13 bits of pts are stored within the frame */ + pict_type = hdr[0]; + t = ((((uint32_t)hdr[1] << 8) | hdr[2]) << 8) | hdr[3]; + switch (this->video_stream->buf_type) { case BUF_VIDEO_RV20: - pict_type = (hdr[0] & 0xC0) >> 6; - seq = ((hdr[1] & 0x7F) << 6) + ((hdr[2] & 0xFC) >> 2); - break; + pict_type >>= 6; + t >>= 10; + break; case BUF_VIDEO_RV30: - pict_type = (hdr[0] & 0x18) >> 3; - seq = ((hdr[1] & 0x0F) << 9) + (hdr[2] << 1) + ((hdr[3] & 0x80) >> 7); - break; + pict_type >>= 3; + t >>= 7; + break; case BUF_VIDEO_RV40: - pict_type = (hdr[0] & 0x60) >> 5; - seq = ((hdr[1] & 0x07) << 10) + (hdr[2] << 2) + ((hdr[3] & 0xC0) >> 6); - break; + pict_type >>= 5; + t >>= 6; + break; default: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: can't fix timestamp for buf type 0x%08x\n", this->video_stream->buf_type); - return ts_in; - break; - } - - switch (pict_type) { - case 0: - case 1: - /* I frame */ - ts_out = this->next_ts; - - this->last_ts = this->next_ts; - this->next_ts = ts_in; - - this->last_seq = this->next_seq; - this->next_seq = seq; - break; - case 2: - /* P frame */ - ts_out = this->next_ts; - - this->last_ts = this->next_ts; - if (seq < this->next_seq) - this->next_ts += seq + 8192 - this->next_seq; - else - this->next_ts += seq - this->next_seq; - - this->last_seq = this->next_seq; - this->next_seq = seq; - break; - case 3: - /* B frame */ - if (seq < this->last_seq) - ts_out = ((seq + 8192 - this->last_seq) + this->last_ts); - else - ts_out = ((seq - this->last_seq) + this->last_ts); - break; - default: - xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, - "demux_real: unknown pict_type: %d\n", pict_type); - ts_out = 0; - break; + return (dts); + break; } - return ts_out; + pict_type &= 3; + t &= 0x1fff; + pts = (dts & (~0x1fff)) | t; + /* snap to dts +/- 4.095 seconds */ + if (dts + 0x1000 < pts) pts -= 0x2000; + else if (dts > pts + 0x1000) pts += 0x2000; + xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, + "demux_real: video pts: %d.%03d:%04d -> %d.%03d (%d)\n", + dts / 1000, dts % 1000, t, pts / 1000, pts % 1000, pict_type); + return (pts); } static int stream_read_char (demux_real_t *this) { @@ -1330,14 +1296,14 @@ static int demux_real_send_chunk(demux_plugin_t *this_gen) { /* if the video stream has b-frames fix the timestamps */ if((this->video_stream->format >= 0x20200002) && (buf->decoder_flags & BUF_FLAG_FRAME_START)) - pts = (int64_t) real_fix_timestamp(this, buf->content, timestamp) * 90; + pts = (int64_t)real_get_reordered_pts (this, buf->content, timestamp) * 90; /* this test was moved from ffmpeg video decoder. * fixme: is pts only valid on frame start? */ - if( buf->decoder_flags & BUF_FLAG_FRAME_START ) + if (buf->decoder_flags & BUF_FLAG_FRAME_START) { buf->pts = pts; - else - buf->pts = 0; + check_newpts (this, pts, PTS_VIDEO, 0); + } else buf->pts = 0; pts = 0; buf->extra_info->input_normpos = normpos; @@ -1640,9 +1606,6 @@ static int demux_real_seek (demux_plugin_t *this_gen, this->old_seqnum = -1; this->fragment_size = 0; - this->next_ts = 0; - this->next_seq = 0; - this->status = DEMUX_OK; return this->status; diff --git a/src/libreal/xine_real_video_decoder.c b/src/libreal/xine_real_video_decoder.c index 48ff6f416..63feaeb15 100644 --- a/src/libreal/xine_real_video_decoder.c +++ b/src/libreal/xine_real_video_decoder.c @@ -420,7 +420,7 @@ static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) XINE_IMGFMT_YV12, VO_BOTH_FIELDS); - img->pts = this->pts; + img->pts = (int64_t)transform_out.timestamp * 90; img->duration = this->duration; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration); img->bad_frame = 0; |