Bugfix: RealVideo was not read correctly from Matroska files. New feature: RealAudio can be read from Matroska files.

This commit is contained in:
Moritz Bunkus 2003-09-16 19:05:36 +00:00
parent 53417a48bb
commit b3b283ee1f
3 changed files with 66 additions and 29 deletions

View File

@ -1,5 +1,10 @@
2003-09-16 Moritz Bunkus <moritz@bunkus.org> 2003-09-16 Moritz Bunkus <moritz@bunkus.org>
* mkvmerge: new feature: RealAudio can be read from Matroska files.
* mkvmerge: bugfix: RealVideo was not read correctly from Matroska
files.
* mkvmerge: bugfix: The SRT reader would abort if there was more * mkvmerge: bugfix: The SRT reader would abort if there was more
than one empty line between subtitle entries line. than one empty line between subtitle entries line.

View File

@ -41,6 +41,11 @@
#define MKV_A_ACM "A_MS/ACM" #define MKV_A_ACM "A_MS/ACM"
#define MKV_A_QDMC "A_QUICKTIME/QDMC" #define MKV_A_QDMC "A_QUICKTIME/QDMC"
#define MKV_A_QDMC2 "A_QUICKTIME/QDM2" #define MKV_A_QDMC2 "A_QUICKTIME/QDM2"
#define MKV_A_REAL_14_4 "A_REAL/14_4"
#define MKV_A_REAL_28_8 "A_REAL/28_8"
#define MKV_A_REAL_COOK "A_REAL/COOK"
#define MKV_A_REAL_SIPR "A_REAL/SIPR"
#define MKV_A_REAL_ATRC "A_REAL/ATRC"
#define MKV_V_MSCOMP "V_MS/VFW/FOURCC" #define MKV_V_MSCOMP "V_MS/VFW/FOURCC"
#define MKV_V_REALV1 "V_REAL/RV10" #define MKV_V_REALV1 "V_REAL/RV10"

View File

@ -38,15 +38,17 @@ extern "C" { // for BITMAPINFOHEADER
#include "common.h" #include "common.h"
#include "pr_generic.h" #include "pr_generic.h"
#include "r_matroska.h" #include "r_matroska.h"
#include "p_vorbis.h"
#include "p_video.h" #include "p_aac.h"
#include "p_pcm.h"
#include "p_textsubs.h"
#include "p_mp3.h"
#include "p_ac3.h" #include "p_ac3.h"
#include "p_dts.h" #include "p_dts.h"
#include "p_aac.h" #include "p_mp3.h"
#include "p_passthrough.h"
#include "p_pcm.h"
#include "p_textsubs.h"
#include "p_video.h"
#include "p_vobsub.h" #include "p_vobsub.h"
#include "p_vorbis.h"
#include <ebml/EbmlContexts.h> #include <ebml/EbmlContexts.h>
#include <ebml/EbmlHead.h> #include <ebml/EbmlHead.h>
@ -401,6 +403,8 @@ void kax_reader_c::verify_tracks() {
!strcmp(t->codec_id, MKV_A_AAC_2SBR) || !strcmp(t->codec_id, MKV_A_AAC_2SBR) ||
!strcmp(t->codec_id, MKV_A_AAC_4SBR)) !strcmp(t->codec_id, MKV_A_AAC_4SBR))
t->a_formattag = FOURCC('M', 'P', '4', 'A'); t->a_formattag = FOURCC('M', 'P', '4', 'A');
else if (!strncmp(t->codec_id, MKV_A_REAL_COOK, strlen("A_REAL/")))
t->a_formattag = FOURCC('r', 'e', 'a', 'l');
else { else {
if (verbose) if (verbose)
mxwarn(PFX "Unknown/unsupported audio " mxwarn(PFX "Unknown/unsupported audio "
@ -1072,8 +1076,8 @@ void kax_reader_c::create_packetizers() {
if (nti.fourcc[0] == 0) if (nti.fourcc[0] == 0)
memcpy(nti.fourcc, t->v_fourcc, 5); memcpy(nti.fourcc, t->v_fourcc, 5);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using video output " mxinfo("+-> Using video output module for track ID %u.\n",
"module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
t->packetizer = new video_packetizer_c(this, t->codec_id, t->v_frate, t->packetizer = new video_packetizer_c(this, t->codec_id, t->v_frate,
t->v_width, t->v_width,
t->v_height, t->v_height,
@ -1093,15 +1097,15 @@ void kax_reader_c::create_packetizers() {
t->a_channels, t->a_bps, t->a_channels, t->a_bps,
&nti); &nti);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using the PCM " mxinfo("+-> Using the PCM output module for track ID %u.\n",
"output module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
} else if (t->a_formattag == 0x0055) { } else if (t->a_formattag == 0x0055) {
t->packetizer = new mp3_packetizer_c(this, t->packetizer = new mp3_packetizer_c(this,
(unsigned long)t->a_sfreq, (unsigned long)t->a_sfreq,
t->a_channels, &nti); t->a_channels, &nti);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using the MP3 " mxinfo("+-> Using the MP3 output module for track ID %u.\n",
"output module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
} else if (t->a_formattag == 0x2000) { } else if (t->a_formattag == 0x2000) {
int bsid; int bsid;
@ -1115,8 +1119,8 @@ void kax_reader_c::create_packetizers() {
(unsigned long)t->a_sfreq, (unsigned long)t->a_sfreq,
t->a_channels, bsid, &nti); t->a_channels, bsid, &nti);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using the AC3 " mxinfo("+-> Using the AC3 output module for track ID %u.\n",
"output module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
} else if (t->a_formattag == 0x2001) { } else if (t->a_formattag == 0x2001) {
mxerror("Reading DTS from Matroska not implemented yet," mxerror("Reading DTS from Matroska not implemented yet,"
"cannot we get a complete DTS_Header here for construction" "cannot we get a complete DTS_Header here for construction"
@ -1135,8 +1139,8 @@ void kax_reader_c::create_packetizers() {
t->headers[2], t->headers[2],
t->header_sizes[2], &nti); t->header_sizes[2], &nti);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using the Vorbis " mxinfo("+-> Using the Vorbis output module for track ID %u.\n",
"output module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
} else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) { } else if (t->a_formattag == FOURCC('M', 'P', '4', 'A')) {
// A_AAC/MPEG2/MAIN // A_AAC/MPEG2/MAIN
// 0123456789012345 // 0123456789012345
@ -1147,8 +1151,8 @@ void kax_reader_c::create_packetizers() {
else if (t->codec_id[10] == '4') else if (t->codec_id[10] == '4')
id = AAC_ID_MPEG4; id = AAC_ID_MPEG4;
else else
mxerror(PFX "Malformed codec id " mxerror(PFX "Malformed codec id '%s' for track %d.\n",
"%s for track %d.\n", t->codec_id, t->tnum); t->codec_id, t->tnum);
if (!strcmp(&t->codec_id[12], "MAIN")) if (!strcmp(&t->codec_id[12], "MAIN"))
profile = AAC_PROFILE_MAIN; profile = AAC_PROFILE_MAIN;
@ -1161,8 +1165,8 @@ void kax_reader_c::create_packetizers() {
else if (!strcmp(&t->codec_id[12], "LC/SBR")) else if (!strcmp(&t->codec_id[12], "LC/SBR"))
profile = AAC_PROFILE_SBR; profile = AAC_PROFILE_SBR;
else else
mxerror(PFX "Malformed codec id " mxerror(PFX "Malformed codec id %s for track %d.\n",
"%s for track %d.\n", t->codec_id, t->tnum); t->codec_id, t->tnum);
for (sbridx = 0; sbridx < ti->aac_is_sbr->size(); sbridx++) for (sbridx = 0; sbridx < ti->aac_is_sbr->size(); sbridx++)
if (((*ti->aac_is_sbr)[sbridx] == t->tnum) || if (((*ti->aac_is_sbr)[sbridx] == t->tnum) ||
@ -1176,11 +1180,29 @@ void kax_reader_c::create_packetizers() {
t->a_channels, &nti, t->a_channels, &nti,
false, true); false, true);
if (verbose) if (verbose)
mxinfo("Matroska demultiplexer (%s): using the AAC " mxinfo("+-> Using the AAC output module for track ID %u.\n",
"output module for track ID %u.\n", ti->fname, t->tnum); ti->fname, t->tnum);
} else if (t->a_formattag == FOURCC('r', 'e', 'a', 'l')) {
passthrough_packetizer_c *ptzr;
ptzr = new passthrough_packetizer_c(this, ti);
t->packetizer = ptzr;
ptzr->set_track_type(track_audio);
ptzr->set_codec_id(t->codec_id);
ptzr->set_codec_private((unsigned char *)t->private_data,
t->private_size);
ptzr->set_audio_sampling_freq(t->a_sfreq);
ptzr->set_audio_channels(t->a_channels);
if (t->a_bps != 0)
ptzr->set_audio_bit_depth(t->a_bps);
if (verbose)
mxinfo("+-> Using the generic audio output module for stream "
"%u (CodecID: %s).\n", t->tnum, t->codec_id);
} else } else
mxerror(PFX "Unsupported track type " mxerror(PFX "Unsupported track type for track %d.\n", t->tnum);
"for track %d.\n", t->tnum);
if ((t->packetizer != NULL) && (t->a_osfreq != 0.0)) if ((t->packetizer != NULL) && (t->a_osfreq != 0.0))
t->packetizer->set_audio_output_sampling_freq(t->a_osfreq); t->packetizer->set_audio_output_sampling_freq(t->a_osfreq);
@ -1266,7 +1288,7 @@ int kax_reader_c::read(generic_packetizer_c *) {
KaxClusterTimecode *ctc; KaxClusterTimecode *ctc;
int64_t block_fref, block_bref, block_duration; int64_t block_fref, block_bref, block_duration;
kax_track_t *block_track; kax_track_t *block_track;
bool found_data; bool found_data, bref_found, fref_found;
if (tracks.size() == 0) if (tracks.size() == 0)
return 0; return 0;
@ -1316,14 +1338,19 @@ int kax_reader_c::read(generic_packetizer_c *) {
block_fref = VFT_NOBFRAME; block_fref = VFT_NOBFRAME;
block_track = NULL; block_track = NULL;
block = NULL; block = NULL;
bref_found = false;
fref_found = false;
ref_block = static_cast<KaxReferenceBlock *> ref_block = static_cast<KaxReferenceBlock *>
(block_group->FindFirstElt(KaxReferenceBlock::ClassInfos, false)); (block_group->FindFirstElt(KaxReferenceBlock::ClassInfos, false));
while (ref_block != NULL) { while (ref_block != NULL) {
if (int64(*ref_block) < 0) if (int64(*ref_block) < 0) {
block_bref = int64(*ref_block) * tc_scale / 1000000; block_bref = int64(*ref_block) * tc_scale / 1000000;
else bref_found = true;
} else {
block_fref = int64(*ref_block) * tc_scale / 1000000; block_fref = int64(*ref_block) * tc_scale / 1000000;
fref_found = true;
}
ref_block = static_cast<KaxReferenceBlock *> ref_block = static_cast<KaxReferenceBlock *>
(block_group->FindNextElt(*ref_block, false)); (block_group->FindNextElt(*ref_block, false));
@ -1351,9 +1378,9 @@ int kax_reader_c::read(generic_packetizer_c *) {
} }
last_timecode = block->GlobalTimecode() / 1000000; last_timecode = block->GlobalTimecode() / 1000000;
if (block_bref != VFT_IFRAME) if (bref_found)
block_bref += (int64_t)last_timecode; block_bref += (int64_t)last_timecode;
if (block_fref != VFT_NOBFRAME) if (fref_found)
block_fref += (int64_t)last_timecode; block_fref += (int64_t)last_timecode;
for (i = 0; i < (int)block->NumberFrames(); i++) { for (i = 0; i < (int)block->NumberFrames(); i++) {