diff --git a/src/net/majorkernelpanic/streaming/Session.java b/src/net/majorkernelpanic/streaming/Session.java
index a904fd4f..0d3590a1 100644
--- a/src/net/majorkernelpanic/streaming/Session.java
+++ b/src/net/majorkernelpanic/streaming/Session.java
@@ -39,6 +39,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.util.Log;
/**
* You should instantiate this class with the {@link SessionBuilder}.
@@ -129,7 +130,7 @@ public Session() {
mOrigin = "127.0.0.1";
}
- /**
+ /**
* The callback interface you need to implement to get some feedback
* Those will be called from the UI thread.
*/
@@ -369,7 +370,9 @@ public void configure() {
public void run() {
try {
syncConfigure();
- } catch (Exception e) {};
+ } catch (Exception e) {
+ Log.e(TAG, Log.getStackTraceString(e));
+ };
}
});
}
@@ -622,11 +625,14 @@ public int getCamera() {
}
+
/**
* Toggles the LED of the phone if it has one.
* You can get the current state of the flash with
* {@link Session#getVideoTrack()} and {@link VideoStream#getFlashState()}.
**/
+
+ /*
public void toggleFlash() {
mHandler.post(new Runnable() {
@Override
@@ -642,6 +648,51 @@ public void run() {
});
}
+
+
+
+public void setSize(final int w, final int h) {
+
+ sHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+ if (mVideoStream != null) {
+ try {
+
+ mVideoStream.setCameraPreviewSize(w,h);
+ } catch (RuntimeException e) {
+
+ }
+ }
+ }
+ });
+
+ }
+
+
+ //
+ public List getAvailableSizes() {
+
+ sHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+ if (mVideoStream != null) {
+ try {
+ size = mVideoStream.getSizes();
+ } catch (RuntimeException e) {
+
+ }
+ }
+ }
+ });
+ return size;
+ }
+
+*/
+
+
/** Deletes all existing tracks & release associated resources. */
public void release() {
removeAudioTrack();
diff --git a/src/net/majorkernelpanic/streaming/SessionBuilder.java b/src/net/majorkernelpanic/streaming/SessionBuilder.java
index 1ba39c41..0fd3b4ef 100644
--- a/src/net/majorkernelpanic/streaming/SessionBuilder.java
+++ b/src/net/majorkernelpanic/streaming/SessionBuilder.java
@@ -74,6 +74,7 @@ public class SessionBuilder {
private SurfaceView mSurfaceView = null;
private String mOrigin = null;
private String mDestination = null;
+ private int mDestinationVideoPort = 5006;
private Session.Callback mCallback = null;
// Removes the default public constructor
@@ -141,7 +142,7 @@ public Session build() {
video.setVideoQuality(mVideoQuality);
video.setSurfaceView(mSurfaceView);
video.setPreviewOrientation(mOrientation);
- video.setDestinationPorts(5006);
+ video.setDestinationPorts(mDestinationVideoPort);
}
if (session.getAudioTrack()!=null) {
@@ -169,6 +170,13 @@ public SessionBuilder setDestination(String destination) {
return this;
}
+ /** Sets the destination IP & video port for the session. */
+ public SessionBuilder setDestination(String destination, int videoPort) {
+ mDestination = destination;
+ mDestinationVideoPort = videoPort;
+ return this;
+ }
+
/** Sets the origin of the session. It appears in the SDP of the session. */
public SessionBuilder setOrigin(String origin) {
mOrigin = origin;
diff --git a/src/net/majorkernelpanic/streaming/exceptions/InvalidSurfaceException.java b/src/net/majorkernelpanic/streaming/exceptions/InvalidSurfaceException.java
index 45cd5b16..f7423b44 100644
--- a/src/net/majorkernelpanic/streaming/exceptions/InvalidSurfaceException.java
+++ b/src/net/majorkernelpanic/streaming/exceptions/InvalidSurfaceException.java
@@ -27,5 +27,8 @@ public class InvalidSurfaceException extends RuntimeException {
public InvalidSurfaceException(String message) {
super(message);
}
+ public InvalidSurfaceException(String message, Throwable t) {
+ super(message, t);
+ }
}
diff --git a/src/net/majorkernelpanic/streaming/gl/SurfaceView.java b/src/net/majorkernelpanic/streaming/gl/SurfaceView.java
index d78b1721..f499f67a 100644
--- a/src/net/majorkernelpanic/streaming/gl/SurfaceView.java
+++ b/src/net/majorkernelpanic/streaming/gl/SurfaceView.java
@@ -90,9 +90,15 @@ public SurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mHandler = new Handler();
getHolder().addCallback(this);
- }
+ }
+
+ public SurfaceView(Context context) {
+ super(context);
+ mHandler = new Handler();
+ getHolder().addCallback(this);
+ }
- public void setAspectRatioMode(int mode) {
+ public void setAspectRatioMode(int mode) {
mAspectRatioMode = mode;
}
diff --git a/src/net/majorkernelpanic/streaming/video/H264Stream.java b/src/net/majorkernelpanic/streaming/video/H264Stream.java
index a45034e1..a67661b6 100644
--- a/src/net/majorkernelpanic/streaming/video/H264Stream.java
+++ b/src/net/majorkernelpanic/streaming/video/H264Stream.java
@@ -125,7 +125,7 @@ private MP4Config testMediaCodecAPI() throws RuntimeException, IOException {
createCamera();
updateCamera();
try {
- if (mQuality.resX>=640) {
+ if (mQuality.resX>=640 && mMode == MODE_MEDIACODEC_API) {
// Using the MediaCodec API with the buffer method for high resolutions is too slow
mMode = MODE_MEDIARECORDER_API;
}
diff --git a/src/net/majorkernelpanic/streaming/video/VideoQuality.java b/src/net/majorkernelpanic/streaming/video/VideoQuality.java
index 8c857f86..a4f558f2 100644
--- a/src/net/majorkernelpanic/streaming/video/VideoQuality.java
+++ b/src/net/majorkernelpanic/streaming/video/VideoQuality.java
@@ -79,7 +79,7 @@ public boolean equals(VideoQuality quality) {
}
public VideoQuality clone() {
- return new VideoQuality(resX,resY,framerate,bitrate);
+ return new VideoQuality(resX,resY,framerate, bitrate);
}
public static VideoQuality parseQuality(String str) {
@@ -113,7 +113,7 @@ public static VideoQuality determineClosestSupportedResolution(Camera.Parameters
for (Iterator it = supportedSizes.iterator(); it.hasNext();) {
Size size = it.next();
supportedSizesStr += size.width+"x"+size.height+(it.hasNext()?", ":"");
- int dist = Math.abs(quality.resX - size.width);
+ int dist = Math.abs(quality.resX - size.width) + Math.abs(quality.resY - size.height);
if (dist size = getSizes();
+ Camera.Size size_to_use = getOptimalSize(size, w, h);
+
+ System.out.println("Setting preview to: "+ w + h);
+
+ if (mCamera != null) {
+
+ if (mStreaming && mMode == MODE_MEDIARECORDER_API) {
+ lockCamera();
+ }
+
+ Parameters parameters = mCamera.getParameters();
+
+ parameters.setPreviewSize(size_to_use.width, size_to_use.height);
+ //parameters.setPreviewSize(176, 144);
+ try {
+ mCamera.setParameters(parameters);
+ System.out.println("Setting preview to: "+ size_to_use.width + size_to_use.height + " DONE!!");
+ Camera.Size z = parameters.getPreviewSize();
+ int w_temp = z.width;
+ int h_temp = z.height;
+ System.out.println("Saved preview is: "+ w_temp + h_temp);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ else {
+ System.out.println("Setting preview to: "+ w + h + " FAILED!!");
+ }
+
+
+
+ }
+
+
+ public synchronized List getSizes() {
+
+ List size = null;
+
+ if (mCamera != null) {
+
+ if (mStreaming && mMode == MODE_MEDIARECORDER_API) {
+ lockCamera();
+ }
+
+
+ try {
+
+ Parameters parameters = mCamera.getParameters();
+ size = parameters.getSupportedPreviewSizes();
+
+ System.out.println("Some of the supported preview is " + size.get(0).width + "x" + size.get(0).height);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+
+
+ }
+
+ else {
+ System.out.println("Failed to get preview sizes");
+ }
+
+ return size;
+ }
+
+
+
+ private Camera.Size getOptimalSize(List sizes, int w, int h) {
+
+ final double ASPECT_TOLERANCE = 0.2;
+ double targetRatio = (double) w / h;
+ if (sizes == null)
+ return null;
+ Camera.Size optimalSize = null;
+ double minDiff = Double.MAX_VALUE;
+ int targetHeight = h;
+ // Try to find an size match aspect ratio and size
+ for (Camera.Size size : sizes)
+ {
+
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+ continue;
+ if (Math.abs(size.height - targetHeight) < minDiff)
+ {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ // Cannot find the one match the aspect ratio, ignore the requirement
+
+ if (optimalSize == null)
+ {
+ minDiff = Double.MAX_VALUE;
+ for (Camera.Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff)
+ {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+
+
+
+ return optimalSize;
+ }
+
+
+
+
+
+
+
/**
* Computes the average frame rate at which the preview callback is called.
* We will then use this average framerate with the MediaCodec.