mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 20:01:53 +00:00
Bugfix: RealVideo was not read correctly from Matroska files. New feature: RealAudio can be read from Matroska files.
This commit is contained in:
parent
53417a48bb
commit
b3b283ee1f
@ -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.
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user