From: <sb...@us...> - 2007-05-30 17:25:13
|
Revision: 993 http://svn.sourceforge.net/iaxclient/?rev=993&view=rev Author: sbalea Date: 2007-05-30 10:25:05 -0700 (Wed, 30 May 2007) Log Message: ----------- Video improvements patch from Erik Bunce: + No longer attempt to send video when no call selected (crash fix). + Improved video codec negotiation. + Actually use the negotiated video format instead of hacking the video format capacity. + Send video whether outgoing or incoming call. + No longer warn on call to send video with format 0 (since it might have been negotiated). + Add IAXC_FORMAT_MAX_VIDEO to match AST_FORMAT_MAX_VIDEO. + Add option (-P) that disables video preview once remote video is available. Modified Paths: -------------- trunk/lib/iaxclient.h trunk/lib/iaxclient_lib.c trunk/lib/video.c trunk/simpleclient/vtestcall/vtestcall.c Modified: trunk/lib/iaxclient.h =================================================================== --- trunk/lib/iaxclient.h 2007-05-24 14:41:51 UTC (rev 992) +++ trunk/lib/iaxclient.h 2007-05-30 17:25:05 UTC (rev 993) @@ -97,8 +97,8 @@ #define IAXC_FORMAT_H264 (1 << 21) /* H264 Video */ #define IAXC_FORMAT_MPEG4 (1 << 22) /* MPEG4 Video */ #define IAXC_FORMAT_THEORA (1 << 24) /* Theora Video */ +#define IAXC_FORMAT_MAX_VIDEO (1 << 24) /* Maximum Video Format */ - #define IAXC_EVENT_TEXT 1 #define IAXC_EVENT_LEVELS 2 #define IAXC_EVENT_STATE 3 Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2007-05-24 14:41:51 UTC (rev 992) +++ trunk/lib/iaxclient_lib.c 2007-05-30 17:25:05 UTC (rev 993) @@ -297,7 +297,7 @@ e.type = IAXC_EVENT_TEXT; e.ev.text.type = type; - + e.ev.text.callNo = -1; va_start(args, fmt); vsnprintf(e.ev.text.message, IAXC_EVENT_BUFSIZ, fmt, args); va_end(args); @@ -774,7 +774,11 @@ iaxc_event e; struct timeval now; long time; - + + // make sure there is a call to do stats on + if (selected_call < 0) + return; + gettimeofday(&now, NULL); time = iaxc_msecdiff(&now, &video_stats_start); if ( time > VIDEO_STATS_INTERVAL ) @@ -795,11 +799,17 @@ static THREADFUNCDECL(video_proc_thread_func) { gettimeofday(&video_stats_start, NULL); - + + struct iaxc_call *call; while ( !video_proc_thread_flag ) { - iaxc_send_video(&calls[selected_call], selected_call); + if (selected_call >= 0) + call = &calls[selected_call]; + else + call = NULL; + iaxc_send_video(call, selected_call); + iaxc_send_video_stats(); // Tight spinloops are bad, mmmkay? @@ -1166,7 +1176,7 @@ iaxc_clear_call(callNo); break; case IAX_EVENT_ACCEPT: - calls[callNo].format = e->ies.format; + calls[callNo].format = e->ies.format & IAXC_AUDIO_FORMAT_MASK; calls[callNo].vformat = e->ies.format & IAXC_VIDEO_FORMAT_MASK; if ( !(e->ies.format & IAXC_VIDEO_FORMAT_MASK) ) { @@ -1658,10 +1668,6 @@ return; } } - else - { - iaxc_video_format_set_cap(video_format, video_format); - } calls[callno].vformat = video_format; calls[callno].format = format; Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2007-05-24 14:41:51 UTC (rev 992) +++ trunk/lib/video.c 2007-05-30 17:25:05 UTC (rev 993) @@ -135,6 +135,10 @@ { int real_pref = 0; int real_allowed = 0; +#ifdef USE_FFMPEG + int tmp_allowed; + int i; +#endif // Make sure resolution is in range if ( width < IAXC_VIDEO_MIN_WIDTH ) @@ -187,7 +191,7 @@ { // If preferred codec is not available switch to the // supported default codec. - fprintf(stderr, "Preferred codec is not available. Switching to default"); + fprintf(stderr, "Preferred codec (0x%08x) is not available. Switching to default", preferred); real_pref = IAXC_FORMAT_THEORA; } @@ -203,8 +207,13 @@ * available valid codecs. With that, we should be able to come up * with a more elegant algorithm here for determining the video codec. */ - if ( iaxc_video_codec_ffmpeg_check_codec(allowed) ) - real_allowed |= allowed; + for ( i = 0; i <= 24; i++) + { + tmp_allowed = 1 << i; + if ( (allowed & tmp_allowed) && + iaxc_video_codec_ffmpeg_check_codec(tmp_allowed) ) + real_allowed |= tmp_allowed; + } #endif #ifdef USE_H264_VSS @@ -411,7 +420,7 @@ int iaxc_send_video(struct iaxc_call *call, int sel_call) { static struct slice_set_t slice_set; - int format = iaxc_video_format_preferred; + int format; int i = 0; const int inlen = iaxc_video_width * iaxc_video_height * 6 / 4; char * videobuf; @@ -435,12 +444,17 @@ iaxc_video_prefs & IAXC_VIDEO_PREF_RECV_RGB32); } - if ( sel_call < 0 || !call || !(call->state & IAXC_CALL_STATE_COMPLETE) ) + if ( sel_call < 0 || !call || !(call->state & (IAXC_CALL_STATE_COMPLETE | IAXC_CALL_STATE_OUTGOING) ) ) + { return -1; + } + // use the calls format, not random preference + format = call->vformat; + if ( format == 0 ) { - fprintf(stderr, "iaxc_send_video: Format is zero (should't happen)!\n"); +// fprintf(stderr, "iaxc_send_video: Format is zero (should't happen)!\n"); return -1; } @@ -472,7 +486,7 @@ if ( !call->vencoder ) { call->vencoder = create_codec(format, 1); - fprintf(stderr,"Created codec %s\n",call->vencoder->name); + fprintf(stderr,"**** Created encoder codec %s\n",call->vencoder->name); } if ( !call->vencoder ) @@ -584,7 +598,7 @@ if ( !call->vdecoder ) { call->vdecoder = create_codec(format, 0); - fprintf(stderr,"Created codec %s\n",call->vdecoder->name); + fprintf(stderr,"**** Created decoder codec %s\n",call->vdecoder->name); } if ( !call->vdecoder ) Modified: trunk/simpleclient/vtestcall/vtestcall.c =================================================================== --- trunk/simpleclient/vtestcall/vtestcall.c 2007-05-24 14:41:51 UTC (rev 992) +++ trunk/simpleclient/vtestcall/vtestcall.c 2007-05-30 17:25:05 UTC (rev 993) @@ -36,15 +36,19 @@ #define MAX_CALLS 6 -static int video; +static int video = 0; -int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; +//int format = IAXC_FORMAT_THEORA | IAXC_FORMAT_SPEEX; +int format = IAXC_FORMAT_H263 | IAXC_FORMAT_H263_PLUS | IAXC_FORMAT_H264 | IAXC_FORMAT_MPEG4 | IAXC_FORMAT_THEORA; +int formatp = IAXC_FORMAT_H264; //IAXC_FORMAT_THEORA; int framerate = 15; int bitrate = 400000; int width = 320; int height = 240; int fragsize = 4000; +int preview = 1; + // Forward declaration int display_video(struct iaxc_ev_video v, int remote); void process_text_message(char *message); @@ -190,6 +194,7 @@ fprintf(stderr, "Mihai: answer call vformat=0x%x\n", s.vformat); //iaxc_unquelch(s.callNo); iaxc_millisleep(1000); + iaxc_answer_call(s.callNo); iaxc_select_call(s.callNo); //iaxc_millisleep(1000); return 0; @@ -375,13 +380,22 @@ } local_data = (unsigned char *)malloc(v.size); memcpy(local_data, v.data, v.size); - + SDL_LockYUVOverlay(lolay); lolay->pixels[0] = local_data; lolay->pixels[1] = local_data + (v.width * v.height); lolay->pixels[2] = local_data + (v.width * v.height * 5 / 4 ); SDL_UnlockYUVOverlay(lolay); - SDL_DisplayYUVOverlay(lolay, &Rrect); + + if (remote_data != NULL) + { + SDL_DisplayYUVOverlay(rolay, &rect); + if (preview) + SDL_DisplayYUVOverlay(lolay, &Rrect); + } + else + SDL_DisplayYUVOverlay(lolay, &Rrect); + } else { // Remote video @@ -401,9 +415,10 @@ rolay->pixels[2] = remote_data + (v.width * v.height * 5/4); SDL_UnlockYUVOverlay(rolay); SDL_DisplayYUVOverlay(rolay, &rect); - + // Display the current local frame as well, to minimize flicker - SDL_DisplayYUVOverlay(lolay, &Rrect); + if (preview) + SDL_DisplayYUVOverlay(lolay, &Rrect); } if( SDL_mutexV(mut) == -1 ) @@ -440,7 +455,7 @@ break; case 'F': /* set video formats */ { - format = 1<<atoi(argv[++i]); + formatp = 1<<atoi(argv[++i]); framerate = atoi(argv[++i]); bitrate = atoi(argv[++i]); width = atoi(argv[++i]); @@ -448,6 +463,9 @@ fragsize = atoi(argv[++i]); } break; + case 'P': /* */ + preview = 0; + break; case 's': if(i+1 >= argc) usage(); silence_threshold = atof(argv[++i]); @@ -485,7 +503,7 @@ } // To receive calls... - iaxc_video_format_set(format, format, framerate, bitrate, width, height, fragsize); + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); fprintf(stderr,">>> Forcing video mode!\n"); video=1; @@ -540,7 +558,11 @@ sprintf(caption, "Calling to %s", dest); fprintf(stderr, "Calling to %s\n", dest); my_safe_caption(caption); - iaxc_call(dest); + int callNo = iaxc_call(dest); + if (callNo <= 0) + iaxc_select_call(callNo); + else + fprintf(stderr, "Failed to make call to '%s'", dest); } /* process keyboard input received by the video window */ @@ -584,8 +606,8 @@ iaxc_video_format_set(0, 0, framerate, bitrate, width, height, fragsize); } else { - fprintf(stderr,"format_set a %d,%d,%d,%d,%d,%d,%d\n",format, format, framerate, bitrate, width, height, fragsize); - iaxc_video_format_set(format, format, framerate, bitrate, width, height, fragsize); + fprintf(stderr,"format_set a %d,%d,%d,%d,%d,%d,%d\n",formatp, format, framerate, bitrate, width, height, fragsize); + iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); } /* if (iaxc_initialize(Vmode|Amode,MAX_CALLS)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |