package tw.jwzhuang.ipcam.h264;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import android.util.Log;
public class H264Protocol extends H264Header {
public static int findMdatIndex(DataInputStream in, int MAXFRAMEBUFFER)
throws IOException {
int seqIndex = 0;
byte c;
for (int i = 0; i < MAXFRAMEBUFFER; i++) {
c = (byte) in.readUnsignedByte();
if (c == mMdat[seqIndex]) {
seqIndex++;
if (seqIndex == mMdat.length)
return (i + 1) - mMdat.length;
} else
seqIndex = 0;
}
return -1;
}
public static byte[] readH264Bytes(DataInputStream in, int MAXFRAMEBUFFER) throws IOException{
//重新定位在frame 長度 00 00 xx xx
in.mark(MAXFRAMEBUFFER);
in.reset();
//取得frame length
byte [] len = new byte[4];
in.readFully(len);
in.reset();
in.skip(len.length);
in.mark(MAXFRAMEBUFFER);
int DataLength = ((len[2] & 0xFF) << 8) | (len[3] & 0xFF);
//取得frame Data
byte [] content = new byte[DataLength];
in.readFully(content);
in.reset();
in.skip(content.length);
return content;
}
public static H264Header findSPSAndPPS(String samplefile, int videoWidth, int videoHeight) throws Exception{
H264Header h264Header = null;
final String TAG = "H264Protocol";
int startMdatIndex = 0;
byte[] SPS;
byte[] PPS;
byte[] ftyp = new byte[28];
File file = new File(samplefile);
FileInputStream fileInput = new FileInputStream(file);
int length = (int)file.length();
byte[] data = new byte[length];
fileInput.read(data);
fileInput.close();
final byte[] mdat = new byte[]{0x6D,0x64,0x61,0x74};
final byte[] avcc = new byte[]{0x61,0x76,0x63,0x43};
for(int i=0 ; i<length; i++){
if(data[i] == mdat[0] && data[i+1] == mdat[1] && data[i+2] == mdat[2] && data[i+3] == mdat[3]){
startMdatIndex = i+4;//find mdat
break;
}
}
for(int i=0 ; i<length; i++){
if(data[i] == avcc[0] && data[i+1] == avcc[1] && data[i+2] == avcc[2] && data[i+3] == avcc[3]){
h264Header = new H264Header();
System.arraycopy(data, 0, ftyp, 0, 28);
h264Header.setFTYP(ftyp);
h264Header.setStartMdatIndex(startMdatIndex);
Log.e(TAG, "StartMdatPlace:" + startMdatIndex);
int sps_start = i+3+7;//其中i+3指到avcc的c,再加7跳过6位AVCDecoderConfigurationRecord参数
//sps length and sps data
byte[] sps_3gp = new byte[2];//sps length
sps_3gp[1] = data[sps_start];
sps_3gp[0] = data[sps_start + 1];
int sps_length = bytes2short(sps_3gp);
Log.e(TAG, "sps_length :" + sps_length);
sps_start += 2;//skip length
SPS = new byte[sps_length];
System.arraycopy(data, sps_start, SPS, 0, sps_length);
for(int si=0;si<sps_length;si++)
Log.e(TAG, "==========SPS :" + si + SPS[si]);
h264Header.setSPS(SPS);
//pps length and pps data
int pps_start = sps_start + sps_length + 1;
byte[] pps_3gp =new byte[2];
pps_3gp[1] = data[pps_start];
pps_3gp[0] =data[pps_start+1];
int pps_length = bytes2short(pps_3gp);
Log.e(TAG, "PPS LENGTH:"+pps_length);
pps_start+=2;
PPS = new byte[pps_length];
System.arraycopy(data, pps_start, PPS,0,pps_length);
for (int pi =0;pi<pps_length;pi++)
Log.e(TAG, "==========PPS :" +pi + PPS[pi]);
//Save PPS
h264Header.setPPS(PPS);
//
Log.e(TAG, "==========SPS :" + SPS+ ", PPS :" +PPS);
return h264Header;
}
}
return h264Header;
}
private static short bytes2short(byte[] b) {
short mask = 0xff;
short temp = 0;
short res = 0;
for (int i = 0; i < 2; i++) {
res <<= 8;
temp = (short) (b[1 - i] & mask);
res |= temp;
}
return res;
}
}