mirror of
https://github.com/mpv-player/mpv
synced 2025-03-24 04:08:19 +00:00
Support for Quicktime stuff in Matroska (e.g. Sorenson, QDesign Music codecs etc.).
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@10845 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
5485f99b4b
commit
2982f7b1d4
libmpdemux
@ -17,6 +17,7 @@ extern "C" {
|
||||
|
||||
#include "../subreader.h"
|
||||
#include "../libvo/sub.h"
|
||||
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
@ -168,6 +169,10 @@ typedef struct mkv_track {
|
||||
int rm_seqnum, rv_kf_base, rv_kf_pts;
|
||||
float rv_pts; // previous video timestamp
|
||||
float ra_pts; // previous audio timestamp
|
||||
|
||||
// Stuff for QuickTime
|
||||
bool fix_i_bps;
|
||||
float qt_last_a_pts;
|
||||
} mkv_track_t;
|
||||
|
||||
typedef struct mkv_demuxer {
|
||||
@ -277,6 +282,30 @@ typedef struct {
|
||||
uint32_t fourcc3; // fourcc
|
||||
} real_audio_v5_props_t;
|
||||
|
||||
// I have to (re)define this struct here because g++ will not compile
|
||||
// components.h from the qtsdk if I include it.
|
||||
typedef struct {
|
||||
uint32_t id_size;
|
||||
uint32_t codec_type;
|
||||
uint32_t reserved1;
|
||||
uint16_t reserved2;
|
||||
uint16_t data_reference_index;
|
||||
uint16_t version;
|
||||
uint16_t revision;
|
||||
uint32_t vendor;
|
||||
uint32_t temporal_quality;
|
||||
uint32_t spatial_quality;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint32_t horizontal_resolution; // 32bit fixed-point number
|
||||
uint32_t vertical_resolution; // 32bit fixed-point number
|
||||
uint32_t data_size;
|
||||
uint16_t frame_count;
|
||||
char compressor_name[32];
|
||||
uint16_t depth;
|
||||
uint16_t color_table_id;
|
||||
} qt_image_description_t;
|
||||
|
||||
#if __GNUC__ == 2
|
||||
#pragma pack()
|
||||
#else
|
||||
@ -623,7 +652,8 @@ static int check_track_information(mkv_demuxer_t *d) {
|
||||
else if (!strcmp(t->codec_id, MKV_A_DTS))
|
||||
// uses same format tag as AC3, only supported with -hwac3
|
||||
t->a_formattag = 0x2000;
|
||||
else if (!strcmp(t->codec_id, MKV_A_PCM))
|
||||
else if (!strcmp(t->codec_id, MKV_A_PCM) ||
|
||||
!strcmp(t->codec_id, MKV_A_PCM_BE))
|
||||
t->a_formattag = 0x0001;
|
||||
else if (!strcmp(t->codec_id, MKV_A_AAC_2MAIN) ||
|
||||
!strcmp(t->codec_id, MKV_A_AAC_2LC) ||
|
||||
@ -686,6 +716,9 @@ static int check_track_information(mkv_demuxer_t *d) {
|
||||
t->a_formattag = mmioFOURCC('d', 'n', 'e', 't');
|
||||
else if (!strcmp(t->codec_id, MKV_A_REALSIPR))
|
||||
t->a_formattag = mmioFOURCC('s', 'i', 'p', 'r');
|
||||
} else if (!strcmp(t->codec_id, MKV_A_QDMC) ||
|
||||
!strcmp(t->codec_id, MKV_A_QDMC2)) {
|
||||
;
|
||||
} else {
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
|
||||
"codec ID '%s' for track %u or missing/faulty private "
|
||||
@ -706,12 +739,6 @@ static int check_track_information(mkv_demuxer_t *d) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->a_formattag == 0) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] The audio format tag was not "
|
||||
"set for track %u.\n", t->tnum);
|
||||
continue;
|
||||
}
|
||||
|
||||
// This track seems to be ok.
|
||||
t->ok = 1;
|
||||
mp_msg(MSGT_DEMUX, MSGL_INFO, "[mkv] Track ID %u: audio (%s), -aid "
|
||||
@ -1049,6 +1076,7 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
|
||||
vector<uint64_t> seekheads_to_parse;
|
||||
vector<uint64_t> cues_to_parse;
|
||||
int64_t current_pos;
|
||||
qt_image_description_t *idesc;
|
||||
|
||||
#ifdef USE_ICONV
|
||||
subcp_open();
|
||||
@ -1470,6 +1498,7 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
|
||||
if (track) {
|
||||
BITMAPINFOHEADER *bih;
|
||||
|
||||
idesc = NULL;
|
||||
bih = (BITMAPINFOHEADER *)calloc(1, track->private_size);
|
||||
if (bih == NULL) {
|
||||
free_mkv_demuxer(mkv_d);
|
||||
@ -1534,6 +1563,31 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
|
||||
memset(&dst[8], 0, 4);
|
||||
track->realmedia = true;
|
||||
|
||||
#if defined(USE_QTX_CODECS)
|
||||
} else if ((track->private_size >= sizeof(qt_image_description_t)) &&
|
||||
(!strcmp(track->codec_id, MKV_V_QUICKTIME))) {
|
||||
idesc = (qt_image_description_t *)track->private_data;
|
||||
idesc->id_size = get_uint32_be(&idesc->id_size);
|
||||
idesc->codec_type = get_uint32(&idesc->codec_type);
|
||||
idesc->version = get_uint16_be(&idesc->version);
|
||||
idesc->revision = get_uint16_be(&idesc->revision);
|
||||
idesc->vendor = get_uint32_be(&idesc->vendor);
|
||||
idesc->temporal_quality = get_uint32_be(&idesc->temporal_quality);
|
||||
idesc->spatial_quality = get_uint32_be(&idesc->spatial_quality);
|
||||
idesc->width = get_uint16_be(&idesc->width);
|
||||
idesc->height = get_uint16_be(&idesc->height);
|
||||
idesc->horizontal_resolution =
|
||||
get_uint32_be(&idesc->horizontal_resolution);
|
||||
idesc->vertical_resolution =
|
||||
get_uint32_be(&idesc->vertical_resolution);
|
||||
idesc->data_size = get_uint32_be(&idesc->data_size);
|
||||
idesc->frame_count = get_uint16_be(&idesc->frame_count);
|
||||
idesc->depth = get_uint16_be(&idesc->depth);
|
||||
idesc->color_table_id = get_uint16_be(&idesc->color_table_id);
|
||||
bih->biPlanes = 1;
|
||||
bih->biCompression = idesc->codec_type;
|
||||
#endif // defined(USE_QTX_CODECS)
|
||||
|
||||
} else {
|
||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported CodecID "
|
||||
"(%s) or missing/bad CodecPrivate data (track %u).\n",
|
||||
@ -1556,6 +1610,8 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
|
||||
sh_v->disp_w = track->v_width;
|
||||
sh_v->disp_h = track->v_height;
|
||||
sh_v->aspect = (float)track->v_dwidth / (float)track->v_dheight;
|
||||
if (idesc != NULL)
|
||||
sh_v->ImageDesc = idesc;
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Aspect: %f\n", sh_v->aspect);
|
||||
|
||||
demuxer->video->id = track->tnum;
|
||||
@ -1642,10 +1698,30 @@ extern "C" int demux_mkv_open(demuxer_t *demuxer) {
|
||||
sh_a->wf->wBitsPerSample = 0;
|
||||
sh_a->samplesize = 0;
|
||||
|
||||
} else if (!strcmp(track->codec_id, MKV_A_PCM)) {
|
||||
} else if (!strcmp(track->codec_id, MKV_A_PCM) ||
|
||||
!strcmp(track->codec_id, MKV_A_PCM_BE)) {
|
||||
sh_a->wf->nAvgBytesPerSec = sh_a->channels * sh_a->samplerate * 2;
|
||||
sh_a->wf->nBlockAlign = sh_a->wf->nAvgBytesPerSec;
|
||||
sh_a->wf->wBitsPerSample = track->a_bps;
|
||||
if (!strcmp(track->codec_id, MKV_A_PCM_BE))
|
||||
sh_a->format = mmioFOURCC('t', 'w', 'o', 's');
|
||||
|
||||
} else if (!strcmp(track->codec_id, MKV_A_QDMC) ||
|
||||
!strcmp(track->codec_id, MKV_A_QDMC2)) {
|
||||
sh_a->wf->wBitsPerSample = track->a_bps;
|
||||
sh_a->wf->nAvgBytesPerSec = 16000;
|
||||
sh_a->wf->nBlockAlign = 1486;
|
||||
track->fix_i_bps = true;
|
||||
track->qt_last_a_pts = 0.0;
|
||||
if (track->private_data != NULL) {
|
||||
sh_a->codecdata = (unsigned char *)calloc(track->private_size, 1);
|
||||
memcpy(sh_a->codecdata, track->private_data, track->private_size);
|
||||
sh_a->codecdata_len = track->private_size;
|
||||
}
|
||||
if (!strcmp(track->codec_id, MKV_A_QDMC))
|
||||
sh_a->format = mmioFOURCC('Q', 'D', 'M', 'C');
|
||||
else
|
||||
sh_a->format = mmioFOURCC('Q', 'D', 'M', '2');
|
||||
|
||||
} else if (track->a_formattag == mmioFOURCC('M', 'P', '4', 'A')) {
|
||||
int profile, srate_idx;
|
||||
@ -2041,6 +2117,31 @@ extern "C" int demux_mkv_fill_buffer(demuxer_t *d) {
|
||||
else if (mkv_d->v_skip_to_keyframe)
|
||||
use_this_block = false;
|
||||
|
||||
if (mkv_d->audio->fix_i_bps && use_this_block) {
|
||||
uint32_t i, sum;
|
||||
sh_audio_t *sh;
|
||||
|
||||
for (i = 0, sum = 0; i < kblock->NumberFrames(); i++) {
|
||||
DataBuffer &data = kblock->GetBuffer(i);
|
||||
sum += data.Size();
|
||||
}
|
||||
sh = (sh_audio_t *)ds->sh;
|
||||
if (block_duration != -1) {
|
||||
sh->i_bps = sum * 1000 / block_duration;
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Changed i_bps to %d.\n",
|
||||
sh->i_bps);
|
||||
mkv_d->audio->fix_i_bps = false;
|
||||
} else if (mkv_d->audio->qt_last_a_pts == 0.0)
|
||||
mkv_d->audio->qt_last_a_pts = current_pts;
|
||||
else if (mkv_d->audio->qt_last_a_pts != current_pts) {
|
||||
sh->i_bps = (int)(sum / (current_pts -
|
||||
mkv_d->audio->qt_last_a_pts));
|
||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] Changed i_bps to %d.\n",
|
||||
sh->i_bps);
|
||||
mkv_d->audio->fix_i_bps = false;
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((current_pts * 1000) < mkv_d->skip_to_timecode)
|
||||
use_this_block = false;
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define MKV_A_DTS "A_DTS"
|
||||
#define MKV_A_MP3 "A_MPEG/L3"
|
||||
#define MKV_A_PCM "A_PCM/INT/LIT"
|
||||
#define MKV_A_PCM_BE "A_PCM/INT/BIG"
|
||||
#define MKV_A_VORBIS "A_VORBIS"
|
||||
#define MKV_A_ACM "A_MS/ACM"
|
||||
#define MKV_A_REAL28 "A_REAL/28_8"
|
||||
@ -26,12 +27,19 @@
|
||||
#define MKV_A_REALCOOK "A_REAL/COOK"
|
||||
#define MKV_A_REALDNET "A_REAL/DNET"
|
||||
#define MKV_A_REALSIPR "A_REAL/SIPR"
|
||||
#define MKV_A_QDMC "A_QDESIGNMUSIC"
|
||||
#define MKV_A_QDMC2 "A_QDESIGNMUSIC/V2"
|
||||
|
||||
#define MKV_V_MSCOMP "V_MS/VFW/FOURCC"
|
||||
#define MKV_V_REALV10 "V_REAL/RV10"
|
||||
#define MKV_V_REALV20 "V_REAL/RV20"
|
||||
#define MKV_V_REALV30 "V_REAL/RV30"
|
||||
#define MKV_V_REALV40 "V_REAL/RV40"
|
||||
#define MKV_V_SORENSONV1 "V_SORENSON/V1"
|
||||
#define MKV_V_SORENSONV2 "V_SORENSON/V2"
|
||||
#define MKV_V_SORENSONV3 "V_SORENSON/V3"
|
||||
#define MKV_V_CINEPAK "V_CINEPAK"
|
||||
#define MKV_V_QUICKTIME "V_QUICKTIME"
|
||||
|
||||
#define MKV_S_TEXTASCII "S_TEXT/ASCII"
|
||||
#define MKV_S_TEXTUTF8 "S_TEXT/UTF8"
|
||||
|
Loading…
Reference in New Issue
Block a user