libavcodec \
libswscale \
libavcore \
- libavutil
+ libavutil \
+ libmsx264 \
+ libx264
+
endif
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([linphone],[3.3.99.9],[linphone-developers@nongnu.org])
+AC_INIT([linphone],[3.3.99.10],[linphone-developers@nongnu.org])
AC_CANONICAL_SYSTEM
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details);
+static bool_t media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd){
+ return !sal_media_description_equals(oldmd,newmd) || call->up_bw!=linphone_core_get_upload_bandwidth(call->core);
+}
+
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
SalMediaDescription *oldmd=call->resultdesc;
if (call->audiostream && call->audiostream->ticker){
/* we already started media: check if we really need to restart it*/
if (oldmd){
- if (sal_media_description_equals(oldmd,new_md) && !call->playing_ringbacktone){
+ if (!media_parameters_changed(call,oldmd,new_md) && !call->playing_ringbacktone){
sal_media_description_unref(oldmd);
if (call->all_muted){
ms_message("Early media finished, unmuting inputs...");
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
-INPUT = . ../
+INPUT = @top_srcdir@/coreapi @top_srcdir@/coreapi/help
FILE_PATTERNS = *.h \
*.c \
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
-EXAMPLE_PATH = ../../ .
+EXAMPLE_PATH = @top_srcdir@ @top_srcdir@/coreapi/help
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
clean-local:
rm -rf doc
+#tutorials
+
noinst_PROGRAMS=helloworld registration buddy_status chatroom
helloworld_SOURCES=helloworld.c
+LINPHONE_TUTOS=$(helloworld_SOURCES)
helloworld_LDADD=$(top_builddir)/coreapi/liblinphone.la \
$(MEDIASTREAMER_LIBS) \
$(ORTP_LIBS)
registration_SOURCES=registration.c
+LINPHONE_TUTOS+=$(registration_SOURCES)
registration_LDADD=$(helloworld_LDADD)
buddy_status_SOURCES=buddy_status.c
+LINPHONE_TUTOS+=$(buddy_status_SOURCES)
buddy_status_LDADD=$(helloworld_LDADD)
chatroom_SOURCES=chatroom.c
+LINPHONE_TUTOS+=$(chatroom_SOURCES)
chatroom_LDADD=$(helloworld_LDADD)
-DORTP_INET6 \
$(VIDEO_CFLAGS)
+
+tutodir=$(datadir)/tutorials/linphone
+
+tuto_DATA=$(LINPHONE_TUTOS)
#endif
-static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, bool_t only_one_codec){
+static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){
MSList *l=NULL;
const MSList *it;
for(it=codecs;it!=NULL;it=it->next){
PayloadType *pt=(PayloadType*)it->data;
- if ((pt->flags & PAYLOAD_TYPE_ENABLED) && linphone_core_check_payload_type_usability(lc,pt)){
- l=ms_list_append(l,payload_type_clone(pt));
- if (only_one_codec) break;
+ if (pt->flags & PAYLOAD_TYPE_ENABLED){
+ if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){
+ ms_message("Codec %s/%i eliminated because of audio bandwidth constraint.",pt->mime_type,pt->clock_rate);
+ continue;
+ }
+ if (linphone_core_check_payload_type_usability(lc,pt)){
+ l=ms_list_append(l,payload_type_clone(pt));
+ }
}
}
return l;
}
-SalMediaDescription *create_local_media_description(LinphoneCore *lc,
- LinphoneCall *call, bool_t with_video, bool_t only_one_codec){
+SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
MSList *l;
PayloadType *pt;
const char *me=linphone_core_get_identity(lc);
md->streams[0].proto=SalProtoRtpAvp;
md->streams[0].type=SalAudio;
md->streams[0].ptime=lc->net_conf.down_ptime;
- l=make_codec_list(lc,lc->codecs_conf.audio_codecs,only_one_codec);
+ l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw);
pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
l=ms_list_append(l,pt);
md->streams[0].payloads=l;
if (lc->dw_audio_bw>0)
md->streams[0].bandwidth=lc->dw_audio_bw;
- if (with_video){
+ if (call->params.has_video){
md->nstreams++;
md->streams[1].port=call->video_port;
md->streams[1].proto=SalProtoRtpAvp;
md->streams[1].type=SalVideo;
- l=make_codec_list(lc,lc->codecs_conf.video_codecs,only_one_codec);
+ l=make_codec_list(lc,lc->codecs_conf.video_codecs,0);
md->streams[1].payloads=l;
if (lc->dw_video_bw)
md->streams[1].bandwidth=lc->dw_video_bw;
linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
linphone_call_init_common(call,from,to);
call->params=*params;
- call->localdesc=create_local_media_description (lc,call,params->has_video,FALSE);
+ call->localdesc=create_local_media_description (lc,call);
call->camera_active=params->has_video;
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
linphone_core_run_stun_tests(call->core,call);
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
linphone_call_init_common(call, from, to);
call->params.has_video=linphone_core_video_enabled(lc);
- call->localdesc=create_local_media_description (lc,call,
- call->params.has_video,lc->sip_conf.only_one_codec);
+ call->localdesc=create_local_media_description (lc,call);
call->camera_active=call->params.has_video;
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
linphone_core_run_stun_tests(call->core,call);
return cp->real_early_media;
}
+/**
+ * Refine bandwidth settings for this call by setting a bandwidth limit for audio streams.
+ * As a consequence, codecs whose bitrates are not compatible with this limit won't be used.
+**/
+void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bandwidth){
+ cp->audio_bw=bandwidth;
+}
+
/**
*
**/
#endif
call->all_muted=all_inputs_muted;
call->playing_ringbacktone=send_ringbacktone;
+ call->up_bw=linphone_core_get_upload_bandwidth(lc);
goto end;
end:
sal_use_session_timers(lc->sal,200);
}
-
tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
linphone_core_set_use_rfc2833_for_dtmf(lc,tmp);
break;
}
}
-
-
-
-
- lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
/*for tuning or test*/
lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
- lc->sip_conf.only_one_codec=lp_config_get_int(lc->config,"sip","only_one_codec",0);
lc->sip_conf.register_only_when_network_is_up=
lp_config_get_int(lc->config,"sip","register_only_when_network_is_up",1);
lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1);
lc->sip_conf.auto_net_state_mon=lp_config_get_int(lc->config,"sip","auto_net_state_mon",1);
lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
+ sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
}
static void rtp_config_read(LinphoneCore *lc)
if (call->localdesc)
sal_media_description_unref(call->localdesc);
- call->localdesc=create_local_media_description (lc,call,
- params->has_video,FALSE);
+ call->params=*params;
+ call->localdesc=create_local_media_description (lc,call);
call->camera_active=params->has_video;
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Modifying call parameters..."));
{ {MS_VIDEO_SIZE_VGA_W,MS_VIDEO_SIZE_VGA_H} , "vga" },
{ {MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H} , "cif" },
{ {MS_VIDEO_SIZE_QVGA_W,MS_VIDEO_SIZE_QVGA_H} , "qvga" },
+ { {MS_VIDEO_SIZE_QVGA_H,MS_VIDEO_SIZE_QVGA_W} , "qvga-portrait" },
{ {MS_VIDEO_SIZE_QCIF_W,MS_VIDEO_SIZE_QCIF_H} , "qcif" },
+ { {MS_VIDEO_SIZE_QCIF_H,MS_VIDEO_SIZE_QCIF_W} , "qcif-portrait" },
{ {0,0} , NULL }
};
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
+void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
void linphone_call_params_destroy(LinphoneCallParams *cp);
/**
#ifdef ANDROID
#include <android/log.h>
extern "C" void libmsilbc_init();
+extern "C" void libmsx264_init();
#endif /*ANDROID*/
extern "C" void ms_andsnd_set_jvm(JavaVM *jvm) ;
#ifdef ANDROID
ms_andsnd_set_jvm(ajvm);
#ifdef VIDEO_ENABLED
- ms_andvid_set_jvm(ajvm);
+ ms_andvid_set_jvm(ajvm);
#endif /*VIDEO_ENABLED*/
#endif /*ANDROID*/
jvm=ajvm;
#ifdef HAVE_ILBC
libmsilbc_init(); // requires an fpu
+#endif
+#ifdef VIDEO_ENABLED
+ libmsx264_init();
#endif
jlong nativePtr = (jlong)linphone_core_new( &ldata->vTable
,userConfig
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateCall(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
}
+
+
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc, jint width, jint height){
+ MSVideoSize vsize;
+ vsize.width = (int)width;
+ vsize.height = (int)height;
+ linphone_core_set_preferred_video_size((LinphoneCore *)lc, vsize);
+}
+
+extern "C" jintArray Java_org_linphone_core_LinphoneCoreImpl_getPreferredVideoSize(JNIEnv *env, jobject thiz, jlong lc){
+ MSVideoSize vsize = linphone_core_get_preferred_video_size((LinphoneCore *)lc);
+ jintArray arr = env->NewIntArray(2);
+ int tVsize [2]= {vsize.width,vsize.height};
+ env->SetIntArrayRegion(arr, 0, 2, tVsize);
+ return arr;
+}
+
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
+ linphone_core_set_download_bandwidth((LinphoneCore *)lc, (int) bw);
+}
+
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
+ linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw);
+}
+
}
}
+bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit)
+{
+ double codec_band;
+ bool_t ret=FALSE;
+
+ switch (pt->type){
+ case PAYLOAD_AUDIO_CONTINUOUS:
+ case PAYLOAD_AUDIO_PACKETIZED:
+ codec_band=get_audio_payload_bandwidth(lc,pt);
+ ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band);
+ /*hack to avoid using uwb codecs when having low bitrate and video*/
+ if (bandwidth_is_greater(199,bandwidth_limit)){
+ if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){
+ ret=FALSE;
+ }
+ }
+ //ms_message("Payload %s: %g",pt->mime_type,codec_band);
+ break;
+ case PAYLOAD_VIDEO:
+ if (bandwidth_limit!=0) {/* infinite (-1) or strictly positive*/
+ /*let the video use all the bandwidth minus the maximum bandwidth used by audio */
+ if (bandwidth_limit>0)
+ pt->normal_bitrate=bandwidth_limit*1000;
+ else
+ pt->normal_bitrate=1500000; /*around 1.5 Mbit/s*/
+ ret=TRUE;
+ }
+ else ret=FALSE;
+ break;
+ }
+ return ret;
+}
+
/* return TRUE if codec can be used with bandwidth, FALSE else*/
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt)
{
#include "sal.h"
#include "offeranswer.h"
+static bool_t only_telephone_event(const MSList *l){
+ PayloadType *p=(PayloadType*)l->data;
+ if (strcasecmp(p->mime_type,"telephone-event")!=0){
+ return FALSE;
+ }
+ return TRUE;
+}
static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){
PayloadType *pt;
return candidate;
}
-static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response){
+static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
const MSList *e2;
MSList *res=NULL;
PayloadType *matched;
+ bool_t found_codec=FALSE;
+
for(e2=remote;e2!=NULL;e2=e2->next){
PayloadType *p2=(PayloadType*)e2->data;
matched=find_payload_type_best_match(local,p2);
PayloadType *newp;
int local_number=payload_type_get_number(matched);
int remote_number=payload_type_get_number(p2);
+
+ if (one_matching_codec){
+ if (strcasecmp(matched->mime_type,"telephone-event")!=0){
+ if (found_codec){/* we have found a real codec already*/
+ continue; /*this codec won't be added*/
+ }else found_codec=TRUE;
+ }
+ }
newp=payload_type_clone(matched);
if (p2->send_fmtp)
return res;
}
-static bool_t only_telephone_event(const MSList *l){
- PayloadType *p=(PayloadType*)l->data;
- if (strcasecmp(p->mime_type,"telephone-event")!=0){
- return FALSE;
- }
- return TRUE;
-}
+
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
SalStreamDir res=local;
const SalStreamDescription *remote_answer,
SalStreamDescription *result){
if (remote_answer->port!=0)
- result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE);
+ result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
result->proto=local_offer->proto;
result->type=local_offer->type;
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
static void initiate_incoming(const SalStreamDescription *local_cap,
const SalStreamDescription *remote_offer,
- SalStreamDescription *result){
- result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE);
+ SalStreamDescription *result, bool_t one_matching_codec){
+ result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
result->proto=local_cap->proto;
result->type=local_cap->type;
if (remote_offer->dir==SalStreamSendOnly)
**/
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
const SalMediaDescription *remote_offer,
- SalMediaDescription *result){
+ SalMediaDescription *result, bool_t one_matching_codec){
int i,j;
const SalStreamDescription *ls,*rs;
ms_message("Processing for stream %i",i);
ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
if (ls){
- initiate_incoming(ls,rs,&result->streams[j]);
+ initiate_incoming(ls,rs,&result->streams[j],one_matching_codec);
++j;
}
}
**/
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
const SalMediaDescription *remote_offer,
- SalMediaDescription *result);
+ SalMediaDescription *result, bool_t one_matching_codec);
#endif
struct _LinphoneCallParams{
LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
+ int audio_bw; /* bandwidth limit for audio stream */
bool_t has_video;
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
bool_t pad[2];
struct _VideoStream *videostream;
char *refer_to;
LinphoneCallParams params;
+ int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
bool_t refer_pending;
bool_t media_pending;
bool_t audio_muted;
bool_t loopback_only;
bool_t ipv6_enabled;
bool_t sdp_200_ack;
- bool_t only_one_codec; /*in SDP answers*/
bool_t register_only_when_network_is_up;
bool_t ping_with_options;
bool_t auto_net_state_mon;
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
-SalMediaDescription *create_local_media_description(LinphoneCore *lc,
- LinphoneCall *call, bool_t with_video, bool_t only_one_codec);
+SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
+
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
+
+bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, PayloadType *pt, int bandwidth_limit);
+
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
void _linphone_core_configure_resolver();
/*keepalive period in ms*/
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
void sal_use_session_timers(Sal *ctx, int expires);
+void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
int sal_iterate(Sal *sal);
MSList * sal_get_pending_auths(Sal *sal);
ctx->session_expires=expires;
}
+void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
+ ctx->one_matching_codec=one_matching_codec;
+}
+
MSList *sal_get_pending_auths(Sal *sal){
return ms_list_copy(sal->pending_auths);
}
offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
}else{
int i;
- offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
+ offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
h->sdp_answer=media_description_to_sdp(h->result);
strcpy(h->result->addr,h->base.remote_media->addr);
h->result->bandwidth=h->base.remote_media->bandwidth;
osip_message_t *reinvite=NULL;
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
return -1;
- osip_message_set_subject(reinvite,osip_strdup("Phone Call Hold"));
+ osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
if (h->base.root->session_expires!=0){
osip_message_set_header(reinvite, "Session-expires", "200");
int session_expires;
int keepalive_period;
void *up;
+ bool_t one_matching_codec;
};
struct SalOp{
static gboolean first_time=TRUE;
unsigned long id;
static unsigned long previd=0;
+ static unsigned long preview_previd=0;
static gboolean in_iterate=FALSE;
/*avoid reentrancy*/
w=gdk_window_foreign_new(id);
#else
w=gdk_window_foreign_new((HANDLE)id);
+#endif
+ if (w) {
+ set_video_window_decorations(w);
+ g_object_unref(G_OBJECT(w));
+ }
+ else ms_error("gdk_window_foreign_new() failed");
+ if (video_needs_update) video_needs_update=FALSE;
+ }
+ }
+ id=linphone_core_get_native_preview_window_id (lc);
+ if (id!=preview_previd ){
+ GdkWindow *w;
+ preview_previd=id;
+ if (id!=0){
+ ms_message("Updating window decorations for preview");
+#ifndef WIN32
+ w=gdk_window_foreign_new(id);
+#else
+ w=gdk_window_foreign_new((HANDLE)id);
#endif
if (w) {
set_video_window_decorations(w);
* Call end
*/
public final static State CallEnd = new State(13,"CallEnd");
+
/**
* Paused by remote
*/
public final static State PausedByRemote = new State(14,"PausedByRemote");
+
+ /**
+ * The call's parameters are updated, used for example when video is asked by remote
+ */
+ public static final State CallUpdatedByRemote = new State(15, "CallUpdatedByRemote");
+
+ /**
+ * We are proposing early media to an incoming call
+ */
+ public static final State CallIncomingEarlyMedia = new State(16,"CallIncomingEarlyMedia");
+
+ /**
+ * The remote accepted the call update initiated by us
+ */
+ public static final State CallUpdated = new State(17, "CallUpdated");
+
+
private State(int value,String stringValue) {
mValue = value;
values.addElement(this);
*
*/
public interface LinphoneCallParams {
- void setVideoEnalbled(boolean b);
+ void setVideoEnabled(boolean b);
boolean getVideoEnabled();
LinphoneCallParams copy();
}
* @param network state
*
*/
- public void setNetworkStateReachable(boolean isReachable);
+ public void setNetworkReachable(boolean isReachable);
+ /**
+ *
+ * @return if false, there is no network connection.
+ */
+ public boolean isNetworkReachable();
/**
* destroy linphone core and free all underlying resources
*/
* @param null if not set
*/
public String getRing();
+ public void setUploadBandwidth(int bw);
+
+ public void setDownloadBandwidth(int bw);
+
+ public void setPreferredVideoSize(VideoSize vSize);
+
+ public VideoSize getPreferredVideoSize();
}
--- /dev/null
+/*
+VideoSize.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;
+
+/**
+ * @author Guillaume Beraudo
+ */
+public final class VideoSize {
+ public static final int QCIF = 0;
+ public static final int CIF = 1;
+ public static final int HVGA = 2;
+
+ private int width;
+ public int getWidth() {return width;}
+ public void setWidth(int width) {this.width = width;}
+
+ private int height;
+ public int getHeight() {return height;}
+ public void setHeight(int height) {this.height = height;}
+
+ public VideoSize() {}
+ private VideoSize(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public static final VideoSize createStandard(int code) {
+ switch (code) {
+ case QCIF:
+ return new VideoSize(176, 144);
+ case CIF:
+ return new VideoSize(352, 288);
+ case HVGA:
+ return new VideoSize(320, 480);
+ default:
+ return new VideoSize(); // Invalid one
+ }
+ }
+
+ public boolean isValid() {
+ return width > 0 && height > 0;
+ }
+
+ // Generated
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + height;
+ result = prime * result + width;
+ return result;
+ }
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VideoSize other = (VideoSize) obj;
+ if (height != other.height)
+ return false;
+ if (width != other.width)
+ return false;
+ return true;
+ }
+
+
+}
-Subproject commit b1a4c2b6470a6de62a8e58d4f2874eda091a8db3
+Subproject commit 28a6e7f22fbdd93a01676fc9cc47a2605c846d75