mkvtoolnix/r_ac3.cpp

150 lines
3.5 KiB
C++
Raw Normal View History

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
\version \$Id: r_ac3.cpp,v 1.7 2003/03/04 10:16:28 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-02-23 22:51:49 +00:00
#include "common.h"
#include "error.h"
2003-02-16 00:05:07 +00:00
#include "queue.h"
#include "r_ac3.h"
2003-02-23 22:51:49 +00:00
#include "p_ac3.h"
2003-02-16 00:05:07 +00:00
#ifdef DMALLOC
#include <dmalloc.h>
#endif
int ac3_reader_c::probe_file(FILE *file, u_int64_t size) {
char buf[4096];
int pos;
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;
}
ac3_reader_c::ac3_reader_c(char *fname, audio_sync_t *nasync)
2003-02-23 22:51:49 +00:00
throw (error_c) {
2003-02-16 00:05:07 +00:00
int pos;
ac3_header_t ac3header;
if ((file = fopen(fname, "r")) == NULL)
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.");
chunk = (unsigned char *)malloc(4096);
if (chunk == NULL)
die("malloc");
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-02-23 22:51:49 +00:00
ac3packetizer = new ac3_packetizer_c(NULL, 0, ac3header.sample_rate,
2003-02-16 00:05:07 +00:00
ac3header.channels,
ac3header.bit_rate / 1000,
nasync);
2003-02-16 00:05:07 +00:00
if (verbose)
fprintf(stdout, "Using AC3 demultiplexer for %s.\n+-> Using " \
2003-02-16 00:05:07 +00:00
"AC3 output module for audio stream.\n", fname);
}
ac3_reader_c::~ac3_reader_c() {
if (file != NULL)
fclose(file);
if (chunk != NULL)
free(chunk);
if (ac3packetizer != NULL)
delete ac3packetizer;
}
int ac3_reader_c::read() {
int nread, last_frame;
do {
2003-02-23 22:51:49 +00:00
if (ac3packetizer->packet_available())
2003-02-16 00:05:07 +00:00
return EMOREDATA;
nread = fread(chunk, 1, 4096, file);
2003-02-23 22:51:49 +00:00
if (nread <= 0)
2003-02-16 00:05:07 +00:00
return 0;
2003-02-23 22:51:49 +00:00
if (nread < 4096)
last_frame = 1;
else
last_frame = 0;
ac3packetizer->process(chunk, nread, last_frame);
2003-02-16 00:05:07 +00:00
bytes_processed += nread;
if (last_frame)
return 0;
2003-02-23 22:51:49 +00:00
} while (1);
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
}
2003-02-23 22:51:49 +00:00
// void ac3_reader_c::reset() {
// if (ac3packetizer != NULL)
// ac3packetizer->reset();
// }
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);
}