mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-25 04:11:44 +00:00
Added a first Vorbis support including the packetizers.
This commit is contained in:
parent
2de297e537
commit
a0f0cfbedc
@ -14,6 +14,7 @@ mkvmerge_SOURCES = mkvmerge.cpp mkvmerge.h \
|
||||
p_mp3.cpp p_mp3.h \
|
||||
p_pcm.cpp p_pcm.h \
|
||||
p_video.cpp p_video.h \
|
||||
p_vorbis.cpp p_vorbis.h \
|
||||
pr_generic.h pr_generic.cpp \
|
||||
queue.cpp queue.h \
|
||||
r_ac3.cpp r_ac3.h \
|
||||
|
5
error.h
5
error.h
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: error.h,v 1.5 2003/02/27 09:52:37 mosu Exp $
|
||||
\version \$Id: error.h,v 1.6 2003/03/03 18:00:30 mosu Exp $
|
||||
\brief class definitions for the error exception class
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -30,8 +30,7 @@ class error_c {
|
||||
private:
|
||||
char *error;
|
||||
public:
|
||||
error_c(char *nerror) { error = strdup(nerror); if (!error) die("strdup"); };
|
||||
~error_c() { if (error) free(error); };
|
||||
error_c(char *nerror) { error = nerror; };
|
||||
char *get_error() { return error; };
|
||||
};
|
||||
|
||||
|
327
p_vorbis.cpp
Normal file
327
p_vorbis.cpp
Normal file
@ -0,0 +1,327 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
p_vorbis.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_vorbis.cpp,v 1.1 2003/03/03 18:00:30 mosu Exp $
|
||||
\brief Vorbis packetizer
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_OGGVORBIS
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "pr_generic.h"
|
||||
#include "p_vorbis.h"
|
||||
// #include "vorbis_header_utils.h"
|
||||
|
||||
#include "KaxTracks.h"
|
||||
#include "KaxTrackAudio.h"
|
||||
|
||||
#ifdef DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
vorbis_packetizer_c::vorbis_packetizer_c(audio_sync_t *nasync, range_t *nrange,
|
||||
void *d_header, int l_header,
|
||||
void *d_comments, int l_comments,
|
||||
void *d_codecsetup, int l_codecsetup)
|
||||
throw (error_c) : q_c() {
|
||||
int i;
|
||||
|
||||
packetno = 0;
|
||||
old_granulepos = 0;
|
||||
memcpy(&async, nasync, sizeof(audio_sync_t));
|
||||
memcpy(&range, nrange, sizeof(range_t));
|
||||
last_granulepos = 0;
|
||||
last_granulepos_seen = 0;
|
||||
memset(headers, 0, 3 * sizeof(ogg_packet));
|
||||
headers[0].packet = (unsigned char *)malloc(l_header);
|
||||
headers[1].packet = (unsigned char *)malloc(l_comments);
|
||||
headers[2].packet = (unsigned char *)malloc(l_codecsetup);
|
||||
if ((headers[0].packet == NULL) || (headers[1].packet == NULL) ||
|
||||
(headers[2].packet == NULL))
|
||||
die("malloc");
|
||||
memcpy(headers[0].packet, d_header, l_header);
|
||||
memcpy(headers[1].packet, d_comments, l_comments);
|
||||
memcpy(headers[2].packet, d_codecsetup, l_codecsetup);
|
||||
headers[0].bytes = l_header;
|
||||
headers[1].bytes = l_comments;
|
||||
headers[2].bytes = l_codecsetup;
|
||||
headers[0].b_o_s = 1;
|
||||
headers[1].packetno = 1;
|
||||
headers[2].packetno = 2;
|
||||
vorbis_info_init(&vi);
|
||||
vorbis_comment_init(&vc);
|
||||
for (i = 0; i < 3; i++)
|
||||
if (vorbis_synthesis_headerin(&vi, &vc, &headers[i]) < 0)
|
||||
throw error_c("Error: vorbis_packetizer: Could not extract the "
|
||||
"stream's parameters from the first packets.\n");
|
||||
set_header();
|
||||
}
|
||||
|
||||
vorbis_packetizer_c::~vorbis_packetizer_c() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (headers[i].packet != NULL)
|
||||
free(headers[i].packet);
|
||||
}
|
||||
|
||||
int vorbis_packetizer_c::encode_silence(int fd) {
|
||||
// vorbis_dsp_state lvds;
|
||||
// vorbis_block lvb;
|
||||
// vorbis_info lvi;
|
||||
// vorbis_comment lvc;
|
||||
// ogg_stream_state loss;
|
||||
// ogg_page log;
|
||||
// ogg_packet lop;
|
||||
// ogg_packet h_main, h_comments, h_codebook;
|
||||
// int samples, i, j, k, eos;
|
||||
// float **buffer;
|
||||
|
||||
// samples = vi.rate * async.displacement / 1000;
|
||||
// vorbis_info_init(&lvi);
|
||||
// if (vorbis_encode_setup_vbr(&lvi, vi.channels, vi.rate, 1))
|
||||
// return EOTHER;
|
||||
// vorbis_encode_setup_init(&lvi);
|
||||
// vorbis_analysis_init(&lvds, &lvi);
|
||||
// vorbis_block_init(&lvds, &lvb);
|
||||
// vorbis_comment_init(&lvc);
|
||||
// lvc.vendor = strdup(VERSIONINFO);
|
||||
// lvc.user_comments = (char **)mmalloc(4);
|
||||
// lvc.comment_lengths = (int *)mmalloc(4);
|
||||
// lvc.comments = 0;
|
||||
// ogg_stream_init(&loss, serialno);
|
||||
// vorbis_analysis_headerout(&lvds, &lvc, &h_main, &h_comments, &h_codebook);
|
||||
// ogg_stream_packetin(&loss, &h_main);
|
||||
// ogg_stream_packetin(&loss, &h_comments);
|
||||
// ogg_stream_packetin(&loss, &h_codebook);
|
||||
// while (ogg_stream_flush(&loss, &log)) {
|
||||
// write(fd, log.header, log.header_len);
|
||||
// write(fd, log.body, log.body_len);
|
||||
// }
|
||||
// eos = 0;
|
||||
// for (i = 0; i <= 1; i++) {
|
||||
// if (i == 0) {
|
||||
// buffer = vorbis_analysis_buffer(&lvds, samples);
|
||||
// for (j = 0; j < samples; j++)
|
||||
// for (k = 0; k < vi.channels; k++)
|
||||
// buffer[k][j] = 0.0f;
|
||||
// vorbis_analysis_wrote(&lvds, samples);
|
||||
// } else
|
||||
// vorbis_analysis_wrote(&lvds, 0);
|
||||
// while (vorbis_analysis_blockout(&lvds, &lvb) == 1) {
|
||||
// vorbis_analysis(&lvb, NULL);
|
||||
// vorbis_bitrate_addblock(&lvb);
|
||||
// while (vorbis_bitrate_flushpacket(&lvds, &lop)) {
|
||||
// ogg_stream_packetin(&loss, &lop);
|
||||
// while (!eos) {
|
||||
// if (!ogg_stream_pageout(&loss, &log))
|
||||
// break;
|
||||
// write(fd, log.header, log.header_len);
|
||||
// write(fd, log.body, log.body_len);
|
||||
// if (ogg_page_eos(&log))
|
||||
// eos = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// ogg_stream_clear(&loss);
|
||||
// vorbis_block_clear(&lvb);
|
||||
// vorbis_dsp_clear(&lvds);
|
||||
// vorbis_info_clear(&lvi);
|
||||
// vorbis_comment_clear(&lvc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vorbis_packetizer_c::setup_displacement() {
|
||||
// char tmpname[30];
|
||||
// int fd, old_verbose, status;
|
||||
// ogm_reader_c *ogm_reader;
|
||||
// audio_sync_t nosync;
|
||||
// range_t norange;
|
||||
// generic_packetizer_c *old_packetizer;
|
||||
// ogmmerge_page_t *mpage;
|
||||
|
||||
// if (async.displacement <= 0)
|
||||
// return;
|
||||
|
||||
// strcpy(tmpname, "/tmp/ogmmerge-XXXXXX");
|
||||
// if ((fd = mkstemp(tmpname)) == -1) {
|
||||
// fprintf(stderr, "FATAL: vorbis_packetizer: mkstemp() failed.\n");
|
||||
// exit(1);
|
||||
// }
|
||||
// if (encode_silence(fd) < 0) {
|
||||
// fprintf(stderr, "FATAL: Could not encode silence.\n");
|
||||
// exit(1);
|
||||
// }
|
||||
// close(fd);
|
||||
|
||||
// old_verbose = verbose;
|
||||
// memset(&norange, 0, sizeof(range_t));
|
||||
// verbose = 0;
|
||||
// nosync.displacement = 0;
|
||||
// nosync.linear = 1.0;
|
||||
// try {
|
||||
// ogm_reader = new ogm_reader_c(tmpname, NULL, NULL, NULL, &nosync,
|
||||
// &norange, NULL, NULL);
|
||||
// } catch (error_c error) {
|
||||
// fprintf(stderr, "FATAL: vorbis_packetizer: Could not create an " \
|
||||
// "ogm_reader for the temporary file.\n%s\n", error.get_error());
|
||||
// exit(1);
|
||||
// }
|
||||
// ogm_reader->overwrite_eos(1);
|
||||
// memcpy(&nosync, &async, sizeof(audio_sync_t));
|
||||
// async.displacement = 0;
|
||||
// async.linear = 1.0;
|
||||
// status = ogm_reader->read();
|
||||
// mpage = ogm_reader->get_header_page();
|
||||
// free(mpage->og->header);
|
||||
// free(mpage->og->body);
|
||||
// free(mpage->og);
|
||||
// free(mpage);
|
||||
// skip_packets = 2;
|
||||
// old_packetizer = ogm_reader->set_packetizer(this);
|
||||
// while (status == EMOREDATA)
|
||||
// status = ogm_reader->read();
|
||||
// ogm_reader->set_packetizer(old_packetizer);
|
||||
// delete ogm_reader;
|
||||
// verbose = old_verbose;
|
||||
// unlink(tmpname);
|
||||
// memcpy(&async, &nosync, sizeof(audio_sync_t));
|
||||
}
|
||||
|
||||
#define AVORBIS "A_VORBIS"
|
||||
|
||||
void vorbis_packetizer_c::set_header() {
|
||||
using namespace LIBMATROSKA_NAMESPACE;
|
||||
|
||||
if (kax_last_entry == NULL)
|
||||
track_entry =
|
||||
&GetChild<KaxTrackEntry>(static_cast<KaxTracks &>(*kax_tracks));
|
||||
else
|
||||
track_entry =
|
||||
&GetNextChild<KaxTrackEntry>(static_cast<KaxTracks &>(*kax_tracks),
|
||||
static_cast<KaxTrackEntry &>(*kax_last_entry));
|
||||
kax_last_entry = track_entry;
|
||||
|
||||
if (serialno == -1)
|
||||
serialno = track_number++;
|
||||
KaxTrackNumber &tnumber =
|
||||
GetChild<KaxTrackNumber>(static_cast<KaxTrackEntry &>(*track_entry));
|
||||
*(static_cast<EbmlUInteger *>(&tnumber)) = serialno;
|
||||
|
||||
*(static_cast<EbmlUInteger *>
|
||||
(&GetChild<KaxTrackType>(static_cast<KaxTrackEntry &>(*track_entry)))) =
|
||||
track_audio;
|
||||
|
||||
KaxCodecID &codec_id =
|
||||
GetChild<KaxCodecID>(static_cast<KaxTrackEntry &>(*track_entry));
|
||||
codec_id.CopyBuffer((binary *)AVORBIS, countof(AVORBIS));
|
||||
|
||||
KaxTrackAudio &track_audio =
|
||||
GetChild<KaxTrackAudio>(static_cast<KaxTrackEntry &>(*track_entry));
|
||||
|
||||
KaxAudioSamplingFreq &kax_freq = GetChild<KaxAudioSamplingFreq>(track_audio);
|
||||
*(static_cast<EbmlFloat *>(&kax_freq)) = (float)vi.rate;
|
||||
|
||||
KaxAudioChannels &kax_chans = GetChild<KaxAudioChannels>(track_audio);
|
||||
*(static_cast<EbmlUInteger *>(&kax_chans)) = vi.channels;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some notes - processing is straight-forward if no AV synchronization
|
||||
* is needed - the packet is simply handed over to ogg_stream_packetin.
|
||||
* Unfortunately things are not that easy if AV sync is done. For a
|
||||
* negative displacement packets are simply discarded if their granulepos
|
||||
* is set before the displacement. For positive displacements the packetizer
|
||||
* has to generate silence and insert this silence just after the first
|
||||
* three stream packets - the Vorbis header, the comment and the
|
||||
* setup packets.
|
||||
* The creation of the silence is done by encoding 0 samples with
|
||||
* libvorbis. This produces an OGG file that is read by a separate
|
||||
* ogm_reader_c. We set this very packetizer as the reader's packetizer
|
||||
* so that we get the packets we want from the 'silenced' file. This means
|
||||
* skipping the very first three packets, hence the 'skip_packets' variable.
|
||||
*/
|
||||
int vorbis_packetizer_c::process(char *data, int size, int64_t timecode) {
|
||||
ogg_packet op;
|
||||
|
||||
/*
|
||||
* We might want to skip a certain amount of packets if this packetizer
|
||||
* is used by a second ogm_reader_c, one that reads from a 'silence'
|
||||
* file. skip_packets is then intially set to 3 in order to skip all
|
||||
* header packets.
|
||||
*/
|
||||
// if (skip_packets > 0) {
|
||||
// skip_packets--;
|
||||
// return EMOREDATA;
|
||||
// }
|
||||
|
||||
op.packet = (unsigned char *)data;
|
||||
op.bytes = size;
|
||||
fprintf(stdout, "packet_bs: %ld\n", vorbis_packet_blocksize(&vi, &op));
|
||||
|
||||
// Recalculate the timecode if needed.
|
||||
if (timecode == -1)
|
||||
die("timecode = -1");
|
||||
|
||||
// Handle the displacement.
|
||||
timecode += async.displacement;
|
||||
|
||||
// Handle the linear sync - simply multiply with the given factor.
|
||||
timecode = (int64_t)((double)timecode * async.linear);
|
||||
|
||||
// // range checking
|
||||
// if ((timecode >= range.start) &&
|
||||
// (last_granulepos_seen >= range.start) &&
|
||||
// ((range.end == 0) || (op->granulepos <= range.end))) {
|
||||
// // Adjust the granulepos
|
||||
// op->granulepos = (u_int64_t)(op->granulepos - range.start);
|
||||
// // If no or a positive displacement is set the packet has to be output.
|
||||
// if (async.displacement >= 0) {
|
||||
// ogg_stream_packetin(&os, op);
|
||||
// packetno++;
|
||||
// }
|
||||
// /*
|
||||
// * Only output the current packet if its granulepos ( = position in
|
||||
// * samples) is bigger than the displacement.
|
||||
// */
|
||||
// else if (op->granulepos > 0) {
|
||||
// ogg_stream_packetin(&os, op);
|
||||
// packetno++;
|
||||
// }
|
||||
// queue_pages();
|
||||
// last_granulepos = op->granulepos;
|
||||
// } else if (op->e_o_s) {
|
||||
|
||||
add_packet(data, size, (u_int64_t)timecode);
|
||||
|
||||
return EMOREDATA;
|
||||
}
|
||||
|
||||
#endif // HAVE_OGGVORBIS
|
65
p_vorbis.h
Normal file
65
p_vorbis.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
mkvmerge -- utility for splicing together matroska files
|
||||
from component media subtypes
|
||||
|
||||
p_vorbis.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_vorbis.h,v 1.1 2003/03/03 18:00:30 mosu Exp $
|
||||
\brief class definition for the Vorbis packetizer
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_OGGVORBIS
|
||||
|
||||
#ifndef __P_VORBIS_H
|
||||
#define __P_VORBIS_H
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "pr_generic.h"
|
||||
#include "queue.h"
|
||||
|
||||
class vorbis_packetizer_c: public q_c {
|
||||
private:
|
||||
ogg_int64_t old_granulepos;
|
||||
ogg_int64_t ogran;
|
||||
ogg_int64_t last_granulepos;
|
||||
ogg_int64_t last_granulepos_seen;
|
||||
int packetno;
|
||||
audio_sync_t async;
|
||||
range_t range;
|
||||
vorbis_info vi;
|
||||
vorbis_comment vc;
|
||||
ogg_packet headers[3];
|
||||
public:
|
||||
vorbis_packetizer_c(audio_sync_t *nasync, range_t *nrange,
|
||||
void *d_header, int l_header, void *d_comments,
|
||||
int l_comments, void *d_codecsetup, int l_codecsetup)
|
||||
throw (error_c);
|
||||
virtual ~vorbis_packetizer_c();
|
||||
|
||||
virtual int process(char *data, int size, int64_t timecode);
|
||||
virtual void set_header();
|
||||
|
||||
private:
|
||||
virtual void setup_displacement();
|
||||
virtual int encode_silence(int fd);
|
||||
};
|
||||
|
||||
|
||||
#endif // __P_VORBIS_H
|
||||
|
||||
#endif // HAVE_OGGVORBIS
|
192
r_ogm.cpp
192
r_ogm.cpp
@ -13,7 +13,7 @@
|
||||
|
||||
/*!
|
||||
\file
|
||||
\version \$Id: r_ogm.cpp,v 1.4 2003/03/03 14:39:03 mosu Exp $
|
||||
\version \$Id: r_ogm.cpp,v 1.5 2003/03/03 18:00:30 mosu Exp $
|
||||
\brief OGG media stream reader
|
||||
\author Moritz Bunkus <moritz @ bunkus.org>
|
||||
*/
|
||||
@ -29,12 +29,16 @@
|
||||
#include <ogg/ogg.h>
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
extern "C" { // for BITMAPINFOHEADER
|
||||
#include "avilib.h"
|
||||
}
|
||||
|
||||
#include "common.h"
|
||||
#include "pr_generic.h"
|
||||
#include "ogmstreams.h"
|
||||
#include "queue.h"
|
||||
#include "r_ogm.h"
|
||||
//#include "p_vorbis.h"
|
||||
#include "p_vorbis.h"
|
||||
#include "p_video.h"
|
||||
#include "p_pcm.h"
|
||||
//#include "p_textsubs.h"
|
||||
@ -195,7 +199,7 @@ void ogm_reader_c::free_demuxer(int idx) {
|
||||
int i;
|
||||
ogm_demuxer_t *dmx;
|
||||
|
||||
if (idx < num_sdemuxers)
|
||||
if (idx >= num_sdemuxers)
|
||||
return;
|
||||
dmx = sdemuxers[idx];
|
||||
for (i = 0; i < 3; i++)
|
||||
@ -255,11 +259,13 @@ void ogm_reader_c::add_new_demuxer(ogm_demuxer_t *dmx) {
|
||||
}
|
||||
|
||||
void ogm_reader_c::create_packetizers() {
|
||||
BITMAPINFOHEADER bih;
|
||||
char *codec;
|
||||
stream_header *sth;
|
||||
int i;
|
||||
ogm_demuxer_t *dmx;
|
||||
|
||||
memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
||||
i = 0;
|
||||
while (i < num_sdemuxers) {
|
||||
dmx = sdemuxers[i];
|
||||
@ -271,23 +277,32 @@ void ogm_reader_c::create_packetizers() {
|
||||
codec = sth->subtype;
|
||||
else
|
||||
codec = fourcc;
|
||||
// AVI compatibility mode. Fill in the values we've got and guess
|
||||
// the others.
|
||||
bih.bi_size = sizeof(BITMAPINFOHEADER);
|
||||
bih.bi_width = sth->sh.video.width;
|
||||
bih.bi_height = sth->sh.video.height;
|
||||
bih.bi_planes = 1;
|
||||
bih.bi_bit_count = 24;
|
||||
memcpy(&bih.bi_compression, codec, 4);
|
||||
bih.bi_size_image = sth->sh.video.width * sth->sh.video.height * 3;
|
||||
try {
|
||||
dmx->packetizer =
|
||||
new video_packetizer_c(NULL, 0, codec,
|
||||
new video_packetizer_c(&bih, sizeof(BITMAPINFOHEADER), codec,
|
||||
(double)10000000 / (double)sth->time_unit,
|
||||
sth->sh.video.width, sth->sh.video.height,
|
||||
sth->bits_per_sample, sth->buffersize, NULL,
|
||||
&range, 1);
|
||||
} catch (error_c error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize video " \
|
||||
"packetizer for stream id %d. Will try to continue and " \
|
||||
} catch (error_c &error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize video "
|
||||
"packetizer for stream id %d. Will try to continue and "
|
||||
"ignore this stream.\n", numstreams);
|
||||
free(dmx);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using video output " \
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using video output "
|
||||
"module for stream %d.\n", filename, numstreams);
|
||||
|
||||
break;
|
||||
@ -298,16 +313,16 @@ void ogm_reader_c::create_packetizers() {
|
||||
new pcm_packetizer_c(NULL, 0, sth->samples_per_unit,
|
||||
sth->sh.audio.channels,
|
||||
sth->bits_per_sample, &async, &range);
|
||||
} catch (error_c error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize PCM " \
|
||||
"packetizer for stream id %d. Will try to continue and " \
|
||||
} catch (error_c &error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize PCM "
|
||||
"packetizer for stream id %d. Will try to continue and "
|
||||
"ignore this stream.\n", numstreams);
|
||||
free_demuxer(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using PCM output " \
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using PCM output "
|
||||
"module for stream %d.\n", filename, numstreams);
|
||||
break;
|
||||
|
||||
@ -318,16 +333,16 @@ void ogm_reader_c::create_packetizers() {
|
||||
sth->sh.audio.channels,
|
||||
sth->sh.audio.avgbytespersec * 8 / 1000,
|
||||
&async, &range);
|
||||
} catch (error_c error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize MP3 " \
|
||||
"packetizer for stream id %d. Will try to continue and " \
|
||||
} catch (error_c &error) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: could not initialize MP3 "
|
||||
"packetizer for stream id %d. Will try to continue and "
|
||||
"ignore this stream.\n", numstreams);
|
||||
free_demuxer(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using MP3 output " \
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using MP3 output "
|
||||
"module for stream %d.\n", filename, numstreams);
|
||||
break;
|
||||
|
||||
@ -338,21 +353,39 @@ void ogm_reader_c::create_packetizers() {
|
||||
sth->sh.audio.channels,
|
||||
sth->sh.audio.avgbytespersec * 8 / 1000,
|
||||
&async, &range);
|
||||
} catch (error_c error) {
|
||||
fprintf(stderr, "FATAL: ogm_reader: could not initialize AC3 " \
|
||||
"packetizer for stream id %d. Will try to continue and " \
|
||||
} catch (error_c &error) {
|
||||
fprintf(stderr, "FATAL: ogm_reader: could not initialize AC3 "
|
||||
"packetizer for stream id %d. Will try to continue and "
|
||||
"ignore this stream.\n", numstreams);
|
||||
free_demuxer(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using AC3 output " \
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using AC3 output "
|
||||
"module for stream %d.\n", filename, numstreams);
|
||||
|
||||
break;
|
||||
|
||||
case OGM_STREAM_TYPE_VORBIS:
|
||||
try {
|
||||
dmx->packetizer =
|
||||
new vorbis_packetizer_c(&async, &range,
|
||||
dmx->packet_data[0], dmx->packet_sizes[0],
|
||||
dmx->packet_data[1], dmx->packet_sizes[1],
|
||||
dmx->packet_data[2], dmx->packet_sizes[2]);
|
||||
} catch (error_c &error) {
|
||||
fprintf(stderr, "FATAL: ogm_reader: could not initialize Vorbis "
|
||||
"packetizer for stream id %d. Will try to continue and "
|
||||
"ignore this stream.\n", numstreams);
|
||||
free_demuxer(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, "OGG/OGM demultiplexer (%s): using Vorbis output "
|
||||
"module for stream %d.\n", filename, numstreams);
|
||||
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
@ -390,7 +423,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
|
||||
u_int32_t codec_id;
|
||||
|
||||
if (ogg_stream_init(&new_oss, ogg_page_serialno(og))) {
|
||||
fprintf(stderr, "Fatal: ogm_reader: ogg_stream_init for stream number " \
|
||||
fprintf(stderr, "Fatal: ogm_reader: ogg_stream_init for stream number "
|
||||
"%d failed. Will try to continue and ignore this stream.",
|
||||
numstreams + 1);
|
||||
return;
|
||||
@ -422,36 +455,22 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
|
||||
ogg_stream_clear(&new_oss);
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Warning: ogm_reader: No Vorbis support at the moment. "
|
||||
"Ignoring stream id %d.\n", numstreams);
|
||||
// try {
|
||||
// dmx->packetizer = new vorbis_packetizer_c(&async, &range, comments);
|
||||
// } catch (error_c error) {
|
||||
// fprintf(stderr, "Fatal: ogm_reader: could not initialize Vorbis " \
|
||||
// "packetizer for stream id %d. Will try to continue and " \
|
||||
// "ignore this stream.\n", numstreams);
|
||||
// free(dmx);
|
||||
// ogg_stream_clear(&new_oss);
|
||||
// return;
|
||||
// }
|
||||
// dmx->stype = OGM_STREAM_TYPE_VORBIS;
|
||||
// dmx->serial = ogg_page_serialno(og);
|
||||
// memcpy(&dmx->os, &new_oss, sizeof(ogg_stream_state));
|
||||
// dmx->sid = nastreams;
|
||||
// add_new_demuxer(dmx);
|
||||
// if (verbose)
|
||||
// fprintf(stdout, "OGG/OGM demultiplexer (%s): using Vorbis audio " \
|
||||
// "output module for stream %d.\n", filename, numstreams);
|
||||
// do {
|
||||
// ((vorbis_packetizer_c *)dmx->packetizer)->
|
||||
// process(&op, ogg_page_granulepos(og));
|
||||
// if (op.e_o_s) {
|
||||
// dmx->packetizer->flush_pages();
|
||||
// dmx->eos = 1;
|
||||
// return;
|
||||
// }
|
||||
// } while (ogg_stream_packetout(&dmx->os, &op));
|
||||
|
||||
|
||||
nastreams++;
|
||||
numstreams++;
|
||||
if (!demuxing_requested(vstreams, nvstreams)) {
|
||||
ogg_stream_clear(&new_oss);
|
||||
free(dmx->packet_data[0]);
|
||||
free(dmx);
|
||||
return;
|
||||
}
|
||||
|
||||
dmx->stype = OGM_STREAM_TYPE_VORBIS;
|
||||
dmx->serial = ogg_page_serialno(og);
|
||||
memcpy(&dmx->os, &new_oss, sizeof(ogg_stream_state));
|
||||
dmx->sid = nastreams;
|
||||
add_new_demuxer(dmx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -536,8 +555,8 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
|
||||
// dmx->packetizer =
|
||||
// new textsubs_packetizer_c(&async, &range, comments);
|
||||
// } catch (error_c error) {
|
||||
// fprintf(stderr, "FATAL: ogm_reader: could not initialize text " \
|
||||
// "subtitle packetizer for stream id %d. Will try to " \
|
||||
// fprintf(stderr, "FATAL: ogm_reader: could not initialize text "
|
||||
// "subtitle packetizer for stream id %d. Will try to "
|
||||
// "continue and ignore this stream.\n", numstreams);
|
||||
// free(dmx);
|
||||
// ogg_stream_clear(&new_oss);
|
||||
@ -550,7 +569,7 @@ void ogm_reader_c::handle_new_stream(ogg_page *og) {
|
||||
// dmx->sid = ntstreams;
|
||||
// add_new_demuxer(dmx);
|
||||
// if (verbose)
|
||||
// fprintf(stdout, "OGG/OGM demultiplexer (%s): using text subtitle " \
|
||||
// fprintf(stdout, "OGG/OGM demultiplexer (%s): using text subtitle "
|
||||
// "output module for stream %d.\n", filename, numstreams);
|
||||
|
||||
return;
|
||||
@ -602,66 +621,57 @@ void ogm_reader_c::process_page(ogg_page *og) {
|
||||
if (o_eos)
|
||||
op.e_o_s = 0;
|
||||
|
||||
switch (dmx->stype) {
|
||||
// case OGM_STREAM_TYPE_VORBIS:
|
||||
// ((vorbis_packetizer_c *)dmx->packetizer)->
|
||||
// process(&op, ogg_page_granulepos(og));
|
||||
// break;
|
||||
if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
switch (dmx->stype) {
|
||||
case OGM_STREAM_TYPE_VORBIS:
|
||||
((vorbis_packetizer_c *)dmx->packetizer)->
|
||||
process((char *)op.packet, op.bytes, ogg_page_granulepos(og));
|
||||
break;
|
||||
|
||||
case OGM_STREAM_TYPE_VIDEO:
|
||||
if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
case OGM_STREAM_TYPE_VIDEO:
|
||||
((video_packetizer_c *)dmx->packetizer)->
|
||||
process((char *)&op.packet[hdrlen + 1], op.bytes - 1 - hdrlen,
|
||||
hdrlen > 0 ? lenbytes : 1,
|
||||
*op.packet & PACKET_IS_SYNCPOINT, op.e_o_s);
|
||||
dmx->units_processed += (hdrlen > 0 ? lenbytes : 1);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case OGM_STREAM_TYPE_PCM:
|
||||
if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
case OGM_STREAM_TYPE_PCM:
|
||||
((pcm_packetizer_c *)dmx->packetizer)->
|
||||
process((char *)&op.packet[hdrlen + 1], op.bytes - 1 - hdrlen,
|
||||
op.e_o_s);
|
||||
dmx->units_processed += op.bytes - 1;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case OGM_STREAM_TYPE_MP3: // MP3
|
||||
if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
case OGM_STREAM_TYPE_MP3: // MP3
|
||||
((mp3_packetizer_c *)dmx->packetizer)->
|
||||
process((char *)&op.packet[hdrlen + 1], op.bytes - 1 - hdrlen,
|
||||
op.e_o_s);
|
||||
dmx->units_processed += op.bytes - 1;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case OGM_STREAM_TYPE_AC3: // AC3
|
||||
if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
case OGM_STREAM_TYPE_AC3: // AC3
|
||||
((ac3_packetizer_c *)dmx->packetizer)->
|
||||
process((char *)&op.packet[hdrlen + 1], op.bytes - 1 - hdrlen,
|
||||
op.e_o_s);
|
||||
dmx->units_processed += op.bytes - 1;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
// case OGM_STREAM_TYPE_TEXT: // text subtitles
|
||||
// if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
// ((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
// char *subs = (char *)&op.packet[1 + hdrlen];
|
||||
// if ((*subs != 0) && (*subs != '\n') && (*subs != '\r') &&
|
||||
// strcmp(subs, " ")) {
|
||||
// ((textsubs_packetizer_c *)dmx->packetizer)->
|
||||
// process(op.granulepos, op.granulepos + lenbytes, subs,
|
||||
// op.e_o_s);
|
||||
// dmx->units_processed++;
|
||||
// case OGM_STREAM_TYPE_TEXT: // text subtitles
|
||||
// if (((*op.packet & 3) != PACKET_TYPE_HEADER) &&
|
||||
// ((*op.packet & 3) != PACKET_TYPE_COMMENT)) {
|
||||
// char *subs = (char *)&op.packet[1 + hdrlen];
|
||||
// if ((*subs != 0) && (*subs != '\n') && (*subs != '\r') &&
|
||||
// strcmp(subs, " ")) {
|
||||
// ((textsubs_packetizer_c *)dmx->packetizer)->
|
||||
// process(op.granulepos, op.granulepos + lenbytes, subs,
|
||||
// op.e_o_s);
|
||||
// dmx->units_processed++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
if (eos) {
|
||||
|
Loading…
Reference in New Issue
Block a user