Skip to content

Commit

Permalink
Merge pull request #5 from bilthon/master
Browse files Browse the repository at this point in the history
 Fixed a bug with the MP4 parser, and a bug in the RTSP client
  • Loading branch information
Simon committed Sep 24, 2013
2 parents 7b73d50 + 2311682 commit 7a25dbe
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/net/majorkernelpanic/streaming/MediaStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public boolean isStreaming() {

/** Starts the stream. */
public synchronized void start() throws IllegalStateException, IOException {

Log.d(TAG, "start");
if (mPacketizer==null)
throw new IllegalStateException("setPacketizer() should be called before start().");

Expand Down
33 changes: 20 additions & 13 deletions src/net/majorkernelpanic/streaming/mp4/MP4Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
* along with this source code; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

package net.majorkernelpanic.streaming.mp4;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.HashMap;

import android.util.Base64;
Expand All @@ -40,7 +40,6 @@ class MP4Parser {
private HashMap<String, Long> boxes = new HashMap<String, Long>();
private final RandomAccessFile file;
private long pos = 0;
private byte[] buffer = new byte[8];

public MP4Parser(final String path) throws IOException, FileNotFoundException {
this.file = new RandomAccessFile(new File(path), "r");
Expand Down Expand Up @@ -85,20 +84,26 @@ public StsdBox getStsdBox() throws IOException {
}

private void parse(String path, long len) throws IOException {
byte[] buffer = new byte[8];
String name="";
long sum = 0, newlen = 0;

boxes.put(path, pos-8);
if(!path.equals(""))
boxes.put(path, pos-8);


while (sum<len) {

file.read(buffer,0,8); sum += 8; pos += 8;
if (validBoxName()) {

newlen = ( buffer[3]&0xFF | (buffer[2]&0xFF)<<8 | (buffer[1]&0xFF)<<16 | (buffer[0]&0xFF)<<24 ) - 8;
// 1061109559+8 correspond to "????" in ASCII the HTC Desire S seems to write that sometimes, maybe other phones do
if (newlen<=0 || newlen==1061109559) throw new IOException();
file.read(buffer,0,8);
sum += 8;
pos += 8;
if (validBoxName(buffer)) {

ByteBuffer byteBuffer = ByteBuffer.wrap(buffer,0,4);
newlen = byteBuffer.getInt()-8;

// a) 1061109559+8 correspond to "????" in ASCII the HTC Desire S seems to write that sometimes, maybe other phones do
// b) wide atom would produce a newlen == 0, and we shouldn't throw an exception because of that
if (newlen < 0 || newlen == 1061109559) throw new IOException();
name = new String(buffer,4,4);
Log.d(TAG,"Atom -> name: "+name+" newlen: "+newlen+" pos: "+pos);
sum += newlen;
Expand All @@ -110,7 +115,8 @@ private void parse(String path, long len) throws IOException {
file.seek(file.getFilePointer() - 8 + len);
sum += len-8;
} else {
if (file.skipBytes((int) (len-8))<len-8) {
int skipped = file.skipBytes((int)(len-8));
if (skipped < ((int)(len-8))) {
throw new IOException();
}
pos += len-8;
Expand All @@ -120,9 +126,10 @@ private void parse(String path, long len) throws IOException {
}
}

private boolean validBoxName() {
private boolean validBoxName(byte[] buffer) {
for (int i=0;i<4;i++) {
if ((buffer[i+4]<97 || buffer[i+4]>122) && (buffer[i+4]<48 || buffer[i+4]>57) ) return false;
// If the next 4 bytes are neither lowercase letters nor numbers
if ((buffer[i+4]< 'a' || buffer[i+4]>'z') && (buffer[i+4]<'0'|| buffer[i+4]>'9') ) return false;
}
return true;
}
Expand Down
15 changes: 7 additions & 8 deletions src/net/majorkernelpanic/streaming/rtsp/RtspClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,17 @@ private void sendRequestAnnounce() throws IllegalStateException, SocketException
"Content-Length: " + body.length() + "\r\n" +
"Content-Type: application/sdp \r\n\r\n" +
body;

Log.i(TAG,request.substring(0, request.indexOf("\r\n")));

mOutputStream.write(request.getBytes("UTF-8"));
Response response = Response.parseResponse(mBufferedReader);

try {
Matcher m = Response.rexegSession.matcher(response.headers.get("session")); m.find();
Matcher m = Response.rexegSession.matcher(response.headers.get("session"));
m.find();
mSessionID = m.group(1);
} catch (Exception e) {
throw new IOException("Invalid response from server");
throw new IOException("Invalid response from server. Session id: "+mSessionID);
}

if (response.status == 401) {
Expand Down Expand Up @@ -246,17 +246,17 @@ private void sendRequestSetup() throws IllegalStateException, SocketException, I
"CSeq: " + (++mCSeq) + "\r\n" +
"Transport: RTP/AVP/UDP;unicast;client_port="+(5000+2*i)+"-"+(5000+2*i+1)+";mode=receive\r\n" +
"Session: " + mSessionID + "\r\n" +
"Authorization: " + mAuthorization+ "\r\n";
"Authorization: " + mAuthorization+ "\r\n\r\n";

Log.i(TAG,request.substring(0, request.indexOf("\r\n")));

mOutputStream.write(request.getBytes("UTF-8"));
Response response = Response.parseResponse(mBufferedReader);

Matcher m;
try {
m = Response.rexegTransport.matcher(response.headers.get("transport")); m.find();
stream.setDestinationPorts(Integer.parseInt(m.group(3)), Integer.parseInt(m.group(4)));
Log.d(TAG, "Setting destination ports: "+Integer.parseInt(m.group(3))+", "+Integer.parseInt(m.group(4)));
} catch (Exception e) {
e.printStackTrace();
int[] ports = stream.getDestinationPorts();
Expand All @@ -274,7 +274,7 @@ private void sendRequestRecord() throws IllegalStateException, SocketException,
"Range: npt=0.000-" +
"CSeq: " + (++mCSeq) + "\r\n" +
"Session: " + mSessionID + "\r\n" +
"Authorization: " + mAuthorization+ "\r\n";
"Authorization: " + mAuthorization+ "\r\n\r\n";
Log.i(TAG,request.substring(0, request.indexOf("\r\n")));
mOutputStream.write(request.getBytes("UTF-8"));
Response.parseResponse(mBufferedReader);
Expand Down Expand Up @@ -325,7 +325,7 @@ static class Response {
// Parses a WWW-Authenticate header
public static final Pattern rexegAuthenticate = Pattern.compile("realm=\"(.+)\",\\s+nonce=\"(\\w+)\"",Pattern.CASE_INSENSITIVE);
// Parses a Session header
public static final Pattern rexegSession = Pattern.compile("(\\d+);",Pattern.CASE_INSENSITIVE);
public static final Pattern rexegSession = Pattern.compile("(\\d+)",Pattern.CASE_INSENSITIVE);
// Parses a Transport header
public static final Pattern rexegTransport = Pattern.compile("client_port=(\\d+)-(\\d+).+server_port=(\\d+)-(\\d+)",Pattern.CASE_INSENSITIVE);

Expand All @@ -338,7 +338,6 @@ public static Response parseResponse(BufferedReader input) throws IOException, I
Response response = new Response();
String line;
Matcher matcher;

// Parsing request method & uri
if ((line = input.readLine())==null) throw new SocketException("Connection lost");
matcher = regexStatus.matcher(line);
Expand Down
2 changes: 1 addition & 1 deletion src/net/majorkernelpanic/streaming/video/H264Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public void onInfo(MediaRecorder mr, int what, int extra) {
} else if (what==MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN) {
Log.d(TAG,"MediaRecorder: INFO_UNKNOWN");
} else {
Log.d(TAG,"WTF ?");
Log.d(TAG,"WTF ?. what: "+what);
}
mLock.release();
}
Expand Down

0 comments on commit 7a25dbe

Please sign in to comment.