mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Preliminary support for DTS files/tracks.
This commit is contained in:
parent
707160a1f0
commit
f9ef2139d2
@ -1,5 +1,12 @@
|
||||
2003-05-11 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* Fixed a bug with the AC3 timecode calculation (patch by Peter
|
||||
Niemayer <niemayer AT isg.de>).
|
||||
|
||||
* Support for reading DTS files & putting them into Matroska
|
||||
(main patch by Peter Niemayer <niemayer AT isg.de>, a few things
|
||||
by me).
|
||||
|
||||
* Released v0.3.2.
|
||||
|
||||
* Fixed the huge memory need if reading from AVI files (introduced
|
||||
|
@ -8,11 +8,13 @@ bin_PROGRAMS = mkvmerge mkvinfo
|
||||
|
||||
mkvmerge_SOURCES = mkvmerge.cpp mkvmerge.h \
|
||||
ac3_common.cpp ac3_common.h \
|
||||
dts_common.cpp dts_common.h \
|
||||
cluster_helper.cpp cluster_helper.h \
|
||||
common.cpp common.h \
|
||||
iso639.cpp iso639.h \
|
||||
mp3_common.cpp mp3_common.h \
|
||||
p_ac3.cpp p_ac3.h \
|
||||
p_dts.cpp p_dts.h \
|
||||
p_mp3.cpp p_mp3.h \
|
||||
p_pcm.cpp p_pcm.h \
|
||||
p_textsubs.cpp p_textsubs.h \
|
||||
@ -21,6 +23,7 @@ mkvmerge_SOURCES = mkvmerge.cpp mkvmerge.h \
|
||||
pr_generic.h pr_generic.cpp \
|
||||
r_ac3.cpp r_ac3.h \
|
||||
r_avi.cpp r_avi.h \
|
||||
r_dts.cpp r_dts.h \
|
||||
r_matroska.cpp r_matroska.h \
|
||||
r_mp3.cpp r_mp3.h \
|
||||
r_srt.cpp r_srt.h \
|
||||
|
3
common.h
3
common.h
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: common.h,v 1.21 2003/05/11 15:52:54 mosu Exp $
|
||||
\version \$Id: common.h,v 1.22 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief definitions used in all programs, helper functions
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -63,6 +63,7 @@
|
||||
#define TYPEMICRODVD 8
|
||||
#define TYPEVOBSUB 9
|
||||
#define TYPEMATROSKA 10
|
||||
#define TYPEDTS 11
|
||||
|
||||
#define FOURCC(a, b, c, d) (unsigned long)((((unsigned char)a) << 24) + \
|
||||
(((unsigned char)b) << 16) + \
|
||||
|
115
dts_common.cpp
Normal file
115
dts_common.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
dts_common.cpp
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: dts_common.cpp,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief helper function for DTS data
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dts_common.h"
|
||||
|
||||
static int DTS_SAMPLEFREQS[16] =
|
||||
{
|
||||
0, 8000, 16000, 32000, 64000, 128000, 11025, 22050,
|
||||
44100, 88200, 176400, 12000, 24000, 48000, 96000, 192000
|
||||
};
|
||||
|
||||
static int DTS_BITRATES[30] =
|
||||
{
|
||||
32000, 56000, 64000, 96000, 112000, 128000, 192000,
|
||||
224000, 256000, 320000, 384000, 448000, 512000, 576000,
|
||||
640000, 768000, 896000, 1024000, 1152000, 1280000, 1344000,
|
||||
1408000, 1411200, 1472000, 1536000, 1920000, 2048000, 3072000,
|
||||
3840000, 4096000
|
||||
};
|
||||
|
||||
|
||||
int find_dts_header(unsigned char *buf, int size, dts_header_t *dts_header) {
|
||||
// dts_header_t header;
|
||||
int i;
|
||||
unsigned char * indata_ptr;
|
||||
int ftype;
|
||||
int surp;
|
||||
int unknown_bit;
|
||||
int fsize;
|
||||
int amode;
|
||||
int nblks;
|
||||
int sfreq;
|
||||
int rate;
|
||||
|
||||
for (i = 0; i < (size - 9); i++) {
|
||||
if ((buf[i] != 0x7f) || (buf[i + 1] != 0xfe) || (buf[i + 2] != 0x80) ||
|
||||
(buf[i + 3] != 0x01))
|
||||
continue;
|
||||
|
||||
indata_ptr = buf + i;
|
||||
|
||||
ftype = indata_ptr[4] >> 7;
|
||||
|
||||
surp = (indata_ptr[4] >> 2) & 0x1f;
|
||||
surp = (surp + 1) % 32;
|
||||
//fprintf(stderr,"surp = %d\n", surp);
|
||||
|
||||
unknown_bit = (indata_ptr[4] >> 1) & 0x01;
|
||||
|
||||
nblks = (indata_ptr[4] & 0x01) << 6 | (indata_ptr[5] >> 2);
|
||||
nblks = nblks + 1;
|
||||
|
||||
fsize = (indata_ptr[5] & 0x03) << 12 | (indata_ptr[6] << 4) |
|
||||
(indata_ptr[7] >> 4);
|
||||
fsize = fsize + 1;
|
||||
|
||||
amode = (indata_ptr[7] & 0x0f) << 2 | (indata_ptr[8] >> 6);
|
||||
sfreq = (indata_ptr[8] >> 2) & 0x0f;
|
||||
rate = (indata_ptr[8] & 0x03) << 3 | ((indata_ptr[9] >> 5) & 0x07);
|
||||
|
||||
if (ftype != 1) {
|
||||
// "DTS: Termination frames not handled, REPORT BUG\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sfreq != 13) {
|
||||
// "DTS: Only 48kHz supported, REPORT BUG\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fsize > 8192) || (fsize < 96)) {
|
||||
// "DTS: fsize: %d invalid, REPORT BUG\n", fsize;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((nblks != 8) &&
|
||||
(nblks != 16) &&
|
||||
(nblks != 32) &&
|
||||
(nblks != 64) &&
|
||||
(nblks != 128) &&
|
||||
(ftype == 1)) {
|
||||
// "DTS: nblks %d not valid for normal frame, REPORT BUG\n", nblks;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// header ok
|
||||
dts_header->sample_rate = DTS_SAMPLEFREQS[sfreq];
|
||||
dts_header->bit_rate = DTS_BITRATES[rate];
|
||||
dts_header->bytes = fsize;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
50
dts_common.h
Normal file
50
dts_common.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
dts_common.h
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: dts_common.h,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief definitions and helper functions for DTS data
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#ifndef __DTSCOMMON_H
|
||||
#define __DTSCOMMON_H
|
||||
|
||||
#define A52_CHANNEL 0
|
||||
#define A52_MONO 1
|
||||
#define A52_STEREO 2
|
||||
#define A52_3F 3
|
||||
#define A52_2F1R 4
|
||||
#define A52_3F1R 5
|
||||
#define A52_2F2R 6
|
||||
#define A52_3F2R 7
|
||||
#define A52_CHANNEL1 8
|
||||
#define A52_CHANNEL2 9
|
||||
#define A52_DOLBY 10
|
||||
#define A52_CHANNEL_MASK 15
|
||||
|
||||
#define A52_LFE 16
|
||||
|
||||
typedef struct {
|
||||
int sample_rate;
|
||||
int bit_rate;
|
||||
// int channels;
|
||||
int flags;
|
||||
int bytes;
|
||||
} dts_header_t;
|
||||
|
||||
int find_dts_header(unsigned char *buf, int size, dts_header_t *dts_header);
|
||||
|
||||
#endif // __DTSCOMMON_H
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: matroska.h,v 1.9 2003/04/30 11:31:47 mosu Exp $
|
||||
\version \$Id: matroska.h,v 1.10 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief Definitions for the various Codec IDs
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#define MKV_A_MP3 "A_MPEG/L3"
|
||||
#define MKV_A_AC3 "A_AC3"
|
||||
#define MKV_A_DTS "A_DTS"
|
||||
#define MKV_A_PCM "A_PCM/INT/LIT"
|
||||
#define MKV_A_VORBIS "A_VORBIS"
|
||||
#define MKV_A_ACM "A_MS/ACM"
|
||||
|
14
mkvmerge.cpp
14
mkvmerge.cpp
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: mkvmerge.cpp,v 1.62 2003/05/11 15:48:57 mosu Exp $
|
||||
\version \$Id: mkvmerge.cpp,v 1.63 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief command line parameter parsing, looping, output handling
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -64,6 +64,7 @@
|
||||
#include "common.h"
|
||||
#include "iso639.h"
|
||||
#include "r_ac3.h"
|
||||
#include "r_dts.h"
|
||||
#include "r_avi.h"
|
||||
#include "r_mp3.h"
|
||||
#include "r_wav.h"
|
||||
@ -146,6 +147,7 @@ file_type_t file_types[] =
|
||||
// {"idx", TYPEVOBSUB, "VobSub subtitles"},
|
||||
{"mp3", TYPEMP3, "MPEG1 layer III audio (CBR and VBR/ABR)"},
|
||||
{"ac3", TYPEAC3, "A/52 (aka AC3)"},
|
||||
{"dts", TYPEDTS, "DTS (Digital Theater System)"},
|
||||
{"output modules:", -1, ""},
|
||||
#ifdef HAVE_OGGVORBIS
|
||||
{" ", -1, "Vorbis audio"},
|
||||
@ -156,6 +158,7 @@ file_type_t file_types[] =
|
||||
// {" ", -1, "VobSub subtitles"},
|
||||
{" ", -1, "MP3 audio"},
|
||||
{" ", -1, "AC3 audio"},
|
||||
{" ", -1, "DTS audio"},
|
||||
{NULL, -1, NULL}};
|
||||
|
||||
static void usage(void) {
|
||||
@ -249,6 +252,8 @@ static int get_type(char *filename) {
|
||||
type = TYPEMP3;
|
||||
else if (ac3_reader_c::probe_file(f, size))
|
||||
type = TYPEAC3;
|
||||
else if (dts_reader_c::probe_file(f, size))
|
||||
type = TYPEDTS;
|
||||
// else if (microdvd_reader_c::probe_file(f, size))
|
||||
// type = TYPEMICRODVD;
|
||||
// else if (vobsub_reader_c::probe_file(f, size))
|
||||
@ -818,6 +823,13 @@ static void parse_args(int argc, char **argv) {
|
||||
"AC3 files.\n");
|
||||
file->reader = new ac3_reader_c(&ti);
|
||||
break;
|
||||
case TYPEDTS:
|
||||
if ((ti.atracks != NULL) || (ti.vtracks != NULL) ||
|
||||
(ti.stracks != NULL))
|
||||
fprintf(stderr, "Warning: -a/-A/-d/-D/-t/-T are ignored for " \
|
||||
"DTS files.\n");
|
||||
file->reader = new dts_reader_c(&ti);
|
||||
break;
|
||||
// case TYPECHAPTERS:
|
||||
// if (chapters != NULL) {
|
||||
// fprintf(stderr, "Error: only one chapter file allowed.\n");
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_ac3.cpp,v 1.22 2003/05/11 12:41:53 mosu Exp $
|
||||
\version \$Id: p_ac3.cpp,v 1.23 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief AC3 output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -165,7 +165,7 @@ int ac3_packetizer_c::process(unsigned char *buf, int size,
|
||||
|
||||
add_to_buffer(buf, size);
|
||||
while ((packet = get_ac3_packet(&header, &ac3header)) != NULL) {
|
||||
if (timecode != -1)
|
||||
if (timecode == -1)
|
||||
my_timecode = (int64_t)(1000.0 * packetno * 1536 * ti->async.linear /
|
||||
samples_per_sec);
|
||||
|
||||
|
180
p_dts.cpp
Normal file
180
p_dts.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
p_dts.h
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_dts.cpp,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief DTS output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "pr_generic.h"
|
||||
#include "dts_common.h"
|
||||
#include "p_dts.h"
|
||||
#include "matroska.h"
|
||||
|
||||
using namespace LIBMATROSKA_NAMESPACE;
|
||||
|
||||
dts_packetizer_c::dts_packetizer_c(generic_reader_c *nreader,
|
||||
unsigned long nsamples_per_sec,
|
||||
track_info_t *nti)
|
||||
throw (error_c): generic_packetizer_c(nreader, nti) {
|
||||
packetno = 0;
|
||||
bytes_output = 0;
|
||||
packet_buffer = NULL;
|
||||
buffer_size = 0;
|
||||
samples_per_sec = nsamples_per_sec;
|
||||
|
||||
set_track_type(track_audio);
|
||||
duplicate_data_on_add(false);
|
||||
}
|
||||
|
||||
dts_packetizer_c::~dts_packetizer_c() {
|
||||
safefree(packet_buffer);
|
||||
}
|
||||
|
||||
void dts_packetizer_c::add_to_buffer(unsigned char *buf, int size) {
|
||||
unsigned char *new_buffer;
|
||||
|
||||
new_buffer = (unsigned char *)saferealloc(packet_buffer, buffer_size + size);
|
||||
|
||||
memcpy(new_buffer + buffer_size, buf, size);
|
||||
packet_buffer = new_buffer;
|
||||
buffer_size += size;
|
||||
}
|
||||
|
||||
int dts_packetizer_c::dts_packet_available() {
|
||||
int pos;
|
||||
dts_header_t dtsheader;
|
||||
|
||||
if (packet_buffer == NULL)
|
||||
return 0;
|
||||
pos = find_dts_header(packet_buffer, buffer_size, &dtsheader);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dts_packetizer_c::remove_dts_packet(int pos, int framesize) {
|
||||
int new_size;
|
||||
unsigned char *temp_buf;
|
||||
|
||||
new_size = buffer_size - (pos + framesize);
|
||||
if (new_size != 0)
|
||||
temp_buf = (unsigned char *)safememdup(&packet_buffer[pos + framesize],
|
||||
new_size);
|
||||
else
|
||||
temp_buf = NULL;
|
||||
safefree(packet_buffer);
|
||||
packet_buffer = temp_buf;
|
||||
buffer_size = new_size;
|
||||
}
|
||||
|
||||
unsigned char *dts_packetizer_c::get_dts_packet(unsigned long *header,
|
||||
dts_header_t *dtsheader) {
|
||||
int pos;
|
||||
unsigned char *buf;
|
||||
double pims;
|
||||
|
||||
if (packet_buffer == NULL)
|
||||
return 0;
|
||||
pos = find_dts_header(packet_buffer, buffer_size, dtsheader);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
if ((pos + dtsheader->bytes) > buffer_size)
|
||||
return 0;
|
||||
|
||||
pims = ((double)((dtsheader->bytes + 511) & (~511))) * 1000.0 /
|
||||
((double)dtsheader->bit_rate / 8.0);
|
||||
|
||||
if (ti->async.displacement < 0) {
|
||||
/*
|
||||
* DTS audio synchronization. displacement < 0 means skipping an
|
||||
* appropriate number of packets at the beginning.
|
||||
*/
|
||||
ti->async.displacement += (int)pims;
|
||||
if (ti->async.displacement > -(pims / 2))
|
||||
ti->async.displacement = 0;
|
||||
|
||||
remove_dts_packet(pos, dtsheader->bytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (verbose && (pos > 1))
|
||||
fprintf(stdout, "dts_packetizer: skipping %d bytes (no valid DTS header "
|
||||
"found). This might make audio/video go out of sync, but this "
|
||||
"stream is damaged.\n", pos);
|
||||
buf = (unsigned char *)safememdup(packet_buffer + pos, dtsheader->bytes);
|
||||
|
||||
if (ti->async.displacement > 0) {
|
||||
/*
|
||||
* DTS audio synchronization. displacement > 0 is solved by duplicating
|
||||
* the very first DTS packet as often as necessary. I cannot create
|
||||
* a packet with total silence because I don't know how, and simply
|
||||
* settings the packet's values to 0 does not work as the DTS header
|
||||
* contains a CRC of its data.
|
||||
*/
|
||||
ti->async.displacement -= (int)pims;
|
||||
if (ti->async.displacement < (pims / 2))
|
||||
ti->async.displacement = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
remove_dts_packet(pos, dtsheader->bytes);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void dts_packetizer_c::set_headers() {
|
||||
set_codec_id(MKV_A_DTS);
|
||||
set_audio_sampling_freq((float)samples_per_sec);
|
||||
set_audio_channels(6);
|
||||
|
||||
generic_packetizer_c::set_headers();
|
||||
}
|
||||
|
||||
int dts_packetizer_c::process(unsigned char *buf, int size,
|
||||
int64_t timecode, int64_t, int64_t, int64_t) {
|
||||
unsigned char *packet;
|
||||
unsigned long header;
|
||||
dts_header_t dtsheader;
|
||||
int64_t my_timecode;
|
||||
double pims;
|
||||
|
||||
if (timecode != -1)
|
||||
my_timecode = timecode;
|
||||
|
||||
add_to_buffer(buf, size);
|
||||
while ((packet = get_dts_packet(&header, &dtsheader)) != NULL) {
|
||||
|
||||
if (timecode == -1) {
|
||||
pims = ((double)((dtsheader.bytes + 511) & (~511))) * 1000.0 /
|
||||
((double)dtsheader.bit_rate / 8.0);
|
||||
my_timecode = (int64_t)(pims * (double)packetno);
|
||||
}
|
||||
|
||||
add_packet(packet, dtsheader.bytes, my_timecode, (int64_t)pims);
|
||||
packetno++;
|
||||
}
|
||||
|
||||
return EMOREDATA;
|
||||
}
|
||||
|
53
p_dts.h
Normal file
53
p_dts.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
p_dts.h
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: p_dts.h,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief class definition for the DTS output module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#ifndef __P_DTS_H
|
||||
#define __P_DTS_H
|
||||
|
||||
#include "common.h"
|
||||
#include "pr_generic.h"
|
||||
#include "dts_common.h"
|
||||
|
||||
class dts_packetizer_c: public generic_packetizer_c {
|
||||
private:
|
||||
int64_t bytes_output, packetno;
|
||||
unsigned long samples_per_sec;
|
||||
int buffer_size;
|
||||
unsigned char *packet_buffer;
|
||||
|
||||
public:
|
||||
dts_packetizer_c(generic_reader_c *nreader, unsigned long nsamples_per_sec,
|
||||
track_info_t *nti) throw (error_c);
|
||||
virtual ~dts_packetizer_c();
|
||||
|
||||
virtual int process(unsigned char *buf, int size, int64_t timecode = -1,
|
||||
int64_t length = -1, int64_t bref = -1,
|
||||
int64_t fref = -1);
|
||||
virtual void set_headers();
|
||||
|
||||
private:
|
||||
virtual void add_to_buffer(unsigned char *buf, int size);
|
||||
virtual unsigned char *get_dts_packet(unsigned long *header,
|
||||
dts_header_t *dtsheader);
|
||||
virtual int dts_packet_available();
|
||||
virtual void remove_dts_packet(int pos, int framesize);
|
||||
};
|
||||
|
||||
#endif // __P_DTS_H
|
124
r_dts.cpp
Normal file
124
r_dts.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
r_dts.h
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: r_dts.cpp,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief DTS demultiplexer module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
// extern "C" {
|
||||
// #include <avilib.h>
|
||||
// }
|
||||
|
||||
#include "mkvmerge.h"
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "r_dts.h"
|
||||
#include "p_dts.h"
|
||||
|
||||
int dts_reader_c::probe_file(FILE *file, int64_t size) {
|
||||
char buf[4096];
|
||||
int pos;
|
||||
dts_header_t dtsheader;
|
||||
|
||||
if (size < 4096)
|
||||
return 0;
|
||||
if (fseek(file, 0, SEEK_SET) != 0)
|
||||
return 0;
|
||||
if (fread(buf, 1, 4096, file) != 4096) {
|
||||
fseek(file, 0, SEEK_SET);
|
||||
return 0;
|
||||
}
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
pos = find_dts_header((unsigned char *)buf, 4096, &dtsheader);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
dts_reader_c::dts_reader_c(track_info_t *nti) throw (error_c):
|
||||
generic_reader_c(nti) {
|
||||
int pos;
|
||||
dts_header_t dtsheader;
|
||||
|
||||
if ((file = fopen(ti->fname, "rb")) == NULL)
|
||||
throw error_c("dts_reader: Could not open source file.");
|
||||
if (fseek(file, 0, SEEK_END) != 0)
|
||||
throw error_c("dts_reader: Could not seek to end of file.");
|
||||
size = ftell(file);
|
||||
if (fseek(file, 0, SEEK_SET) != 0)
|
||||
throw error_c("dts_reader: Could not seek to beginning of file.");
|
||||
chunk = (unsigned char *)safemalloc(4096);
|
||||
if (fread(chunk, 1, 4096, file) != 4096)
|
||||
throw error_c("dts_reader: Could not read 4096 bytes.");
|
||||
if (fseek(file, 0, SEEK_SET) != 0)
|
||||
throw error_c("dts_reader: Could not seek to beginning of file.");
|
||||
pos = find_dts_header(chunk, 4096, &dtsheader);
|
||||
if (pos < 0)
|
||||
throw error_c("dts_reader: No valid DTS packet found in the first " \
|
||||
"4096 bytes.\n");
|
||||
bytes_processed = 0;
|
||||
dtspacketizer = new dts_packetizer_c(this, dtsheader.sample_rate, ti);
|
||||
if (verbose)
|
||||
fprintf(stdout, "Using DTS demultiplexer for %s.\n+-> Using " \
|
||||
"DTS output module for audio stream.\n", ti->fname);
|
||||
}
|
||||
|
||||
dts_reader_c::~dts_reader_c() {
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
safefree(chunk);
|
||||
if (dtspacketizer != NULL)
|
||||
delete dtspacketizer;
|
||||
}
|
||||
|
||||
int dts_reader_c::read() {
|
||||
int nread;
|
||||
|
||||
nread = fread(chunk, 1, 4096, file);
|
||||
if (nread <= 0)
|
||||
return 0;
|
||||
|
||||
dtspacketizer->process(chunk, nread);
|
||||
bytes_processed += nread;
|
||||
|
||||
return EMOREDATA;
|
||||
}
|
||||
|
||||
packet_t *dts_reader_c::get_packet() {
|
||||
return dtspacketizer->get_packet();
|
||||
}
|
||||
|
||||
int dts_reader_c::display_priority() {
|
||||
return DISPLAYPRIORITY_HIGH - 1;
|
||||
}
|
||||
|
||||
void dts_reader_c::display_progress() {
|
||||
fprintf(stdout, "progress: %lld/%lld bytes (%d%%)\r",
|
||||
bytes_processed, size,
|
||||
(int)(bytes_processed * 100L / size));
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void dts_reader_c::set_headers() {
|
||||
dtspacketizer->set_headers();
|
||||
}
|
52
r_dts.h
Normal file
52
r_dts.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
r_avi.h
|
||||
|
||||
Written by Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
Distributed under the GPL
|
||||
see the file COPYING for details
|
||||
or visit http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file r_avi.h
|
||||
\version \$Id: r_dts.h,v 1.1 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief class definitions for the AVI demultiplexer module
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#ifndef __R_DTS_H
|
||||
#define __R_DTS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pr_generic.h"
|
||||
#include "common.h"
|
||||
#include "error.h"
|
||||
#include "p_dts.h"
|
||||
#include "dts_common.h"
|
||||
|
||||
class dts_reader_c: public generic_reader_c {
|
||||
private:
|
||||
unsigned char *chunk;
|
||||
FILE *file;
|
||||
class dts_packetizer_c *dtspacketizer;
|
||||
int64_t bytes_processed, size;
|
||||
|
||||
public:
|
||||
dts_reader_c(track_info_t *nti) throw (error_c);
|
||||
virtual ~dts_reader_c();
|
||||
|
||||
virtual int read();
|
||||
virtual packet_t *get_packet();
|
||||
virtual int display_priority();
|
||||
virtual void display_progress();
|
||||
virtual void set_headers();
|
||||
|
||||
static int probe_file(FILE *file, int64_t size);
|
||||
};
|
||||
|
||||
#endif // __R_DTS_H
|
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: r_matroska.cpp,v 1.30 2003/05/11 09:24:02 mosu Exp $
|
||||
\version \$Id: r_matroska.cpp,v 1.31 2003/05/15 08:58:52 mosu Exp $
|
||||
\brief Matroska reader
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -40,6 +40,7 @@ extern "C" { // for BITMAPINFOHEADER
|
||||
#include "p_textsubs.h"
|
||||
#include "p_mp3.h"
|
||||
#include "p_ac3.h"
|
||||
#include "p_dts.h"
|
||||
|
||||
#include "EbmlContexts.h"
|
||||
#include "EbmlHead.h"
|
||||
@ -304,6 +305,8 @@ void mkv_reader_c::verify_tracks() {
|
||||
t->a_formattag = 0x0055;
|
||||
else if (!strcmp(t->codec_id, MKV_A_AC3))
|
||||
t->a_formattag = 0x2000;
|
||||
else if (!strcmp(t->codec_id, MKV_A_DTS))
|
||||
t->a_formattag = 0x2001;
|
||||
else if (!strcmp(t->codec_id, MKV_A_PCM))
|
||||
t->a_formattag = 0x0001;
|
||||
else if (!strcmp(t->codec_id, MKV_A_VORBIS)) {
|
||||
@ -856,6 +859,10 @@ void mkv_reader_c::create_packetizers() {
|
||||
t->packetizer = new ac3_packetizer_c(this,
|
||||
(unsigned long)t->a_sfreq,
|
||||
t->a_channels, &nti);
|
||||
else if (t->a_formattag == 0x2001)
|
||||
t->packetizer = new dts_packetizer_c(this,
|
||||
(unsigned long)t->a_sfreq,
|
||||
&nti);
|
||||
else if (t->a_formattag == 0xFFFE)
|
||||
t->packetizer = new vorbis_packetizer_c(this,
|
||||
t->headers[0],
|
||||
|
Loading…
Reference in New Issue
Block a user