/*
* @(#)StripAudio
*
* Copyright (c) 2005 by dvb.matt, All rights reserved.
*
* This file is part of ProjectX, a free Java based demux utility.
* By the authors, ProjectX is intended for educational purposes only,
* as a non-commercial test project.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package net.sourceforge.dvb.projectx.parser;
import java.io.PushbackInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
import net.sourceforge.dvb.projectx.xinput.XInputFile;
import net.sourceforge.dvb.projectx.common.Common;
import net.sourceforge.dvb.projectx.parser.CommonParsing;
public class StripAudio extends Object {
private byte[] DD_header = { 0x72, (byte)0xF8, 0x1F, 0x4E, 1, 0, 0, 0 };
private byte[] DTS44_header = { (byte)0xFF, 0x1F, 0, (byte)0xE8 };
private byte[] DTS48_header = { (byte)0xFE, 0x7F, 01, (byte)0x80 };
private boolean isAC3 = false;
private boolean isDTS = false;
private boolean isDTS48 = false;
private long val;
/**
*
*/
public StripAudio()
{}
/**
*
*/
public XInputFile process(XInputFile xInputFile)
{
String temp_file = xInputFile.toString() + "[stripped].$es$";
XInputFile newXInputFile;
try {
PushbackInputStream in = new PushbackInputStream(xInputFile.getInputStream(), 8);
BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream(temp_file), 5096000);
int sector = 0;
byte[] data = new byte[0x1800];
in.skip(0x2C); //std pcm wave header, already known through streaminfo
for (int ret, len;;)
{
ret = in.read(data, 0, 8);
if (ret < 8)
break;
if (!verifyHeader(data))
{
in.unread(data, 1, 7);
continue;
}
if (isAC3)
{
len = (0xFF & data[7])<<8 | (0xFF & data[6]);
len >>>= 3;
ret = in.read(data, 8, len);
sector++;
if (ret < len)
{
Common.setMessage("!> not enough data in sector " + sector + ", dropped..", true);
continue;
}
Common.changeByteOrder(data, 8, len + 8);
out.write(data, 8, len);
in.skip(0x1800 - len - 8);
}
else if (isDTS)
{
len = 0x1000;
ret = in.read(data, 8, len - 8);
sector++;
if (ret < len - 8)
{
Common.setMessage("!> not enough data in sector " + sector + ", dropped..", true);
continue;
}
int j = 0;
// dts44 with padding
if (!isDTS48)
{
for (int i = 0, k; i < len; i += 8, j += 7)
{
val = (0xFFL & data[i])<<42;
val |= (0x3FL & data[i + 1])<<50;
val |= (0xFFL & data[i + 2])<<28;
val |= (0x3FL & data[i + 3])<<36;
val |= (0xFFL & data[i + 4])<<14;
val |= (0x3FL & data[i + 5])<<22;
val |= (0xFFL & data[i + 6]);
val |= (0x3FL & data[i + 7])<<8;
CommonParsing.setValue(data, j, 7, !CommonParsing.BYTEREORDERING, val);
}
}
// dts48
else
{
j = len;
Common.changeByteOrder(data, 0, len);
}
out.write(data, 0, j);
}
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
Common.setExceptionMessage(e);
return null;
}
if (isAC3)
return finish(temp_file, xInputFile.toString() + "[stripped].ac3");
else if (isDTS)
return finish(temp_file, xInputFile.toString() + "[stripped].dts");
return null;
}
/**
*
*/
private XInputFile finish(String temp_file, String new_file)
{
File file = new File(new_file);
if (file.exists())
file.delete();
Common.renameTo(new File(temp_file), file);
return (new XInputFile(file));
}
/**
*
*/
private boolean verifyHeader(byte[] header)
{
if (!isAC3 && !isDTS)
{
isAC3 = getAC3(header);
if (!isAC3)
isDTS = getDTS(header);
}
if (isAC3)
return getAC3(header);
if (isDTS)
return getDTS(header);
return false;
}
/**
*
*/
private boolean getAC3(byte[] header)
{
for (int i = 0; i < 6; i++)
if (DD_header[i] != header[i])
return false;
return true;
}
/**
*
*/
private boolean getDTS(byte[] header)
{
if (!isDTS)
isDTS48 = getDTS48(header);
if (isDTS48)
return getDTS48(header);
for (int i = 0; i < 4; i++)
if (DTS44_header[i] != header[i])
return false;
return true;
}
/**
*
*/
private boolean getDTS48(byte[] header)
{
for (int i = 0; i < 4; i++)
if (DTS48_header[i] != header[i])
return false;
return true;
}
}