1
0
mirror of https://github.com/mpv-player/mpv synced 2025-03-01 20:00:37 +00:00

demux_mkv: use libavcodec parser for realvideo

Appears to work, so we can drop some code. For some really odd reason,
the descrambling done on the timestamp requires millisecond units (due
to the "algorithm", not the libavcodec API).
This commit is contained in:
wm4 2015-02-05 21:53:49 +01:00
parent 5e9ba816cf
commit e2f4554fd9

View File

@ -1243,6 +1243,7 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track)
extradata_size = cnt + 8; extradata_size = cnt + 8;
extradata = src - 8; extradata = src - 8;
track->realmedia = 1; track->realmedia = 1;
track->parse = track->parse_timestamps = true;
mp_set_codec_from_tag(sh); mp_set_codec_from_tag(sh);
} else if (strcmp(track->codec_id, MKV_V_UNCOMPRESSED) == 0) { } else if (strcmp(track->codec_id, MKV_V_UNCOMPRESSED) == 0) {
// raw video, "like AVI" - this is a FourCC // raw video, "like AVI" - this is a FourCC
@ -1950,68 +1951,6 @@ static int demux_mkv_read_block_lacing(bstr *buffer, int *laces,
return 1; return 1;
} }
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 {
timestamp = *kf_base - ((*kf_pts - pts) & 0x1FFF);
}
return timestamp;
}
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
bstr data, bool keyframe)
{
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
demux_packet_t *dp;
int64_t timestamp = mkv_d->last_pts * 1000;
dp = new_demux_packet_from(data.start, data.len);
if (!dp)
return;
if (mkv_d->v_skip_to_keyframe) {
dp->pts = mkv_d->last_pts;
track->rv_kf_base = 0;
track->rv_kf_pts = 0;
} else {
dp->pts =
real_fix_timestamp(dp->buffer, dp->len, timestamp,
track->stream->format,
&track->rv_kf_base, &track->rv_kf_pts) * 0.001;
}
dp->pos = mkv_d->last_filepos;
dp->keyframe = keyframe;
demux_add_packet(track->stream, dp);
}
static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track, static void handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
bstr data, bool keyframe) bstr data, bool keyframe)
{ {
@ -2249,12 +2188,9 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
{ {
struct sh_stream *stream = track->stream; struct sh_stream *stream = track->stream;
if (track->realmedia) { if (track->realmedia && stream->type == STREAM_AUDIO) {
bstr block = {dp->buffer, dp->len}; bstr block = {dp->buffer, dp->len};
if (stream->type == STREAM_VIDEO) handle_realaudio(demuxer, track, block, dp->keyframe);
handle_realvideo(demuxer, track, block, dp->keyframe);
if (stream->type == STREAM_AUDIO)
handle_realaudio(demuxer, track, block, dp->keyframe);
talloc_free(dp); talloc_free(dp);
return; return;
} }
@ -2300,7 +2236,7 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
return; return;
} }
double tb = 1e9; double tb = track->realmedia ? 1e3 : 1e9;
int64_t pts = dp->pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : dp->pts * tb; int64_t pts = dp->pts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : dp->pts * tb;
int64_t dts = dp->dts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : dp->dts * tb; int64_t dts = dp->dts == MP_NOPTS_VALUE ? AV_NOPTS_VALUE : dp->dts * tb;