enable/disable self view

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@193 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
smorlat 2008-12-01 21:25:20 +00:00
parent c857c51b0b
commit 16ee0f2008
6 changed files with 269 additions and 225 deletions

View file

@ -1423,6 +1423,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
if (video_params->relay_session_id!=NULL)
video_stream_set_relay_session_id(lc->videostream,video_params->relay_session_id);
video_stream_set_sent_video_size(lc->videostream,linphone_core_get_preferred_video_size(lc));
video_stream_enable_self_view(lc->videostream,lc->video_conf.selfview);
if (lc->video_conf.display && lc->video_conf.capture)
video_stream_start(lc->videostream,
call->profile, video_params->remoteaddr, video_params->remoteport,
@ -2001,6 +2002,17 @@ bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc){
return lc->video_conf.show_local;
}
void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val){
lc->video_conf.selfview=val;
if (lc->videostream){
video_stream_enable_self_view(lc->videostream,val);
}
}
bool_t linphone_core_self_view_enabled(const LinphoneCore *lc){
return lc->video_conf.selfview;
}
int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
MSWebCam *olddev=lc->video_conf.device;
if (id!=NULL){

View file

@ -116,6 +116,7 @@ typedef struct video_config{
bool_t capture;
bool_t show_local;
bool_t display;
bool_t selfview; /*during calls*/
}video_config_t;
typedef struct ui_config
@ -692,6 +693,8 @@ void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char
void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val);
bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc);
void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val);
bool_t linphone_core_self_view_enabled(const LinphoneCore *lc);
/* returns a null terminated static array of string describing the webcams */

View file

@ -379,6 +379,11 @@ void linphone_gtk_set_audio_only(){
linphone_core_enable_video(linphone_gtk_get_core(),FALSE,FALSE);
}
void linphone_gtk_enable_self_view(GtkWidget *w){
linphone_core_enable_self_view(linphone_gtk_get_core(),
gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
}
void linphone_gtk_used_identity_changed(GtkWidget *w){
int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w));
char *sel=gtk_combo_box_get_active_text(GTK_COMBO_BOX(w));

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.5 on Thu Nov 20 09:20:39 2008 -->
<!--Generated with glade3 3.4.5 on Mon Dec 1 22:04:04 2008 -->
<glade-interface>
<widget class="GtkWindow" id="main">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
@ -93,6 +93,20 @@
<signal name="activate" handler="linphone_gtk_set_audio_video"/>
</widget>
</child>
<child>
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
<property name="visible">True</property>
</widget>
</child>
<child>
<widget class="GtkCheckMenuItem" id="menuitem3">
<property name="visible">True</property>
<property name="label" translatable="yes">Enable self-view</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<signal name="toggled" handler="linphone_gtk_enable_self_view"/>
</widget>
</child>
</widget>
</child>
</widget>
@ -398,235 +412,17 @@ Online users</property>
<property name="n_columns">4</property>
<property name="homogeneous">True</property>
<child>
<widget class="GtkButton" id="dtmf_1">
<widget class="GtkButton" id="dtmf_D">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">1</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">2</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">3</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_A">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">A</property>
<property name="label" translatable="yes">D</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">4</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_5">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">5</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">6</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_B">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">B</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_7">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">7</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_8">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">8</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_9">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">9</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_C">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">C</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_star">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">*</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_0">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">0</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
@ -652,19 +448,237 @@ Online users</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_D">
<widget class="GtkButton" id="dtmf_0">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">D</property>
<property name="label" translatable="yes">0</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_star">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">*</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_C">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">C</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_9">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">9</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_8">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">8</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_7">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">7</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_B">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">B</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">6</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_5">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">5</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">4</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_A">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">A</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">3</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">2</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkButton" id="dtmf_1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">1</property>
<property name="response_id">0</property>
</widget>
<packing>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>

View file

@ -124,6 +124,7 @@ struct _VideoStream
MSFilter *rtpsend;
OrtpEvQueue *evq;
MSVideoSize sent_vsize;
int corner; /*for selfview*/
bool_t adapt_bitrate;
};
@ -140,6 +141,7 @@ void video_stream_iterate(VideoStream *stream);
void video_stream_send_vfu(VideoStream *stream);
void video_stream_stop(VideoStream * stream);
void video_stream_set_sent_video_size(VideoStream *stream, MSVideoSize vsize);
void video_stream_enable_self_view(VideoStream *stream, bool_t val);
VideoStream * video_preview_start(MSWebCam *device, MSVideoSize vsize);
void video_preview_stop(VideoStream *stream);

View file

@ -179,6 +179,13 @@ void video_stream_set_relay_session_id(VideoStream *stream, const char *id){
ms_filter_call_method(stream->rtpsend, MS_RTP_SEND_SET_RELAY_SESSION_ID,(void*)id);
}
void video_stream_enable_self_view(VideoStream *stream, bool_t val){
MSFilter *out=stream->output;
stream->corner=val ? 0 : -1;
if (out){
ms_filter_call_method(out,MS_VIDEO_OUT_SET_CORNER,&stream->corner);
}
}
void video_stream_enable_adaptive_bitrate_control(VideoStream *s, bool_t yesno){
s->adapt_bitrate=yesno;
@ -281,6 +288,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
ms_filter_call_method(stream->output,MS_FILTER_SET_VIDEO_SIZE,&disp_size);
ms_filter_call_method(stream->output,MS_VIDEO_OUT_AUTO_FIT,&tmp);
ms_filter_call_method(stream->output,MS_FILTER_SET_PIX_FMT,&format);
ms_filter_call_method(stream->output,MS_VIDEO_OUT_SET_CORNER,&stream->corner);
if (pt->recv_fmtp!=NULL)
ms_filter_call_method(stream->decoder,MS_FILTER_ADD_FMTP,(void*)pt->recv_fmtp);