Commit 52c3634a authored by smorlat's avatar smorlat

- rewrite mirroring

- fix bug with handling of remote RTP address while generating SDP answer
- fix H264 packetization-mode handling in SDP answer



git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@54 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
parent e11af615
......@@ -490,14 +490,14 @@ static int find_payload_type_number_best_match(RtpProfile *prof, const char *rtp
pt=rtp_profile_get_payload(prof,localpt);
if (strcasecmp(pt->mime_type,"H264")==0){
/*hack for H264: need to answer with same packetization-mode*/
PayloadType tmp;
memset(&tmp,0,sizeof(tmp));
tmp.mime_type="H264";
tmp.clock_rate=pt->clock_rate;
if (fmtp && fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){
PayloadType tmp;
memset(&tmp,0,sizeof(tmp));
tmp.mime_type="H264";
tmp.clock_rate=pt->clock_rate;
tmp.recv_fmtp=(atoi(value)==1) ? "packetization-mode=1" : NULL;
localpt=find_payload_type_number(prof,&tmp);
}
localpt=find_payload_type_number(prof,&tmp);
}
return localpt;
}
......@@ -643,12 +643,12 @@ int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload)
params->line=payload->line;
params->pt=payload->pt; /* remember the first payload accepted */
if (payload->relay_host!=NULL){
params->remoteaddr=payload->relay_host;
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
params->remoteport=payload->relay_port;
params->remotertcpport=payload->relay_port;
params->relay_session_id=payload->relay_session_id;
}else{
params->remoteaddr=payload->c_addr;
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
params->remoteport=payload->remoteport;
params->remotertcpport=payload->remoteport+1;
}
......@@ -694,12 +694,12 @@ int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload)
params->line=payload->line;
params->pt=payload->pt; /* remember the first payload accepted */
if (payload->relay_host!=NULL){
params->remoteaddr=payload->relay_host;
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
params->remoteport=payload->relay_port;
params->remotertcpport=payload->relay_port;
params->relay_session_id=payload->relay_session_id;
}else{
params->remoteaddr=payload->c_addr;
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
params->remoteport=payload->remoteport;
params->remotertcpport=params->remoteport+1;
}
......@@ -735,12 +735,12 @@ int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload)
params->line=payload->line;
params->pt=payload->pt; /* remember the first payload accepted */
if (payload->relay_host!=NULL){
params->remoteaddr=payload->relay_host;
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
params->remoteport=payload->relay_port;
params->remotertcpport=payload->relay_port;
params->relay_session_id=payload->relay_session_id;
}else{
params->remoteaddr=payload->c_addr;
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
params->remoteport=payload->remoteport;
params->remotertcpport=payload->remoteport+1;
}
......@@ -774,12 +774,12 @@ int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload)
params->line=payload->line;
params->pt=payload->pt; /* remember the first payload accepted */
if (payload->relay_host!=NULL){
params->remoteaddr=payload->relay_host;
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
params->remoteport=payload->relay_port;
params->remotertcpport=payload->relay_port;
params->relay_session_id=payload->relay_session_id;
}else{
params->remoteaddr=payload->c_addr;
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
params->remoteport=payload->remoteport;
params->remotertcpport=payload->remoteport+1;
}
......
......@@ -1506,18 +1506,13 @@ int linphone_core_accept_call(LinphoneCore *lc, const char *url)
ms_error("fail to generate sdp offer !");
return -1;
}
ms_message("sdp message generated (sdpmesg=%p):\n%s",sdpmesg,sdpmesg);
linphone_set_sdp(msg,sdpmesg);
ms_message("sdp message attached to SIP answer");
linphone_core_init_media_streams(lc);
ms_message("init_media_streams done");
}else{
linphone_set_sdp(msg,sdpmesg);
}
eXosip_lock();
ms_message("eXosip_lock() done");
eXosip_call_send_answer(call->tid,200,msg);
ms_message("SIP answer sent.");
eXosip_unlock();
lc->vtable.display_status(lc,_("Connected."));
gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
......
......@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mscommon.h"
#define LINPHONE_IPADDR_SIZE 64
#define LINPHONE_HOSTNAME_SIZE 128
#ifdef __cplusplus
extern "C" {
......@@ -144,11 +145,11 @@ typedef struct _StreamParams
int localport;
int remoteport;
int remotertcpport;
char *remoteaddr;
int pt;
char *relay_session_id;
char natd_addr[LINPHONE_IPADDR_SIZE];
int natd_port;
char remoteaddr[LINPHONE_HOSTNAME_SIZE];
char natd_addr[LINPHONE_HOSTNAME_SIZE];
} StreamParams;
typedef enum _LCState{
......
......@@ -104,6 +104,7 @@ void yuv_buf_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, int w, int h);
mblk_t * yuv_buf_alloc(MSPicture *buf, int w, int h);
void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi);
void yuv_buf_mirror(YuvBuf *buf);
#ifdef __cplusplus
}
#endif
......
......@@ -174,11 +174,11 @@ static int enc_set_br(MSFilter *f, void *arg){
d->bitrate=*(int*)arg;
if (d->bitrate>=1024000){
d->vsize=MS_VIDEO_SIZE_VGA;
d->fps=15;
d->vsize=MS_VIDEO_SIZE_VGA;
d->fps=15;
}else if (d->bitrate>=384000){
d->vsize=MS_VIDEO_SIZE_CIF;
d->fps=30;
d->vsize=MS_VIDEO_SIZE_CIF;
d->fps=30;
}else if (d->bitrate>=256000){
d->vsize=MS_VIDEO_SIZE_CIF;
d->fps=15;
......
......@@ -105,6 +105,26 @@ void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
plane_copy(src_planes[2],src_strides[2],dst_planes[2],dst_strides[2],roi);
}
static void plane_mirror(uint8_t *p, int linesize, int w, int h){
int i,j;
uint8_t tmp;
for(j=0;j<h;++j){
for(i=0;i<w/2;++i){
tmp=p[i];
p[i]=p[w-1-i];
p[w-1-i]=tmp;
}
p+=linesize;
}
}
/*in place mirroring*/
void yuv_buf_mirror(YuvBuf *buf){
plane_mirror(buf->planes[0],buf->strides[0],buf->w,buf->h);
plane_mirror(buf->planes[1],buf->strides[1],buf->w/2,buf->h/2);
plane_mirror(buf->planes[2],buf->strides[2],buf->w/2,buf->h/2);
}
#ifndef MAKEFOURCC
#define MAKEFOURCC(a,b,c,d) ((d)<<24 | (c)<<16 | (b)<<8 | (a))
#endif
......
......@@ -521,9 +521,6 @@ typedef struct VideoOut
MSPicture local_pic;
MSRect local_rect;
mblk_t *local_msg;
MSPicture tmp_local_pic;
mblk_t *tmp_local_msg;
mblk_t *previous_selfview;
int corner;
struct SwsContext *sws1;
struct SwsContext *sws2;
......@@ -537,44 +534,42 @@ typedef struct VideoOut
static void set_corner(VideoOut *s, int corner)
{
s->corner=corner;
s->local_pic.w=s->fbuf.w/SCALE_FACTOR;
s->local_pic.h=s->fbuf.h/SCALE_FACTOR;
s->tmp_local_pic.h = s->local_pic.h;
s->tmp_local_pic.w = s->local_pic.w;
if (corner==1)
{
/* top left corner */
s->corner=corner;
s->local_pic.w=s->fbuf.w/SCALE_FACTOR;
s->local_pic.h=s->fbuf.h/SCALE_FACTOR;
if (corner==1)
{
/* top left corner */
s->local_rect.x=0;
s->local_rect.y=0;
s->local_rect.w=s->local_pic.w;
s->local_rect.h=s->local_pic.h;
}
else if (corner==2)
{
/* top right corner */
}
else if (corner==2)
{
/* top right corner */
s->local_rect.x=s->fbuf.w-s->local_pic.w;
s->local_rect.y=0;
s->local_rect.w=s->local_pic.w;
s->local_rect.h=s->local_pic.h;
}
else if (corner==3)
{
/* bottom left corner */
}
else if (corner==3)
{
/* bottom left corner */
s->local_rect.x=0;
s->local_rect.y=s->fbuf.h-s->local_pic.h;
s->local_rect.w=s->local_pic.w;
s->local_rect.h=s->local_pic.h;
}
else
{
/* default: bottom right corner */
/* corner can be set to -1: to disable the self view... */
}
else
{
/* default: bottom right corner */
/* corner can be set to -1: to disable the self view... */
s->local_rect.x=s->fbuf.w-s->local_pic.w;
s->local_rect.y=s->fbuf.h-s->local_pic.h;
s->local_rect.w=s->local_pic.w;
s->local_rect.h=s->local_pic.h;
}
}
}
static void set_vsize(VideoOut *s, MSVideoSize *sz){
......@@ -595,8 +590,6 @@ static void video_out_init(MSFilter *f){
def_size.width=MS_VIDEO_SIZE_CIF_W;
def_size.height=MS_VIDEO_SIZE_CIF_H;
obj->local_msg=NULL;
obj->tmp_local_msg=NULL;
obj->previous_selfview=NULL;
obj->corner=0;
obj->sws1=NULL;
obj->sws2=NULL;
......@@ -624,15 +617,6 @@ static void video_out_uninit(MSFilter *f){
freemsg(obj->local_msg);
obj->local_msg=NULL;
}
if (obj->previous_selfview!=NULL)
{
freemsg(obj->previous_selfview);
obj->previous_selfview=NULL;
}
if (obj->tmp_local_msg!=NULL) {
freemsg(obj->tmp_local_msg);
obj->tmp_local_msg=NULL;
}
ms_free(obj);
}
......@@ -663,32 +647,12 @@ static void video_out_preprocess(MSFilter *f){
freemsg(obj->local_msg);
obj->local_msg=NULL;
}
if (obj->previous_selfview!=NULL)
{
freemsg(obj->previous_selfview);
obj->previous_selfview=NULL;
}
if (obj->tmp_local_msg!=NULL) {
freemsg(obj->tmp_local_msg);
obj->tmp_local_msg=NULL;
}
obj->ready=TRUE;
}
static void video_out_postprocess(MSFilter *f){
}
static void mirror(unsigned char* dst,unsigned char* src,int dststride,int srcstride,int w,int h){
int y;
for(y=0;y<h;y++){
int x;
for(x=0;x<w;x++)
dst[x]=src[w-x-1];
src+=srcstride;
dst+=dststride;
}
}
static void video_out_process(MSFilter *f){
VideoOut *obj=(VideoOut*)f->data;
......@@ -702,85 +666,39 @@ static void video_out_process(MSFilter *f){
if (obj->display==NULL){
ms_filter_unlock(f);
if (f->inputs[0]!=NULL)
ms_queue_flush(f->inputs[0]);
ms_queue_flush(f->inputs[0]);
if (f->inputs[1]!=NULL)
ms_queue_flush(f->inputs[1]);
ms_queue_flush(f->inputs[1]);
return;
}
/*get most recent message and draw it*/
if (f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) {
if (obj->corner==-1)
{
if (obj->tmp_local_msg!=NULL) {
freemsg(obj->tmp_local_msg);
obj->tmp_local_msg=NULL;
}
if (obj->local_msg!=NULL) {
freemsg(obj->local_msg);
obj->local_msg=NULL;
}
if (obj->previous_selfview!=NULL)
{
freemsg(obj->previous_selfview);
obj->previous_selfview=NULL;
}
}
else
{
MSPicture src;
static mblk_t *previous_selfview = NULL;
if (yuv_buf_init_from_mblk(&src,inm)==0){
if (obj->sws2==NULL){
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
obj->tmp_local_pic.h = obj->local_pic.h;
obj->tmp_local_pic.w = obj->local_pic.w;
if (obj->tmp_local_msg==NULL){
obj->tmp_local_msg=yuv_buf_alloc(&obj->tmp_local_pic,
obj->tmp_local_pic.w,obj->tmp_local_pic.h);
}
if (obj->local_msg==NULL){
obj->local_msg=yuv_buf_alloc(&obj->local_pic,
obj->local_pic.w,obj->local_pic.h);
}
if (previous_selfview==NULL
|| (msgdsize(inm)!=msgdsize(previous_selfview))
|| memcmp(inm->b_rptr, previous_selfview->b_rptr, msgdsize(inm))!=0)
{
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
src.h, obj->tmp_local_pic.planes, obj->tmp_local_pic.strides)<0){
ms_error("Error in sws_scale().");
}
mirror(obj->local_pic.planes[0],obj->tmp_local_pic.planes[0],
obj->local_pic.strides[0],obj->tmp_local_pic.strides[0],
obj->local_pic.w,obj->local_pic.h);
mirror(obj->local_pic.planes[1],obj->tmp_local_pic.planes[1],
obj->local_pic.strides[1],obj->tmp_local_pic.strides[1],
obj->local_pic.w>>1,obj->local_pic.h>>1);
mirror(obj->local_pic.planes[2],obj->tmp_local_pic.planes[2],
obj->local_pic.strides[2],obj->tmp_local_pic.strides[2],
obj->local_pic.w>>1,obj->local_pic.h>>1);
}
else
{
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
src.h, obj->local_pic.planes, obj->local_pic.strides)<0){
ms_error("Error in sws_scale().");
}
}
if (previous_selfview!=NULL)
freemsg(previous_selfview);
previous_selfview = dupb(inm);
}
}
ms_queue_flush(f->inputs[1]);
if (obj->corner==-1){
if (obj->local_msg!=NULL) {
freemsg(obj->local_msg);
obj->local_msg=NULL;
}
}else{
MSPicture src;
if (yuv_buf_init_from_mblk(&src,inm)==0){
if (obj->sws2==NULL){
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
}
if (obj->local_msg==NULL){
obj->local_msg=yuv_buf_alloc(&obj->local_pic,
obj->local_pic.w,obj->local_pic.h);
}
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
src.h, obj->local_pic.planes, obj->local_pic.strides)<0){
ms_error("Error in sws_scale().");
}
yuv_buf_mirror(&obj->local_pic);
}
}
ms_queue_flush(f->inputs[1]);
}
if (f->inputs[0]!=NULL && (inm=ms_queue_peek_last(f->inputs[0]))!=0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment