2003-02-16 00:05:07 +00:00
|
|
|
/*
|
2003-02-23 22:51:49 +00:00
|
|
|
mkvmerge -- utility for splicing together matroska files
|
|
|
|
from component media subtypes
|
2003-02-16 00:05:07 +00:00
|
|
|
|
2003-02-23 23:23:10 +00:00
|
|
|
r_ac3.h
|
2003-02-16 00:05:07 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
2003-02-23 22:51:49 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
\file
|
2003-05-09 10:05:26 +00:00
|
|
|
\version \$Id: r_ac3.cpp,v 1.20 2003/05/09 10:05:26 mosu Exp $
|
2003-02-23 23:23:10 +00:00
|
|
|
\brief AC3 demultiplexer module
|
2003-02-23 22:51:49 +00:00
|
|
|
\author Moritz Bunkus <moritz @ bunkus.org>
|
|
|
|
*/
|
|
|
|
|
2003-02-16 00:05:07 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
2003-02-23 22:51:49 +00:00
|
|
|
extern "C" {
|
|
|
|
#include <avilib.h>
|
|
|
|
}
|
2003-02-16 00:05:07 +00:00
|
|
|
|
2003-04-18 10:08:24 +00:00
|
|
|
#include "mkvmerge.h"
|
2003-02-23 22:51:49 +00:00
|
|
|
#include "common.h"
|
|
|
|
#include "error.h"
|
2003-02-16 00:05:07 +00:00
|
|
|
#include "r_ac3.h"
|
2003-02-23 22:51:49 +00:00
|
|
|
#include "p_ac3.h"
|
2003-02-16 00:05:07 +00:00
|
|
|
|
2003-04-13 15:23:03 +00:00
|
|
|
int ac3_reader_c::probe_file(FILE *file, int64_t size) {
|
2003-05-02 20:11:34 +00:00
|
|
|
char buf[4096];
|
|
|
|
int pos;
|
2003-02-16 00:05:07 +00:00
|
|
|
ac3_header_t ac3header;
|
|
|
|
|
|
|
|
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_ac3_header((unsigned char *)buf, 4096, &ac3header);
|
|
|
|
if (pos < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2003-03-05 13:51:20 +00:00
|
|
|
ac3_reader_c::ac3_reader_c(track_info_t *nti) throw (error_c):
|
|
|
|
generic_reader_c(nti) {
|
2003-05-02 20:11:34 +00:00
|
|
|
int pos;
|
2003-02-16 00:05:07 +00:00
|
|
|
ac3_header_t ac3header;
|
|
|
|
|
2003-05-09 10:05:26 +00:00
|
|
|
if ((file = fopen(ti->fname, "rb")) == NULL)
|
2003-02-16 00:05:07 +00:00
|
|
|
throw error_c("ac3_reader: Could not open source file.");
|
|
|
|
if (fseek(file, 0, SEEK_END) != 0)
|
|
|
|
throw error_c("ac3_reader: Could not seek to end of file.");
|
|
|
|
size = ftell(file);
|
|
|
|
if (fseek(file, 0, SEEK_SET) != 0)
|
|
|
|
throw error_c("ac3_reader: Could not seek to beginning of file.");
|
2003-05-05 18:37:36 +00:00
|
|
|
chunk = (unsigned char *)safemalloc(4096);
|
2003-02-16 00:05:07 +00:00
|
|
|
if (fread(chunk, 1, 4096, file) != 4096)
|
|
|
|
throw error_c("ac3_reader: Could not read 4096 bytes.");
|
|
|
|
if (fseek(file, 0, SEEK_SET) != 0)
|
|
|
|
throw error_c("ac3_reader: Could not seek to beginning of file.");
|
|
|
|
pos = find_ac3_header(chunk, 4096, &ac3header);
|
|
|
|
if (pos < 0)
|
|
|
|
throw error_c("ac3_reader: No valid AC3 packet found in the first " \
|
|
|
|
"4096 bytes.\n");
|
|
|
|
bytes_processed = 0;
|
2003-05-05 21:55:02 +00:00
|
|
|
ac3packetizer = new ac3_packetizer_c(this, ac3header.sample_rate,
|
2003-04-11 11:30:18 +00:00
|
|
|
ac3header.channels, ti);
|
2003-02-16 00:05:07 +00:00
|
|
|
if (verbose)
|
2003-02-25 13:25:51 +00:00
|
|
|
fprintf(stdout, "Using AC3 demultiplexer for %s.\n+-> Using " \
|
2003-03-05 13:51:20 +00:00
|
|
|
"AC3 output module for audio stream.\n", ti->fname);
|
2003-02-16 00:05:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ac3_reader_c::~ac3_reader_c() {
|
|
|
|
if (file != NULL)
|
|
|
|
fclose(file);
|
|
|
|
if (chunk != NULL)
|
2003-05-05 18:37:36 +00:00
|
|
|
safefree(chunk);
|
2003-02-16 00:05:07 +00:00
|
|
|
if (ac3packetizer != NULL)
|
|
|
|
delete ac3packetizer;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ac3_reader_c::read() {
|
2003-04-17 12:30:20 +00:00
|
|
|
int nread;
|
2003-02-16 00:05:07 +00:00
|
|
|
|
2003-05-06 07:51:24 +00:00
|
|
|
nread = fread(chunk, 1, 4096, file);
|
|
|
|
if (nread <= 0)
|
|
|
|
return 0;
|
2003-02-23 22:51:49 +00:00
|
|
|
|
2003-05-06 07:51:24 +00:00
|
|
|
ac3packetizer->process(chunk, nread);
|
|
|
|
bytes_processed += nread;
|
2003-02-16 00:05:07 +00:00
|
|
|
|
2003-05-06 07:51:24 +00:00
|
|
|
return EMOREDATA;
|
2003-02-16 00:05:07 +00:00
|
|
|
}
|
|
|
|
|
2003-02-23 22:51:49 +00:00
|
|
|
packet_t *ac3_reader_c::get_packet() {
|
|
|
|
return ac3packetizer->get_packet();
|
2003-02-16 00:05:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int ac3_reader_c::display_priority() {
|
|
|
|
return DISPLAYPRIORITY_HIGH - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ac3_reader_c::display_progress() {
|
|
|
|
fprintf(stdout, "progress: %lld/%lld bytes (%d%%)\r",
|
|
|
|
bytes_processed, size,
|
|
|
|
(int)(bytes_processed * 100L / size));
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
2003-05-02 21:49:42 +00:00
|
|
|
void ac3_reader_c::set_headers() {
|
|
|
|
ac3packetizer->set_headers();
|
|
|
|
}
|