diff --git a/.gitmodules b/.gitmodules
index 391eac1a0..bfd0edac3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -19,3 +19,15 @@
[submodule "submodules/libilbc-rfc3951"]
path = submodules/libilbc-rfc3951
url = git://git.linphone.org/libilbc-rfc3951.git
+[submodule "submodules/externals/ffmpeg"]
+ path = submodules/externals/ffmpeg
+ url = git://git.ffmpeg.org/ffmpeg
+[submodule "submodules/externals/libswscale"]
+ path = submodules/externals/libswscale
+ url = git://git.ffmpeg.org/libswscale
+[submodule "submodules/externals/x264"]
+ path = submodules/externals/x264
+ url = git://git.videolan.org/x264.git
+[submodule "submodules/msx264"]
+ path = submodules/msx264
+ url = git://git.linphone.org/msx264.git
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index db8884510..6171b52ef 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,8 +20,19 @@
+
+
+
+
+
+
+ android:label="Hello World"
+ android:enabled="false">
@@ -60,7 +71,11 @@
-
+
+
+
+
+
@@ -103,6 +118,10 @@
+
+
+
+
diff --git a/jni/Android.mk b/jni/Android.mk
index 2c48606fe..477bb04af 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -1,5 +1,9 @@
root-dir:=$(APP_PROJECT_PATH)
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+LINPHONE_VIDEO=1
+endif
+
include $(root-dir)/submodules/externals/build/speex/Android.mk
include $(root-dir)/submodules/externals/build/gsm/Android.mk
@@ -14,11 +18,14 @@ include $(root-dir)/submodules/linphone/mediastreamer2/build/android/Android.mk
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
include $(root-dir)/submodules/msilbc/Android.mk
+include $(root-dir)/submodules/msx264/Android.mk
+include $(root-dir)/submodules/externals/build/ffmpeg/Android.mk
+include $(root-dir)/submodules/externals/build/x264/Android.mk
+
endif
-
-
include $(root-dir)/submodules/linphone/build/android/Android.mk
+
diff --git a/jni/Application.mk b/jni/Application.mk
index fc0c90e73..0b1d358e1 100644
--- a/jni/Application.mk
+++ b/jni/Application.mk
@@ -1,10 +1,12 @@
APP_PROJECT_PATH := $(call my-dir)/../
-APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone
+APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone
+
+
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
-APP_MODULES +=libmsilbc
+APP_MODULES +=libmsilbc libavutil libavcore libavcodec libswscale libx264 libmsx264
endif
APP_BUILD_SCRIPT:=$(call my-dir)/Android.mk
-APP_PLATFORM := android-3
+APP_PLATFORM := android-8
APP_ABI := armeabi armeabi-v7a
#APP_OPTIM := debug
diff --git a/libs/armeabi-v7a/liblinphone.so b/libs/armeabi-v7a/liblinphone.so
index 86e77e8bc..8e4ce1a95 100755
Binary files a/libs/armeabi-v7a/liblinphone.so and b/libs/armeabi-v7a/liblinphone.so differ
diff --git a/libs/armeabi/liblinphone.so b/libs/armeabi/liblinphone.so
index 45642237f..0d6fdb167 100755
Binary files a/libs/armeabi/liblinphone.so and b/libs/armeabi/liblinphone.so differ
diff --git a/res/drawable/startvideo_green.png b/res/drawable/startvideo_green.png
new file mode 100644
index 000000000..1cc2e3e4b
Binary files /dev/null and b/res/drawable/startvideo_green.png differ
diff --git a/res/layout-land/dialer.xml b/res/layout-land/dialer.xml
index 59acaaee3..cc395e052 100644
--- a/res/layout-land/dialer.xml
+++ b/res/layout-land/dialer.xml
@@ -5,32 +5,42 @@
-
-
-
-
+
+
+
+
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
diff --git a/res/layout-land/videocall.xml b/res/layout-land/videocall.xml
new file mode 100644
index 000000000..22bcc2b79
--- /dev/null
+++ b/res/layout-land/videocall.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml
index c19f024cc..0943935bd 100644
--- a/res/layout/dialer.xml
+++ b/res/layout/dialer.xml
@@ -15,14 +15,25 @@
-
-
-
+
+
+
+
+
+
+
-
+
+
-
-
-
-
+
+
+
-
-
+
diff --git a/res/layout/videocall.xml b/res/layout/videocall.xml
new file mode 100644
index 000000000..33da7f149
--- /dev/null
+++ b/res/layout/videocall.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/videotest.xml b/res/layout/videotest.xml
new file mode 100644
index 000000000..a1a269a06
--- /dev/null
+++ b/res/layout/videotest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/menu/videocall_activity_menu.xml b/res/menu/videocall_activity_menu.xml
new file mode 100644
index 000000000..4a3b5e099
--- /dev/null
+++ b/res/menu/videocall_activity_menu.xml
@@ -0,0 +1,12 @@
+
+
diff --git a/res/raw/linphonerc b/res/raw/linphonerc
index a38bdeccc..246591bbd 100644
--- a/res/raw/linphonerc
+++ b/res/raw/linphonerc
@@ -1,8 +1,8 @@
[net]
-download_bw=128
-upload_bw=128
+download_bw=256
+upload_bw=256
firewall_policy=0
-mtu=0
+mtu=1300
[sip]
sip_port=5060
@@ -12,7 +12,7 @@ contact=sip:unknown@unknown-host
inc_timeout=15
use_info=0
use_ipv6=0
-register_only_when_network_is_up=0
+register_only_when_network_is_up=1
default_proxy=0
auto_net_state_mon=0
keepalive_period=3600000
@@ -30,6 +30,8 @@ ringer_dev_id=ANDROID SND: Android Sound card
capture_dev_id=ANDROID SND: Android Sound card
remote_ring=/data/data/org.linphone/files/ringback.wav
local_ring=/data/data/org.linphone/files/oldphone_mono.wav
-ec_tail_len=200
+ec_tail_len=100
+[video]
+size=qvga-portrait
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 57f6e9297..6f9dad17d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,5 +1,35 @@
+ Use front camera
+ pref_video_use_front_camera_key
+ Video
+ Preferences
+ H263
+ pref_video_codec_h263_key
+ MPEG4
+ pref_video_codec_mpeg4_key
+ H264
+ pref_video_codec_h264_key
+ Codecs
+ pref_video_codecs_key
+ Display dialer
+ Front/Rear Camera
+ Try High resolution
+ Low resolution
+ Change resolution
+ Mute/Unmute camera
+ Disable camera
+ Enable camera
+ Terminate call
+ Video settings
+ pref_video_automatically_share_my_video_key
+ Share my camera
+ Automatically send my camera on incoming calls
+ pref_video_initiate_call_with_video_key
+ Initiate video calls
+ Always send my camera on outgoing calls
+ pref_video_enable_key
+ Enable Video
Replace + by 00
pref_escape_plus_key
iLBC might be unavailable depending on ARM processor and Android OS version.
@@ -61,9 +91,13 @@
History
Cannot build destination address from [%s]
Clear
+Cannot get call parameters
+Cannot create default call parameters
Cannot invite destination address [%s]
registered to %s
fails to register to %s
started
-Removes the echo heared by the other end.
+Removes the echo heard by other end
+Stun server
+pref_stun_server_key
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index d86d2334d..60304b22f 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -1,40 +1,117 @@
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:title="@string/pref_codec_speex16" android:defaultValue="true"
+ android:enabled="false">
-
+
+ android:title="@string/pref_codec_gsm" android:defaultValue="true">
+ android:title="@string/pref_codec_pcmu" android:defaultValue="true">
-
-
-
-
+ android:title="@string/pref_codec_pcma" android:defaultValue="true">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/linphone/AboutActivity.java b/src/org/linphone/AboutActivity.java
index 3797305cd..0e54ed1fc 100644
--- a/src/org/linphone/AboutActivity.java
+++ b/src/org/linphone/AboutActivity.java
@@ -38,4 +38,5 @@ public class AboutActivity extends Activity {
Log.e(LinphoneService.TAG, "cannot get version name", e);
}
}
+
}
diff --git a/src/org/linphone/BandwidthManager.java b/src/org/linphone/BandwidthManager.java
new file mode 100644
index 000000000..6af77423c
--- /dev/null
+++ b/src/org/linphone/BandwidthManager.java
@@ -0,0 +1,128 @@
+/*
+BandwithManager.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone;
+
+import org.linphone.core.AndroidCameraRecordManager;
+import org.linphone.core.LinphoneCallParams;
+import org.linphone.core.LinphoneCore;
+import org.linphone.core.VideoSize;
+
+public class BandwidthManager {
+
+ public static final int HIGH_RESOLUTION = 0;
+ public static final int LOW_RESOLUTION = 1;
+ public static final int LOW_BANDWIDTH = 2;
+ private static final boolean portraitMode = true; // FIXME: preference?
+
+ private static final int[][] bandwidthes = {{256,256}, {128,128}, {80,80}};
+ private static BandwidthManager instance;
+
+ private int currentProfile = HIGH_RESOLUTION;
+ public int getCurrentProfile() {return currentProfile;}
+
+ public static final synchronized BandwidthManager getInstance() {
+ if (instance == null) instance = new BandwidthManager();
+ return instance;
+ }
+
+
+ private BandwidthManager() {
+ // FIXME register a listener on NetworkManager to get notified of network state
+ // FIXME register a listener on Preference to get notified of change in video enable value
+
+ // FIXME initially get those values
+ }
+
+ private boolean userRestriction;
+ public boolean isUserRestriction() {return userRestriction;}
+ public void setUserRestriction(boolean limit) {
+ userRestriction = limit;
+ computeNewProfile();
+ }
+
+
+ private void computeNewProfile() {
+ int newProfile = userRestriction ? LOW_RESOLUTION : HIGH_RESOLUTION;
+ if (newProfile != currentProfile) {
+ currentProfile = newProfile;
+ onProfileChanged(currentProfile);
+ }
+ }
+
+ private void onProfileChanged(int newProfile) {
+ LinphoneCore lc = LinphoneService.instance().getLinphoneCore();
+ lc.setUploadBandwidth(bandwidthes[newProfile][0]);
+ lc.setDownloadBandwidth(bandwidthes[newProfile][1]);
+
+ if (lc.isIncall()) {
+ InviteManager.getInstance().reinvite();
+ } else {
+ updateWithProfileSettings(lc, null);
+ }
+ }
+
+
+ public void updateWithProfileSettings(LinphoneCore lc, LinphoneCallParams callParams) {
+ // Setting Linphone Core Preferred Video Size
+ AndroidCameraRecordManager cameraManager = AndroidCameraRecordManager.getInstance();
+
+ boolean bandwidthOKForVideo = isVideoPossible();
+ if (bandwidthOKForVideo) {
+ VideoSize targetVideoSize = cameraManager.doYouSupportThisVideoSize(getMaximumVideoSize());
+
+ lc.setPreferredVideoSize(targetVideoSize);
+ VideoSize actualVideoSize = lc.getPreferredVideoSize();
+ if (!targetVideoSize.equals(actualVideoSize)) {
+ lc.setPreferredVideoSize(VideoSize.createStandard(VideoSize.QCIF, targetVideoSize.isPortrait()));
+ }
+ }
+
+ if (callParams != null) { // in call
+ // Update video parm if
+ if (!bandwidthOKForVideo) { // NO VIDEO
+ callParams.setVideoEnabled(false);
+ callParams.setAudioBandwidth(40);
+ } else {
+ callParams.setVideoEnabled(true);
+ callParams.setAudioBandwidth(0); // disable limitation
+ }
+ }
+ }
+
+
+ private VideoSize maximumVideoSize(int profile) {
+ switch (profile) {
+ case LOW_RESOLUTION:
+ return VideoSize.createStandard(VideoSize.QCIF, portraitMode);
+ case HIGH_RESOLUTION:
+ return VideoSize.createStandard(VideoSize.QVGA, portraitMode);
+ default:
+ throw new RuntimeException("profile not managed : " + profile);
+ }
+ }
+
+
+ public boolean isVideoPossible() {
+ return currentProfile != LOW_BANDWIDTH;
+ }
+
+ public VideoSize getMaximumVideoSize() {
+ return maximumVideoSize(currentProfile);
+ }
+}
diff --git a/src/org/linphone/BootReceiver.java b/src/org/linphone/BootReceiver.java
index 097767fab..836e62d12 100644
--- a/src/org/linphone/BootReceiver.java
+++ b/src/org/linphone/BootReceiver.java
@@ -34,5 +34,4 @@ public class BootReceiver extends BroadcastReceiver {
context.startService(lLinphoneServiceIntent);;
}
}
-
}
diff --git a/src/org/linphone/ContactPickerActivity.java b/src/org/linphone/ContactPickerActivity.java
index 397c8486d..ad3d0392d 100644
--- a/src/org/linphone/ContactPickerActivity.java
+++ b/src/org/linphone/ContactPickerActivity.java
@@ -21,8 +21,6 @@ package org.linphone;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
-
-
import android.os.Bundle;
import android.provider.Contacts;
import android.provider.Contacts.People;
diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java
index c680f5f44..e87898fac 100644
--- a/src/org/linphone/DialerActivity.java
+++ b/src/org/linphone/DialerActivity.java
@@ -18,8 +18,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone;
-import java.io.IOException;
-
+import org.linphone.component.ToggleImageButton;
+import org.linphone.component.ToggleImageButton.OnCheckedChangeListener;
+import org.linphone.core.AndroidCameraRecordManager;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatRoom;
@@ -30,15 +31,14 @@ import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.LinphoneCall.State;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
-import android.media.Ringtone;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
@@ -51,24 +51,20 @@ import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
-import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
-import android.widget.ToggleButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
public class DialerActivity extends Activity implements LinphoneCoreListener {
private TextView mAddress;
private TextView mDisplayNameView;
-
+
private TextView mStatus;
private ImageButton mCall;
private ImageButton mDecline;
@@ -88,13 +84,13 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private Button mStar;
private Button mHash;
- private ToggleButton mMute;
- private ToggleButton mSpeaker;
+ private ToggleImageButton mMute;
+ private ToggleImageButton mSpeaker;
private LinearLayout mCallControlRow;
private TableRow mInCallControlRow;
- private LinearLayout mAddressLayout;
- private LinearLayout mInCallAddressLayout;
+ private View mAddressLayout;
+ private View mInCallAddressLayout;
private static DialerActivity theDialer;
@@ -102,10 +98,13 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private AudioManager mAudioManager;
private PowerManager.WakeLock mWakeLock;
private SharedPreferences mPref;
+ private ImageButton mAddVideo;
- static String PREF_CHECK_CONFIG = "pref_check_config";
+ private static final String PREF_CHECK_CONFIG = "pref_check_config";
+ private static final String PREF_FIRST_LAUNCH = "pref_first_launch";
private static String CURRENT_ADDRESS = "org.linphone.current-address";
private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
+ static int VIDEO_VIEW_ACTIVITY = 100;
Settings.System mSystemSettings = new Settings.System();
MediaPlayer mRingerPlayer;
@@ -162,9 +161,20 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
mAddress.getEditableText().clear();
return true;
}
-
});
-
+
+ mAddVideo = (ImageButton) findViewById(R.id.AddVideo);
+ mAddVideo.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ // If no in video call; try to reinvite with video
+ boolean alreadyInVideoCall = !InviteManager.getInstance().reinviteWithVideo();
+ if (alreadyInVideoCall) {
+ // In video call; going back to video call activity
+ startVideoView(VIDEO_VIEW_ACTIVITY);
+ }
+ }
+ });
+
mCall = (ImageButton) findViewById(R.id.Call);
mCall.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
@@ -204,10 +214,10 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
mCallControlRow = (LinearLayout) findViewById(R.id.CallControlRow);
mInCallControlRow = (TableRow) findViewById(R.id.IncallControlRow);
- mAddressLayout = (LinearLayout) findViewById(R.id.Addresslayout);
- mInCallAddressLayout = (LinearLayout) findViewById(R.id.IncallAddressLayout);
- mMute = (ToggleButton)findViewById(R.id.mic_mute_button);
- mSpeaker = (ToggleButton)findViewById(R.id.speaker_button);
+ mAddressLayout = (View) findViewById(R.id.Addresslayout);
+ mInCallAddressLayout = (View) findViewById(R.id.IncallAddressLayout);
+ mMute = (ToggleImageButton)findViewById(R.id.mic_mute_button);
+ mSpeaker = (ToggleImageButton)findViewById(R.id.speaker_button);
mInCallControlRow.setVisibility(View.GONE);
mInCallAddressLayout.setVisibility(View.GONE);
@@ -225,15 +235,11 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
} else {
mCall.setEnabled(false);
mHangup.setEnabled(!mCall.isEnabled());
+ updateIncallVideoCallButton();
mCallControlRow.setVisibility(View.GONE);
mInCallControlRow.setVisibility(View.VISIBLE);
mAddressLayout.setVisibility(View.GONE);
mInCallAddressLayout.setVisibility(View.VISIBLE);
- mMute.setChecked(!lLinphoneCore.isMicMuted());
- mMute.setCompoundDrawablesWithIntrinsicBounds(0
- , mMute.isChecked()?R.drawable.mic_active:R.drawable.mic_muted
- , 0
- , 0);
String DisplayName = lLinphoneCore.getRemoteAddress().getDisplayName();
if (DisplayName!=null) {
@@ -241,10 +247,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
} else {
mDisplayNameView.setText(lLinphoneCore.getRemoteAddress().getUserName());
}
- if ((Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getMode() == AudioManager.MODE_NORMAL)
- || Integer.parseInt(Build.VERSION.SDK) >4 &&mAudioManager.isSpeakerphoneOn()) {
- mSpeaker.setChecked(true);
- }
+ configureMuteAndSpeakerButtons();
mWakeLock.acquire();
}
}
@@ -253,35 +256,25 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
mMute.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ public void onCheckedChanged(ToggleImageButton button, boolean isChecked) {
LinphoneCore lc = LinphoneService.instance().getLinphoneCore();
if (isChecked) {
- lc.muteMic(false);
- mMute.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.mic_active, 0, 0);
- } else {
lc.muteMic(true);
- mMute.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.mic_muted, 0, 0);
+ } else {
+ lc.muteMic(false);
}
-
}
-
});
mSpeaker.setOnCheckedChangeListener(new OnCheckedChangeListener() {
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ public void onCheckedChanged(ToggleImageButton buttonView, boolean isChecked) {
if (isChecked) {
routeAudioToSpeaker();
- mSpeaker.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.speaker_32_on, 0, 0);
} else {
routeAudioToReceiver();
- mSpeaker.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.speaker_32_off, 0, 0);
}
-
}
-
});
mZero = (Button) findViewById(R.id.Button00) ;
@@ -335,6 +328,15 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
}
+ private void updateIncallVideoCallButton() {
+ boolean prefVideoEnabled = mPref.getBoolean(getString(R.string.pref_video_enable_key), false);
+ if (prefVideoEnabled && !mCall.isEnabled()) {
+ mAddVideo.setVisibility(View.VISIBLE);
+ mAddVideo.setEnabled(true);
+ } else {
+ mAddVideo.setVisibility(View.GONE);
+ }
+ }
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
@@ -386,36 +388,42 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
if (state == LinphoneCore.GlobalState.GlobalOn) {
mCall.setEnabled(!lc.isIncall());
mHangup.setEnabled(!mCall.isEnabled());
+ updateIncallVideoCallButton();
try{
LinphoneService.instance().initFromConf();
} catch (LinphoneConfigException ec) {
- Log.w(LinphoneService.TAG,"no valid settings found",ec);
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- TextView lDialogTextView = new TextView(this);
- lDialogTextView.setAutoLinkMask(0x0f/*all*/);
- lDialogTextView.setPadding(10, 10, 10, 10);
- lDialogTextView.setText(Html.fromHtml(getString(R.string.initial_config_error) ));
- builder.setCustomTitle(lDialogTextView)
- .setCancelable(false)
- .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- LinphoneActivity.instance().startprefActivity();
- }
- }).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
+ if (mPref.getBoolean(PREF_FIRST_LAUNCH, true)) {
+ Log.w(LinphoneService.TAG,"no valid settings found - first launch",ec);
+ LinphoneActivity.instance().startprefActivity();
+ mPref.edit().putBoolean(PREF_FIRST_LAUNCH, false).commit();
+ } else {
+ Log.w(LinphoneService.TAG,"no valid settings found", ec);
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ TextView lDialogTextView = new TextView(this);
+ lDialogTextView.setAutoLinkMask(0x0f/*all*/);
+ lDialogTextView.setPadding(10, 10, 10, 10);
+ lDialogTextView.setText(Html.fromHtml(getString(R.string.initial_config_error)));
+ builder.setCustomTitle(lDialogTextView)
+ .setCancelable(false)
+ .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ LinphoneActivity.instance().startprefActivity();
+ }
+ }).setNeutralButton(getString(R.string.no), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ }).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit();
+ dialog.cancel();
+ }
+ });
+ if (mPref.getBoolean(PREF_CHECK_CONFIG, false) == false) {
+ builder.create().show();
}
- }).setNegativeButton(getString(R.string.never_remind), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- mPref.edit().putBoolean(PREF_CHECK_CONFIG, true).commit();
- dialog.cancel();
- }
- });
- if (mPref.getBoolean(PREF_CHECK_CONFIG, false) == false) {
- builder.create().show();
}
-
} catch (Exception e ) {
Log.e(LinphoneService.TAG,"Cannot get initial config", e);
}
@@ -425,6 +433,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
}
}
+ private void startVideoView(int requestCode) {
+ Intent lIntent = new Intent();
+ lIntent.setClass(this, VideoCallActivity.class);
+ startActivityForResult(lIntent,requestCode);
+ }
+
public void registrationState(final LinphoneCore lc, final LinphoneProxyConfig cfg,final LinphoneCore.RegistrationState state,final String smessage) {/*nop*/};
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
if (mCurrentCallState == LinphoneCall.State.IncomingReceived) {
@@ -436,6 +450,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
enterIncalMode(lc);
routeAudioToReceiver();
} else if (state == LinphoneCall.State.IncomingReceived) {
+ resetCameraFromPreferences();
callPending();
} else if (state == LinphoneCall.State.Connected) {
enterIncalMode(lc);
@@ -448,6 +463,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
exitCallMode();
} else if (state == LinphoneCall.State.CallEnd) {
exitCallMode();
+ } else if (state == LinphoneCall.State.StreamsRunning) {
+ if (LinphoneService.instance().getLinphoneCore().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()) {
+ if (!VideoCallActivity.launched) {
+ startVideoView(VIDEO_VIEW_ACTIVITY);
+ }
+ }
}
mCurrentCallState = state;
}
@@ -458,12 +479,12 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
private void enterIncalMode(LinphoneCore lc) {
-
mCallControlRow.setVisibility(View.GONE);
mInCallControlRow.setVisibility(View.VISIBLE);
mAddressLayout.setVisibility(View.GONE);
mInCallAddressLayout.setVisibility(View.VISIBLE);
mCall.setEnabled(false);
+ updateIncallVideoCallButton();
mHangup.setEnabled(true);
LinphoneAddress remote=lc.getRemoteAddress();
if (remote!=null){
@@ -476,6 +497,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
mDisplayNameView.setText(lc.getRemoteAddress().toString());
}
}
+ configureMuteAndSpeakerButtons();
+
if (mSpeaker.isChecked()) {
routeAudioToSpeaker();
} else {
@@ -483,18 +506,39 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
+ private void configureMuteAndSpeakerButtons() {
+ mMute.setChecked(LinphoneService.instance().getLinphoneCore().isMicMuted());
+ if ((Integer.parseInt(Build.VERSION.SDK) <=4 && mAudioManager.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_SPEAKER)
+ || Integer.parseInt(Build.VERSION.SDK) >4 &&mAudioManager.isSpeakerphoneOn()) {
+ mSpeaker.setChecked(true);
+ } else {
+ mSpeaker.setChecked(false);
+ }
+ }
+
+ private void resetCameraFromPreferences() {
+ boolean useFrontCam = mPref.getBoolean(getString(R.string.pref_video_use_front_camera_key), false);
+ AndroidCameraRecordManager.getInstance().setUseFrontCamera(useFrontCam);
+ }
+
private void exitCallMode() {
mCallControlRow.setVisibility(View.VISIBLE);
mInCallControlRow.setVisibility(View.GONE);
mAddressLayout.setVisibility(View.VISIBLE);
mInCallAddressLayout.setVisibility(View.GONE);
mCall.setEnabled(true);
+ updateIncallVideoCallButton();
mHangup.setEnabled(false);
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
- mMute.setChecked(true);
- mSpeaker.setChecked(false);
mDecline.setEnabled(false);
+ if (LinphoneService.instance().getLinphoneCore().isVideoEnabled()) {
+ finishActivity(VIDEO_VIEW_ACTIVITY);
+ }
if (mWakeLock.isHeld())mWakeLock.release();
+ mSpeaker.setChecked(false);
+ routeAudioToReceiver();
+ BandwidthManager.getInstance().setUserRestriction(false);
+ resetCameraFromPreferences();
}
private void routeAudioToSpeaker() {
if (Integer.parseInt(Build.VERSION.SDK) <= 4 /*0) ? FirewallPolicy.UseStun : FirewallPolicy.NoFirewall);
+
//auth
mLinphoneCore.clearAuthInfos();
LinphoneAuthInfo lAuthInfo = LinphoneCoreFactory.instance().createAuthInfo(lUserName, lPasswd,null);
@@ -394,6 +401,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
+
protected LinphoneCore getLinphoneCore() {
return mLinphoneCore;
}
@@ -426,6 +434,9 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
}
+ public static LinphoneCore getLc() {
+ return instance().getLinphoneCore();
+ }
}
diff --git a/src/org/linphone/VideoCallActivity.java b/src/org/linphone/VideoCallActivity.java
new file mode 100644
index 000000000..aaa065691
--- /dev/null
+++ b/src/org/linphone/VideoCallActivity.java
@@ -0,0 +1,200 @@
+/*
+VideoCallActivity.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone;
+
+
+
+import org.linphone.core.AndroidCameraRecordManager;
+import org.linphone.core.LinphoneCore;
+import org.linphone.core.VideoSize;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.SurfaceView;
+import android.view.ViewGroup.LayoutParams;
+
+public class VideoCallActivity extends Activity {
+ private SurfaceView mVideoView;
+ private SurfaceView mVideoCaptureView;
+ private AndroidCameraRecordManager recordManager;
+ private static final String tag = "Linphone";
+ public static boolean launched = false;
+ private WakeLock mWakeLock;
+ private static final int capturePreviewLargestDimension = 150;
+// private static final float similarRatio = 0.1f;
+
+ public void onCreate(Bundle savedInstanceState) {
+ launched = true;
+ Log.d(tag, "onCreate VideoCallActivity");
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.videocall);
+
+ mVideoView = (SurfaceView) findViewById(R.id.video_surface);
+ LinphoneCore lc = LinphoneService.getLc();
+ lc.setVideoWindow(mVideoView);
+
+ mVideoCaptureView = (SurfaceView) findViewById(R.id.video_capture_surface);
+
+ final int rotation = getWindowManager().getDefaultDisplay().getOrientation();
+ recordManager = AndroidCameraRecordManager.getInstance();
+ recordManager.setSurfaceView(mVideoCaptureView, rotation);
+ mVideoCaptureView.setZOrderOnTop(true);
+
+ if (!recordManager.isMuted()) sendStaticImage(false);
+ PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK|PowerManager.ON_AFTER_RELEASE,"Linphone");
+ mWakeLock.acquire();
+
+ if (Integer.parseInt(Build.VERSION.SDK) < 8) {
+ // Force to display in portrait orientation for old devices
+ // as they do not support surfaceView rotation
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
+
+ // Handle the fact that the preferred size may have a ratio /an orientation different from the one
+ // in the videocall.xml as the front camera on Samsung captures in landscape.
+ updateSvLayoutParamsFromVideoSize(mVideoCaptureView, lc.getPreferredVideoSize());
+ }
+
+
+ private void rewriteToggleCameraItem(MenuItem item) {
+ if (recordManager.isRecording()) {
+ item.setTitle(getString(R.string.menu_videocall_toggle_camera_disable));
+ } else {
+ item.setTitle(getString(R.string.menu_videocall_toggle_camera_enable));
+ }
+ }
+
+ private void rewriteChangeResolutionItem(MenuItem item) {
+ if (BandwidthManager.getInstance().isUserRestriction()) {
+ item.setTitle(getString(R.string.menu_videocall_change_resolution_when_low_resolution));
+ } else {
+ item.setTitle(getString(R.string.menu_videocall_change_resolution_when_high_resolution));
+ }
+ }
+
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the currently selected menu XML resource.
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.videocall_activity_menu, menu);
+
+ rewriteToggleCameraItem(menu.findItem(R.id.videocall_menu_toggle_camera));
+ rewriteChangeResolutionItem(menu.findItem(R.id.videocall_menu_change_resolution));
+
+ return true;
+ }
+
+ private void sendStaticImage(boolean send) {
+ LinphoneCore lc = LinphoneService.getLc();
+ if (lc.isIncall()) {
+ lc.getCurrentCall().enableCamera(!send);
+ }
+ }
+
+ private void updateSvLayoutParamsFromVideoSize(SurfaceView sv, VideoSize vs) {
+ LayoutParams lp = sv.getLayoutParams();
+ float newRatio = ratioWidthHeight(vs);
+
+ // float previewRatio = (float) lp.width / lp.height;
+// if (Math.abs((newRatio-previewRatio)/newRatio) < similarRatio) return;
+
+ if (vs.isPortrait()) {
+ lp.height = capturePreviewLargestDimension;
+ lp.width = Math.round(lp.height * newRatio);
+ } else {
+ lp.width = capturePreviewLargestDimension;
+ lp.height = Math.round(lp.width / newRatio);
+ }
+
+ sv.setLayoutParams(lp);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.videocall_menu_back_to_dialer:
+ if (!recordManager.isMuted()) sendStaticImage(true);
+ finish();
+ break;
+ case R.id.videocall_menu_change_resolution:
+ BandwidthManager manager = BandwidthManager.getInstance();
+ manager.setUserRestriction(!manager.isUserRestriction());
+ sendStaticImage(recordManager.isMuted());
+ rewriteChangeResolutionItem(item);
+
+ // Resize preview frame
+ VideoSize newVideoSize = LinphoneService.getLc().getPreferredVideoSize();
+ updateSvLayoutParamsFromVideoSize(mVideoCaptureView, newVideoSize);
+ break;
+ case R.id.videocall_menu_terminate_call:
+ LinphoneCore lc = LinphoneService.getLc();
+ if (lc.isIncall()) {
+ lc.terminateCall(lc.getCurrentCall());
+ }
+ finish();
+ break;
+ case R.id.videocall_menu_toggle_camera:
+ sendStaticImage(recordManager.toggleMute());
+ rewriteToggleCameraItem(item);
+ break;
+/* case R.id.videocall_menu_switch_camera:
+ recordManager.stopVideoRecording();
+ recordManager.toggleUseFrontCamera();
+ InviteManager.getInstance().reinvite();
+ // camera will be restarted when mediastreamer chain is recreated and setParameters is called
+ break;
+*/ default:
+ Log.e(LinphoneService.TAG, "Unknown menu item ["+item+"]");
+ break;
+ }
+
+ return false;
+ }
+
+
+ @Override
+ protected void onDestroy() {
+ launched = false;
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause() {
+ Log.d(tag, "onPause VideoCallActivity");
+ if (mWakeLock.isHeld()) mWakeLock.release();
+ super.onPause();
+ }
+
+
+ public float ratioWidthHeight(VideoSize vs) {
+ return (float) vs.getWidth() / vs.getHeight();
+ }
+
+}
diff --git a/src/org/linphone/component/ToggleImageButton.java b/src/org/linphone/component/ToggleImageButton.java
new file mode 100644
index 000000000..8cfa1e917
--- /dev/null
+++ b/src/org/linphone/component/ToggleImageButton.java
@@ -0,0 +1,87 @@
+/*
+ToggleImageButton.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.component;
+
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ImageButton;
+
+/**
+ * Image button storing a checked state to display alternating drawables.
+ * The "checked" drawable is displayed when button is down / checked.
+ * The "unchecked" drawable is displayed when button is up / unchecked.
+ *
+ * @author Guillaume Beraudo
+ *
+ */
+public class ToggleImageButton extends ImageButton implements OnClickListener {
+ private static final String namespace = null;
+ private boolean checked;
+ private Drawable stateChecked;
+ private Drawable stateUnChecked;
+ private OnCheckedChangeListener onCheckedChangeListener;
+
+ public ToggleImageButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ stateChecked = getResources().getDrawable(attrs.getAttributeResourceValue(namespace, "checked", -1));
+ stateUnChecked = getResources().getDrawable(attrs.getAttributeResourceValue(namespace, "unchecked", -1));
+ setBackgroundColor(Color.TRANSPARENT);
+
+ setOnClickListener(this);
+ handleCheckChanged();
+ }
+
+
+
+ public void setChecked(boolean checked) {
+ this.checked = checked;
+ handleCheckChanged();
+ }
+
+ public boolean isChecked() {
+ return checked;
+ }
+
+
+ private void handleCheckChanged() {
+ setImageDrawable(checked?stateChecked:stateUnChecked);
+ requestLayout();
+ invalidate();
+ if (onCheckedChangeListener != null) onCheckedChangeListener.onCheckedChanged(this, checked);
+ }
+
+
+ public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
+ onCheckedChangeListener = listener;
+ }
+
+ public static interface OnCheckedChangeListener {
+ void onCheckedChanged(ToggleImageButton button, boolean checked);
+ }
+
+ public void onClick(View v) {
+ checked = !checked;
+ handleCheckChanged();
+ }
+}
diff --git a/src/org/linphone/core/AndroidCameraRecord.java b/src/org/linphone/core/AndroidCameraRecord.java
new file mode 100644
index 000000000..84ad452ef
--- /dev/null
+++ b/src/org/linphone/core/AndroidCameraRecord.java
@@ -0,0 +1,217 @@
+/*
+AndroidCameraRecordImpl.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import android.hardware.Camera;
+import android.hardware.Camera.ErrorCallback;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.PreviewCallback;
+import android.hardware.Camera.Size;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+
+public abstract class AndroidCameraRecord {
+
+ protected Camera camera;
+ private RecorderParams params;
+
+ private PreviewCallback storedPreviewCallback;
+ private boolean previewStarted;
+ protected int displayOrientation;
+ protected static final String tag="Linphone";
+ private List supportedVideoSizes;
+ private Size currentPreviewSize;
+
+ public AndroidCameraRecord(RecorderParams parameters) {
+ this.params = parameters;
+ setDisplayOrientation(parameters.rotation);
+ }
+
+ protected List getSupportedPreviewSizes(Camera.Parameters parameters) {
+ return Collections.emptyList();
+ }
+
+ public void startPreview() { // FIXME throws exception?
+ if (previewStarted) {
+ Log.w(tag, "Already started");
+ throw new RuntimeException("Video recorder already started");
+ // return
+ }
+
+ if (params.surfaceView.getVisibility() != SurfaceView.VISIBLE) {
+ // Illegal state
+ Log.e(tag, "Illegal state: video capture surface view is not visible");
+ return;
+ }
+
+
+ camera=Camera.open();
+ camera.setErrorCallback(new ErrorCallback() {
+ public void onError(int error, Camera camera) {
+ Log.e(tag, "Camera error : " + error);
+ }
+ });
+
+
+ Camera.Parameters parameters=camera.getParameters();
+ parameters.set("camera-id",params.cameraId);
+ camera.setParameters(parameters);
+ parameters = camera.getParameters();
+ if (supportedVideoSizes == null) {
+ supportedVideoSizes = new ArrayList(getSupportedPreviewSizes(parameters));
+ }
+
+
+ if (!params.videoDimensionsInverted) {
+ parameters.setPreviewSize(params.width, params.height);
+ } else {
+ parameters.setPreviewSize(params.height, params.width);
+ }
+ parameters.setPreviewFrameRate(Math.round(params.fps));
+
+
+ onSettingCameraParameters(parameters);
+ camera.setParameters(parameters);
+
+ currentPreviewSize = camera.getParameters().getPreviewSize();
+
+ SurfaceHolder holder = params.surfaceView.getHolder();
+ try {
+ camera.setPreviewDisplay(holder);
+ }
+ catch (Throwable t) {
+ Log.e(tag, "Exception in Video capture setPreviewDisplay()", t);
+ }
+
+
+ try {
+ camera.startPreview();
+ previewStarted = true;
+ } catch (Throwable e) {
+ Log.e(tag, "Can't start camera preview");
+ }
+
+ previewStarted = true;
+
+
+ // Register callback to get capture buffer
+ lowLevelSetPreviewCallback(camera, storedPreviewCallback);
+
+
+ onPreviewStarted(camera);
+ }
+
+
+
+
+ protected void onSettingCameraParameters(Parameters parameters) {}
+
+ /**
+ * Hook.
+ * @param camera
+ */
+ public void onPreviewStarted(Camera camera) {}
+
+ public void storePreviewCallBack(PreviewCallback cb) {
+ this.storedPreviewCallback = cb;
+ if (camera == null) {
+ Log.w(tag, "Capture camera not ready, storing callback");
+ return;
+ }
+
+ lowLevelSetPreviewCallback(camera, cb);
+ }
+
+
+ public void stopPreview() {
+ if (!previewStarted) return;
+ lowLevelSetPreviewCallback(camera, null);
+ camera.stopPreview();
+ camera.release();
+ camera=null;
+ if (currentPreviewSize != null) currentPreviewSize = null;
+ previewStarted = false;
+ }
+
+
+ public void stopCaptureCallback() {
+ if (camera != null) {
+ lowLevelSetPreviewCallback(camera, null);
+ }
+ }
+
+ protected abstract void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb);
+
+ public void setDisplayOrientation(int rotation) {
+ displayOrientation = rotation;
+ }
+
+ protected int rotateCapturedFrame() {
+ if (params.videoDimensionsInverted) {
+ return 1; // always rotate 90°
+ } else if (params.cameraId == 2) {
+ return 0;
+ } else {
+ return (4 + 1 - displayOrientation) % 4;
+ }
+ }
+
+
+
+
+ public static class RecorderParams {
+ public float fps;
+ public int height;
+ public int width;
+
+ final long filterDataNativePtr;
+ public int cameraId;
+ public int rotation;
+ public SurfaceView surfaceView;
+ public boolean videoDimensionsInverted;
+
+ public RecorderParams(long ptr) {
+ filterDataNativePtr = ptr;
+ }
+ }
+
+
+
+
+ public boolean isStarted() {
+ return previewStarted;
+ }
+
+ public List getSupportedVideoSizes() {
+ return new ArrayList(supportedVideoSizes);
+ }
+
+
+ protected int getExpectedBufferLength() {
+ if (currentPreviewSize == null) return -1;
+
+ return currentPreviewSize.width * currentPreviewSize.height * 3 /2;
+ }
+}
diff --git a/src/org/linphone/core/AndroidCameraRecordBufferedImpl.java b/src/org/linphone/core/AndroidCameraRecordBufferedImpl.java
new file mode 100644
index 000000000..ad54341c3
--- /dev/null
+++ b/src/org/linphone/core/AndroidCameraRecordBufferedImpl.java
@@ -0,0 +1,73 @@
+/*
+AndroidCameraRecord8Impl.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.PreviewCallback;
+import android.hardware.Camera.Size;
+import android.util.Log;
+
+/**
+ *
+ * Android >= 8 (2.2) version.
+ * @author Guillaume Beraudo
+ *
+ */
+public class AndroidCameraRecordBufferedImpl extends AndroidCameraRecordImplAPI5 {
+
+
+ public AndroidCameraRecordBufferedImpl(RecorderParams parameters) {
+ super(parameters);
+ }
+
+ @Override
+ protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) {
+ if (cb != null) {
+ Log.d("Linphone", "Setting optimized callback with buffer (Android >= 8). Remember to manage the pool of buffers!!!");
+ }
+ camera.setPreviewCallbackWithBuffer(cb);
+ }
+
+ @Override
+ public void onPreviewStarted(Camera camera) {
+ super.onPreviewStarted(camera);
+
+ Size s = camera.getParameters().getPreviewSize();
+ int wishedBufferSize = s.height * s.width * 3 / 2;
+
+ camera.addCallbackBuffer(new byte[wishedBufferSize]);
+ camera.addCallbackBuffer(new byte[wishedBufferSize]);
+ }
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ super.onPreviewFrame(data, camera);
+ camera.addCallbackBuffer(data);
+ }
+
+ @Override
+ protected void onSettingCameraParameters(Parameters parameters) {
+ super.onSettingCameraParameters(parameters);
+ // Only on v8 hardware
+ camera.setDisplayOrientation(90 * rotateCapturedFrame());
+ }
+
+
+}
diff --git a/src/org/linphone/core/AndroidCameraRecordImpl.java b/src/org/linphone/core/AndroidCameraRecordImpl.java
new file mode 100644
index 000000000..daf26ea4e
--- /dev/null
+++ b/src/org/linphone/core/AndroidCameraRecordImpl.java
@@ -0,0 +1,97 @@
+/*
+AndroidCameraRecordImpl.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+import android.hardware.Camera;
+import android.hardware.Camera.PreviewCallback;
+import android.util.Log;
+
+/**
+ * Record from Android camera.
+ *
+ * @author Guillaume Beraudo
+ *
+ */
+public class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback {
+
+ private long filterCtxPtr;
+ private double timeElapsedBetweenFrames = 0;
+ private long lastFrameTime = 0;
+ private final double expectedTimeBetweenFrames;
+ private boolean sizesInverted;
+
+ public AndroidCameraRecordImpl(RecorderParams parameters) {
+ super(parameters);
+ expectedTimeBetweenFrames = 1d / Math.round(parameters.fps);
+ filterCtxPtr = parameters.filterDataNativePtr;
+ sizesInverted = parameters.videoDimensionsInverted;
+
+ storePreviewCallBack(this);
+ }
+
+
+ private native void putImage(long filterCtxPtr, byte[] buffer, int rotate, boolean sizesInverted);
+
+
+ public void onPreviewFrame(byte[] data, Camera camera) {
+ if (data == null) {
+ Log.e("Linphone", "onPreviewFrame Called with null buffer");
+ return;
+ }
+ if (filterCtxPtr == 0l) {
+ Log.e("Linphone", "onPreviewFrame Called with no filterCtxPtr set");
+ return;
+ }
+
+ int expectedBuffLength = getExpectedBufferLength();
+ if (expectedBuffLength != data.length) {
+ Log.e("Linphone", "onPreviewFrame called with bad buffer length " + data.length
+ + " whereas expected is " + expectedBuffLength + " don't calling putImage");
+ return;
+ }
+
+ long curTime = System.currentTimeMillis();
+ if (lastFrameTime == 0) {
+ lastFrameTime = curTime;
+ putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
+ return;
+ }
+
+ double currentTimeElapsed = 0.8 * (curTime - lastFrameTime) / 1000 + 0.2 * timeElapsedBetweenFrames;
+ if (currentTimeElapsed < expectedTimeBetweenFrames) {
+// Log.d("Linphone", "Clipping frame " + Math.round(1 / currentTimeElapsed) + " > " + fps);
+ return;
+ }
+ lastFrameTime = curTime;
+ timeElapsedBetweenFrames = currentTimeElapsed;
+
+ // Log.d("onPreviewFrame: ", Integer.toString(data.length));
+ putImage(filterCtxPtr, data, rotateCapturedFrame(), sizesInverted);
+ }
+
+
+
+ @Override
+ protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) {
+ camera.setPreviewCallback(cb);
+ }
+
+
+
+}
diff --git a/src/org/linphone/core/AndroidCameraRecordImplAPI5.java b/src/org/linphone/core/AndroidCameraRecordImplAPI5.java
new file mode 100644
index 000000000..7ff307d03
--- /dev/null
+++ b/src/org/linphone/core/AndroidCameraRecordImplAPI5.java
@@ -0,0 +1,64 @@
+/*
+AndroidCameraRecordImplAPI5.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+import java.util.List;
+
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.Size;
+import android.util.Log;
+
+
+public class AndroidCameraRecordImplAPI5 extends AndroidCameraRecordImpl {
+
+ public AndroidCameraRecordImplAPI5(RecorderParams parameters) {
+ super(parameters);
+ }
+
+ @Override
+ protected void onSettingCameraParameters(Parameters parameters) {
+ super.onSettingCameraParameters(parameters);
+
+ if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
+ Log.w(tag, "Auto Focus supported by camera device");
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
+ } else {
+ Log.w(tag, "Auto Focus not supported by camera device");
+ if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
+ Log.w(tag, "Infinity Focus supported by camera device");
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
+ } else {
+ Log.w(tag, "Infinity Focus not supported by camera device");
+ }
+ }
+ }
+
+ public static List oneShotSupportedVideoSizes() {
+ Camera camera = Camera.open();
+ List supportedVideoSizes =camera.getParameters().getSupportedPreviewSizes();
+ camera.release();
+ return supportedVideoSizes;
+ }
+
+ @Override
+ protected List getSupportedPreviewSizes(Parameters parameters) {
+ return parameters.getSupportedPreviewSizes();
+ }
+}
diff --git a/src/org/linphone/core/AndroidCameraRecordManager.java b/src/org/linphone/core/AndroidCameraRecordManager.java
new file mode 100644
index 000000000..023dcffa4
--- /dev/null
+++ b/src/org/linphone/core/AndroidCameraRecordManager.java
@@ -0,0 +1,245 @@
+/*
+AndroidCameraRecordManager.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+import java.util.List;
+
+import org.linphone.core.AndroidCameraRecord.RecorderParams;
+
+import android.hardware.Camera.Size;
+import android.os.Build;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder.Callback;
+
+
+
+/**
+ * Manage the video capture, only on for all cameras.
+ *
+ * @author Guillaume Beraudo
+ *
+ */
+public class AndroidCameraRecordManager {
+ private static final int version = Integer.parseInt(Build.VERSION.SDK);
+ private static final String tag = "Linphone";
+ private static AndroidCameraRecordManager instance;
+
+ // singleton
+ private AndroidCameraRecordManager() {}
+
+
+ /**
+ * @return instance
+ */
+ public static final synchronized AndroidCameraRecordManager getInstance() {
+ if (instance == null) {
+ instance = new AndroidCameraRecordManager();
+ }
+ return instance;
+ }
+
+ private AndroidCameraRecord.RecorderParams parameters;
+ private SurfaceView surfaceView;
+ private boolean muted;
+
+
+ private AndroidCameraRecord recorder;
+
+
+ private List supportedVideoSizes;
+ private int rotation;
+
+ private boolean useFrontCamera;
+ public void setUseFrontCamera(boolean value) {
+ if (useFrontCamera == value) return;
+ this.useFrontCamera = value;
+
+ if (parameters != null) {
+ parameters.cameraId = cameraId();
+ if (isRecording()) {
+ stopVideoRecording();
+ tryToStartVideoRecording();
+ }
+ }
+ }
+ public boolean isUseFrontCamera() {return useFrontCamera;}
+ public boolean toggleUseFrontCamera() {
+ setUseFrontCamera(!useFrontCamera);
+ return useFrontCamera;
+ }
+
+
+
+ public void setParametersFromFilter(long filterDataPtr, int height, int width, float fps) {
+ stopVideoRecording();
+ RecorderParams p = new RecorderParams(filterDataPtr);
+ p.fps = fps;
+ p.width = width;
+ p.height = height;
+ p.cameraId = cameraId();
+ p.videoDimensionsInverted = width < height;
+ // width and height will be inverted in Recorder on startPreview
+ parameters = p;
+ tryToStartVideoRecording();
+ }
+
+
+ public final void setSurfaceView(final SurfaceView sv, final int rotation) {
+ this.rotation = useFrontCamera ? 1 : rotation;
+ SurfaceHolder holder = sv.getHolder();
+ holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+
+ holder.addCallback(new Callback() {
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ surfaceView = null;
+ Log.d(tag , "Video capture surface destroyed");
+ stopVideoRecording();
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ surfaceView = sv;
+ Log.d(tag , "Video capture surface created");
+ tryToStartVideoRecording();
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int width,
+ int height) {
+ Log.d(tag , "Video capture surface changed");
+ }
+ });
+ }
+
+ public void setMuted(boolean muteState) {
+ if (muteState == muted) return;
+ muted = muteState;
+ if (muted) {
+ stopVideoRecording();
+ } else {
+ tryToStartVideoRecording();
+ }
+ }
+ public boolean toggleMute() {
+ setMuted(!muted);
+ return muted;
+ }
+ public boolean isMuted() {
+ return muted;
+ }
+
+ public void tryResumingVideoRecording() {
+ if (isRecording()) return;
+ tryToStartVideoRecording();
+ }
+
+ private void tryToStartVideoRecording() {
+ if (muted || surfaceView == null || parameters == null) return;
+
+ parameters.rotation = rotation;
+ parameters.surfaceView = surfaceView;
+ if (version >= 8) {
+ recorder = new AndroidCameraRecordBufferedImpl(parameters);
+ } else if (version >= 5) {
+ recorder = new AndroidCameraRecordImplAPI5(parameters);
+ } else {
+ recorder = new AndroidCameraRecordImpl(parameters);
+ }
+
+ recorder.startPreview();
+ }
+
+ public void stopVideoRecording() {
+ if (recorder != null) {
+ recorder.stopPreview();
+ recorder = null;
+ }
+ }
+
+
+ // FIXME select right camera
+ /**
+ * Eventually null if API < 5.
+ *
+ */
+ public List supportedVideoSizes() {
+ if (supportedVideoSizes != null) {
+ return supportedVideoSizes;
+ }
+
+ if (recorder != null) {
+ supportedVideoSizes = recorder.getSupportedVideoSizes();
+ if (supportedVideoSizes != null) return supportedVideoSizes;
+ }
+
+ if (version >= 5) {
+ supportedVideoSizes = AndroidCameraRecordImplAPI5.oneShotSupportedVideoSizes();
+ }
+
+ // eventually null
+
+ return supportedVideoSizes;
+ }
+
+
+ public boolean isRecording() {
+ if (recorder != null) {
+ return recorder.isStarted();
+ }
+
+ return false;
+ }
+
+
+ public void invalidateParameters() {
+ stopVideoRecording();
+ parameters = null;
+ }
+
+ /**
+ * Naive simple version.
+ * @param askedSize
+ * @return
+ */
+ public VideoSize doYouSupportThisVideoSize(VideoSize askedSize) {
+ Log.d(tag, "Asking camera if it supports size "+askedSize);
+ if (useFrontCamera && askedSize.isPortrait()) {
+ return askedSize.createInverted(); // only landscape supported
+ } else {
+ return askedSize;
+ }
+ }
+
+
+ private VideoSize closestVideoSize(VideoSize vSize, int defaultSizeCode, boolean defaultIsPortrait) {
+ VideoSize testSize = vSize.isPortrait() ? vSize.createInverted() : vSize;
+
+ for (Size s : AndroidCameraRecordManager.getInstance().supportedVideoSizes()) {
+ if (s.height == testSize.getHeight() && s.width == testSize.getWidth()) {
+ return vSize;
+ }
+ }
+
+ return VideoSize.createStandard(defaultSizeCode, defaultIsPortrait);
+ }
+
+ private static final int rearCamId() {return 1;}
+ private static final int frontCamId() {return 2;}
+ private final int cameraId() {return useFrontCamera? frontCamId() : rearCamId(); }
+}
diff --git a/src/org/linphone/core/AndroidVideoWindowImpl.java b/src/org/linphone/core/AndroidVideoWindowImpl.java
new file mode 100644
index 000000000..ec7eb2cbb
--- /dev/null
+++ b/src/org/linphone/core/AndroidVideoWindowImpl.java
@@ -0,0 +1,89 @@
+package org.linphone.core;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Bitmap.Config;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceHolder.Callback;
+
+public class AndroidVideoWindowImpl {
+ private Bitmap mBitmap;
+ private SurfaceView mView;
+ private Surface mSurface;
+ private VideoWindowListener mListener;
+ static private String TAG = "Linphone";
+ public static interface VideoWindowListener{
+ void onSurfaceReady(AndroidVideoWindowImpl vw);
+ void onSurfaceDestroyed(AndroidVideoWindowImpl vw);
+ };
+ public AndroidVideoWindowImpl(SurfaceView view){
+ mView=view;
+ mBitmap=null;
+ mSurface=null;
+ mListener=null;
+ view.getHolder().addCallback(new Callback(){
+ public void surfaceChanged(SurfaceHolder holder, int format,
+ int width, int height) {
+ Log.i(TAG,"Surface is being changed.");
+ synchronized(AndroidVideoWindowImpl.this){
+ mBitmap=Bitmap.createBitmap(width,height,Config.RGB_565);
+ mSurface=holder.getSurface();
+ }
+ if (mListener!=null) mListener.onSurfaceReady(AndroidVideoWindowImpl.this);
+ Log.w("Linphone", "Video display surface changed");
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ Log.w("Linphone", "Video display surface created");
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ synchronized(AndroidVideoWindowImpl.this){
+ mSurface=null;
+ mBitmap=null;
+ }
+ if (mListener!=null)
+ mListener.onSurfaceDestroyed(AndroidVideoWindowImpl.this);
+ Log.d("Linphone", "Video display surface destroyed");
+ }
+ });
+ }
+ static final int LANDSCAPE=0;
+ static final int PORTRAIT=1;
+ public void requestOrientation(int orientation){
+ //Surface.setOrientation(0, orientation==LANDSCAPE ? 1 : 0);
+ //Log.d("Linphone", "Orientation changed.");
+ }
+ public void setListener(VideoWindowListener l){
+ mListener=l;
+ }
+ public Surface getSurface(){
+ return mView.getHolder().getSurface();
+ }
+ public Bitmap getBitmap(){
+ return mBitmap;
+ }
+ //Called by the mediastreamer2 android display filter
+ public synchronized void update(){
+ if (mSurface!=null){
+ try {
+ Canvas canvas=mSurface.lockCanvas(null);
+ canvas.drawBitmap(mBitmap, 0, 0, null);
+ mSurface.unlockCanvasAndPost(canvas);
+
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (OutOfResourcesException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+}
+
+
diff --git a/src/org/linphone/core/LinphoneCallImpl.java b/src/org/linphone/core/LinphoneCallImpl.java
index ca9d9d55f..74c701a72 100644
--- a/src/org/linphone/core/LinphoneCallImpl.java
+++ b/src/org/linphone/core/LinphoneCallImpl.java
@@ -29,6 +29,9 @@ class LinphoneCallImpl implements LinphoneCall {
private native boolean isIncoming(long nativePtr);
native private long getRemoteAddress(long nativePtr);
native private int getState(long nativePtr);
+ private native long getCurrentParamsCopy(long nativePtr);
+ private native void enableCamera(long nativePtr, boolean enabled);
+
protected LinphoneCallImpl(long aNativePtr) {
nativePtr = aNativePtr;
ref(nativePtr);
@@ -58,12 +61,11 @@ class LinphoneCallImpl implements LinphoneCall {
public State getState() {
return LinphoneCall.State.fromInt(getState(nativePtr));
}
- public LinphoneCallParams getCurrentParamsReadOnly() {
- throw new RuntimeException("Not Implemenetd yet");
+ public LinphoneCallParams getCurrentParamsCopy() {
+ return new LinphoneCallParamsImpl(getCurrentParamsCopy(nativePtr));
}
+
public void enableCamera(boolean enabled) {
- throw new RuntimeException("Not Implemenetd yet");
+ enableCamera(nativePtr, enabled);
}
-
-
}
diff --git a/src/org/linphone/core/LinphoneCallLogImpl.java b/src/org/linphone/core/LinphoneCallLogImpl.java
index c9c8b8ffe..1bdb84720 100644
--- a/src/org/linphone/core/LinphoneCallLogImpl.java
+++ b/src/org/linphone/core/LinphoneCallLogImpl.java
@@ -43,8 +43,7 @@ class LinphoneCallLogImpl implements LinphoneCallLog {
return new LinphoneAddressImpl(getTo(nativePtr));
}
public CallStatus getStatus() {
- // TODO Auto-generated method stub
- return null;
+ throw new RuntimeException("not implemented yet");
}
}
diff --git a/src/org/linphone/core/LinphoneCallParamsImpl.java b/src/org/linphone/core/LinphoneCallParamsImpl.java
new file mode 100644
index 000000000..ef05eb228
--- /dev/null
+++ b/src/org/linphone/core/LinphoneCallParamsImpl.java
@@ -0,0 +1,51 @@
+/*
+LinphoneCallParamsImpl.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core;
+
+public class LinphoneCallParamsImpl implements LinphoneCallParams {
+ protected final long nativePtr;
+
+ public LinphoneCallParamsImpl(long nativePtr) {
+ this.nativePtr = nativePtr;
+ }
+
+ private native void enableVideo(long nativePtr, boolean b);
+ private native boolean getVideoEnabled(long nativePtr);
+ private native void audioBandwidth(long nativePtr, int bw);
+ private native void destroy(long nativePtr);
+
+
+ public boolean getVideoEnabled() {
+ return getVideoEnabled(nativePtr);
+ }
+
+ public void setVideoEnabled(boolean b) {
+ enableVideo(nativePtr, b);
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ destroy(nativePtr);
+ super.finalize();
+ }
+
+ public void setAudioBandwidth(int value) {
+ audioBandwidth(nativePtr, value);
+ }
+}
diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java
index 83df6de86..929403c9d 100644
--- a/src/org/linphone/core/LinphoneCoreImpl.java
+++ b/src/org/linphone/core/LinphoneCoreImpl.java
@@ -22,6 +22,8 @@ import java.io.File;
import java.io.IOException;
import java.util.Vector;
+import android.view.SurfaceView;
+
class LinphoneCoreImpl implements LinphoneCore {
@@ -53,6 +55,7 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void muteMic(long nativePtr,boolean isMuted);
private native long interpretUrl(long nativePtr,String destination);
private native long inviteAddress(long nativePtr,long to);
+ private native long inviteAddressWithParams(long nativePtrLc,long to, long nativePtrParam);
private native void sendDtmf(long nativePtr,char dtmf);
private native void clearCallLogs(long nativePtr);
private native boolean isMicMuted(long nativePtr);
@@ -63,12 +66,31 @@ class LinphoneCoreImpl implements LinphoneCore {
private native long getCurrentCall(long nativePtr) ;
private native void playDtmf(long nativePtr,char dtmf,int duration);
private native void stopDtmf(long nativePtr);
-
+ private native void setVideoWindowId(long nativePtr, Object wid);
+ private native void setPreviewWindowId(long nativePtr, Object wid);
+ private AndroidVideoWindowImpl mVideoWindow;
+ private AndroidVideoWindowImpl mPreviewWindow;
private native void addFriend(long nativePtr,long friend);
private native void setPresenceInfo(long nativePtr,int minute_away, String alternative_contact,int status);
private native long createChatRoom(long nativePtr,String to);
+ private native void enableVideo(long nativePtr,boolean vcap_enabled,boolean display_enabled);
+ private native boolean isVideoEnabled(long nativePtr);
+ private native void setFirewallPolicy(long nativePtr, int enum_value);
+ private native int getFirewallPolicy(long nativePtr);
+ private native void setStunServer(long nativePtr, String stun_server);
+ private native String getStunServer(long nativePtr);
+ private native long createDefaultCallParams(long nativePtr);
+ private native int updateCall(long ptrLc, long ptrCall, long ptrParams);
+ private native void setUploadBandwidth(long nativePtr, int bw);
+ private native void setDownloadBandwidth(long nativePtr, int bw);
+ private native void setPreferredVideoSize(long nativePtr, int width, int heigth);
+ private native int[] getPreferredVideoSize(long nativePtr);
private native void setRing(long nativePtr, String path);
private native String getRing(long nativePtr);
+ private native long[] listVideoPayloadTypes(long nativePtr);
+
+
+ private static final String TAG = "LinphoneCore";
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
mListener=listener;
@@ -200,14 +222,15 @@ class LinphoneCoreImpl implements LinphoneCore {
throw new LinphoneCoreException("Cannot interpret ["+destination+"]");
}
}
- public LinphoneCall invite(LinphoneAddress to) {
+ public LinphoneCall invite(LinphoneAddress to) throws LinphoneCoreException {
long lNativePtr = inviteAddress(nativePtr,((LinphoneAddressImpl)to).nativePtr);
if (lNativePtr!=0) {
return new LinphoneCallImpl(lNativePtr);
} else {
- return null;
+ throw new LinphoneCoreException("Unable to invite address " + to.asString());
}
}
+
public void sendDtmf(char number) {
sendDtmf(nativePtr,number);
}
@@ -295,73 +318,114 @@ class LinphoneCoreImpl implements LinphoneCore {
return new LinphoneChatRoomImpl(createChatRoom(nativePtr,to));
}
public void setPreviewWindow(Object w) {
- throw new RuntimeException("not implemented yet");
- // TODO Auto-generated method stub
-
+ if (mPreviewWindow!=null)
+ mPreviewWindow.setListener(null);
+ mPreviewWindow=new AndroidVideoWindowImpl((SurfaceView)w);
+ mPreviewWindow.setListener(new AndroidVideoWindowImpl.VideoWindowListener(){
+ public void onSurfaceDestroyed(AndroidVideoWindowImpl vw) {
+ setPreviewWindowId(nativePtr,null);
+ }
+
+ public void onSurfaceReady(AndroidVideoWindowImpl vw) {
+ setPreviewWindowId(nativePtr,vw);
+ }
+ });
}
public void setVideoWindow(Object w) {
- throw new RuntimeException("not implemented yet");
- // TODO Auto-generated method stub
+ if (mVideoWindow!=null)
+ mVideoWindow.setListener(null);
+ mVideoWindow=new AndroidVideoWindowImpl((SurfaceView) w);
+ mVideoWindow.setListener(new AndroidVideoWindowImpl.VideoWindowListener(){
+ public void onSurfaceDestroyed(AndroidVideoWindowImpl vw) {
+ setVideoWindowId(nativePtr,null);
+ }
+
+ public void onSurfaceReady(AndroidVideoWindowImpl vw) {
+ setVideoWindowId(nativePtr,vw);
+ }
+ });
}
public void enableVideo(boolean vcap_enabled, boolean display_enabled) {
- // TODO Auto-generated method stub
-
+ enableVideo(nativePtr,vcap_enabled, display_enabled);
}
public boolean isVideoEnabled() {
- // TODO Auto-generated method stub
- return false;
- }
- public void setStunServer(String stun_server) {
- // TODO Auto-generated method stub
-
- }
- public String getStunServer() {
- // TODO Auto-generated method stub
- return null;
- }
- public void setFirewallPolicy(FirewallPolicy pol) {
- // TODO Auto-generated method stub
-
+ return isVideoEnabled(nativePtr);
}
public FirewallPolicy getFirewallPolicy() {
- // TODO Auto-generated method stub
- return null;
+ return FirewallPolicy.fromInt(getFirewallPolicy(nativePtr));
+ }
+ public String getStunServer() {
+ return getStunServer(nativePtr);
+ }
+ public void setFirewallPolicy(FirewallPolicy pol) {
+ setFirewallPolicy(nativePtr,pol.value());
+ }
+ public void setStunServer(String stunServer) {
+ setStunServer(nativePtr,stunServer);
+ }
+
+ public LinphoneCallParams createDefaultCallParameters() {
+ return new LinphoneCallParamsImpl(createDefaultCallParams(nativePtr));
+ }
+
+ public LinphoneCall inviteAddressWithParams(LinphoneAddress to, LinphoneCallParams params) throws LinphoneCoreException {
+ long ptrDestination = ((LinphoneAddressImpl)to).nativePtr;
+ long ptrParams =((LinphoneCallParamsImpl)params).nativePtr;
+
+ long lcNativePtr = inviteAddressWithParams(nativePtr, ptrDestination, ptrParams);
+ if (lcNativePtr!=0) {
+ return new LinphoneCallImpl(lcNativePtr);
+ } else {
+ throw new LinphoneCoreException("Unable to invite with params " + to.asString());
+ }
+ }
+
+ public int updateCall(LinphoneCall call, LinphoneCallParams params) {
+ long ptrCall = ((LinphoneCallImpl) call).nativePtr;
+ long ptrParams = ((LinphoneCallParamsImpl)params).nativePtr;
+
+ return updateCall(nativePtr, ptrCall, ptrParams);
+ }
+ public void setUploadBandwidth(int bw) {
+ setUploadBandwidth(nativePtr, bw);
+ }
+
+ public void setDownloadBandwidth(int bw) {
+ setDownloadBandwidth(nativePtr, bw);
+ }
+
+ public void setPreferredVideoSize(VideoSize vSize) {
+ setPreferredVideoSize(nativePtr, vSize.getWidth(), vSize.getHeight());
+ }
+
+ public VideoSize getPreferredVideoSize() {
+ int[] nativeSize = getPreferredVideoSize(nativePtr);
+
+ VideoSize vSize = new VideoSize();
+ vSize.setWidth(nativeSize[0]);
+ vSize.setHeight(nativeSize[1]);
+ return vSize;
}
public void setRing(String path) {
- setRing(nativePtr,path);
-
+ setRing(nativePtr, path);
}
public String getRing() {
return getRing(nativePtr);
}
- public LinphoneCall inviteAddressWithParams(LinphoneAddress destination,
- LinphoneCallParams params) throws LinphoneCoreException {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public int updateCall(LinphoneCall call, LinphoneCallParams params) {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public LinphoneCallParams createDefaultCallParameters() {
- throw new RuntimeException("Not Implemenetd yet");
+
+ public PayloadType[] listVideoCodecs() {
+ long[] typesPtr = listVideoPayloadTypes(nativePtr);
+ if (typesPtr == null) return null;
+
+ PayloadType[] codecs = new PayloadType[typesPtr.length];
+
+ for (int i=0; i < codecs.length; i++) {
+ codecs[i] = new PayloadTypeImpl(typesPtr[i]);
+ }
+
+ return codecs;
}
public boolean isNetworkReachable() {
- throw new RuntimeException("Not Implemenetd yet");
+ throw new RuntimeException("Not implemented");
}
- public void setUploadBandwidth(int bw) {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public void setDownloadBandwidth(int bw) {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public void setPreferredVideoSize(VideoSize vSize) {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public VideoSize getPreferredVideoSize() {
- throw new RuntimeException("Not Implemenetd yet");
- }
- public PayloadType[] listVideoCodecs() {
- throw new RuntimeException("Not Implemenetd yet");
- }
-
-
}
diff --git a/src/org/linphone/core/PayloadTypeImpl.java b/src/org/linphone/core/PayloadTypeImpl.java
index 821e1a091..864b094ff 100644
--- a/src/org/linphone/core/PayloadTypeImpl.java
+++ b/src/org/linphone/core/PayloadTypeImpl.java
@@ -24,15 +24,22 @@ class PayloadTypeImpl implements PayloadType {
protected final long nativePtr;
private native String toString(long ptr);
-
+ private native String getMime(long ptr);
+ private native int getRate(long ptr);
+
protected PayloadTypeImpl(long aNativePtr) {
nativePtr = aNativePtr;
}
- public String toString() {
- return toString(nativePtr);
+
+ public int getRate() {
+ return getRate(nativePtr);
}
public String getMime() {
- throw new RuntimeException("Not Implemenetd yet");
+ return getMime(nativePtr);
+ }
+
+ public String toString() {
+ return toString(nativePtr);
}
}
diff --git a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java
new file mode 100644
index 000000000..33cc6b22e
--- /dev/null
+++ b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java
@@ -0,0 +1,81 @@
+/*
+JavaCameraRecordImpl.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core.tutorials;
+
+import org.linphone.core.AndroidCameraRecord;
+
+import android.hardware.Camera;
+import android.hardware.Camera.PreviewCallback;
+import android.hardware.Camera.Size;
+import android.util.Log;
+import android.widget.TextView;
+
+public class JavaCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback {
+
+ private TextView debug;
+ private long count = 0;
+ private float averageCalledRate;
+
+ private long startTime;
+ private long endTime;
+ private int fps;
+
+
+ public JavaCameraRecordImpl(AndroidCameraRecord.RecorderParams parameters) {
+ super(parameters);
+ storePreviewCallBack(this);
+ fps = Math.round(parameters.fps);
+ }
+
+
+ public void setDebug(TextView debug) {
+ this.debug = debug;
+ }
+
+ public void onPreviewFrame(byte[] data, Camera camera) {
+
+ Size s = camera.getParameters().getPreviewSize();
+ int expectedBuffLength = s.width * s.height * 3 /2;
+ if (expectedBuffLength != data.length) {
+ Log.e("Linphone", "onPreviewFrame called with bad buffer length " + data.length
+ + " whereas expected is " + expectedBuffLength + " don't calling putImage");
+ return;
+ }
+
+ if ((count % 2 * fps) == 0) {
+ endTime = System.currentTimeMillis();
+ averageCalledRate = (100000 * 2 * fps) / (endTime - startTime);
+ averageCalledRate /= 100f;
+ startTime = endTime;
+ }
+
+ count++;
+
+ String msg = "Frame " + count + ": " + data.length + "bytes (avg="+averageCalledRate+"frames/s)";
+ if (debug != null) debug.setText(msg);
+ Log.d("onPreviewFrame:", msg);
+ }
+
+
+ @Override
+ protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) {
+ camera.setPreviewCallback(cb);
+ }
+
+}
diff --git a/src/org/linphone/core/tutorials/TestVideoActivity.java b/src/org/linphone/core/tutorials/TestVideoActivity.java
new file mode 100644
index 000000000..971b8f73f
--- /dev/null
+++ b/src/org/linphone/core/tutorials/TestVideoActivity.java
@@ -0,0 +1,191 @@
+/*
+TutorialHelloWorldActivity.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+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 org.linphone.core.tutorials;
+
+import java.util.Stack;
+
+import org.linphone.R;
+import org.linphone.core.AndroidCameraRecord;
+import org.linphone.core.VideoSize;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.SurfaceHolder.Callback;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.Button;
+import android.widget.TextView;
+import static org.linphone.core.VideoSize.*;
+
+/**
+ * Activity for displaying and starting the HelloWorld example on Android phone.
+ *
+ * @author Guillaume Beraudo
+ *
+ */
+public class TestVideoActivity extends Activity implements Callback, OnClickListener {
+
+ private SurfaceView surfaceView;
+ private static final int rate = 7;
+ private JavaCameraRecordImpl recorder;
+ private static String tag = "Linphone";
+ private TextView debugView;
+ private Button nextSize;
+ private Button changeCamera;
+ private Button changeOrientation;
+ private AndroidCameraRecord.RecorderParams params;
+
+ private Stack videoSizes = createSizesToTest();
+ private int currentCameraId = 2;
+ private boolean currentOrientationIsPortrait = false;
+ private int width;
+ private int height;
+ private boolean started;
+
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.videotest);
+
+ surfaceView=(SurfaceView)findViewById(R.id.videotest_surfaceView);
+
+ nextSize = (Button) findViewById(R.id.test_video_size);
+ nextSize.setOnClickListener(this);
+
+ changeCamera = (Button) findViewById(R.id.test_video_camera);
+ changeCamera.setText("Cam"+otherCameraId(currentCameraId));
+ changeCamera.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ changeCamera.setText("Cam"+currentCameraId);
+ currentCameraId = otherCameraId(currentCameraId);
+ updateRecording();
+ }
+ });
+
+ changeOrientation = (Button) findViewById(R.id.test_video_orientation);
+ changeOrientation.setText(orientationToString(!currentOrientationIsPortrait));
+ changeOrientation.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ currentOrientationIsPortrait = !currentOrientationIsPortrait;
+ changeOrientation.setText(orientationToString(!currentOrientationIsPortrait));
+
+ if (width == 0 || height == 0) return;
+ int newWidth = currentOrientationIsPortrait? Math.min(height, width) : Math.max(height, width);
+ int newHeight = currentOrientationIsPortrait? Math.max(height, width) : Math.min(height, width);
+ changeSurfaceViewLayout(newWidth, newHeight); // will change width and height on surfaceChanged
+ }
+ });
+
+ SurfaceHolder holder = surfaceView.getHolder();
+ holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ holder.addCallback(this);
+
+
+ debugView = (TextView) findViewById(R.id.videotest_debug);
+ }
+
+ protected void updateRecording() {
+ if (width == 0 || height == 0) return;
+ if (recorder != null) recorder.stopPreview();
+
+ params = new AndroidCameraRecord.RecorderParams(0);
+ params.surfaceView = surfaceView;
+ params.width = width;
+ params.height = height;
+ params.fps = rate;
+ params.cameraId = currentCameraId;
+
+ recorder = new JavaCameraRecordImpl(params);
+// recorder.setDebug(debugView);
+ debugView.setText(orientationToString(currentOrientationIsPortrait)
+ + " w="+width + " h="+height+ " cam"+currentCameraId);
+ recorder.startPreview();
+
+ }
+
+ private String orientationToString(boolean orientationIsPortrait) {
+ return orientationIsPortrait? "Por" : "Lan";
+ }
+ private int otherCameraId(int currentId) {
+ return (currentId == 2) ? 1 : 2;
+ }
+ public void onClick(View v) {
+ nextSize.setText("Next");
+ started=true;
+ if (videoSizes.isEmpty()) {
+ videoSizes = createSizesToTest();
+ }
+
+ VideoSize size = videoSizes.pop();
+ changeSurfaceViewLayout(size.getWidth(), size.getHeight());
+
+ // on surface changed the recorder will be restarted with new values
+ // and the surface will be resized
+ }
+
+
+ private void changeSurfaceViewLayout(int width, int height) {
+ LayoutParams params = surfaceView.getLayoutParams();
+ params.height = height;
+ params.width = width;
+ surfaceView.setLayoutParams(params);
+
+ }
+
+ private Stack createSizesToTest() {
+ Stack stack = new Stack();
+
+ stack.push(VideoSize.createStandard(QCIF, false));
+ stack.push(VideoSize.createStandard(CIF, false));
+ stack.push(VideoSize.createStandard(QVGA, false));
+ stack.push(VideoSize.createStandard(HVGA, false));
+ stack.push(new VideoSize(640,480));
+ stack.push(new VideoSize(800,480));
+ return stack;
+ }
+
+
+
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ surfaceView = null;
+ Log.d(tag , "Video capture surface destroyed");
+ if (recorder != null) recorder.stopPreview();
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ Log.d(tag , "Video capture surface created");
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ if (!started) return;
+ if (recorder != null) recorder.stopPreview();
+
+ this.width = width;
+ this.height = height;
+
+ updateRecording();
+ }
+}
diff --git a/src/org/linphone/core/tutorials/TutorialRegistrationActivity.java b/src/org/linphone/core/tutorials/TutorialRegistrationActivity.java
index 820360294..94670480c 100644
--- a/src/org/linphone/core/tutorials/TutorialRegistrationActivity.java
+++ b/src/org/linphone/core/tutorials/TutorialRegistrationActivity.java
@@ -76,6 +76,7 @@ public class TutorialRegistrationActivity extends TutorialHelloWorldActivity {
}
});
+
Button buttonStop = (Button) findViewById(R.id.ButtonStop);
buttonStop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
diff --git a/submodules/externals/build/ffmpeg/Android.mk b/submodules/externals/build/ffmpeg/Android.mk
new file mode 100755
index 000000000..d4c5f3df5
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/Android.mk
@@ -0,0 +1,5 @@
+include $(root-dir)/submodules/externals/build/ffmpeg/Android_libavutil.mk
+include $(root-dir)/submodules/externals/build/ffmpeg/Android_libavcodec.mk
+include $(root-dir)/submodules/externals/build/ffmpeg/Android_libswscale.mk
+include $(root-dir)/submodules/externals/build/ffmpeg/Android_libavcore.mk
+
diff --git a/submodules/externals/build/ffmpeg/Android_libavcodec.mk b/submodules/externals/build/ffmpeg/Android_libavcodec.mk
new file mode 100755
index 000000000..43771da28
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/Android_libavcodec.mk
@@ -0,0 +1,103 @@
+LOCAL_PATH:= $(call my-dir)/../../ffmpeg
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libavcodec
+
+LOCAL_SRC_FILES = \
+ libavcodec/allcodecs.c \
+ libavcodec/aandcttab.c \
+ libavcodec/arm/dsputil_arm.S.arm \
+ libavcodec/arm/dsputil_armv6.S.arm \
+ libavcodec/arm/dsputil_init_arm.c \
+ libavcodec/arm/dsputil_init_armv5te.c \
+ libavcodec/arm/dsputil_init_armv6.c \
+ libavcodec/arm/dsputil_init_neon.c \
+ libavcodec/arm/dsputil_init_vfp.c \
+ libavcodec/arm/dsputil_neon.S.neon \
+ libavcodec/arm/dsputil_vfp.S.neon \
+ libavcodec/arm/fft_init_arm.c \
+ libavcodec/arm/h264dsp_init_arm.c \
+ libavcodec/arm/h264dsp_neon.S.neon \
+ libavcodec/arm/h264idct_neon.S.neon \
+ libavcodec/arm/h264pred_init_arm.c \
+ libavcodec/arm/h264pred_neon.S.neon \
+ libavcodec/arm/int_neon.S.neon \
+ libavcodec/arm/jrevdct_arm.S \
+ libavcodec/arm/mpegvideo_arm.c \
+ libavcodec/arm/mpegvideo_armv5te.c \
+ libavcodec/arm/mpegvideo_armv5te_s.S \
+ libavcodec/arm/mpegvideo_neon.S.neon \
+ libavcodec/arm/simple_idct_arm.S \
+ libavcodec/arm/simple_idct_armv5te.S \
+ libavcodec/arm/simple_idct_armv6.S \
+ libavcodec/arm/simple_idct_neon.S.neon \
+ libavcodec/audioconvert.c.arm \
+ libavcodec/avpacket.c \
+ libavcodec/bitstream.c \
+ libavcodec/bitstream_filter.c \
+ libavcodec/cabac.c \
+ libavcodec/dsputil.c.arm \
+ libavcodec/error_resilience.c \
+ libavcodec/faandct.c \
+ libavcodec/faanidct.c \
+ libavcodec/flvdec.c \
+ libavcodec/flvenc.c \
+ libavcodec/golomb.c \
+ libavcodec/h263.c.arm \
+ libavcodec/h263_parser.c \
+ libavcodec/h263dec.c \
+ libavcodec/h264.c \
+ libavcodec/h264_cabac.c.arm \
+ libavcodec/h264_cavlc.c.arm \
+ libavcodec/h264_direct.c.arm \
+ libavcodec/h264_loopfilter.c \
+ libavcodec/h264_ps.c \
+ libavcodec/h264_refs.c \
+ libavcodec/h264_sei.c \
+ libavcodec/h264dsp.c \
+ libavcodec/h264idct.c \
+ libavcodec/h264pred.c \
+ libavcodec/imgconvert.c \
+ libavcodec/intelh263dec.c \
+ libavcodec/inverse.c \
+ libavcodec/ituh263dec.c \
+ libavcodec/ituh263enc.c \
+ libavcodec/jfdctfst.c \
+ libavcodec/jfdctint.c \
+ libavcodec/jrevdct.c \
+ libavcodec/mjpeg.c.arm \
+ libavcodec/mjpegdec.c.arm \
+ libavcodec/motion_est.c.arm \
+ libavcodec/mpeg12data.c \
+ libavcodec/mpeg4video.c.arm \
+ libavcodec/mpeg4video_parser.c \
+ libavcodec/mpeg4videodec.c.arm \
+ libavcodec/mpeg4videoenc.c.arm \
+ libavcodec/mpegvideo.c.arm \
+ libavcodec/mpegvideo_enc.c.arm \
+ libavcodec/opt.c \
+ libavcodec/options.c \
+ libavcodec/parser.c \
+ libavcodec/ratecontrol.c \
+ libavcodec/raw.c \
+ libavcodec/resample.c \
+ libavcodec/resample2.c \
+ libavcodec/simple_idct.c \
+ libavcodec/utils.c \
+ libavcodec/pthread.c
+
+
+LOCAL_ARM_MODE := arm
+
+#LOCAL_CFLAGS += -DHAVE_AV_CONFIG_H -Wa,-I$(LOCAL_PATH)/libavcodec/arm
+LOCAL_CFLAGS += -DHAVE_AV_CONFIG_H
+
+#for including config.h:
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../build/ffmpeg \
+ $(LOCAL_PATH)/libavcodec/arm \
+ $(LOCAL_PATH)/ \
+ $(LOCAL_PATH)/libavutil
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/submodules/externals/build/ffmpeg/Android_libavcore.mk b/submodules/externals/build/ffmpeg/Android_libavcore.mk
new file mode 100644
index 000000000..82a180f77
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/Android_libavcore.mk
@@ -0,0 +1,21 @@
+
+LOCAL_PATH:= $(call my-dir)/../../ffmpeg/
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libavcore
+
+
+LOCAL_SRC_FILES := \
+ libavcore/imgutils.c \
+ libavcore/parseutils.c \
+ libavcore/utils.c
+
+
+LOCAL_CFLAGS += -DHAVE_AV_CONFIG_H
+
+
+
+#for including config.h:
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../build/ffmpeg $(LOCAL_PATH)/
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/submodules/externals/build/ffmpeg/Android_libavutil.mk b/submodules/externals/build/ffmpeg/Android_libavutil.mk
new file mode 100755
index 000000000..08d65b5dd
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/Android_libavutil.mk
@@ -0,0 +1,45 @@
+
+LOCAL_PATH:= $(call my-dir)/../../ffmpeg/
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libavutil
+
+
+LOCAL_SRC_FILES = \
+ libavutil/adler32.c \
+ libavutil/aes.c \
+ libavutil/arm/cpu.c \
+ libavutil/avstring.c \
+ libavutil/base64.c \
+ libavutil/cpu.c \
+ libavutil/crc.c \
+ libavutil/des.c \
+ libavutil/error.c \
+ libavutil/eval.c \
+ libavutil/fifo.c \
+ libavutil/intfloat_readwrite.c \
+ libavutil/inverse.c \
+ libavutil/lfg.c \
+ libavutil/lls.c \
+ libavutil/log.c \
+ libavutil/lzo.c \
+ libavutil/mathematics.c \
+ libavutil/md5.c \
+ libavutil/mem.c \
+ libavutil/opt.c \
+ libavutil/pixdesc.c \
+ libavutil/random_seed.c \
+ libavutil/rational.c \
+ libavutil/rc4.c \
+ libavutil/sha.c \
+ libavutil/tree.c \
+ libavutil/utils.c
+
+LOCAL_CFLAGS += -DHAVE_AV_CONFIG_H
+
+LOCAL_ARM_MODE := arm
+
+#for including config.h:
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../build/ffmpeg $(LOCAL_PATH)/
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/submodules/externals/build/ffmpeg/Android_libswscale.mk b/submodules/externals/build/ffmpeg/Android_libswscale.mk
new file mode 100755
index 000000000..6bd8cc828
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/Android_libswscale.mk
@@ -0,0 +1,25 @@
+##lib swcale###################
+LOCAL_PATH:= $(call my-dir)/../../libswscale/
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libswscale
+
+LOCAL_SRC_FILES = \
+ options.c \
+ rgb2rgb.c \
+ swscale.c \
+ utils.c \
+ yuv2rgb.c
+
+LOCAL_CFLAGS += -DHAVE_AV_CONFIG_H
+
+LOCAL_ARM_MODE := arm
+
+#for including config.h:
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../build/ffmpeg \
+ $(LOCAL_PATH)/../ffmpeg \
+ $(LOCAL_PATH)/ \
+ $(LOCAL_PATH)/../
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/submodules/externals/build/ffmpeg/README b/submodules/externals/build/ffmpeg/README
new file mode 100644
index 000000000..77d16a1e2
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/README
@@ -0,0 +1,3 @@
+config.h and list of sources files generated by the following configure invocation:
+
+./configure --disable-mmx --prefix=/Users/jehanmonnier/opt --enable-cross-compile --arch=arm --target-os=linux --cc=arm-none-linux-gnueabi-gcc --disable-ffplay --disable-ffmpeg --disable-ffprobe --disable-ffserver --disable-avdevice --disable-avcore --disable-avfilter --disable-network --disable-everything --enable-decoder=mpeg4 --enable-encoder=mpeg4 --enable-decoder=h264 --enable-decoder=mjpeg --disable-avformat --enable-armv6 --enable-armv6t2 --enable-armvfp --enable-neon --enable-pic --extra-cflags='-fPIC -march=armv7-a -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=neon'
diff --git a/submodules/externals/build/ffmpeg/config.h b/submodules/externals/build/ffmpeg/config.h
new file mode 100644
index 000000000..0ea96b84c
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/config.h
@@ -0,0 +1,941 @@
+/* Automatically generated by configure - do not modify! */
+#ifndef FFMPEG_CONFIG_H
+#define FFMPEG_CONFIG_H
+#define FFMPEG_CONFIGURATION "--disable-mmx --prefix=/Users/jehanmonnier/opt --enable-cross-compile --arch=arm --target-os=linux --cc=arm-none-linux-gnueabi-gcc --disable-ffplay --disable-ffmpeg --disable-ffprobe --disable-ffserver --disable-avdevice --disable-avcore --disable-avfilter --disable-network --disable-everything --enable-decoder=mpeg4 --enable-encoder=mpeg4 --enable-decoder=h264 --disable-avformat --enable-armv6 --enable-armv6t2 --enable-armvfp --enable-neon --enable-pic --extra-cflags='-fPIC -march=armv7-a -mcpu=cortex-a8 -mfloat-abi=softfp -mfpu=neon'"
+#define FFMPEG_LICENSE "LGPL version 2.1 or later"
+#define FFMPEG_DATADIR "/Users/jehanmonnier/opt/share/ffmpeg"
+#define CC_TYPE "gcc"
+#define CC_VERSION __VERSION__
+#define restrict
+#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t"
+#define EXTERN_PREFIX ""
+#define EXTERN_ASM
+#define ARCH_ALPHA 0
+#define ARCH_ARM 1
+#define ARCH_AVR32 0
+#define ARCH_AVR32_AP 0
+#define ARCH_AVR32_UC 0
+#define ARCH_BFIN 0
+#define ARCH_IA64 0
+#define ARCH_M68K 0
+#define ARCH_MIPS 0
+#define ARCH_MIPS64 0
+#define ARCH_PARISC 0
+#define ARCH_PPC 0
+#define ARCH_PPC64 0
+#define ARCH_S390 0
+#define ARCH_SH4 0
+#define ARCH_SPARC 0
+#define ARCH_SPARC64 0
+#define ARCH_TOMI 0
+#define ARCH_X86 0
+#define ARCH_X86_32 0
+#define ARCH_X86_64 0
+#define HAVE_ALTIVEC 0
+#define HAVE_AMD3DNOW 0
+#define HAVE_AMD3DNOWEXT 0
+#define HAVE_ARMV5TE 1
+#define HAVE_ARMV6 1
+#define HAVE_ARMV6T2 1
+#define HAVE_ARMVFP 1
+#define HAVE_IWMMXT 0
+#define HAVE_MMI 0
+#define HAVE_MMX 0
+#define HAVE_MMX2 0
+#define HAVE_NEON 1
+#define HAVE_PPC4XX 0
+#define HAVE_SSE 0
+#define HAVE_SSSE3 0
+#define HAVE_VIS 0
+#define HAVE_BIGENDIAN 0
+#define HAVE_FAST_UNALIGNED 1
+#define HAVE_PTHREADS 1
+#define HAVE_W32THREADS 0
+#define HAVE_ALIGNED_STACK 0
+#define HAVE_ALSA_ASOUNDLIB_H 0
+#define HAVE_ALTIVEC_H 0
+#define HAVE_ARPA_INET_H 0
+#define HAVE_ATTRIBUTE_MAY_ALIAS 1
+#define HAVE_ATTRIBUTE_PACKED 1
+#define HAVE_BSWAP 0
+#define HAVE_CLOSESOCKET 0
+#define HAVE_CMOV 0
+#define HAVE_CONIO_H 0
+#define HAVE_DCBZL 0
+#define HAVE_DEV_BKTR_IOCTL_BT848_H 0
+#define HAVE_DEV_BKTR_IOCTL_METEOR_H 0
+#define HAVE_DEV_IC_BT8XX_H 0
+#define HAVE_DEV_VIDEO_METEOR_IOCTL_METEOR_H 0
+#define HAVE_DEV_VIDEO_BKTR_IOCTL_BT848_H 0
+#define HAVE_DLFCN_H 1
+#define HAVE_DLOPEN 1
+#define HAVE_DOS_PATHS 0
+#define HAVE_EBP_AVAILABLE 0
+#define HAVE_EBX_AVAILABLE 0
+#define HAVE_EXP2 1
+#define HAVE_EXP2F 1
+#define HAVE_FAST_64BIT 0
+#define HAVE_FAST_CLZ 1
+#define HAVE_FAST_CMOV 0
+#define HAVE_FCNTL 1
+#define HAVE_FORK 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETHRTIME 0
+#define HAVE_GETPROCESSMEMORYINFO 0
+#define HAVE_GETPROCESSTIMES 0
+#define HAVE_GETRUSAGE 1
+#define HAVE_GNU_AS 1
+#define HAVE_STRUCT_RUSAGE_RU_MAXRSS 1
+#define HAVE_IBM_ASM 0
+#define HAVE_INET_ATON 1
+#define HAVE_INLINE_ASM 1
+#define HAVE_ISATTY 1
+#define HAVE_LDBRX 0
+#define HAVE_LIBDC1394_1 0
+#define HAVE_LIBDC1394_2 0
+#define HAVE_LLRINT 1
+#define HAVE_LLRINTF 1
+#define HAVE_LOCAL_ALIGNED_16 0
+#define HAVE_LOCAL_ALIGNED_8 0
+#define HAVE_LOG2 1
+#define HAVE_LOG2F 1
+#define HAVE_LOONGSON 0
+#define HAVE_LRINT 1
+#define HAVE_LRINTF 1
+#define HAVE_LZO1X_999_COMPRESS 0
+#define HAVE_MACHINE_IOCTL_BT848_H 0
+#define HAVE_MACHINE_IOCTL_METEOR_H 0
+#define HAVE_MALLOC_H 1
+#define HAVE_MEMALIGN 1
+#define HAVE_MKSTEMP 1
+#define HAVE_PLD 1
+#define HAVE_POSIX_MEMALIGN 0
+#define HAVE_ROUND 1
+#define HAVE_ROUNDF 1
+#define HAVE_SDL 0
+#define HAVE_SDL_VIDEO_SIZE 0
+#define HAVE_SETMODE 0
+#define HAVE_SOCKLEN_T 0
+#define HAVE_SOUNDCARD_H 0
+#define HAVE_POLL_H 1
+#define HAVE_SETRLIMIT 1
+#define HAVE_STRERROR_R 1
+#define HAVE_STRTOK_R 1
+#define HAVE_STRUCT_ADDRINFO 0
+#define HAVE_STRUCT_IPV6_MREQ 0
+#define HAVE_STRUCT_SOCKADDR_IN6 0
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 0
+#define HAVE_STRUCT_SOCKADDR_STORAGE 0
+#define HAVE_SYMVER 1
+#define HAVE_SYMVER_GNU_ASM 1
+#define HAVE_SYMVER_ASM_LABEL 0
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_SYS_RESOURCE_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_SOUNDCARD_H 1
+#define HAVE_SYS_VIDEOIO_H 0
+#define HAVE_TEN_OPERANDS 0
+#define HAVE_TERMIOS_H 1
+#define HAVE_THREADS 1
+#define HAVE_TRUNCF 1
+#define HAVE_VFP_ARGS 0
+#define HAVE_VIRTUALALLOC 0
+#define HAVE_WINSOCK2_H 0
+#define HAVE_XFORM_ASM 0
+#define HAVE_YASM 0
+#define CONFIG_BSFS 0
+#define CONFIG_DECODERS 1
+#define CONFIG_DEMUXERS 0
+#define CONFIG_ENCODERS 1
+#define CONFIG_FILTERS 0
+#define CONFIG_HWACCELS 0
+#define CONFIG_INDEVS 0
+#define CONFIG_MUXERS 0
+#define CONFIG_OUTDEVS 0
+#define CONFIG_PARSERS 1
+#define CONFIG_PROTOCOLS 1
+#define CONFIG_AANDCT 1
+#define CONFIG_AVCODEC 1
+#define CONFIG_AVCORE 0
+#define CONFIG_AVDEVICE 0
+#define CONFIG_AVFILTER 0
+#define CONFIG_AVFORMAT 0
+#define CONFIG_AVISYNTH 0
+#define CONFIG_BZLIB 0
+#define CONFIG_DCT 0
+#define CONFIG_DOC 0
+#define CONFIG_DWT 0
+#define CONFIG_DXVA2 0
+#define CONFIG_FASTDIV 1
+#define CONFIG_FFMPEG 0
+#define CONFIG_FFPLAY 0
+#define CONFIG_FFPROBE 0
+#define CONFIG_FFSERVER 0
+#define CONFIG_FFT 0
+#define CONFIG_FREI0R 0
+#define CONFIG_GOLOMB 1
+#define CONFIG_GPL 0
+#define CONFIG_GRAY 0
+#define CONFIG_H264DSP 1
+#define CONFIG_H264PRED 1
+#define CONFIG_HARDCODED_TABLES 0
+#define CONFIG_HUFFMAN 0
+#define CONFIG_LIBDC1394 0
+#define CONFIG_LIBDIRAC 0
+#define CONFIG_LIBFAAC 0
+#define CONFIG_LIBGSM 0
+#define CONFIG_LIBMP3LAME 0
+#define CONFIG_LIBNUT 0
+#define CONFIG_LIBOPENCORE_AMRNB 0
+#define CONFIG_LIBOPENCORE_AMRWB 0
+#define CONFIG_LIBOPENCV 0
+#define CONFIG_LIBOPENJPEG 0
+#define CONFIG_LIBRTMP 0
+#define CONFIG_LIBSCHROEDINGER 0
+#define CONFIG_LIBSPEEX 0
+#define CONFIG_LIBTHEORA 0
+#define CONFIG_LIBVORBIS 0
+#define CONFIG_LIBVPX 0
+#define CONFIG_LIBX264 0
+#define CONFIG_LIBXAVS 0
+#define CONFIG_LIBXVID 0
+#define CONFIG_LPC 0
+#define CONFIG_LSP 0
+#define CONFIG_MDCT 0
+#define CONFIG_MEMALIGN_HACK 0
+#define CONFIG_MLIB 0
+#define CONFIG_MPEGAUDIO_HP 1
+#define CONFIG_NETWORK 0
+#define CONFIG_NONFREE 0
+#define CONFIG_PIC 1
+#define CONFIG_POSTPROC 0
+#define CONFIG_RDFT 0
+#define CONFIG_RUNTIME_CPUDETECT 0
+#define CONFIG_SHARED 0
+#define CONFIG_SMALL 0
+#define CONFIG_SRAM 0
+#define CONFIG_STATIC 1
+#define CONFIG_SWSCALE 1
+#define CONFIG_SWSCALE_ALPHA 1
+#define CONFIG_VAAPI 0
+#define CONFIG_VDPAU 0
+#define CONFIG_VERSION3 0
+#define CONFIG_X11GRAB 0
+#define CONFIG_ZLIB 0
+#define CONFIG_AVUTIL 1
+#define CONFIG_GPLV3 0
+#define CONFIG_LGPLV3 0
+#define CONFIG_AASC_DECODER 0
+#define CONFIG_AMV_DECODER 0
+#define CONFIG_ANM_DECODER 0
+#define CONFIG_ANSI_DECODER 0
+#define CONFIG_ASV1_DECODER 0
+#define CONFIG_ASV2_DECODER 0
+#define CONFIG_AURA_DECODER 0
+#define CONFIG_AURA2_DECODER 0
+#define CONFIG_AVS_DECODER 0
+#define CONFIG_BETHSOFTVID_DECODER 0
+#define CONFIG_BFI_DECODER 0
+#define CONFIG_BINK_DECODER 0
+#define CONFIG_BMP_DECODER 0
+#define CONFIG_C93_DECODER 0
+#define CONFIG_CAVS_DECODER 0
+#define CONFIG_CDGRAPHICS_DECODER 0
+#define CONFIG_CINEPAK_DECODER 0
+#define CONFIG_CLJR_DECODER 0
+#define CONFIG_CSCD_DECODER 0
+#define CONFIG_CYUV_DECODER 0
+#define CONFIG_DNXHD_DECODER 0
+#define CONFIG_DPX_DECODER 0
+#define CONFIG_DSICINVIDEO_DECODER 0
+#define CONFIG_DVVIDEO_DECODER 0
+#define CONFIG_DXA_DECODER 0
+#define CONFIG_EACMV_DECODER 0
+#define CONFIG_EAMAD_DECODER 0
+#define CONFIG_EATGQ_DECODER 0
+#define CONFIG_EATGV_DECODER 0
+#define CONFIG_EATQI_DECODER 0
+#define CONFIG_EIGHTBPS_DECODER 0
+#define CONFIG_EIGHTSVX_EXP_DECODER 0
+#define CONFIG_EIGHTSVX_FIB_DECODER 0
+#define CONFIG_ESCAPE124_DECODER 0
+#define CONFIG_FFV1_DECODER 0
+#define CONFIG_FFVHUFF_DECODER 0
+#define CONFIG_FLASHSV_DECODER 0
+#define CONFIG_FLIC_DECODER 0
+#define CONFIG_FLV_DECODER 0
+#define CONFIG_FOURXM_DECODER 0
+#define CONFIG_FRAPS_DECODER 0
+#define CONFIG_FRWU_DECODER 0
+#define CONFIG_GIF_DECODER 0
+#define CONFIG_H261_DECODER 0
+#define CONFIG_H263_DECODER 1
+#define CONFIG_H263I_DECODER 0
+#define CONFIG_H264_DECODER 1
+#define CONFIG_H264_VDPAU_DECODER 0
+#define CONFIG_HUFFYUV_DECODER 0
+#define CONFIG_IDCIN_DECODER 0
+#define CONFIG_IFF_BYTERUN1_DECODER 0
+#define CONFIG_IFF_ILBM_DECODER 0
+#define CONFIG_INDEO2_DECODER 0
+#define CONFIG_INDEO3_DECODER 0
+#define CONFIG_INDEO5_DECODER 0
+#define CONFIG_INTERPLAY_VIDEO_DECODER 0
+#define CONFIG_JPEGLS_DECODER 0
+#define CONFIG_KGV1_DECODER 0
+#define CONFIG_KMVC_DECODER 0
+#define CONFIG_LOCO_DECODER 0
+#define CONFIG_MDEC_DECODER 0
+#define CONFIG_MIMIC_DECODER 0
+#define CONFIG_MJPEG_DECODER 1
+#define CONFIG_MJPEGB_DECODER 0
+#define CONFIG_MMVIDEO_DECODER 0
+#define CONFIG_MOTIONPIXELS_DECODER 0
+#define CONFIG_MPEG_XVMC_DECODER 0
+#define CONFIG_MPEG1VIDEO_DECODER 0
+#define CONFIG_MPEG2VIDEO_DECODER 0
+#define CONFIG_MPEG4_DECODER 1
+#define CONFIG_MPEG4_VDPAU_DECODER 0
+#define CONFIG_MPEGVIDEO_DECODER 0
+#define CONFIG_MPEG_VDPAU_DECODER 0
+#define CONFIG_MPEG1_VDPAU_DECODER 0
+#define CONFIG_MSMPEG4V1_DECODER 0
+#define CONFIG_MSMPEG4V2_DECODER 0
+#define CONFIG_MSMPEG4V3_DECODER 0
+#define CONFIG_MSRLE_DECODER 0
+#define CONFIG_MSVIDEO1_DECODER 0
+#define CONFIG_MSZH_DECODER 0
+#define CONFIG_NUV_DECODER 0
+#define CONFIG_PAM_DECODER 0
+#define CONFIG_PBM_DECODER 0
+#define CONFIG_PCX_DECODER 0
+#define CONFIG_PGM_DECODER 0
+#define CONFIG_PGMYUV_DECODER 0
+#define CONFIG_PICTOR_DECODER 0
+#define CONFIG_PNG_DECODER 0
+#define CONFIG_PPM_DECODER 0
+#define CONFIG_PTX_DECODER 0
+#define CONFIG_QDRAW_DECODER 0
+#define CONFIG_QPEG_DECODER 0
+#define CONFIG_QTRLE_DECODER 0
+#define CONFIG_R10K_DECODER 0
+#define CONFIG_R210_DECODER 0
+#define CONFIG_RAWVIDEO_DECODER 0
+#define CONFIG_RL2_DECODER 0
+#define CONFIG_ROQ_DECODER 0
+#define CONFIG_RPZA_DECODER 0
+#define CONFIG_RV10_DECODER 0
+#define CONFIG_RV20_DECODER 0
+#define CONFIG_RV30_DECODER 0
+#define CONFIG_RV40_DECODER 0
+#define CONFIG_SGI_DECODER 0
+#define CONFIG_SMACKER_DECODER 0
+#define CONFIG_SMC_DECODER 0
+#define CONFIG_SNOW_DECODER 0
+#define CONFIG_SP5X_DECODER 0
+#define CONFIG_SUNRAST_DECODER 0
+#define CONFIG_SVQ1_DECODER 0
+#define CONFIG_SVQ3_DECODER 0
+#define CONFIG_TARGA_DECODER 0
+#define CONFIG_THEORA_DECODER 0
+#define CONFIG_THP_DECODER 0
+#define CONFIG_TIERTEXSEQVIDEO_DECODER 0
+#define CONFIG_TIFF_DECODER 0
+#define CONFIG_TMV_DECODER 0
+#define CONFIG_TRUEMOTION1_DECODER 0
+#define CONFIG_TRUEMOTION2_DECODER 0
+#define CONFIG_TSCC_DECODER 0
+#define CONFIG_TXD_DECODER 0
+#define CONFIG_ULTI_DECODER 0
+#define CONFIG_V210_DECODER 0
+#define CONFIG_V210X_DECODER 0
+#define CONFIG_VB_DECODER 0
+#define CONFIG_VC1_DECODER 0
+#define CONFIG_VC1_VDPAU_DECODER 0
+#define CONFIG_VCR1_DECODER 0
+#define CONFIG_VMDVIDEO_DECODER 0
+#define CONFIG_VMNC_DECODER 0
+#define CONFIG_VP3_DECODER 0
+#define CONFIG_VP5_DECODER 0
+#define CONFIG_VP6_DECODER 0
+#define CONFIG_VP6A_DECODER 0
+#define CONFIG_VP6F_DECODER 0
+#define CONFIG_VP8_DECODER 0
+#define CONFIG_VQA_DECODER 0
+#define CONFIG_WMV1_DECODER 0
+#define CONFIG_WMV2_DECODER 0
+#define CONFIG_WMV3_DECODER 0
+#define CONFIG_WMV3_VDPAU_DECODER 0
+#define CONFIG_WNV1_DECODER 0
+#define CONFIG_XAN_WC3_DECODER 0
+#define CONFIG_XL_DECODER 0
+#define CONFIG_YOP_DECODER 0
+#define CONFIG_ZLIB_DECODER 0
+#define CONFIG_ZMBV_DECODER 0
+#define CONFIG_AAC_DECODER 0
+#define CONFIG_AC3_DECODER 0
+#define CONFIG_ALAC_DECODER 0
+#define CONFIG_ALS_DECODER 0
+#define CONFIG_AMRNB_DECODER 0
+#define CONFIG_APE_DECODER 0
+#define CONFIG_ATRAC1_DECODER 0
+#define CONFIG_ATRAC3_DECODER 0
+#define CONFIG_BINKAUDIO_DCT_DECODER 0
+#define CONFIG_BINKAUDIO_RDFT_DECODER 0
+#define CONFIG_COOK_DECODER 0
+#define CONFIG_DCA_DECODER 0
+#define CONFIG_DSICINAUDIO_DECODER 0
+#define CONFIG_EAC3_DECODER 0
+#define CONFIG_FLAC_DECODER 0
+#define CONFIG_GSM_DECODER 0
+#define CONFIG_GSM_MS_DECODER 0
+#define CONFIG_IMC_DECODER 0
+#define CONFIG_MACE3_DECODER 0
+#define CONFIG_MACE6_DECODER 0
+#define CONFIG_MLP_DECODER 0
+#define CONFIG_MP1_DECODER 0
+#define CONFIG_MP1FLOAT_DECODER 0
+#define CONFIG_MP2_DECODER 0
+#define CONFIG_MP2FLOAT_DECODER 0
+#define CONFIG_MP3_DECODER 0
+#define CONFIG_MP3FLOAT_DECODER 0
+#define CONFIG_MP3ADU_DECODER 0
+#define CONFIG_MP3ADUFLOAT_DECODER 0
+#define CONFIG_MP3ON4_DECODER 0
+#define CONFIG_MP3ON4FLOAT_DECODER 0
+#define CONFIG_MPC7_DECODER 0
+#define CONFIG_MPC8_DECODER 0
+#define CONFIG_NELLYMOSER_DECODER 0
+#define CONFIG_QCELP_DECODER 0
+#define CONFIG_QDM2_DECODER 0
+#define CONFIG_RA_144_DECODER 0
+#define CONFIG_RA_288_DECODER 0
+#define CONFIG_SHORTEN_DECODER 0
+#define CONFIG_SIPR_DECODER 0
+#define CONFIG_SMACKAUD_DECODER 0
+#define CONFIG_SONIC_DECODER 0
+#define CONFIG_TRUEHD_DECODER 0
+#define CONFIG_TRUESPEECH_DECODER 0
+#define CONFIG_TTA_DECODER 0
+#define CONFIG_TWINVQ_DECODER 0
+#define CONFIG_VMDAUDIO_DECODER 0
+#define CONFIG_VORBIS_DECODER 0
+#define CONFIG_WAVPACK_DECODER 0
+#define CONFIG_WMAPRO_DECODER 0
+#define CONFIG_WMAV1_DECODER 0
+#define CONFIG_WMAV2_DECODER 0
+#define CONFIG_WMAVOICE_DECODER 0
+#define CONFIG_WS_SND1_DECODER 0
+#define CONFIG_PCM_ALAW_DECODER 0
+#define CONFIG_PCM_BLURAY_DECODER 0
+#define CONFIG_PCM_DVD_DECODER 0
+#define CONFIG_PCM_F32BE_DECODER 0
+#define CONFIG_PCM_F32LE_DECODER 0
+#define CONFIG_PCM_F64BE_DECODER 0
+#define CONFIG_PCM_F64LE_DECODER 0
+#define CONFIG_PCM_MULAW_DECODER 0
+#define CONFIG_PCM_S8_DECODER 0
+#define CONFIG_PCM_S16BE_DECODER 0
+#define CONFIG_PCM_S16LE_DECODER 0
+#define CONFIG_PCM_S16LE_PLANAR_DECODER 0
+#define CONFIG_PCM_S24BE_DECODER 0
+#define CONFIG_PCM_S24DAUD_DECODER 0
+#define CONFIG_PCM_S24LE_DECODER 0
+#define CONFIG_PCM_S32BE_DECODER 0
+#define CONFIG_PCM_S32LE_DECODER 0
+#define CONFIG_PCM_U8_DECODER 0
+#define CONFIG_PCM_U16BE_DECODER 0
+#define CONFIG_PCM_U16LE_DECODER 0
+#define CONFIG_PCM_U24BE_DECODER 0
+#define CONFIG_PCM_U24LE_DECODER 0
+#define CONFIG_PCM_U32BE_DECODER 0
+#define CONFIG_PCM_U32LE_DECODER 0
+#define CONFIG_PCM_ZORK_DECODER 0
+#define CONFIG_INTERPLAY_DPCM_DECODER 0
+#define CONFIG_ROQ_DPCM_DECODER 0
+#define CONFIG_SOL_DPCM_DECODER 0
+#define CONFIG_XAN_DPCM_DECODER 0
+#define CONFIG_ADPCM_4XM_DECODER 0
+#define CONFIG_ADPCM_ADX_DECODER 0
+#define CONFIG_ADPCM_CT_DECODER 0
+#define CONFIG_ADPCM_EA_DECODER 0
+#define CONFIG_ADPCM_EA_MAXIS_XA_DECODER 0
+#define CONFIG_ADPCM_EA_R1_DECODER 0
+#define CONFIG_ADPCM_EA_R2_DECODER 0
+#define CONFIG_ADPCM_EA_R3_DECODER 0
+#define CONFIG_ADPCM_EA_XAS_DECODER 0
+#define CONFIG_ADPCM_G722_DECODER 0
+#define CONFIG_ADPCM_G726_DECODER 0
+#define CONFIG_ADPCM_IMA_AMV_DECODER 0
+#define CONFIG_ADPCM_IMA_DK3_DECODER 0
+#define CONFIG_ADPCM_IMA_DK4_DECODER 0
+#define CONFIG_ADPCM_IMA_EA_EACS_DECODER 0
+#define CONFIG_ADPCM_IMA_EA_SEAD_DECODER 0
+#define CONFIG_ADPCM_IMA_ISS_DECODER 0
+#define CONFIG_ADPCM_IMA_QT_DECODER 0
+#define CONFIG_ADPCM_IMA_SMJPEG_DECODER 0
+#define CONFIG_ADPCM_IMA_WAV_DECODER 0
+#define CONFIG_ADPCM_IMA_WS_DECODER 0
+#define CONFIG_ADPCM_MS_DECODER 0
+#define CONFIG_ADPCM_SBPRO_2_DECODER 0
+#define CONFIG_ADPCM_SBPRO_3_DECODER 0
+#define CONFIG_ADPCM_SBPRO_4_DECODER 0
+#define CONFIG_ADPCM_SWF_DECODER 0
+#define CONFIG_ADPCM_THP_DECODER 0
+#define CONFIG_ADPCM_XA_DECODER 0
+#define CONFIG_ADPCM_YAMAHA_DECODER 0
+#define CONFIG_DVBSUB_DECODER 0
+#define CONFIG_DVDSUB_DECODER 0
+#define CONFIG_PGSSUB_DECODER 0
+#define CONFIG_XSUB_DECODER 0
+#define CONFIG_LIBDIRAC_DECODER 0
+#define CONFIG_LIBGSM_DECODER 0
+#define CONFIG_LIBGSM_MS_DECODER 0
+#define CONFIG_LIBOPENCORE_AMRNB_DECODER 0
+#define CONFIG_LIBOPENCORE_AMRWB_DECODER 0
+#define CONFIG_LIBOPENJPEG_DECODER 0
+#define CONFIG_LIBSCHROEDINGER_DECODER 0
+#define CONFIG_LIBSPEEX_DECODER 0
+#define CONFIG_LIBVPX_DECODER 0
+#define CONFIG_A64MULTI_ENCODER 0
+#define CONFIG_A64MULTI5_ENCODER 0
+#define CONFIG_ASV1_ENCODER 0
+#define CONFIG_ASV2_ENCODER 0
+#define CONFIG_BMP_ENCODER 0
+#define CONFIG_DNXHD_ENCODER 0
+#define CONFIG_DVVIDEO_ENCODER 0
+#define CONFIG_FFV1_ENCODER 0
+#define CONFIG_FFVHUFF_ENCODER 0
+#define CONFIG_FLASHSV_ENCODER 0
+#define CONFIG_FLV_ENCODER 0
+#define CONFIG_GIF_ENCODER 0
+#define CONFIG_H261_ENCODER 0
+#define CONFIG_H263_ENCODER 1
+#define CONFIG_H263P_ENCODER 0
+#define CONFIG_HUFFYUV_ENCODER 0
+#define CONFIG_JPEGLS_ENCODER 0
+#define CONFIG_LJPEG_ENCODER 0
+#define CONFIG_MJPEG_ENCODER 0
+#define CONFIG_MPEG1VIDEO_ENCODER 0
+#define CONFIG_MPEG2VIDEO_ENCODER 0
+#define CONFIG_MPEG4_ENCODER 1
+#define CONFIG_MSMPEG4V1_ENCODER 0
+#define CONFIG_MSMPEG4V2_ENCODER 0
+#define CONFIG_MSMPEG4V3_ENCODER 0
+#define CONFIG_PAM_ENCODER 0
+#define CONFIG_PBM_ENCODER 0
+#define CONFIG_PCX_ENCODER 0
+#define CONFIG_PGM_ENCODER 0
+#define CONFIG_PGMYUV_ENCODER 0
+#define CONFIG_PNG_ENCODER 0
+#define CONFIG_PPM_ENCODER 0
+#define CONFIG_QTRLE_ENCODER 0
+#define CONFIG_RAWVIDEO_ENCODER 0
+#define CONFIG_ROQ_ENCODER 0
+#define CONFIG_RV10_ENCODER 0
+#define CONFIG_RV20_ENCODER 0
+#define CONFIG_SGI_ENCODER 0
+#define CONFIG_SNOW_ENCODER 0
+#define CONFIG_SVQ1_ENCODER 0
+#define CONFIG_TARGA_ENCODER 0
+#define CONFIG_TIFF_ENCODER 0
+#define CONFIG_V210_ENCODER 0
+#define CONFIG_WMV1_ENCODER 0
+#define CONFIG_WMV2_ENCODER 0
+#define CONFIG_ZLIB_ENCODER 0
+#define CONFIG_ZMBV_ENCODER 0
+#define CONFIG_AAC_ENCODER 0
+#define CONFIG_AC3_ENCODER 0
+#define CONFIG_ALAC_ENCODER 0
+#define CONFIG_FLAC_ENCODER 0
+#define CONFIG_MP2_ENCODER 0
+#define CONFIG_NELLYMOSER_ENCODER 0
+#define CONFIG_RA_144_ENCODER 0
+#define CONFIG_SONIC_ENCODER 0
+#define CONFIG_SONIC_LS_ENCODER 0
+#define CONFIG_VORBIS_ENCODER 0
+#define CONFIG_WMAV1_ENCODER 0
+#define CONFIG_WMAV2_ENCODER 0
+#define CONFIG_PCM_ALAW_ENCODER 0
+#define CONFIG_PCM_F32BE_ENCODER 0
+#define CONFIG_PCM_F32LE_ENCODER 0
+#define CONFIG_PCM_F64BE_ENCODER 0
+#define CONFIG_PCM_F64LE_ENCODER 0
+#define CONFIG_PCM_MULAW_ENCODER 0
+#define CONFIG_PCM_S8_ENCODER 0
+#define CONFIG_PCM_S16BE_ENCODER 0
+#define CONFIG_PCM_S16LE_ENCODER 0
+#define CONFIG_PCM_S24BE_ENCODER 0
+#define CONFIG_PCM_S24DAUD_ENCODER 0
+#define CONFIG_PCM_S24LE_ENCODER 0
+#define CONFIG_PCM_S32BE_ENCODER 0
+#define CONFIG_PCM_S32LE_ENCODER 0
+#define CONFIG_PCM_U8_ENCODER 0
+#define CONFIG_PCM_U16BE_ENCODER 0
+#define CONFIG_PCM_U16LE_ENCODER 0
+#define CONFIG_PCM_U24BE_ENCODER 0
+#define CONFIG_PCM_U24LE_ENCODER 0
+#define CONFIG_PCM_U32BE_ENCODER 0
+#define CONFIG_PCM_U32LE_ENCODER 0
+#define CONFIG_PCM_ZORK_ENCODER 0
+#define CONFIG_ROQ_DPCM_ENCODER 0
+#define CONFIG_ADPCM_ADX_ENCODER 0
+#define CONFIG_ADPCM_G722_ENCODER 0
+#define CONFIG_ADPCM_G726_ENCODER 0
+#define CONFIG_ADPCM_IMA_QT_ENCODER 0
+#define CONFIG_ADPCM_IMA_WAV_ENCODER 0
+#define CONFIG_ADPCM_MS_ENCODER 0
+#define CONFIG_ADPCM_SWF_ENCODER 0
+#define CONFIG_ADPCM_YAMAHA_ENCODER 0
+#define CONFIG_DVBSUB_ENCODER 0
+#define CONFIG_DVDSUB_ENCODER 0
+#define CONFIG_XSUB_ENCODER 0
+#define CONFIG_LIBDIRAC_ENCODER 0
+#define CONFIG_LIBFAAC_ENCODER 0
+#define CONFIG_LIBGSM_ENCODER 0
+#define CONFIG_LIBGSM_MS_ENCODER 0
+#define CONFIG_LIBMP3LAME_ENCODER 0
+#define CONFIG_LIBOPENCORE_AMRNB_ENCODER 0
+#define CONFIG_LIBSCHROEDINGER_ENCODER 0
+#define CONFIG_LIBTHEORA_ENCODER 0
+#define CONFIG_LIBVORBIS_ENCODER 0
+#define CONFIG_LIBVPX_ENCODER 0
+#define CONFIG_LIBX264_ENCODER 0
+#define CONFIG_LIBXAVS_ENCODER 0
+#define CONFIG_LIBXVID_ENCODER 0
+#define CONFIG_H263_VAAPI_HWACCEL 0
+#define CONFIG_H264_DXVA2_HWACCEL 0
+#define CONFIG_H264_VAAPI_HWACCEL 0
+#define CONFIG_MPEG2_DXVA2_HWACCEL 0
+#define CONFIG_MPEG2_VAAPI_HWACCEL 0
+#define CONFIG_MPEG4_VAAPI_HWACCEL 0
+#define CONFIG_VC1_DXVA2_HWACCEL 0
+#define CONFIG_VC1_VAAPI_HWACCEL 0
+#define CONFIG_WMV3_DXVA2_HWACCEL 0
+#define CONFIG_WMV3_VAAPI_HWACCEL 0
+#define CONFIG_AAC_PARSER 0
+#define CONFIG_AC3_PARSER 0
+#define CONFIG_CAVSVIDEO_PARSER 0
+#define CONFIG_DCA_PARSER 0
+#define CONFIG_DIRAC_PARSER 0
+#define CONFIG_DNXHD_PARSER 0
+#define CONFIG_DVBSUB_PARSER 0
+#define CONFIG_DVDSUB_PARSER 0
+#define CONFIG_H261_PARSER 0
+#define CONFIG_H263_PARSER 1
+#define CONFIG_H264_PARSER 0
+#define CONFIG_MJPEG_PARSER 0
+#define CONFIG_MLP_PARSER 0
+#define CONFIG_MPEG4VIDEO_PARSER 1
+#define CONFIG_MPEGAUDIO_PARSER 0
+#define CONFIG_MPEGVIDEO_PARSER 0
+#define CONFIG_PNM_PARSER 0
+#define CONFIG_VC1_PARSER 0
+#define CONFIG_VP3_PARSER 0
+#define CONFIG_VP8_PARSER 0
+#define CONFIG_AAC_ADTSTOASC_BSF 0
+#define CONFIG_CHOMP_BSF 0
+#define CONFIG_DUMP_EXTRADATA_BSF 0
+#define CONFIG_H264_MP4TOANNEXB_BSF 0
+#define CONFIG_IMX_DUMP_HEADER_BSF 0
+#define CONFIG_MJPEGA_DUMP_HEADER_BSF 0
+#define CONFIG_MP3_HEADER_COMPRESS_BSF 0
+#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0
+#define CONFIG_MOV2TEXTSUB_BSF 0
+#define CONFIG_NOISE_BSF 0
+#define CONFIG_REMOVE_EXTRADATA_BSF 0
+#define CONFIG_TEXT2MOVSUB_BSF 0
+#define CONFIG_AAC_DEMUXER 0
+#define CONFIG_AC3_DEMUXER 0
+#define CONFIG_AEA_DEMUXER 0
+#define CONFIG_AIFF_DEMUXER 0
+#define CONFIG_AMR_DEMUXER 0
+#define CONFIG_ANM_DEMUXER 0
+#define CONFIG_APC_DEMUXER 0
+#define CONFIG_APE_DEMUXER 0
+#define CONFIG_APPLEHTTP_DEMUXER 0
+#define CONFIG_ASF_DEMUXER 0
+#define CONFIG_ASS_DEMUXER 0
+#define CONFIG_AU_DEMUXER 0
+#define CONFIG_AVI_DEMUXER 0
+#define CONFIG_AVISYNTH_DEMUXER 0
+#define CONFIG_AVS_DEMUXER 0
+#define CONFIG_BETHSOFTVID_DEMUXER 0
+#define CONFIG_BFI_DEMUXER 0
+#define CONFIG_BINK_DEMUXER 0
+#define CONFIG_C93_DEMUXER 0
+#define CONFIG_CAF_DEMUXER 0
+#define CONFIG_CAVSVIDEO_DEMUXER 0
+#define CONFIG_CDG_DEMUXER 0
+#define CONFIG_DAUD_DEMUXER 0
+#define CONFIG_DIRAC_DEMUXER 0
+#define CONFIG_DNXHD_DEMUXER 0
+#define CONFIG_DSICIN_DEMUXER 0
+#define CONFIG_DTS_DEMUXER 0
+#define CONFIG_DV_DEMUXER 0
+#define CONFIG_DXA_DEMUXER 0
+#define CONFIG_EA_DEMUXER 0
+#define CONFIG_EA_CDATA_DEMUXER 0
+#define CONFIG_EAC3_DEMUXER 0
+#define CONFIG_FFM_DEMUXER 0
+#define CONFIG_FILMSTRIP_DEMUXER 0
+#define CONFIG_FLAC_DEMUXER 0
+#define CONFIG_FLIC_DEMUXER 0
+#define CONFIG_FLV_DEMUXER 0
+#define CONFIG_FOURXM_DEMUXER 0
+#define CONFIG_G722_DEMUXER 0
+#define CONFIG_GSM_DEMUXER 0
+#define CONFIG_GXF_DEMUXER 0
+#define CONFIG_H261_DEMUXER 0
+#define CONFIG_H263_DEMUXER 0
+#define CONFIG_H264_DEMUXER 0
+#define CONFIG_IDCIN_DEMUXER 0
+#define CONFIG_IFF_DEMUXER 0
+#define CONFIG_IMAGE2_DEMUXER 0
+#define CONFIG_IMAGE2PIPE_DEMUXER 0
+#define CONFIG_INGENIENT_DEMUXER 0
+#define CONFIG_IPMOVIE_DEMUXER 0
+#define CONFIG_ISS_DEMUXER 0
+#define CONFIG_IV8_DEMUXER 0
+#define CONFIG_IVF_DEMUXER 0
+#define CONFIG_LMLM4_DEMUXER 0
+#define CONFIG_M4V_DEMUXER 0
+#define CONFIG_MATROSKA_DEMUXER 0
+#define CONFIG_MJPEG_DEMUXER 0
+#define CONFIG_MLP_DEMUXER 0
+#define CONFIG_MM_DEMUXER 0
+#define CONFIG_MMF_DEMUXER 0
+#define CONFIG_MOV_DEMUXER 0
+#define CONFIG_MP3_DEMUXER 0
+#define CONFIG_MPC_DEMUXER 0
+#define CONFIG_MPC8_DEMUXER 0
+#define CONFIG_MPEGPS_DEMUXER 0
+#define CONFIG_MPEGTS_DEMUXER 0
+#define CONFIG_MPEGTSRAW_DEMUXER 0
+#define CONFIG_MPEGVIDEO_DEMUXER 0
+#define CONFIG_MSNWC_TCP_DEMUXER 0
+#define CONFIG_MTV_DEMUXER 0
+#define CONFIG_MVI_DEMUXER 0
+#define CONFIG_MXF_DEMUXER 0
+#define CONFIG_NC_DEMUXER 0
+#define CONFIG_NSV_DEMUXER 0
+#define CONFIG_NUT_DEMUXER 0
+#define CONFIG_NUV_DEMUXER 0
+#define CONFIG_OGG_DEMUXER 0
+#define CONFIG_OMA_DEMUXER 0
+#define CONFIG_PCM_ALAW_DEMUXER 0
+#define CONFIG_PCM_MULAW_DEMUXER 0
+#define CONFIG_PCM_F64BE_DEMUXER 0
+#define CONFIG_PCM_F64LE_DEMUXER 0
+#define CONFIG_PCM_F32BE_DEMUXER 0
+#define CONFIG_PCM_F32LE_DEMUXER 0
+#define CONFIG_PCM_S32BE_DEMUXER 0
+#define CONFIG_PCM_S32LE_DEMUXER 0
+#define CONFIG_PCM_S24BE_DEMUXER 0
+#define CONFIG_PCM_S24LE_DEMUXER 0
+#define CONFIG_PCM_S16BE_DEMUXER 0
+#define CONFIG_PCM_S16LE_DEMUXER 0
+#define CONFIG_PCM_S8_DEMUXER 0
+#define CONFIG_PCM_U32BE_DEMUXER 0
+#define CONFIG_PCM_U32LE_DEMUXER 0
+#define CONFIG_PCM_U24BE_DEMUXER 0
+#define CONFIG_PCM_U24LE_DEMUXER 0
+#define CONFIG_PCM_U16BE_DEMUXER 0
+#define CONFIG_PCM_U16LE_DEMUXER 0
+#define CONFIG_PCM_U8_DEMUXER 0
+#define CONFIG_PVA_DEMUXER 0
+#define CONFIG_QCP_DEMUXER 0
+#define CONFIG_R3D_DEMUXER 0
+#define CONFIG_RAWVIDEO_DEMUXER 0
+#define CONFIG_RL2_DEMUXER 0
+#define CONFIG_RM_DEMUXER 0
+#define CONFIG_ROQ_DEMUXER 0
+#define CONFIG_RPL_DEMUXER 0
+#define CONFIG_RSO_DEMUXER 0
+#define CONFIG_RTSP_DEMUXER 0
+#define CONFIG_SDP_DEMUXER 0
+#define CONFIG_SEGAFILM_DEMUXER 0
+#define CONFIG_SHORTEN_DEMUXER 0
+#define CONFIG_SIFF_DEMUXER 0
+#define CONFIG_SMACKER_DEMUXER 0
+#define CONFIG_SOL_DEMUXER 0
+#define CONFIG_SOX_DEMUXER 0
+#define CONFIG_SRT_DEMUXER 0
+#define CONFIG_STR_DEMUXER 0
+#define CONFIG_SWF_DEMUXER 0
+#define CONFIG_THP_DEMUXER 0
+#define CONFIG_TIERTEXSEQ_DEMUXER 0
+#define CONFIG_TMV_DEMUXER 0
+#define CONFIG_TRUEHD_DEMUXER 0
+#define CONFIG_TTA_DEMUXER 0
+#define CONFIG_TXD_DEMUXER 0
+#define CONFIG_TTY_DEMUXER 0
+#define CONFIG_VC1_DEMUXER 0
+#define CONFIG_VC1T_DEMUXER 0
+#define CONFIG_VMD_DEMUXER 0
+#define CONFIG_VOC_DEMUXER 0
+#define CONFIG_VQF_DEMUXER 0
+#define CONFIG_W64_DEMUXER 0
+#define CONFIG_WAV_DEMUXER 0
+#define CONFIG_WC3_DEMUXER 0
+#define CONFIG_WSAUD_DEMUXER 0
+#define CONFIG_WSVQA_DEMUXER 0
+#define CONFIG_WV_DEMUXER 0
+#define CONFIG_XA_DEMUXER 0
+#define CONFIG_YOP_DEMUXER 0
+#define CONFIG_YUV4MPEGPIPE_DEMUXER 0
+#define CONFIG_LIBNUT_DEMUXER 0
+#define CONFIG_A64_MUXER 0
+#define CONFIG_AC3_MUXER 0
+#define CONFIG_ADTS_MUXER 0
+#define CONFIG_AIFF_MUXER 0
+#define CONFIG_AMR_MUXER 0
+#define CONFIG_ASF_MUXER 0
+#define CONFIG_ASS_MUXER 0
+#define CONFIG_ASF_STREAM_MUXER 0
+#define CONFIG_AU_MUXER 0
+#define CONFIG_AVI_MUXER 0
+#define CONFIG_AVM2_MUXER 0
+#define CONFIG_CAVSVIDEO_MUXER 0
+#define CONFIG_CRC_MUXER 0
+#define CONFIG_DAUD_MUXER 0
+#define CONFIG_DIRAC_MUXER 0
+#define CONFIG_DNXHD_MUXER 0
+#define CONFIG_DTS_MUXER 0
+#define CONFIG_DV_MUXER 0
+#define CONFIG_EAC3_MUXER 0
+#define CONFIG_FFM_MUXER 0
+#define CONFIG_FILMSTRIP_MUXER 0
+#define CONFIG_FLAC_MUXER 0
+#define CONFIG_FLV_MUXER 0
+#define CONFIG_FRAMECRC_MUXER 0
+#define CONFIG_FRAMEMD5_MUXER 0
+#define CONFIG_G722_MUXER 0
+#define CONFIG_GIF_MUXER 0
+#define CONFIG_GXF_MUXER 0
+#define CONFIG_H261_MUXER 0
+#define CONFIG_H263_MUXER 0
+#define CONFIG_H264_MUXER 0
+#define CONFIG_IMAGE2_MUXER 0
+#define CONFIG_IMAGE2PIPE_MUXER 0
+#define CONFIG_IPOD_MUXER 0
+#define CONFIG_M4V_MUXER 0
+#define CONFIG_MD5_MUXER 0
+#define CONFIG_MATROSKA_MUXER 0
+#define CONFIG_MATROSKA_AUDIO_MUXER 0
+#define CONFIG_MJPEG_MUXER 0
+#define CONFIG_MLP_MUXER 0
+#define CONFIG_MMF_MUXER 0
+#define CONFIG_MOV_MUXER 0
+#define CONFIG_MP2_MUXER 0
+#define CONFIG_MP3_MUXER 0
+#define CONFIG_MP4_MUXER 0
+#define CONFIG_MPEG1SYSTEM_MUXER 0
+#define CONFIG_MPEG1VCD_MUXER 0
+#define CONFIG_MPEG1VIDEO_MUXER 0
+#define CONFIG_MPEG2DVD_MUXER 0
+#define CONFIG_MPEG2SVCD_MUXER 0
+#define CONFIG_MPEG2VIDEO_MUXER 0
+#define CONFIG_MPEG2VOB_MUXER 0
+#define CONFIG_MPEGTS_MUXER 0
+#define CONFIG_MPJPEG_MUXER 0
+#define CONFIG_MXF_MUXER 0
+#define CONFIG_MXF_D10_MUXER 0
+#define CONFIG_NULL_MUXER 0
+#define CONFIG_NUT_MUXER 0
+#define CONFIG_OGG_MUXER 0
+#define CONFIG_PCM_ALAW_MUXER 0
+#define CONFIG_PCM_MULAW_MUXER 0
+#define CONFIG_PCM_F64BE_MUXER 0
+#define CONFIG_PCM_F64LE_MUXER 0
+#define CONFIG_PCM_F32BE_MUXER 0
+#define CONFIG_PCM_F32LE_MUXER 0
+#define CONFIG_PCM_S32BE_MUXER 0
+#define CONFIG_PCM_S32LE_MUXER 0
+#define CONFIG_PCM_S24BE_MUXER 0
+#define CONFIG_PCM_S24LE_MUXER 0
+#define CONFIG_PCM_S16BE_MUXER 0
+#define CONFIG_PCM_S16LE_MUXER 0
+#define CONFIG_PCM_S8_MUXER 0
+#define CONFIG_PCM_U32BE_MUXER 0
+#define CONFIG_PCM_U32LE_MUXER 0
+#define CONFIG_PCM_U24BE_MUXER 0
+#define CONFIG_PCM_U24LE_MUXER 0
+#define CONFIG_PCM_U16BE_MUXER 0
+#define CONFIG_PCM_U16LE_MUXER 0
+#define CONFIG_PCM_U8_MUXER 0
+#define CONFIG_PSP_MUXER 0
+#define CONFIG_RAWVIDEO_MUXER 0
+#define CONFIG_RM_MUXER 0
+#define CONFIG_ROQ_MUXER 0
+#define CONFIG_RSO_MUXER 0
+#define CONFIG_RTP_MUXER 0
+#define CONFIG_RTSP_MUXER 0
+#define CONFIG_SOX_MUXER 0
+#define CONFIG_SPDIF_MUXER 0
+#define CONFIG_SRT_MUXER 0
+#define CONFIG_SWF_MUXER 0
+#define CONFIG_TG2_MUXER 0
+#define CONFIG_TGP_MUXER 0
+#define CONFIG_TRUEHD_MUXER 0
+#define CONFIG_VC1T_MUXER 0
+#define CONFIG_VOC_MUXER 0
+#define CONFIG_WAV_MUXER 0
+#define CONFIG_WEBM_MUXER 0
+#define CONFIG_YUV4MPEGPIPE_MUXER 0
+#define CONFIG_LIBNUT_MUXER 0
+#define CONFIG_ANULL_FILTER 0
+#define CONFIG_ANULLSRC_FILTER 0
+#define CONFIG_ANULLSINK_FILTER 0
+#define CONFIG_ASPECT_FILTER 0
+#define CONFIG_BLACKFRAME_FILTER 0
+#define CONFIG_CROP_FILTER 0
+#define CONFIG_DRAWBOX_FILTER 0
+#define CONFIG_FIFO_FILTER 0
+#define CONFIG_FORMAT_FILTER 0
+#define CONFIG_FREI0R_FILTER 0
+#define CONFIG_HFLIP_FILTER 0
+#define CONFIG_NOFORMAT_FILTER 0
+#define CONFIG_NULL_FILTER 0
+#define CONFIG_OCV_SMOOTH_FILTER 0
+#define CONFIG_PAD_FILTER 0
+#define CONFIG_PIXDESCTEST_FILTER 0
+#define CONFIG_PIXELASPECT_FILTER 0
+#define CONFIG_SCALE_FILTER 0
+#define CONFIG_SLICIFY_FILTER 0
+#define CONFIG_UNSHARP_FILTER 0
+#define CONFIG_VFLIP_FILTER 0
+#define CONFIG_YADIF_FILTER 0
+#define CONFIG_BUFFER_FILTER 0
+#define CONFIG_COLOR_FILTER 0
+#define CONFIG_NULLSRC_FILTER 0
+#define CONFIG_NULLSINK_FILTER 0
+#define CONFIG_CONCAT_PROTOCOL 0
+#define CONFIG_FILE_PROTOCOL 0
+#define CONFIG_GOPHER_PROTOCOL 0
+#define CONFIG_HTTP_PROTOCOL 0
+#define CONFIG_MMSH_PROTOCOL 0
+#define CONFIG_MMST_PROTOCOL 0
+#define CONFIG_MD5_PROTOCOL 0
+#define CONFIG_PIPE_PROTOCOL 0
+#define CONFIG_RTMP_PROTOCOL 0
+#define CONFIG_RTMPT_PROTOCOL 0
+#define CONFIG_RTMPE_PROTOCOL 0
+#define CONFIG_RTMPTE_PROTOCOL 0
+#define CONFIG_RTMPS_PROTOCOL 0
+#define CONFIG_RTP_PROTOCOL 0
+#define CONFIG_TCP_PROTOCOL 0
+#define CONFIG_UDP_PROTOCOL 0
+#define CONFIG_ALSA_INDEV 0
+#define CONFIG_BKTR_INDEV 0
+#define CONFIG_DV1394_INDEV 0
+#define CONFIG_JACK_INDEV 0
+#define CONFIG_OSS_INDEV 0
+#define CONFIG_V4L2_INDEV 0
+#define CONFIG_V4L_INDEV 0
+#define CONFIG_VFWCAP_INDEV 0
+#define CONFIG_X11_GRAB_DEVICE_INDEV 0
+#define CONFIG_LIBDC1394_INDEV 0
+#define CONFIG_ALSA_OUTDEV 0
+#define CONFIG_OSS_OUTDEV 0
+#endif /* FFMPEG_CONFIG_H */
diff --git a/submodules/externals/build/ffmpeg/libavutil/avconfig.h b/submodules/externals/build/ffmpeg/libavutil/avconfig.h
new file mode 100644
index 000000000..f10aa6186
--- /dev/null
+++ b/submodules/externals/build/ffmpeg/libavutil/avconfig.h
@@ -0,0 +1,6 @@
+/* Generated by ffconf */
+#ifndef AVUTIL_AVCONFIG_H
+#define AVUTIL_AVCONFIG_H
+#define AV_HAVE_BIGENDIAN 0
+#define AV_HAVE_FAST_UNALIGNED 1
+#endif /* AVUTIL_AVCONFIG_H */
diff --git a/submodules/externals/build/speex/Android.mk b/submodules/externals/build/speex/Android.mk
index e661e838e..1836b4f36 100644
--- a/submodules/externals/build/speex/Android.mk
+++ b/submodules/externals/build/speex/Android.mk
@@ -66,11 +66,33 @@ LOCAL_SRC_FILES := \
$(libspeexdsp_SRC_FILES)
# -DARM4_ASM
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_CFLAGS +=\
- -DARM5E_ASM \
+
+
+USE_FLOAT=0
+
+FIXED_POINT_FLAGS=\
+ -DARM5E_ASM\
-DDISABLE_FLOAT_API \
-DFIXED_POINT=1
+
+ifeq ($(TARGET_ARCH),arm)
+ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+ ifeq ($(USE_FLOAT),1)
+ LOCAL_CFLAGS += -DFLOATING_POINT=1
+ LOCAL_CFLAGS += -DOVERRIDE_INTERPOLATE_PRODUCT_SINGLE
+ ifeq ($(LINPHONE_VIDEO),1)
+ LOCAL_CFLAGS += -DOVERRIDE_INNER_PRODUCT_SINGLE -Dinner_product_single=ff_scalarproduct_float_neon
+ endif
+ else
+ LOCAL_CFLAGS += $(FIXED_POINT_FLAGS)
+ LOCAL_CFLAGS += -DOVERRIDE_INTERPOLATE_PRODUCT_SINGLE -Dinterpolate_product_single=interpolate_product_single_int
+ ifeq ($(LINPHONE_VIDEO),1)
+ LOCAL_CFLAGS += -DOVERRIDE_INNER_PRODUCT_SINGLE -Dinner_product_single=ff_scalarproduct_int16_neon
+ endif
+ endif
+ else
+ LOCAL_CFLAGS += $(FIXED_POINT_FLAGS)
+ endif
else
LOCAL_CFLAGS += \
-DFLOATING_POINT=1
diff --git a/submodules/externals/build/speex/speex/speex_config_types.h b/submodules/externals/build/speex/speex/speex_config_types.h
index bd548546b..0c9eed695 100644
--- a/submodules/externals/build/speex/speex/speex_config_types.h
+++ b/submodules/externals/build/speex/speex/speex_config_types.h
@@ -7,5 +7,13 @@ typedef unsigned short spx_uint16_t;
typedef int spx_int32_t;
typedef unsigned int spx_uint32_t;
+extern float ff_scalarproduct_float_neon (const float *v1, const float *v2, int len);
+
+#ifndef FIXED_POINT
+extern float interpolate_product_single(const float *a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac);
+#else
+extern int interpolate_product_single_int(const spx_int16_t *a, const spx_int16_t *b, unsigned int len, const spx_uint32_t oversample, spx_int16_t *frac);
+#endif
+
#endif
diff --git a/submodules/externals/build/x264/Android.mk b/submodules/externals/build/x264/Android.mk
new file mode 100644
index 000000000..2943c71b1
--- /dev/null
+++ b/submodules/externals/build/x264/Android.mk
@@ -0,0 +1,61 @@
+#
+# List of compiled files and related options obtained using
+# ./configure --cross-prefix=arm-none-linux-gnueabi- --host=arm-none-linux-gnueabi --disable-pthread --enable-pic
+# && make
+#
+
+LOCAL_PATH:= $(call my-dir)/../../x264
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libx264
+
+LOCAL_SRC_FILES = \
+ common/mc.c \
+ common/predict.c \
+ common/pixel.c \
+ common/macroblock.c \
+ common/frame.c \
+ common/dct.c \
+ common/cpu.c \
+ common/cabac.c \
+ common/common.c \
+ common/mdate.c \
+ common/rectangle.c \
+ common/set.c \
+ common/quant.c \
+ common/deblock.c \
+ common/vlc.c \
+ common/mvpred.c \
+ common/bitstream.c \
+ encoder/analyse.c \
+ encoder/me.c \
+ encoder/ratecontrol.c \
+ encoder/set.c \
+ encoder/macroblock.c \
+ encoder/cabac.c \
+ encoder/cavlc.c \
+ encoder/encoder.c \
+ encoder/lookahead.c \
+ common/arm/mc-c.c \
+ common/arm/predict-c.c \
+ common/arm/cpu-a.S \
+ common/arm/pixel-a.S \
+ common/arm/mc-a.S \
+ common/arm/dct-a.S \
+ common/arm/quant-a.S \
+ common/arm/deblock-a.S \
+ common/arm/predict-a.S
+
+
+LOCAL_ARM_MODE := arm
+
+
+LOCAL_CFLAGS += -DPIC -DBIT_DEPTH=8 -std=gnu99
+
+#for including config.h:
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/../build/x264 \
+ $(LOCAL_PATH)/
+
+include $(BUILD_STATIC_LIBRARY)
+
diff --git a/submodules/externals/build/x264/config.h b/submodules/externals/build/x264/config.h
new file mode 100644
index 000000000..9e532298c
--- /dev/null
+++ b/submodules/externals/build/x264/config.h
@@ -0,0 +1,24 @@
+#define HAVE_MALLOC_H 1
+#define HAVE_ARMV6 1
+#define HAVE_ARMV6T2 1
+#define HAVE_NEON 1
+#define ARCH_ARM 1
+#define SYS_LINUX 1
+#define HAVE_LOG2F 0
+#define fseek fseeko
+#define ftell ftello
+#define BIT_DEPTH 8
+#define HAVE_GPL 1
+#define HAVE_ALTIVEC 0
+#define HAVE_ALTIVEC_H 0
+#define HAVE_MMX 0
+#define HAVE_PTHREAD 0
+#define HAVE_VISUALIZE 0
+#define HAVE_SWSCALE 0
+#define HAVE_LAVF 0
+#define HAVE_FFMS 0
+#define HAVE_GPAC 0
+#define HAVE_GF_MALLOC 0
+#define HAVE_AVS 0
+#define X264_VERSION " r1804 e89c4cf"
+#define X264_POINTVER "0.110.1804 e89c4cf"
diff --git a/submodules/externals/ffmpeg b/submodules/externals/ffmpeg
new file mode 160000
index 000000000..76393d0b7
--- /dev/null
+++ b/submodules/externals/ffmpeg
@@ -0,0 +1 @@
+Subproject commit 76393d0b78fd47857fd7bd27756945c1bb021efd
diff --git a/submodules/externals/libswscale b/submodules/externals/libswscale
new file mode 160000
index 000000000..e75b939d4
--- /dev/null
+++ b/submodules/externals/libswscale
@@ -0,0 +1 @@
+Subproject commit e75b939d479ce8120d2d30d7275849e3377a990e
diff --git a/submodules/externals/x264 b/submodules/externals/x264
new file mode 160000
index 000000000..e89c4cfc9
--- /dev/null
+++ b/submodules/externals/x264
@@ -0,0 +1 @@
+Subproject commit e89c4cfc9f37d0b7684507974b333545b5bcc37a
diff --git a/submodules/linphone b/submodules/linphone
index b75917753..6ff25215b 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit b75917753c938bf3df327dc6acee2618e8d57076
+Subproject commit 6ff25215befafa58466eea541beae27d2d685e7f
diff --git a/submodules/msx264 b/submodules/msx264
new file mode 160000
index 000000000..52e11ce34
--- /dev/null
+++ b/submodules/msx264
@@ -0,0 +1 @@
+Subproject commit 52e11ce3436eab7a8a344d34bef564ff2a9d0a6e