/* mkvmerge -- utility for splicing together matroska files from component media subtypes r_ac3.h Written by Moritz Bunkus Distributed under the GPL see the file COPYING for details or visit http://www.gnu.org/copyleft/gpl.html */ /*! \file \version \$Id: r_ac3.cpp,v 1.5 2003/02/26 19:20:26 mosu Exp $ \brief AC3 demultiplexer module \author Moritz Bunkus */ #include #include #include #include extern "C" { #include } #include "common.h" #include "error.h" #include "queue.h" #include "r_ac3.h" #include "p_ac3.h" #ifdef DMALLOC #include #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, range_t *nrange) throw (error_c) { 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; ac3packetizer = new ac3_packetizer_c(NULL, 0, ac3header.sample_rate, ac3header.channels, ac3header.bit_rate / 1000, nasync, nrange); if (verbose) fprintf(stdout, "Using AC3 demultiplexer for %s.\n+-> Using " \ "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 { if (ac3packetizer->packet_available()) return EMOREDATA; nread = fread(chunk, 1, 4096, file); if (nread <= 0) return 0; if (nread < 4096) last_frame = 1; else last_frame = 0; ac3packetizer->process((char *)chunk, nread, last_frame); bytes_processed += nread; if (last_frame) return 0; } while (1); } packet_t *ac3_reader_c::get_packet() { return ac3packetizer->get_packet(); } // void ac3_reader_c::reset() { // if (ac3packetizer != NULL) // ac3packetizer->reset(); // } 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); }