📄 scan.java
字号:
/*
* @(#)SCAN.java - pre-scanning to check supported files
*
* Copyright (c) 2002-2005 by dvb.matt, All Rights Reserved.
*
* This file is part of X, a free Java based demux utility.
* X is intended for educational purposes only, as a non-commercial test project.
* It may not be used otherwise. Most parts are only experimental.
*
*
* This program is free software; you can redistribute it free of charge
* 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.ByteArrayOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import net.sourceforge.dvb.projectx.audio.Audio;
import net.sourceforge.dvb.projectx.common.Resource;
import net.sourceforge.dvb.projectx.common.X;
import net.sourceforge.dvb.projectx.common.Common;
import net.sourceforge.dvb.projectx.video.Video;
import net.sourceforge.dvb.projectx.xinput.XInputFile;
public class Scan
{
//DM14092004 081.8.02 add
private final String msg_1 = Resource.getString("scan.msg1");
private final String msg_2 = Resource.getString("scan.msg2");
private final String msg_3 = Resource.getString("scan.msg3");
private final String msg_4 = Resource.getString("scan.msg4");
private final String msg_5 = Resource.getString("scan.msg5");
private final String msg_6 = Resource.getString("scan.msg6");
private final String msg_7 = Resource.getString("scan.msg7");
private final String msg_8 = Resource.getString("scan.msg8");
private final String msg_9 = Resource.getString("scan.msg9");
private final String[] type = {
Resource.getString("scan.unsupported"),
"PVA (Video/Audio PES)",
"MPEG-1 PS/SS (Video/Audio PES)",
"MPEG-2 PS/SS (Video/Audio PES)",
"PES (Video/Audio/TTX)",
"PES (MPEG Audio)",
"PES (private stream 1)",
"ES (AC-3 Audio)",
"ES (MPEG Audio)",
"ES (MPEG Video)",
"ES (AC-3 Audio) (psb. SMPTE)",
"DVB/MPEG2 TS",
"ES (DTS Audio)", //DM19122003 081.6 int07
"ES (DTS Audio) (psb. SMPTE)",
"ES (RIFF Audio)", //DM30122003 081.6 int10
"ES (compressed RIFF Audio)",
"ES (Subpicture 2-bit RLE)" //DM31012004 081.6 int13
};
String video =" ", audio=" ", addInfo="", playtime="", text="", pics=""; //DM10032004 081.6 int18 add, //DM28042004 081.7 int02 changed
XInputFile origFile;
ArrayList pidlist = new ArrayList();
boolean hasVideo=false, nullpacket=false;
byte[] vbasic = new byte[12];
int buffersize=1024000; //DM04122003 081.6_int02
int filetype = 0; //DM26032004 081.6_int18 add
java.text.DateFormat timeformat = new java.text.SimpleDateFormat("HH:mm:ss.SSS");
ArrayList video_streams, audio_streams, ttx_streams, pic_streams;
Audio Audio = new Audio();
//DM18062004 081.7 int05 add
public Scan()
{
video_streams = new ArrayList();
audio_streams = new ArrayList();
ttx_streams = new ArrayList();
pic_streams = new ArrayList();
}
//DM26032004 081.6_int18 changed
public int inputInt(XInputFile aXInputFile)
{
filetype = testFile(aXInputFile, false);
return filetype;
}
//DM26032004 081.6_int18 changed
public String Type(XInputFile aXInputFile)
{
origFile = aXInputFile;
filetype = testFile(aXInputFile, true);
return type[filetype] + addInfo;
}
//DM26032004 081.6_int18 add
public boolean isSupported()
{
return (filetype == 0 ? false : true);
}
//DM18062004 081.7 int05 changed
public String Date(XInputFile aXInputFile)
{
return DateFormat.getDateInstance(DateFormat.LONG).format(new Date(aXInputFile.lastModified()))
+ " "
+ DateFormat.getTimeInstance(DateFormat.LONG).format(new Date(aXInputFile.lastModified()));
}
private String readStreams(ArrayList streams, String str)
{
str = streams.get(0).toString();
for (int a = 1; a < streams.size(); a++)
str += "\n\r\t" + streams.get(a).toString();
return str;
}
//DM10032004 081.6 int18 changed
public String getVideo()
{
if (video_streams.size() == 0)
return video;
return readStreams(video_streams, video);
}
//DM10032004 081.6 int18 changed
public String getAudio()
{
if (audio_streams.size() == 0)
return audio;
return readStreams(audio_streams, audio);
}
//DM10032004 081.6 int18 add
public String getText()
{
if (ttx_streams.size() == 0)
return text;
return readStreams(ttx_streams, text);
}
//DM28042004 081.7 int02 add
public String getPics()
{
if (pic_streams.size() == 0)
return pics;
return readStreams(pic_streams, pics);
}
//DM10032004 081.6 int18 changed
public String getPlaytime()
{
return playtime;
}
//DM18062004 081.7 int05 changed
public boolean isEditable()
{
if (origFile == null)
return false;
return (origFile.exists() && hasVideo);
}
public XInputFile getFile()
{
return origFile;
}
public byte[] getVBasic()
{
return vbasic;
}
//DM19122003 081.6 int07 changed
public int AC3Audio(byte[] check)
{
audiocheck:
for (int a=0; a<10000; a++)
{
if (Audio.AC3_parseHeader(check,a) < 0)
continue audiocheck;
for (int b=0; b < 17; b++)
{
if (Audio.AC3_parseNextHeader(check,a+Audio.Size+b) == 1)
{
if ( (0xFF & check[a+Audio.Size]) > 0x3f || (0xFF & check[a+Audio.Size])==0 ) //smpte
continue audiocheck;
audio_streams.add(Audio.AC3_saveAnddisplayHeader());
return 1;
}
}
}
return 0;
}
/* DTS stuff taken from the VideoLAN project. */
/* Added by R One, 2003/12/18. */
public void DTSAudio(byte[] check)
{
audiocheck:
for (int a=0; a<10000; a++)
{
if (Audio.DTS_parseHeader(check,a) < 0)
continue audiocheck;
for (int b=0; b < 15; b++)
{
if (Audio.DTS_parseNextHeader(check,a+Audio.Size+b) == 1)
{
if ( (0xFF & check[a+Audio.Size]) > 0x7f || (0xFF & check[a+Audio.Size])==0 ) //smpte
continue audiocheck;
audio_streams.add(Audio.DTS_saveAnddisplayHeader());
return;
}
}
}
}
public void MPEGAudio(byte[] check)
{
audiocheck:
for (int a=0; a < 10000; a++)
{
if (Audio.MPA_parseHeader(check, a) < 0)
continue audiocheck;
if (Audio.MPA_parseNextHeader(check, a + Audio.Size) < 0)
continue audiocheck;
audio_streams.add(Audio.MPA_saveAnddisplayHeader());
return;
}
}
public byte[] loadPES(byte[] check, int a)
{
ByteArrayOutputStream bytecheck = new ByteArrayOutputStream();
int jump, offs, len;
boolean mpg1;
for (; a < check.length; )
{
jump = (0xFF & check[a + 4])<<8 | (0xFF & check[a + 5]);
mpg1 = (0x80 & check[a + 6]) == 0 ? true : false;
offs = a + 6 + ( !mpg1 ? 3 + (0xFF & check[a+8]) : 0);
len = jump - ( !mpg1 ? 3 + (0xFF & check[a+8]) : 0);
if (offs + len > check.length)
break;
bytecheck.write(check, offs, len);
a += 6 + jump;
}
return bytecheck.toByteArray();
}
public void loadMPG2(byte[] check, int b, boolean vdr, boolean mpg1, int size) throws IOException
{
video = msg_1;
audio = msg_2;
Hashtable table = new Hashtable();
ScanObject scanobject;
String str;
int jump = 1, id;
mpg2check:
for (int a=b; a < 500000; a += jump)
{
if ( check[a] != 0 || check[a+1] != 0 || check[a+2] != 1 )
{
jump = 1;
continue mpg2check;
}
id = 0xFF & check[a+3];
str = String.valueOf(id);
if ( id == 0xBA )
{
jump = (0xC0 & check[a+4]) == 0 ? 12 : 14;
}
//video mpg e0..0f
else if ( (0xF0 & id) == 0xE0 )
{
jump = nullpacket ? 2048 : (6 + ((0xFF & check[a+4])<<8 | (0xFF & check[a+5])) );
if (!table.containsKey(str))
table.put(str, new ScanObject(id));
scanobject = (ScanObject)table.get(str);
scanobject.write(check, a + 6 + ((!mpg1) ? 3 + (0xFF & check[a+8]) : 0), jump - ((!mpg1) ? 6 - 3 - (0xFF & check[a+8]) : 0) );
}
//audio mpg c0..df
else if ( (0xE0 & id) == 0xC0 )
{
jump = 6 + ((0xFF & check[a+4])<<8 | (0xFF & check[a+5]));
if (!table.containsKey(str))
table.put(str, new ScanObject(id));
scanobject = (ScanObject)table.get(str);
scanobject.write(check, a, jump );
}
//private bd
else if ( id == 0xBD )
{
jump = 6 + ((0xFF & check[a+4])<<8 | (0xFF & check[a+5]));
int pes_headerlength = 0xFF & check[a + 8];
boolean pes_alignment = (4 & check[a + 6]) != 0 ? true : false;
//DM10032004 081.6 int18 add
if (pes_headerlength == 0x24 && (0xF0 & check[a + 9 + pes_headerlength])>>>4 == 1)
{
text = "SubID 0x" + Integer.toHexString((0xFF & check[a + 9 + pes_headerlength])).toUpperCase();
}
else if ( ((!mpg1 && !vdr) || (vdr && pes_alignment)) && ((0xF0 & check[a + 9 + pes_headerlength])>>>4 == 2 || (0xF0 & check[a + 9 + pes_headerlength])>>>4 == 3))
{
pics = "SubID 0x" + Integer.toHexString((0xFF & check[a + 9 + pes_headerlength])).toUpperCase();
}
else
{
if (!vdr)
{
id = 0xFF & check[a + 9 + pes_headerlength];
str = String.valueOf(id);
check[a + 8] = (byte)(4 + pes_headerlength);
}
if (!table.containsKey(str))
table.put(str, new ScanObject(id));
scanobject = (ScanObject)table.get(str);
scanobject.write(check, a, jump );
}
}
else
{
switch (id)
{
case 0xBB:
case 0xBC:
case 0xBE:
case 0xBF:
case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF6:
case 0xF7:
case 0xF8:
case 0xF9:
case 0xFA:
case 0xFB:
case 0xFC:
case 0xFD:
case 0xFE:
case 0xFF:
jump = 6 + ((0xFF & check[a+4])<<8 | (0xFF & check[a+5]));
break;
default:
jump=1;
}
}
}
for (Enumeration n = table.keys(); n.hasMoreElements() ; )
{
str = n.nextElement().toString();
id = Integer.parseInt(str);
scanobject = (ScanObject)table.get(str);
if ( (0xF0 & id) == 0xE0)
{
try
{
checkVid(scanobject.getData());
}
catch ( Exception e)
{
video_streams.add(msg_8);
}
}
else
{
try
{
checkPES(scanobject.getData());
}
catch ( Exception e)
{
audio_streams.add(msg_8);
}
}
}
table.clear();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -