From bluesky-commits-return-165-apmail-incubator-bluesky-commits-archive=incubator.apache.org@incubator.apache.org Fri Oct 09 08:59:18 2009 Return-Path: Delivered-To: apmail-incubator-bluesky-commits-archive@minotaur.apache.org Received: (qmail 1169 invoked from network); 9 Oct 2009 08:59:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 9 Oct 2009 08:59:17 -0000 Received: (qmail 16054 invoked by uid 500); 9 Oct 2009 08:59:17 -0000 Delivered-To: apmail-incubator-bluesky-commits-archive@incubator.apache.org Received: (qmail 16038 invoked by uid 500); 9 Oct 2009 08:59:17 -0000 Mailing-List: contact bluesky-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: bluesky-dev@incubator.apache.org Delivered-To: mailing list bluesky-commits@incubator.apache.org Received: (qmail 16029 invoked by uid 99); 9 Oct 2009 08:59:17 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Oct 2009 08:59:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 09 Oct 2009 08:59:08 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 782262388901; Fri, 9 Oct 2009 08:58:45 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r823467 [2/6] - in /incubator/bluesky/trunk/RealClass/Teacher: ./ src/ src/pic/ Date: Fri, 09 Oct 2009 08:58:44 -0000 To: bluesky-commits@incubator.apache.org From: ping@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091009085845.782262388901@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: incubator/bluesky/trunk/RealClass/Teacher/src/callbacks.hh URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/callbacks.hh?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/callbacks.hh (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/callbacks.hh Fri Oct 9 08:58:41 2009 @@ -0,0 +1,141 @@ +#include +#include "languagechoose.h" + +#ifndef _CALLBACK_H +#define _CALLBACK_H + +gboolean ncteacher_timer_callback(void *); + +void +on_login_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_exitsys_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_creatclass_activate(GtkMenuItem *menuitem, gpointer user_data); +void +on_stopclass_activate(GtkMenuItem *menuitem, gpointer user_data); +void +on_modecomu_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_modetech_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_set_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_stuimg_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_techimg_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_login_cancelbutton_destroy(GtkObject *object, gpointer user_data); + +void +on_loginokbutton_clicked(GtkButton *button, gpointer user_data); +void +on_networkokbutton_clicked(GtkButton *button, gpointer netdialo); + +void +on_networkcancelbutton_clicked(GtkObject *object, gpointer user_data); + +void +on_creat_cancelbut_clicked(GtkButton *button, gpointer user_data); + +void +on_creat_okbutton_clicked(GtkButton *button, gpointer user_data); +void +on_advance_button_clicked(GtkButton *button, gpointer user_data); + +void +on_set_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_join_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_exit_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_creat_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_cancel_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_tech_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_commu_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_concentrate_add_button_clicked(GtkButton *button, gpointer user_data); + +void +on_concentrate_concel_button_clicked(GtkButton *button, gpointer user_data); + +void +on_chat_button_clicked(GtkButton *button, gpointer user_data); +void +on_chat_entry_activate(GtkWidget *widget, GtkWidget *entry); + +void +on_student_clist_select_row(GtkCList *clist, gint row, gint column, + GdkEvent *event, gpointer user_data); + +void +on_allow_chat_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); + +void +on_choose_activate(GtkMenuItem *menuitem, gpointer user_data); +void +on_radiobutton_choose_clicked(GtkButton *button, gpointer user_data); + +void +on_view_but_clicked(GtkButton *button, gpointer user_data); +void +on_work_mode_activate(GtkMenuItem *menuitem, gpointer user_data); + +void +on_rec_toolbutton_clicked(GtkToolButton *toolbutton, gpointer user_data); +void +on_radiobutton_work_clicked(GtkButton *button, gpointer user_data); + +void +on_choose_cancel_but_clicked(GtkButton *button, gpointer user_data); +void +on_choose_ok_but_clicked(GtkButton *button, gpointer user_data); +void +on_work_ok_but_clicked(GtkButton *button, gpointer user_data); +void +on_work_cancel_but_clicked(GtkButton *button, gpointer user_data); +gint +choose_dialog_delete_event(GtkWidget *widget, GdkEvent *event, + gpointer user_data); +void +on_exit_rec_cancel_clicked(GtkButton *button, gpointer user_data); +void +on_exit_rec_yes_clicked(GtkButton *button, gpointer user_data); +void +on_combo_box_choose1(GtkObject *object, gpointer user_data); +void +on_clearchatitem_activate(GtkMenuItem *menuitem, gpointer user_data); +void +on_exit_class_cancel_clicked(GtkButton *button, gpointer user_data); +void +on_exit_class_yes_clicked(GtkButton *button, gpointer user_data); + +void +on_exit_system_cancel_clicked(GtkButton *button, gpointer user_data); +void +on_exit_system_yes_clicked(GtkButton *button, gpointer user_data); +gint +window1_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data); +void +on_rec_delay_cancel_clicked(GtkButton *button, gpointer user_data); +void +on_rec_delay_yes_clicked(GtkButton *button, gpointer user_data); +#endif Added: incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.cc URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.cc?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.cc (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.cc Fri Oct 9 08:58:41 2009 @@ -0,0 +1,636 @@ +#include "client_communicate.h" +#include +#include +#include +#include +#include +#include +#include + +#include "en_de_common.h" +#include "errorinfo.h" +#include "interface.hh" +#include "support.hh" + +#include "languagechoose.h" + +extern GtkWidget *modetech; +extern GtkWidget *modecomu; + +extern GtkWidget *tech_toolbutton; +extern GtkWidget *commu_toolbutton; + +extern GtkWidget *creatclass; +extern GtkWidget *stopclass; + +extern GtkWidget *creat_toolbutton; +extern GtkWidget *cancel_toolbutton; +extern GtkWidget *allow_chat_toolbutton; + +extern GtkWidget *student_clist; + +extern GtkWidget *concentrate_add_button; +extern GtkWidget *concentrate_concel_button; + +extern GtkWidget *chat_button; + +extern GtkTextBuffer *commu_buffer; +extern GtkTextIter commu_end; + +extern GtkWidget *join_toolbutton; +extern GtkWidget *login; +extern GtkWidget *exitsys; +extern GtkWidget *exit_toolbutton; + +extern GtkWidget *set_item; +extern GtkWidget *set_toolbutton; + +extern int get_client_clist(); //define in callback.cc +extern int is_focus_set; //0: haven't 1:set already +extern int clist_focusid; //record focus student +extern int allow_chat_set;//0:stop chat;1:allow chat + +extern CVideoReceiver g_studet_videoreceiver; +extern CAudioReceiver g_student_audioreceiver; + +extern CAudioSender g_teacher_audiosender; //define in techmm.cc +extern CV4LVideoSender g_teacher_v4lvideosender; +extern CScreenSender g_teacher_screensender; + +extern int g_work_mode; +extern int g_video_mode; + +extern int error_info_no; //define in callback.cc + +extern GtkWidget *commu_textview; + +gint y_position, height; + +JMutex client_ts_communicate::studentlist_mutex; + +client_ts_communicate::client_ts_communicate() +{ + studentlist_mutex.Init(); + textview_mutex.Init(); +} + +client_ts_communicate::~client_ts_communicate() +{ + +} + +int client_ts_communicate::close_socket(int nHow) +{ + if (client_socket.ShutDown(nHow) == false) + { + perror("close socket error!"); + return -1; + } + else + return 0; +} + +int client_ts_communicate::establish_connect(LPCTSTR ts_IP, UINT ts_Port, + UINT nSocketPort) +{ + if (client_socket.Create(nSocketPort) != true) + { + printf("Create socket failed!/n"); + return -1; + } + + if (client_socket.Connect(ts_IP, ts_Port) != true) + { + perror("connet error!"); + return -1; + } + + client_socket_thread.Attach(&client_socket); + + if (client_socket_thread.Init() != true) + { + printf("Fail to initilize thread!/n"); + return -1; + } + client_socket_thread.Start(); + + return 0; + +} + +int client_ts_communicate::send_mes(CRCLMSG mes, int mes_length) +{ + + if (client_socket.Send(&mes, mes_length) == -1) + { + perror("Send message failed!"); + return -1; + } + return 0; +} + +int client_ts_communicate::recevie_msg(char *buf, int buf_length) +{ + CRCLMSG * receive_str; + receive_str = (CRCLMSG *) buf; + + switch (receive_str->rclType) + { + case 5001: + //teacher login,response message + CRCLTeacherLoginR *TeacherLoginR; + TeacherLoginR = (CRCLTeacherLoginR *) receive_str->msg; + + if (TeacherLoginR->ResponseType != 0) + { + error_info_no = 3; + perror("teacher login error!"); + gtk_widget_set_sensitive(creatclass, FALSE); + gtk_widget_set_sensitive(creat_toolbutton, FALSE); + + gtk_widget_set_sensitive(exitsys, FALSE); + gtk_widget_set_sensitive(exit_toolbutton, FALSE); + + gtk_widget_set_sensitive(set_item, TRUE); + gtk_widget_set_sensitive(set_toolbutton, TRUE); + + gtk_widget_set_sensitive(login, TRUE); + gtk_widget_set_sensitive(join_toolbutton, TRUE); + + return -1; + } + + TeacherID = TeacherLoginR->TeacherID; + cout << "teachloginr.ResponseType" << " " + << TeacherLoginR->ResponseType << endl; + cout << "teachloginr.TeacherID" << " " << TeacherLoginR->TeacherID + << endl; + + gtk_widget_set_sensitive(set_item, FALSE); + gtk_widget_set_sensitive(set_toolbutton, FALSE); + + break; + + case 10001: + { + //teacher create class, response message A + CRCLCreateGroupR *CreateGroupR; + CreateGroupR = (CRCLCreateGroupR *) receive_str->msg; + + if (CreateGroupR->ResponseType == 0) + { + GroupID = CreateGroupR->GroupID; + printf("create class OK!\n"); + } + else + { + error_info_no = 5; + perror("creat class error!"); + return -1; + } + + printf("MCU ip is %s\n", CreateGroupR->MCUIP); + printf("MCU port is %d,%d\n", CreateGroupR->TVPort, + CreateGroupR->TSPort); + + gtk_widget_set_sensitive(stopclass, TRUE); + gtk_widget_set_sensitive(cancel_toolbutton, TRUE); + + gtk_widget_set_sensitive(creatclass, FALSE); + gtk_widget_set_sensitive(creat_toolbutton, FALSE); + + gtk_widget_set_sensitive(modetech, FALSE); + gtk_widget_set_sensitive(tech_toolbutton, FALSE); + + gtk_widget_set_sensitive(modecomu, TRUE); + gtk_widget_set_sensitive(commu_toolbutton, TRUE); + + gtk_widget_set_sensitive(chat_button, TRUE); + allow_chat_set = 0; + gtk_widget_set_sensitive(allow_chat_toolbutton, TRUE); + allow_chat_set = 0; + + //create send thread + + unsigned long intIP2 = inet_addr(CreateGroupR->MCUIP); + + intIP2 = ntohl(intIP2); //put in host byte order + RTPIPv4Address rtpAddr1(intIP2, CreateGroupR->TVPort); + RTPIPv4Address rtpAddr2(intIP2, CreateGroupR->TSPort); + RTPIPv4Address rtpAddr3(intIP2, CreateGroupR->TAPort); + + /*Create directory by current time*/ + char strAudioFile[255]; + char strVideoFile[255]; + char strScreenFile[255]; + char strpath[255] = "/root/kejian/"; + + mkdir(strpath, S_IRWXU); + + time_t now; + + now = time(0); + tm *tnow = localtime(&now); + sprintf(strpath + strlen(strpath), "%d_%0.2d_%0.2d_%0.2d_%0.2d", 1900 + + tnow->tm_year, tnow->tm_mon + 1, tnow->tm_mday, + tnow->tm_hour, tnow->tm_min); + printf("%s\n", strpath); + + if (mkdir(strpath, S_IRWXU) != 0) + { + printf("Warning:Create directory of %s failed!\n", strpath); + } + + sprintf(strAudioFile, "%s/audio_CW_A.mp3", strpath); + sprintf(strVideoFile, "%s/video_CW_V.mpg", strpath); + sprintf(strScreenFile, "%s/screen_CW_S.mpg", strpath); + + if (access(strAudioFile, F_OK) == 0) + { + printf("Warning:%s has exsited\n", strAudioFile); + } + if (access(strVideoFile, F_OK) == 0) + { + printf("Warning:%s has exsited\n", strVideoFile); + } + if (access(strScreenFile, F_OK) == 0) + { + printf("Warning:%s has exsited\n", strScreenFile); + } + //init screen sender. + if (!g_teacher_screensender.Init(6000)) + exit(1); + g_teacher_screensender.AddDestination(rtpAddr2); + if (g_teacher_screensender.Start(strScreenFile, true) < 0) + exit(1); + + //init video sender. + switch (g_video_mode) + { + + case 1: + if (!g_teacher_v4lvideosender.IsInitialized()) + { + if (!g_teacher_v4lvideosender.Init(6002)) + Error_dia(ERROR022, ERROR_S022); + } + + g_teacher_v4lvideosender.SetMode(CV4LVideoSender::ModeTransmit); + g_teacher_v4lvideosender.AddDestination(rtpAddr1); + g_teacher_v4lvideosender.Start(strVideoFile, true); + g_teacher_v4lvideosender.Record(true); + break; + } + + if (!g_teacher_audiosender.Init(6004)) + { + printf("fdsafsfesfds\n"); + exit(1); + } + + g_teacher_audiosender.AddDestination(rtpAddr3); + if (g_teacher_audiosender.Start(strAudioFile, true) < 0) + { + printf("fdsafsfesfds\n"); + + } + break; + } + + case 1031: + { + //text chat, broadcast to other clients + CRCLClientTextBroadcastR *Client_text_r; + Client_text_r = (CRCLClientTextBroadcastR *) receive_str->msg; + + char text_Info[1045]; + + strcpy(text_Info, Client_text_r->ClientName); + strcat(text_Info, ": "); + strcat(text_Info, Client_text_r->Info); + strcat(text_Info, "\n"); + + gtk_text_buffer_insert(commu_buffer, &commu_end, text_Info, -1); + flush_scrollar(); + } + break; + + case 1071: + //teacher get students' info, response to the teachers + client_ts_communicate::studentlist_mutex.Lock(); + + gtk_clist_freeze( GTK_CLIST(student_clist)); + CRCLTeacherGetClientListR *teacher_GetClientList; + teacher_GetClientList = (CRCLTeacherGetClientListR *) receive_str->msg; + + int index; + char tmp[100]; + memset(tmp, 0, sizeof(tmp)); + + char studentInfo[1024][3][limitbit]; + char *ptr_studentInfo[1024][3]; + memset(studentInfo, 0, sizeof(studentInfo)); + memset(ptr_studentInfo, 0, sizeof(ptr_studentInfo)); + + char avmode[15]; + char no_avmode[16]; + memset(avmode, 0, sizeof(avmode)); + memset(no_avmode, 0, sizeof(no_avmode)); + + strcpy(avmode, pYES); + strcpy(no_avmode, pNO); + if (teacher_GetClientList->ResponseType == 0) + { + printf("I get client %d\n", teacher_GetClientList->ClientNum); + + gtk_clist_clear( GTK_CLIST(student_clist)); + + for (index = 0; index < teacher_GetClientList->ClientNum; index++) + { + printf("get STUID %d\n", + teacher_GetClientList->ClientList[index].ClientID); + printf(" student name is %s ,AVMOde is %d\n", + teacher_GetClientList->ClientList[index].ClientName, + teacher_GetClientList->ClientList[index].IsFocus); + + sprintf(tmp, "%d", + teacher_GetClientList->ClientList[index].ClientID); + memcpy(studentInfo[index][0], tmp, strlen(tmp)); + ptr_studentInfo[index][0] = studentInfo[index][0]; + + memcpy( + studentInfo[index][1], + teacher_GetClientList->ClientList[index].ClientName, + strlen( + teacher_GetClientList->ClientList[index].ClientName)); + ptr_studentInfo[index][1] = studentInfo[index][1]; + + if (teacher_GetClientList->ClientList[index].IsFocus == 0) + { + + memcpy(studentInfo[index][2], avmode, strlen(avmode)); + ptr_studentInfo[index][2] = studentInfo[index][2]; + } + + else if (teacher_GetClientList->ClientList[index].IsFocus == 1) + { + + memcpy(studentInfo[index][2], no_avmode, strlen(no_avmode)); + ptr_studentInfo[index][2] = studentInfo[index][2]; + } + + gtk_clist_append(GTK_CLIST(student_clist), + ptr_studentInfo[index]); + + } + } + + gtk_clist_thaw( GTK_CLIST(student_clist)); + + client_ts_communicate::studentlist_mutex.Unlock(); + printf("\n1071 finished!!!!!!!!\n"); + break; + + case 1012: + { + //student apply for focus, send message to MCU and the teacher + CRCLClientApplyFocusRToTM *client_apply_focus; + client_apply_focus = (CRCLClientApplyFocusRToTM *) receive_str->msg; + char text_Info[1045]; + + strcpy(text_Info, ptext); + char tmp[10]; + sprintf(tmp, "%d", client_apply_focus->FocusClientID); + strcat(text_Info, tmp); + + strcat(text_Info, "\n\n"); + textview_mutex.Lock(); + gtk_text_buffer_insert(commu_buffer, &commu_end, text_Info, -1); + textview_mutex.Unlock(); + flush_scrollar(); + + } + break; + + case 1022: + { + //student cancel focus, send message to MCU and the teacher + CRCLClientDestroyFocusRToTM *client_destroy_focus; + client_destroy_focus = (CRCLClientDestroyFocusRToTM *) receive_str->msg; + char text_Info[1045]; + + strcpy(text_Info, ptext01); + char tmp[10]; + sprintf(tmp, "%d", client_destroy_focus->FocusClientID); + strcat(text_Info, tmp); + strcat(text_Info, "\n\n"); + textview_mutex.Lock(); + gtk_text_buffer_insert(commu_buffer, &commu_end, text_Info, -1); + textview_mutex.Unlock(); + flush_scrollar(); + } + break; + + case 10022: + { //student join the class, response message B, send to other clients + client_ts_communicate::studentlist_mutex.Lock(); + gtk_clist_freeze( GTK_CLIST(student_clist)); + CRCLClientJoinInGroupRAll *client_join_group_response; + client_join_group_response + = (CRCLClientJoinInGroupRAll *) receive_str->msg; + + char *add_student[3]; + char comm_mode[5]; + char no_comm_mode[6]; + char temp[10]; + + strcpy(comm_mode, pYES); + strcpy(no_comm_mode, pNO); + + sprintf(temp, "%d", client_join_group_response->ClientInfo.ClientID); + add_student[0] = temp; + + add_student[1] = client_join_group_response->ClientInfo.ClientName; + + if (client_join_group_response->ClientInfo.IsFocus == 0) + add_student[2] = comm_mode; + + else if (client_join_group_response->ClientInfo.IsFocus == 1) + add_student[2] = no_comm_mode; + + gtk_clist_append(GTK_CLIST(student_clist), add_student); + + gtk_clist_thaw( GTK_CLIST(student_clist)); + client_ts_communicate::studentlist_mutex.Unlock(); + break; + } + case 1051: + //teacher appoint the focus srudent, response message + CRCLTeacherAllowClientFocusR *allow_client_response; + allow_client_response + = (CRCLTeacherAllowClientFocusR *) receive_str->msg; + + if (allow_client_response->ResponseType != 0) + { + error_info_no = 10; + perror("failed to set focus!"); + return -1; + } + + if (get_client_clist() < 0) + { + perror("get client clist failed!"); + return -1; + } + + is_focus_set = 1; + + gtk_widget_set_sensitive(concentrate_concel_button, TRUE); + break; + + case 1061: + //teacher cancel the focus, response message + CRCLTeacherCancelClientFocusR *cancel_client_response; + cancel_client_response + = (CRCLTeacherCancelClientFocusR *) receive_str->msg; + + printf("cancel client focus response is %d\n", + cancel_client_response->ResponseType); + if (cancel_client_response->ResponseType != 0) + { + error_info_no = 12; + perror("failed to cancel focus!"); + return -1; + } + + if (is_focus_set == 1) + { + + if (get_client_clist() < 0) + { + perror("get client clist failed!"); + return -1; + } + is_focus_set = 0; + } + break; + + case 10032: + //student leave the class, response message B, send to other clients + CRCLClientLeaveGroupRAll *client_leave_group_response; + client_leave_group_response + = (CRCLClientLeaveGroupRAll *) receive_str->msg; + + if (client_leave_group_response->ClientInfo.ClientID == clist_focusid) + { + if (is_focus_set == 1) + is_focus_set = 0; + gtk_widget_set_sensitive(concentrate_concel_button, FALSE); + + } + + if (get_client_clist() < 0) + { + perror("get client clist failed!"); + return -1; + } + + break; + + case 10042: + //MCU leave the class, send message to other clients + CRCLMCULeaveGroupRAll *mcu_leave_group; + mcu_leave_group = (CRCLMCULeaveGroupRAll *) receive_str->msg; + g_student_audioreceiver.Stop(); + + g_studet_videoreceiver.CloseXImage(); + g_studet_videoreceiver.Stop(); + + switch (g_video_mode) + { + + case 1: + g_teacher_v4lvideosender.CloseXImage(); + g_teacher_v4lvideosender.Stop(); + g_teacher_v4lvideosender.ClearDestinations(); + break; + } + + g_teacher_audiosender.Pause(); + g_teacher_screensender.Stop(); + + is_focus_set = 0; + + gtk_widget_set_sensitive(creatclass, TRUE); + gtk_widget_set_sensitive(creat_toolbutton, TRUE); + + gtk_widget_set_sensitive(stopclass, FALSE); + gtk_widget_set_sensitive(cancel_toolbutton, FALSE); + + gtk_widget_set_sensitive(modetech, FALSE); + gtk_widget_set_sensitive(tech_toolbutton, FALSE); + + gtk_widget_set_sensitive(modecomu, FALSE); + gtk_widget_set_sensitive(commu_toolbutton, FALSE); + + gtk_widget_set_sensitive(chat_button, FALSE); + + break; + case 1091: + //teacher send allow/forbid message + struct CRCLTeacherIfAllowChatR *allow_chat_response; + allow_chat_response = (CRCLTeacherIfAllowChatR *) receive_str->msg; + if (allow_chat_response->ResponseType != 0) + { + + if (allow_chat_set == 0) + { + error_info_no = 19; + gtk_tool_button_set_label( + (GtkToolButton*) allow_chat_toolbutton, pmodeswich); + + } + else + { + error_info_no = 20; + gtk_tool_button_set_label( + (GtkToolButton*) allow_chat_toolbutton, palwcht); + + } + perror("failed to set chat!"); + return -1; + } + if (allow_chat_set == 0) + { + allow_chat_set = 1; + + } + + else + { + allow_chat_set = 0; + + } + break; + default: + + break; + } + + return 0; + +} + +void client_ts_communicate::get_text_from_msg(char *Message) +{ + textview_mutex.Lock(); + gtk_text_buffer_insert(commu_buffer, &commu_end, Message, -1); + textview_mutex.Unlock(); +} + +void client_ts_communicate::flush_scrollar() +{ + textview_mutex.Lock(); + error_info_no = 40; + textview_mutex.Unlock(); +} Added: incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.h URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.h?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.h (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/client_communicate.h Fri Oct 9 08:58:41 2009 @@ -0,0 +1,31 @@ +#ifndef CLIENT_COMMUNICATE_H +#define CLIENT_COMMUNICATE_H +#include +#include "stdafx.h" +#include "clientsocket.h" +#include "singlecomm.h" +#include "trcclient.hh" + +class client_ts_communicate +{ +public: + client_ts_communicate(); + ~client_ts_communicate(); + + int establish_connect(LPCTSTR, UINT, UINT nSocketPort = 0); + int send_mes(struct CRCLMSG, int mes_length); + int recevie_msg(char *buf, int buf_length); + int close_socket(int nHow); + void get_text_from_msg(char *Message); + void flush_scrollar(); + DWORD TeacherID; + DWORD GroupID; + + static JMutex studentlist_mutex; +private: + CClientSocket client_socket; + CSingleComm client_socket_thread; + JMutex textview_mutex; +}; + +#endif Added: incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.cpp URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.cpp?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.cpp (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.cpp Fri Oct 9 08:58:41 2009 @@ -0,0 +1,57 @@ +// ClientSocket.cpp: implementation of the CClientSocket class. + +#include "stdafx.h" +#include "clientsocket.h" +#include "client_communicate.h" + +extern client_ts_communicate client_comm; + +CClientSocket::CClientSocket() +{ + +} + +CClientSocket::~CClientSocket() +{ +} + +void CClientSocket::OnEvent() +{ + unsigned long len; + if (m_lEvent == 0) + return; + IOCtl(FIONREAD, &len); + if (len == 0) + { + Close(); + printf("\nA client disconnected."); + return; + } + + char buffer[10008] = + { '\0' }; + int receive_length = 0; + + memset(buffer, '\0', 10008); + if ((receive_length = Receive(buffer, 10008)) == -1) + { + perror("Receive failed!"); + return; + } + + CRCLMSG* pM = (CRCLMSG*) buffer; + printf("message lenth is %d\n", pM->msglen); + int index = receive_length; + int to_receive_length = pM->msglen + 8 - receive_length; + while (to_receive_length > 0) + { + receive_length = Receive(buffer + index, to_receive_length); + printf("recv a message lenth is %d\n", receive_length); + index += receive_length; + to_receive_length -= receive_length; + } + + client_comm.recevie_msg(buffer, receive_length); + + return; +} Added: incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.h URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.h?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.h (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/clientsocket.h Fri Oct 9 08:58:41 2009 @@ -0,0 +1,19 @@ +// ClientSocket.h: interface for the CClientSocket class. + +#if !defined(CLIENTSOCKET_H) +#define CLIENTSOCKET_H + +#include "asyncsocketex.h" + +class CClientSocket: public CAsyncSocketEx +{ +public: + CClientSocket(); + virtual ~CClientSocket(); + +protected: + virtual void OnEvent(); + +}; + +#endif // !defined(CLIENTSOCKET_H) Added: incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.cpp URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.cpp?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.cpp (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.cpp Fri Oct 9 08:58:41 2009 @@ -0,0 +1,1412 @@ +#include "en_de_audio.h" + +#define ENCODE_ID CODEC_ID_MP2 +#define DECODE_ID CODEC_ID_MP3 + +#define STATIC_AUDIO_FRAMES 10 + +extern void PErrorText(const char* error); + +int CADecoder::g_count = 0; + +CAEncoder::CAEncoder() : + m_soundcard("/dev/dsp") +{ + + m_pCodec = 0; + m_pCodecCtx = 0; + m_bInit = false; + + m_audio_buf = 0; + m_fifo = 0; + m_data = 0; + m_datasize = 0; + +} + +CAEncoder::~CAEncoder() +{ + m_bInit = false; + CloseAudio(); + + if (m_data) + { + free( m_data); + m_data = 0; + m_datasize = 0; + } + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + + if (m_audio_buf) + free( m_audio_buf); + + if (m_fifo) + { + fifo_free( m_fifo); + free(m_fifo); + } + +} + +void CAEncoder::CloseAudio() +{ +} + +bool CAEncoder::OpenAudio() +{ + if (m_soundcard.start_record() < 0) + { + printf("\nopen audio error.\n"); + return false; + } + + SOUNDPARAMS sp; + sp.format = 2; + + sp.channels = 1; + + sp.rate = AUDIO_ENCODE_sample_rate; + + m_soundcard.setparams(&sp); + + printf("\nopen audio success.\n"); + return true; + +} + +#define MAX_AUDIO_PACKET_SIZE (128 * 1024) +bool CAEncoder::Init(enum CodecID nCodecID /*=CODEC_ID_MPEG4*/) +{ + m_bInit = false; + /*Init for encode*/ + avienc_init(); + av_register_all(); + + if (!OpenAudio()) + return false; + + m_pCodec = avcodec_find_encoder(nCodecID); + if (!m_pCodec) + { + PErrorText("codec not found"); + return false; + } + + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + + m_pCodecCtx = avcodec_alloc_context(); + /* put sample parameters */ + m_pCodecCtx->codec_id = nCodecID; + m_pCodecCtx->codec_type = CODEC_TYPE_AUDIO; + m_pCodecCtx->bit_rate = AUDIO_ENCODE_bit_rate; + m_pCodecCtx->sample_rate = AUDIO_ENCODE_sample_rate; + m_pCodecCtx->channels = 1; + + if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) + { + PErrorText("could not open codec"); + return false; + } + + if (0 == m_audio_buf) + m_audio_buf = (uint8_t*) av_malloc(2 * MAX_AUDIO_PACKET_SIZE); + + if (m_fifo == 0) + { + m_fifo = (FifoBuffer*) malloc(sizeof(FifoBuffer)); + fifo_init(m_fifo, 10000); + + } + + m_bInit = true; + return true; +} + +int CAEncoder::EncodeProcess(uint8_t* data, uint8_t *pOutBuf[2], int nOutsize) +{ + int size_out = nOutsize; + int loop_times = 0; + + if (!m_bInit) + return -1; + + /* now encode as many frames as possible */ + if (m_pCodecCtx->frame_size > 1) + { + + fifo_write(m_fifo, data, nOutsize, &m_fifo->wptr); + + int frame_bytes = m_pCodecCtx->frame_size * 2 * m_pCodecCtx->channels; + + while (fifo_read(m_fifo, m_audio_buf, frame_bytes, &m_fifo->rptr) == 0) + { + + m_encode_length[loop_times] = avcodec_encode_audio(m_pCodecCtx, + pOutBuf[loop_times], 4 * MAX_AUDIO_PACKET_SIZE, + (short *) m_audio_buf); + ++loop_times; + + if (loop_times >= 2) + break; + + } + } + else + { + + switch (m_pCodecCtx->codec->id) + { + case CODEC_ID_PCM_S16LE: + case CODEC_ID_PCM_S16BE: + case CODEC_ID_PCM_U16LE: + case CODEC_ID_PCM_U16BE: + break; + default: + size_out = size_out >> 1; + break; + } + m_encode_length[0] = avcodec_encode_audio(m_pCodecCtx, pOutBuf[0], + size_out, (short *) data); + loop_times = 1; + printf("now encode here!\n"); + } + + return loop_times; + +} + +int CAEncoder::Capture(uint8_t** pOutBuf, int &size) +{ + int ret; + static uint8_t buf[10000]; + if (!m_bInit) + return -1; + + m_soundcard.sounddata(buf, ret); + if (ret > 0) + { + *pOutBuf = buf; + size = ret; + return ret; + } + + return -1; +} + +// For CADecoder class. +CADecoder::CADecoder() +{ + m_pCodec = 0; + m_pCodecCtx = 0; + m_pSDLBuf = 0; + m_bInit = false; + + if (g_count <= 0) + { + if (g_count < 0) + g_count = 0; + } + +} + +CADecoder::~CADecoder() +{ + + m_bInit = false; + + CloseAudio(); + + if (m_pSDLBuf) + { + free( m_pSDLBuf); + m_pSDLBuf = 0; + } + + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + +} + +void CADecoder::CloseAudio() +{ + +} + +bool CADecoder::OpenAudio() +{ + + return true; +} + +bool CADecoder::Init(enum CodecID nCodecID/* = CODEC_ID_MP3*/, int nOutBufSize /*= SDLBufSize*/) +{ + m_bInit = false; + + avcodec_init(); + avcodec_register_all(); + + if (!OpenAudio()) + { + printf("\n Open audio device faild!"); + return false; + } + //malloc SDLBuf. + if (m_pSDLBuf) + { + free( m_pSDLBuf); + m_pSDLBuf = 0; + } + + m_pSDLBuf = (uint8_t*) malloc(nOutBufSize * sizeof(uint8_t)); + if (m_pSDLBuf == 0) + { + PErrorText("OutBuf malloc failed!"); + return false; + } + // find the video decoder + m_pCodec = avcodec_find_decoder(nCodecID); + if (!m_pCodec) + { + PErrorText("Codec not found"); + return false; + } + + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + m_pCodecCtx = avcodec_alloc_context(); + + // frames per second + m_pCodecCtx->frame_rate = A_DECODE_framerate; + m_pCodecCtx->frame_rate_base = A_DECODE_frame_rate_base; + // emit one intra frame every ten frames + m_pCodecCtx->gop_size = A_DECODE_gop_size; + m_pCodecCtx->bit_rate = AUDIO_DECODE_bit_rate; + m_pCodecCtx->sample_rate = AUDIO_DECODE_sample_rate; + m_pCodecCtx->channels = 1; + + m_pCodecCtx->codec_type = CODEC_TYPE_AUDIO; + + if (m_pCodec->capabilities & CODEC_CAP_TRUNCATED) + m_pCodecCtx->flags |= CODEC_FLAG_TRUNCATED; + + // open it + if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) + { + PErrorText("could not open codec"); + return false; + } + m_bInit = true; + return true; +} + +int SetFormat(unsigned int fd, unsigned int bits, unsigned int chn, + unsigned int hz) +{ + int ioctl_val; + + /* set bit format */ + ioctl_val = bits; + if (ioctl(fd, SNDCTL_DSP_SETFMT, &ioctl_val) == -1) + { + fprintf(stderr, "Set fmt to bit failed:\n"); + return (-1); + } + if (ioctl_val != bits) + { + fprintf(stderr, "do not support bit supported \n"); + return (-1); + } + + /*set channel */ + ioctl_val = chn; + if ((ioctl(fd, SNDCTL_DSP_CHANNELS, &ioctl_val)) == -1) + { + fprintf(stderr, "Set Audio Channels %d failed:\n", chn); + return (-1); + } + if (ioctl_val != chn) + { + fprintf(stderr, "do not support channel %d,supported\n", chn); + return (-1); + } + + /*set speed */ + ioctl_val = hz; + if (ioctl(fd, SNDCTL_DSP_SPEED, &ioctl_val) == -1) + { + fprintf(stderr, "Set speed to %d failed:\n", hz); + return (-1); + } + if (ioctl_val != hz) + { + fprintf(stderr, "do not support speed %d,supported is\n", hz); + return (-1); + } + + return (0); +} + +int CADecoder::DecodeProcess(uint8_t *encodeddata_a, + const int encodeddatasize_a) +{ + + static JMutex writemutex; + int len; + int encodedAudioSize; + int outAudioBufSize; + int kkk; + + if (!m_bInit) + { + return -1; + } + + if (!writemutex.IsInitialized()) + { + if (!writemutex.Init()) + { + PErrorText("\nDecodeProcess: writemutex Init error\n"); + return -1; + + } + } + + encodedAudioSize = encodeddatasize_a; + len = 0; + kkk = 0; + while (encodedAudioSize > 0) + { + len = avcodec_decode_audio(m_pCodecCtx, (short *) m_pSDLBuf, + &outAudioBufSize, encodeddata_a + kkk, encodedAudioSize); + if (len < 0) + { + PErrorText("Error While Decoding Audio"); + return -2; + } + + encodedAudioSize -= len; + kkk += len; + } + static int s_iloops = 0; + static char s_chAudioBuf[STATIC_AUDIO_FRAMES * 2 * 4096]; + static int s_AudioBuflength = 0; + memcpy(s_chAudioBuf + s_AudioBuflength, m_pSDLBuf, outAudioBufSize); + s_AudioBuflength += outAudioBufSize; + s_iloops++; + + if (outAudioBufSize > 0) + if (s_iloops >= STATIC_AUDIO_FRAMES) + { + writemutex.Lock(); + static int64_t pre, cur, inteval; + pre = av_gettime(); + //write + int fd2; + fd2 = open("/dev/dsp", O_WRONLY); + if (SetFormat(fd2, AFMT_S16_LE, 1, 44100) < 0) + { + fprintf(stderr, "cannot set............\n"); + return (-1); + } + printf("here test 2 %d , %d ........\n", m_pCodecCtx->sample_rate, + fd2); + write(fd2, s_chAudioBuf, s_AudioBuflength); + close(fd2); + + s_iloops = 0; + s_AudioBuflength = 0; + cur = av_gettime(); + inteval = (cur - pre); + + writemutex.Unlock(); + } + + return 0; +} + +//CAudioSender class. + +CAudioSender::CAudioSender() +{ + stop = false; + m_bIsRecord = false; + m_bInit = 0; + m_sendpause = false; + + m_hFile = 0; +} + +CAudioSender::~CAudioSender() +{ + Stop(); + + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + if (m_pOutBuf[0] != 0) + free( m_pOutBuf[0]); + + if (m_pOutBuf[1] != 0) + free( m_pOutBuf[1]); +} + +#define MAX_PACKET_SIZE 10*1024 +bool CAudioSender::Init(int nPort) +{ + if (m_bInit) + return true; + + //init rtpsession. + RTPSessionParams sessParams1; + sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second + sessParams1.SetUsePollThread(0); //background thread to call virtual callbacks - set by default, but just to be sure + sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE); + //setup transmission parameters + RTPUDPv4TransmissionParams transParams1; + transParams1.SetPortbase(nPort); + //CREATE THE SESSION + int status1 = m_fecrtpsession.Create(sessParams1, &transParams1); + if (status1) + { + return false; + } + //must set for fec SendFECPacket. + m_fecrtpsession.SetDefaultMark(true); + m_fecrtpsession.SetDefaultPayloadType(1); + m_fecrtpsession.SetDefaultTimestampIncrement(0); + + for (int i = 0; i <= 1; i++) + { + if (m_pOutBuf[i] == 0) + { + m_pOutBuf[i] = (uint8_t*) malloc(CAEncoder::A_OutBufSize); + if (m_pOutBuf[i] == 0) + { + return false; + } + } + } + + //Init vencoder. + if (!m_aencoder.Init(ENCODE_ID)) + { + return false; + } + + m_bIsRecord = false; + m_bInit = true; + return m_bInit; +} + +int CAudioSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */) +{ + if (!m_bInit) + return -1; + + if (JThread::IsRunning()) + return 0; + + if (!stopmutex.IsInitialized()) + { + if (stopmutex.Init() < 0) + return -2; + } + + stop = false; + + if (!m_sendpausemutex.IsInitialized()) + { + if (m_sendpausemutex.Init() < 0) + return -2; + } + + m_sendpause = false; + + if (!m_recordmutex.IsInitialized()) + { + if (m_recordmutex.Init() < 0) + return -2; + } + + m_bIsRecord = bIsRecord; + + if (bIsRecord && szFile != 0) + { + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + m_hFile = fopen(szFile, "wb"); + + if (m_hFile == 0) + { + return -3; + } + + m_bIsRecord = true; + } + + if (JThread::Start() < 0) + { + m_bIsRecord = false; + return -6; + } + + return 0; +} + +void CAudioSender::Stop() +{ + if (!IsRunning()) + return; + + stopmutex.Lock(); + stop = true; + stopmutex.Unlock(); + + sleep(2); + if (JThread::IsRunning()) + { + JThread::Kill(); + } + stop = false; + + //close file. + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + m_bIsRecord = false; +} + +void CAudioSender::Pause() +{ + if (!m_bInit) + return; + m_sendpausemutex.Lock(); + m_sendpause = true; + m_sendpausemutex.Unlock(); + +} + +void CAudioSender::Resume() +{ + if (!m_bInit) + return; + + m_sendpausemutex.Lock(); + m_sendpause = false; + m_sendpausemutex.Unlock(); + +} + +void CAudioSender::Record(bool bInRecord /* =true */) +{ + if (!m_bInit) + return; + + m_recordmutex.Lock(); + m_bIsRecord = bInRecord; + m_recordmutex.Unlock(); + +} + +void *CAudioSender::Thread() +{ + uint8_t * data; + int datasize; + int OutBufSzie; + int status; + int i = 0; + + JThread::ThreadStarted(); + + bool stopthread; + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + + bool sendpause; + + m_sendpausemutex.Lock(); + sendpause = m_sendpause; + m_sendpausemutex.Unlock(); + + bool isrecord; + m_recordmutex.Lock(); + isrecord = m_bIsRecord; + m_recordmutex.Unlock(); + + int64_t pre_time, cur_time; + useconds_t delay = 0; + pre_time = av_gettime(); + while (!stopthread) + { + + cur_time = av_gettime(); + delay = cur_time - pre_time; + if (delay < 20000 * 2) + { + usleep(20000 * 2 - delay); + + } + pre_time = av_gettime(); + + if ((status = m_aencoder.Capture(&data, datasize)) < 0) + { + printf("\naudio capture failed"); + stopthread = true; + } + else + { + if (datasize <= 0) + continue; + OutBufSzie = datasize; + if ((status = m_aencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie)) + < 0) + { + printf("\naudio EncodeProcess failed"); + stopthread = true; + } + else + { + if (status > 0) + { + + if (!sendpause) + { + static int s_iTemp = 0; + s_iTemp++; + + for (i = 0; i < status; i++) + { + + static char temp_buf[1000]; + int *temp_p = (int *) temp_buf; + *temp_p = s_iTemp; + memcpy(temp_buf + sizeof(int), m_pOutBuf[i], + m_aencoder.encodelength(i)); + m_fecrtpsession.SendPacket(temp_buf, + m_aencoder.encodelength(i) + sizeof(int)); + if (m_hFile != 0 && isrecord) + { + + fwrite(m_pOutBuf[i], + m_aencoder.encodelength(i), 1, m_hFile); + } + } + } + } + + m_recordmutex.Lock(); + isrecord = m_bIsRecord; + m_recordmutex.Unlock(); + + m_sendpausemutex.Lock(); + sendpause = m_sendpause; + m_sendpausemutex.Unlock(); + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + } + } + + } + printf("\naudio thread stop normally."); + return 0; +} + +bool CAudioSender::AddDestination(const RTPIPv4Address &des) +{ + if (!m_bInit) + return false; + if (m_fecrtpsession.AddDestination(des) < 0) + return false; + + return true; +} + +void CAudioSender::ClearDestinations() +{ + if (!m_bInit) + return; + m_fecrtpsession.ClearDestinations(); +} + +//CStuAudioSender class. + +CStuAudioSender::CStuAudioSender() +{ + stop = false; + m_bInit = 0; + m_sendpause = false; + + m_pOutBuf[0] = 0; + m_pOutBuf[1] = 0; + +} + +CStuAudioSender::~CStuAudioSender() +{ + Stop(); + + if (m_pOutBuf[0] != 0) + free( m_pOutBuf[0]); + if (m_pOutBuf[1] != 0) + free( m_pOutBuf[1]); +} + +bool CStuAudioSender::Init(int nPort) +{ + if (m_bInit) + return true; + + //init rtpsession. + RTPSessionParams sessParams1; + sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second + sessParams1.SetUsePollThread(0); //background thread to call virtual callbacks - set by default, but just to be sure + sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE); + //setup transmission parameters + RTPUDPv4TransmissionParams transParams1; + transParams1.SetPortbase(nPort); + //CREATE THE SESSION + int status1 = m_fecrtpsession.Create(sessParams1, &transParams1); + if (status1) + { + return false; //unable to create the session + } + //must set for fec SendFECPacket. + m_fecrtpsession.SetDefaultMark(true); + m_fecrtpsession.SetDefaultPayloadType(1); + m_fecrtpsession.SetDefaultTimestampIncrement(0); + + for (int i = 0; i <= 1; i++) + { + if (m_pOutBuf[i] == 0) + { + m_pOutBuf[i] = (uint8_t*) malloc(CAEncoder::A_OutBufSize); + if (m_pOutBuf[i] == 0) + { + return false; + } + + } + } + //Init vencoder. + if (!m_aencoder.Init(ENCODE_ID)) + { + return false; + } + + m_bInit = true; + return m_bInit; +} + +int CStuAudioSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */) +{ + if (!m_bInit) + return -1; + + if (JThread::IsRunning()) + return 0; + + if (!stopmutex.IsInitialized()) + { + if (stopmutex.Init() < 0) + return -2; + } + + stop = false; + + if (!m_sendpausemutex.IsInitialized()) + { + if (m_sendpausemutex.Init() < 0) + return -2; + } + + m_sendpause = false; + + if (JThread::Start() < 0) + { + return -6; + } + + return 0; +} + +void CStuAudioSender::Stop() +{ + if (!IsRunning()) + return; + + stopmutex.Lock(); + stop = true; + stopmutex.Unlock(); + + sleep(1); + if (JThread::IsRunning()) + { + JThread::Kill(); + } + stop = false; + +} + +void CStuAudioSender::Pause() +{ + if (!m_bInit) + return; + m_sendpausemutex.Lock(); + m_sendpause = true; + m_sendpausemutex.Unlock(); + +} + +void CStuAudioSender::Resume() +{ + if (!m_bInit) + return; + + m_sendpausemutex.Lock(); + m_sendpause = false; + m_sendpausemutex.Unlock(); + +} + +void *CStuAudioSender::Thread() +{ + uint8_t * data; + int datasize; + int OutBufSzie; + int status; + + JThread::ThreadStarted(); + + bool stopthread; + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + + bool sendpause; + + m_sendpausemutex.Lock(); + sendpause = m_sendpause; + m_sendpausemutex.Unlock(); + + int64_t pre_time, cur_time; + useconds_t delay; + pre_time = av_gettime(); + while (!stopthread) + { + + cur_time = av_gettime(); + delay = cur_time - pre_time; + if (delay < 20000 * 2) + { + usleep(20000 * 2 - delay); + pre_time = av_gettime(); + } + if ((status = m_aencoder.Capture(&data, datasize)) < 0) + { + printf("\naudio capture failed"); + stopthread = true; + } + else + { + + if (datasize <= 0) + continue; + OutBufSzie = datasize; + if ((status = m_aencoder.EncodeProcess(data, m_pOutBuf, OutBufSzie)) + < 0) + { + printf("\naudio EncodeProcess failed"); + stopthread = true; + } + else + { + if (status > 0) + { + if (!sendpause) + { + static int s_iTemp1 = 0; + s_iTemp1++; + for (int i = 0; i < status; i++) + { + static char temp_buf[1000]; + int *temp_p = (int *) temp_buf; + static int s_iTemp1 = 0; + s_iTemp1++; + + *temp_p = s_iTemp1; + memcpy(temp_buf + sizeof(int), m_pOutBuf[i], + m_aencoder.encodelength(i)); + m_fecrtpsession.SendPacket(temp_buf, + m_aencoder.encodelength(i) + sizeof(int)); + } + } + } + + m_sendpausemutex.Lock(); + sendpause = m_sendpause; + m_sendpausemutex.Unlock(); + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + } + } + + } + printf("\nAudio capture thread stoped.\n"); + return 0; +} + +bool CStuAudioSender::AddDestination(const RTPIPv4Address &des) +{ + if (!m_bInit) + return false; + if (m_fecrtpsession.AddDestination(des) < 0) + return false; + + return true; +} + +void CStuAudioSender::ClearDestinations() +{ + if (!m_bInit) + return; + m_fecrtpsession.ClearDestinations(); +} + +//CAudioReceiver class. + +CAudioReceiver::CAudioReceiver() +{ + m_bInit = false; +} + +CAudioReceiver::~CAudioReceiver() +{ + +} + +bool CAudioReceiver::Init() +{ + if (m_bInit) + return m_bInit; + + //init video decoder. + if (!m_adecoder.Init(DECODE_ID)) + { + return false; + } + + m_bInit = true; + return m_bInit; + +} + +int CAudioReceiver::Start(int nPort) +{ + if (!m_bInit) + return -1; + + if (IsActive()) + return 0; + + //init rtpsession. + RTPSessionParams sessParams1; + sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second + sessParams1.SetUsePollThread(1); //background thread to call virtual callbacks - set by default, but just to be sure + sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE); + //setup transmission parameters + RTPUDPv4TransmissionParams transParams1; + transParams1.SetPortbase(nPort); + //CREATE THE SESSION + int status1 = Create(sessParams1, &transParams1); + if (status1) + { + return -2; //unable to create the session + } + + return 0; +} + +void CAudioReceiver::Stop() +{ + Destroy(); +} + +void CAudioReceiver::OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, + const RTPAddress *senderaddress) +{ + int *iTemp = 0; + iTemp = (int *) pack->GetPayloadData(); + printf("now receive audio sequen is %d\n", *iTemp); + + m_adecoder.DecodeProcess(pack->GetPayloadData() + sizeof(int), + pack->GetPayloadLength() - sizeof(int)); + +} + +/* ---------------------------------------------------------------------- */ + +Soundcard::Soundcard(const char *dev) +{ + if (dev) + strcpy(devname, dev); + else + strcpy(devname, "/dev/dsp"); + + driver_name[0] = '\0'; + + stat = STATUS_CLOSED; + get_capabilities(); + channels = 1; + rate = 22050; + fd = -1; +} + +Soundcard::~Soundcard() +{ + close_dev(); +} + +int Soundcard::start_record() +{ + switch (stat) + { + case STATUS_CLOSED: + if (!init_done) + get_capabilities(); + if (!init_done) + return -1; + return open_dev(TRUE); + case STATUS_RECORD: + return 0; + case STATUS_PLAYBACK: + close_dev(); + return open_dev(TRUE); + } + return -1; +} + +int Soundcard::start_playback() +{ + switch (stat) + { + case STATUS_CLOSED: + if (!init_done) + get_capabilities(); + if (!init_done) + return -1; + return open_dev(FALSE); + case STATUS_RECORD: + close_dev(); + return open_dev(FALSE); + case STATUS_PLAYBACK: + return 0; + } + return -1; +} + +int Soundcard::kill_buffer() +{ + ioctl(fd, SNDCTL_DSP_RESET, 0); + return 0; +} + +int Soundcard::stop() +{ + if (stat != STATUS_CLOSED) + close_dev(); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +void Soundcard::get_capabilities() +{ + int i, dsp; + int try_afmt; + int try_channels; + + afmt = 0; + if (-1 != (dsp = open(devname, O_RDONLY))) + { + + ioctl(dsp, SNDCTL_DSP_SETFMT, &afmt); /* current */ + ioctl(dsp, SNDCTL_DSP_GETFMTS, &afmt_hw); /* hardware cap */ + afmt_sw = 0; + + for (i = 0; i < 16; i++) + { + try_afmt = (1 << i); + if (-1 == ioctl(dsp, SNDCTL_DSP_SETFMT, &try_afmt)) + continue; + if (try_afmt != (1 << i)) + continue; + afmt_sw |= try_afmt; + } + + try_channels = 2; + if (-1 != ioctl(dsp, SNDCTL_DSP_CHANNELS, &try_channels) && 2 + == try_channels) + channels_hw = 2; + else + channels_hw = 1; + + close(dsp); + init_done = 1; + + } + else + { + init_done = 0; + } +} + +int Soundcard::has_channels() +{ + if (!init_done) + return -1; + return channels_hw; +} + +int Soundcard::has_format(int f) +{ + if (!init_done) + return -1; + switch (f) + { + case FMT_8BIT: + return (afmt_hw & AFMT_U8) ? 1 : 0; + break; + case FMT_16BIT: + return (afmt_hw & AFMT_S16_LE) ? 1 : 0; + break; + case FMT_MULAW: + case FMT_ALAW: + default: + return 0; + } +} + +char* +Soundcard::driver() +{ + return driver_name; +} + +int Soundcard::open_dev(int record) +{ + struct SOUNDPARAMS p; + int frag, rrate; + + if (-1 == (fd = open(devname, record ? O_RDONLY : O_WRONLY))) + goto err; + fcntl(fd, F_SETFD, FD_CLOEXEC); + + /* try to get ~50 ms latency */ + blocksize = 50 * channels * rate / 1000; + if (afmt == AFMT_U16_BE || afmt == AFMT_S16_BE || afmt == AFMT_U16_LE + || afmt == AFMT_S16_LE) + blocksize *= 2; + for (frag = 0; blocksize != 1; frag++) + blocksize >>= 1; + + frag |= 0x7fff0000; + if (-1 == ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag)) + perror("ioctl SNDCTL_DSP_SETFRAGMENT"); + + rrate = rate; + if (-1 == ioctl(fd, SNDCTL_DSP_SETFMT, &afmt)) + { + perror("ioctl SNDCTL_DSP_SETFMT"); + goto err; + } + if (-1 == ioctl(fd, SNDCTL_DSP_CHANNELS, &channels)) + { + perror("ioctl SNDCTL_DSP_SETFMT"); + goto err; + } + if (-1 == ioctl(fd, SNDCTL_DSP_SPEED, &rrate)) + { + perror("ioctl SNDCTL_DSP_SETFMT"); + goto err; + } + if (-1 == ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blocksize)) + { + perror("ioctl SNDCTL_DSP_SETFMT"); + goto err; + } + if (0 == blocksize) + blocksize = 4096; + if (rrate != rate) + { + fprintf(stderr, "sample rate: asked for %d, hardware uses %d. ", rate, + rrate); + if (abs(rate - rrate) * 100 < rate) + { + fprintf(stderr, "that's fine (diff <1%%).\n"); + } + else + { + fprintf(stderr, "way off, using hardware rate.\n"); + rate = rrate; + } + } + + latency = blocksize * 1000 / channels / rate; + if (afmt == AFMT_U16_BE || afmt == AFMT_S16_BE || afmt == AFMT_U16_LE + || afmt == AFMT_S16_LE) + latency = latency / 2; + + stat = record ? STATUS_RECORD : STATUS_PLAYBACK; + + p.channels = channels; + p.rate = rate; + p.blocksize = blocksize; + p.latency = latency; + switch (afmt) + { + case AFMT_U8: + p.format = FMT_8BIT; + break; + case AFMT_S16_LE: + p.format = FMT_16BIT; + break; + default: + fprintf(stderr, "oops(open): unsupported sound format\n"); + exit(1); + } + + if (record) + { + trigger = ~PCM_ENABLE_INPUT; + ioctl(fd, SNDCTL_DSP_SETTRIGGER, &trigger); + trigger = PCM_ENABLE_INPUT; + ioctl(fd, SNDCTL_DSP_SETTRIGGER, &trigger); + } + return 0; + + err: if (-1 != fd) + close( fd); + stat = STATUS_CLOSED; + fd = -1; + return -1; +} + +void Soundcard::close_dev() +{ + close( fd); + fd = -1; + stat = STATUS_CLOSED; + + return; +} + +void Soundcard::setparams(struct SOUNDPARAMS *p) +{ + rate = p->rate; + channels = p->channels; + switch (p->format) + { + case FMT_8BIT: + afmt = AFMT_U8; + break; + case FMT_16BIT: + afmt = AFMT_S16_LE; + break; + default: + fprintf(stderr, "oops(set): unsupported sound format\n"); + exit(1); + } + + switch (stat) + { + case STATUS_RECORD: + close_dev(); + open_dev( TRUE); + break; + case STATUS_PLAYBACK: + close_dev(); + open_dev( FALSE); + break; + case STATUS_CLOSED: + if (!init_done) + get_capabilities(); + if (!init_done) + return; + if (0 == open_dev(TRUE)) + close_dev(); + break; + } + + printf("\nchannels=%d\n", channels); + printf("\nrate=%d\n", rate); + printf("\nblocksize=%d\n", blocksize); + printf("\nlatency=%d\n", latency); + +} + +void Soundcard::sounddata(uint8_t* buf, int &size) +{ + int rc, have; + + switch (stat) + { + case STATUS_RECORD: + /* read */ + for (have = 0; have < blocksize;) + { + rc = read(fd, buf + have, blocksize - have); + switch (rc) + { + case -1: + { + printf("\naudio capture failed\n"); + size = -1; + return; + } + break; + case 0: + fprintf(stderr, "Huh? got 0 bytes from sound device?\n"); + exit(1); + default: + have += rc; + } + } + size = have; + break; + case STATUS_PLAYBACK: + if (-1 != fd) + write(fd, buffer, blocksize); + break; + } +} Added: incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.h URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.h?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.h (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/en_de_audio.h Fri Oct 9 08:58:41 2009 @@ -0,0 +1,269 @@ +//en_de_audio.h + +#include "fecrtpsession.h" + +// Linux sys. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// FFmpeg +#include +#include +#include +#include + +#include +#include + +#include + +#define STATUS_CLOSED 0 +#define STATUS_RECORD 1 +#define STATUS_PLAYBACK 2 + +#define FMT_UNDEFINED 0 +#define FMT_8BIT 1 /* unsigned */ +#define FMT_16BIT 2 /* signed - native byte order */ +#define FMT_MULAW 4 /* NOT SUPPORTED (yet) */ +#define FMT_ALAW 8 /* NOT SUPPORTED (yet) */ + +#define FMT_MAX 2 + +struct SOUNDPARAMS +{ + int format; + int channels; + int rate; + int blocksize; + int latency; +}; + +class Soundcard +{ + +public: + /* sound card capabilities */ + char devname[32]; + int init_done; + int afmt_hw; + int afmt_sw; + int channels_hw; + + int trigger; + char driver_name[64]; + + int afmt; + int channels; + int rate; + int blocksize; + int latency; + + int fd, stat; + char buffer[65536]; + void get_capabilities(); + int open_dev(int record); + void close_dev(); + +public: + Soundcard(const char *dev); + ~Soundcard(); + char *driver(); + void setparams(struct SOUNDPARAMS *params); + int start_record(); + int start_playback(); + int kill_buffer(); + int stop(); + + int has_channels(); /* # of channels (1=mono,2=stereo) */ + int has_format(int f); /* check format availibity */ + +public: + void sounddata(uint8_t* buf, int &size); + +}; + +#if !defined(_EN_DE_AUDIO_H__INCLUDED_) +#define _EN_DE_AUDIO_H__INCLUDED_ + +// Audio decoder. +class CADecoder +{ +public: +private: + enum ADECODERBUFSIZE + { + A_SDLBufSize = AVCODEC_MAX_AUDIO_FRAME_SIZE + }; + enum AUDIO_DECODEC_PARA + { + AUDIO_DECODE_bit_rate = 64000, + AUDIO_DECODE_sample_rate = 44100, + A_DECODE_framerate = 25, + A_DECODE_frame_rate_base = 1, + A_DECODE_gop_size = 12 + }; + +public: + CADecoder(); + virtual ~CADecoder(); +public: + int DecodeProcess(uint8_t *encodeddata_a, const int encodeddatasize_a); + bool Init(enum CodecID nCodecID = CODEC_ID_MP3, int nOutBufSize = + A_SDLBufSize); +private: + bool OpenAudio(); + void CloseAudio(); +private: + bool m_bInit; + AVCodec *m_pCodec; + AVCodecContext *m_pCodecCtx; + uint8_t *m_pSDLBuf; + +public: + static int g_count; + char name[32]; + +}; + +// Audio encoder. + +class CAEncoder +{ + friend class CAudioSender; + friend class CStuAudioSender; +private: + enum AUDIO_ENCODEC_PARA + { + AUDIO_ENCODE_bit_rate = 64000, + AUDIO_ENCODE_sample_rate = 44100, + A_ENCODE_framerate = 25, + A_ENCODE_frame_rate_base = 1, + A_ENCODE_gop_size = 12 + }; +private: + bool OpenAudio(); + void CloseAudio(); + +private: + + enum AENCODERBUFSIZE + { + A_OutBufSize = 4 * 128 * 1024 + }; +public: + int Capture(uint8_t** pOutBuf, int &size); + int EncodeProcess(uint8_t* data, uint8_t *pOutBuf[2], int nOutsize); + bool Init(enum CodecID nCodecID = CODEC_ID_MP2); + CAEncoder(); + virtual ~CAEncoder(); + inline int encodelength(int i) + { + return m_encode_length[i]; + } +private: + + // for audio. +private: + uint8_t* m_data; + int m_datasize; + // for encode. +private: + bool m_bInit; + AVCodec *m_pCodec; + AVCodecContext *m_pCodecCtx; + int m_encode_length[2]; +public: + Soundcard m_soundcard; + uint8_t* m_audio_buf; + FifoBuffer *m_fifo; +}; + +class CAudioSender: private JThread +{ +public: + CAudioSender(); + ~CAudioSender(); + bool Init(int nPort); + bool AddDestination(const RTPIPv4Address &des); + void ClearDestinations(); + int Start(char* szFile = 0, bool bIsRecord = false); + void Pause(); + void Resume(); + void Record(bool bInRecord = true); + void Stop(); +private: + void *Thread(); + bool stop; + + JMutex stopmutex; + +private: + bool m_bIsRecord; + JMutex m_recordmutex; + + CAEncoder m_aencoder; + uint8_t *m_pOutBuf[2]; + FILE* m_hFile; + RTPSession m_fecrtpsession; + int m_bInit; + bool m_sendpause; + JMutex m_sendpausemutex; +}; + +//audio sender. +class CStuAudioSender: private JThread +{ +public: + CStuAudioSender(); + ~CStuAudioSender(); + bool Init(int nPort); + bool AddDestination(const RTPIPv4Address &des); + void ClearDestinations(); + int Start(char* szFile = 0, bool bIsRecord = false); + void Pause(); + void Resume(); +private: + void Stop(); + void *Thread(); + bool stop; + JMutex stopmutex; +private: + CAEncoder m_aencoder; + + uint8_t *m_pOutBuf[2]; + RTPSession m_fecrtpsession; + int m_bInit; + bool m_sendpause; + JMutex m_sendpausemutex; +}; + +//audio receiver + +class CAudioReceiver: public RTPSession +{ +public: + CAudioReceiver(); + virtual ~CAudioReceiver(); + + bool Init(); + int Start(int nPort); + void Stop(); + +private: + virtual void OnRTPPacket(RTPPacket *pack, const RTPTime &receivetime, + const RTPAddress *senderaddress); + +private: + bool m_bInit; + CADecoder m_adecoder; +}; + +#endif // !defined(_EN_DE_AUDIO_H__INCLUDED_) Added: incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.cpp URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.cpp?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.cpp (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.cpp Fri Oct 9 08:58:41 2009 @@ -0,0 +1,17 @@ +#include "en_de_common.h" + +static char g_error_txt[550]; + +char* GetLastErrText() +{ + return g_error_txt; +} + +void PErrorText(const char* error) +{ + if (strlen(error) <= 500) + { + sprintf(g_error_txt, "\nEn_De Error:%s", error); + } +} + Added: incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.h URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.h?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.h (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/en_de_common.h Fri Oct 9 08:58:41 2009 @@ -0,0 +1,12 @@ +//en_de_common.h + +#if !defined(_EN_DE_COMMON_INCLUDED_) +#define _EN_DE_COMMON_INCLUDED_ + +extern char* GetLastErrText(); + +#include "en_de_audio.h" +#include "en_de_video.h" +#include "en_de_screen.h" + +#endif // !defined(_EN_DE_COMMON_INCLUDED_) Added: incubator/bluesky/trunk/RealClass/Teacher/src/en_de_screen.cpp URL: http://svn.apache.org/viewvc/incubator/bluesky/trunk/RealClass/Teacher/src/en_de_screen.cpp?rev=823467&view=auto ============================================================================== --- incubator/bluesky/trunk/RealClass/Teacher/src/en_de_screen.cpp (added) +++ incubator/bluesky/trunk/RealClass/Teacher/src/en_de_screen.cpp Fri Oct 9 08:58:41 2009 @@ -0,0 +1,1392 @@ +#include "en_de_screen.h" + +extern int delay_time; + +extern void PErrorText(const char* error); +//CSEncoder class. + +CSEncoder::CSEncoder() +{ + m_pFrameBuf = 0; + m_pFrame = 0; + m_pCodec = 0; + m_pCodecCtx = 0; + m_bInit = false; + m_bInitScreen = false; + + m_image = 0; + m_display = 0; + m_d = 0; + m_width = 0; + m_height = 0; + m_screen_num = 0; + +} + +CSEncoder::~CSEncoder() +{ + m_bInitScreen = false; + m_bInit = false; + + if (m_pFrameBuf) + { + free( m_pFrameBuf); + m_pFrameBuf = 0; + } + + if (m_pFrame) + { + free( m_pFrame); + m_pFrame = 0; + } + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + + if (m_image) + { + XDestroyImage( m_image); + m_image = 0; + } + + if (m_display) + { + if (m_d) + { + XClearWindow(m_display, m_d); + m_d = 0; + } + + XCloseDisplay( m_display); + m_display = 0; + } + +} + +bool CSEncoder::Init(enum CodecID nCodecID /*=CODEC_ID_MPEG4*/) +{ + m_bInit = false; + /*Init for encode*/ + avcodec_init(); + avcodec_register_all(); + + if (!InitScreen(S_CODEC_width, S_CODEC_height)) + return false; + + if (m_pFrame) + { + free( m_pFrame); + m_pFrame = 0; + } + m_pFrame = avcodec_alloc_frame(); + + /* find the mpeg4 video encoder */ + m_pCodec = avcodec_find_encoder(nCodecID); + if (!m_pCodec) + { + PErrorText("codec not found\n"); + return false; + } + + if (m_pCodecCtx) + { + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + + m_pCodecCtx = avcodec_alloc_context(); + /* resolution must be a multiple of two */ + m_pCodecCtx->width = m_width; + m_pCodecCtx->height = m_height; + /* frames per second */ + m_pCodecCtx->frame_rate = S_CODEC_framerate; + m_pCodecCtx->frame_rate_base = S_CODEC_frame_rate_base; + m_pCodecCtx->gop_size = S_CODEC_gop_size; /* emit one intra frame every ten frames */ + + m_pCodecCtx->bit_rate = 512 * 1024; + m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P; + m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO; + + /* open it */ + if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) + { + fprintf(stderr, "could not open codec\n"); + return false; + } + + if (m_pFrameBuf) + { + free( m_pFrameBuf); + m_pFrameBuf = 0; + } + + int image_size = avpicture_get_size(PIX_FMT_YUV420P, m_pCodecCtx->width, + m_pCodecCtx->height); + + m_pFrameBuf = (uint8_t*) malloc(image_size); + if (m_pFrameBuf == 0) + { + PErrorText("FrameBuf malloc failed!"); + return false; + } + /*Init for encode*/ + + avpicture_fill((AVPicture*) m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, + m_pCodecCtx->width, m_pCodecCtx->height); + m_pFrame->type = FF_BUFFER_TYPE_SHARED; + + m_bInit = true; + return true; +} + +int CSEncoder::EncodeProcess(XImage *image, uint8_t *pOutBuf, int nOutsize) +{ + + if (!m_bInit) + return -1; + + if (nOutsize < S_En_OutBufSize) + { + return -2; + } + + int k, j; + unsigned long r32, g32, b32, color32; + + for (k = 0; k < m_pCodecCtx->height; k++) + { + for (j = 0; j < m_pCodecCtx->width; j++) + { + color32 = *((unsigned long*) (image->data + k * m_pCodecCtx->width + * 4 + j * 4)); + r32 = color32 & (image->red_mask); + g32 = color32 & (image->green_mask); + b32 = color32 & (image->blue_mask); + r32 = ((r32 >> 16) & 255) << 16; + g32 = ((g32 >> 8) & 255) << 8; + b32 = ((b32) & 255); + color32 = r32 | g32 | b32; + color32 = color32 & 16777215; + *((unsigned long*) (image->data + k * m_pCodecCtx->width * 4 + j + * 4)) = color32; + } + } + GetColorInfo(image, &c_info); + switch (image->bits_per_pixel) + { + case 8: + input_pixfmt = PIX_FMT_PAL8; + break; + case 16: + if (image->red_mask == 0xF800 && image->green_mask == 0x07E0 + && image->blue_mask == 0x1F) + { + input_pixfmt = PIX_FMT_RGB565; + } + else if (image->red_mask == 0x7C00 && image->green_mask == 0x03E0 + && image->blue_mask == 0x1F) + { + input_pixfmt = PIX_FMT_RGB555; + } + else + { + fprintf( + stderr, + "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth %i not supported ... aborting\n", + image->bits_per_pixel); + fprintf( + stderr, + "xtoffmpeg.XImageToFFMPEG(): color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n", + image->red_mask, image->green_mask, image->blue_mask); + } + break; + case 24: + if (image->red_mask == 0xFF0000 && image->green_mask == 0xFF00 + && image->blue_mask == 0xFF) + { + input_pixfmt = PIX_FMT_BGR24; + } + else if (image->red_mask == 0xFF && image->green_mask == 0xFF00 + && image->blue_mask == 0xFF0000) + { + input_pixfmt = PIX_FMT_RGB24; + } + else + { + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth not supported ... aborting\n"); + PErrorText("xtoffmpeg.XImageToFFMPEG()"); + return false; + } + break; + case 32: + if (c_info.alpha_mask == 0xFF000000 && image->green_mask == 0xFF00) + { + input_pixfmt = PIX_FMT_RGBA32; + } + else + { + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting"); + return false; + } + break; + default: + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting"); + return false; + } + + avpicture_fill(&m_pic_rgb, (uint8_t *) image->data, input_pixfmt, + m_pCodecCtx->width, m_pCodecCtx->height); + avpicture_fill((AVPicture*) m_pFrame, m_pFrameBuf, PIX_FMT_YUV420P, + m_pCodecCtx->width, m_pCodecCtx->height); + + if (img_convert((AVPicture*) m_pFrame, PIX_FMT_YUV420P, &m_pic_rgb, + input_pixfmt, m_pCodecCtx->width, m_pCodecCtx->height) < 0) + { + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): pixel format conversion not handled ... aborting"); + return -2; + } + + m_ScreenHeader.width = m_width; + m_ScreenHeader.height = m_height; + memcpy((char *) pOutBuf, &m_ScreenHeader, sizeof(ScreenHeader)); + + int ret; + ret = avcodec_encode_video(m_pCodecCtx, pOutBuf + sizeof(ScreenHeader), + nOutsize, m_pFrame); + + if (ret <= 0) + return ret; + + return ret + sizeof(ScreenHeader); + +} + +bool CSEncoder::InitScreen(int width, int height) +{ + if (m_bInitScreen) + return true; + m_display = XOpenDisplay(NULL); + + m_width = width; + m_height = height; + m_screen_num = DefaultScreen(m_display); + + m_d = RootWindow(m_display, m_screen_num); + + XWindowAttributes win_attr; + + if (!XGetWindowAttributes(m_display, m_d, &win_attr)) + + perror("Can't get window attributes!\n"); + + m_image = 0; + m_bInitScreen = true; + return true; +} + +bool CSEncoder::GetScreenSize(int &width, int &height) +{ + if (!m_bInit) + return false; + + width = m_pCodecCtx->width; + height = m_pCodecCtx->height; + + return true; +} + +//Mouse capture. +uint16_t mousePointerBlack[] = +{ 0, 49152, 40960, 36864, 34816, 33792, 33280, 33024, 32896, 32832, 33728, + 37376, 43264, 51456, 1152, 1152, 576, 576, 448, 0 }; +uint16_t mousePointerWhite[] = +{ 0, 0, 16384, 24576, 28672, 30720, 31744, 32256, 32512, 32640, 31744, 27648, + 17920, 1536, 768, 768, 384, 384, 0, 0 }; + +void CSEncoder::getCurrentPointer(int *x, int *y) +{ + Window mrootwindow, childwindow; + int dummy; + + if (!m_bInit) + return; + + mrootwindow = DefaultRootWindow(m_display); + + if (XQueryPointer(m_display, mrootwindow, &mrootwindow, &childwindow, x, y, + &dummy, &dummy, (unsigned int *) &dummy)) + { + + } + else + { + *x = -1; + *y = -1; + } + + XClearWindow(m_display, mrootwindow); +} + +void CSEncoder::paintMousePointer(int *x, int *y, XImage *image) +{ + // only paint a mouse pointer into the dummy frame if the position of the mouse + // is within the rectangle defined by the capture frame + + if (*x >= 0 && *x < S_CODEC_width - 25 && //25 is width and height of cursor . + *y >= 0 && *y < S_CODEC_height - 25) + { + int line; + uint8_t *im_data = (uint8_t *) image->data; + + // move the cursor to the right starting position + im_data += (image->bytes_per_line * (*y)); // shift to right line + im_data += (image->bits_per_pixel / 8 * (*x)); // shift to right pixel + + uint32_t *cursor; + int width; + uint16_t bm_b, bm_w, mask; + + // the dummy mouse pointer is 20 pixels high ... + for (line = 0; line < 20; line++) + { + bm_b = mousePointerBlack[line]; + bm_w = mousePointerWhite[line]; + + mask = (0x0001 << 15); + + // ... and 16 pixels wide + for (cursor = (uint32_t*) im_data, width = 0; ((width + *x) + < S_CODEC_width && width < 16); cursor++, width++) + { + if ((bm_b & mask) > 0) + { + *cursor &= ((~image->red_mask) & (~image->green_mask) + & (~image->blue_mask)); + } + else if ((bm_w & mask) > 0) + { + *cursor |= (image->red_mask | image->green_mask + | image->blue_mask); + } + mask >>= 1; + } + im_data += image->bytes_per_line; + } + + } +} + +//Mouse capture. + +bool CSEncoder::Capture(XImage **image) +{ + int x, y; + if (!m_bInitScreen) + return false; + + if (m_image) + { + m_image->f.destroy_image(m_image); + m_image = 0; + } + getCurrentPointer(&x, &y); + m_image = XGetImage(m_display, m_d, 0, 0, m_width, m_height, AllPlanes, + ZPixmap); + + if (m_image == 0) + { + PErrorText("GetImage error"); + return false; + } + paintMousePointer(&x, &y, m_image); + + *image = m_image; + return true; +} + +void CSEncoder::GetColorInfo(XImage *image, ColorInfo *ci /* return struct */) +{ + unsigned long red_mask, green_mask, blue_mask, alpha_mask; + // the shifts are unsigned longs as well + + if (!ci) + return; + + // setting shifts and bit_depths to zero + ci->red_shift = ci->green_shift = ci->blue_shift = ci->alpha_shift = 0; + ci->red_bit_depth = ci->green_bit_depth = ci->blue_bit_depth + = ci->alpha_bit_depth = 0; + + red_mask = image->red_mask; + if (red_mask > 0) + { + // shift red_mask to the right till all empty bits have been + // shifted out and count how many they were + while ((red_mask & 0x01) == 0) + { + red_mask >>= 1; + ci->red_shift++; + } + // count how many bits are set in the mask = depth + while ((red_mask & 0x01) == 1) + { + red_mask >>= 1; + ci->red_bit_depth++; + } + } + + ci->red_max_val = (1 << ci->red_bit_depth) - 1; + + green_mask = image->green_mask; + if (green_mask > 0) + { + while ((green_mask & 0x01) == 0) + { + green_mask >>= 1; + ci->green_shift++; + } + while ((green_mask & 0x01) == 1) + { + green_mask >>= 1; + ci->green_bit_depth++; + } + } + ci->green_max_val = (1 << ci->green_bit_depth) - 1; + + blue_mask = image->blue_mask; + if (blue_mask > 0) + { + while ((blue_mask & 0x01) == 0) + { + blue_mask >>= 1; + ci->blue_shift++; + } + while ((blue_mask & 0x01) == 1) + { + blue_mask >>= 1; + ci->blue_bit_depth++; + } + } + ci->blue_max_val = (1 << ci->blue_bit_depth) - 1; + + ci->max_val = max(ci->red_max_val, ci->green_max_val); + ci->max_val = max(ci->blue_max_val, ci->max_val); + ci->bit_depth = max(ci->red_bit_depth, ci->green_bit_depth); + ci->bit_depth = max(ci->blue_bit_depth, ci->bit_depth); + if (image->bits_per_pixel > image->depth) + { + + ci->alpha_mask = ~(image->red_mask | image->blue_mask + | image->green_mask); + alpha_mask = ci->alpha_mask; + if (alpha_mask > 0) + { + while ((alpha_mask & 0x01) == 0) + { + alpha_mask >>= 1; + ci->alpha_shift++; + } + while ((alpha_mask & 0x01) == 1) + { + alpha_mask >>= 1; + ci->alpha_bit_depth++; + } + } + ci->alpha_max_val = (1 << ci->alpha_bit_depth) - 1; + } +} +//CSDecoder class. +CSDecoder::CSDecoder() +{ + m_pCodec = 0; + m_pCodecCtx = 0; + m_pOutFrame = 0; + m_bInit = false; + m_display = 0; + m_win = 0; + m_d = 0; + m_image = 0; + m_parent = 0; + + m_width = 0; + m_height = 0; + +} + +CSDecoder::~CSDecoder() +{ + m_bInit = false; + + if (m_image) + { + XDestroyImage( m_image); + m_image = 0; + } + + if (m_display) + { + if (m_win) + { + XClearWindow(m_display, m_win); + m_win = 0; + } + if (m_d) + { + XClearWindow(m_display, m_d); + m_d = 0; + } + + XCloseDisplay( m_display); + m_display = 0; + } + + if (m_pOutFrame) + { + free( m_pOutFrame); + m_pOutFrame = 0; + } + if (m_pCodecCtx) + { + if (m_pCodecCtx->extradata) + { + free(m_pCodecCtx->extradata); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + } + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + +} + +bool CSDecoder::CreateXImage(Drawable parent, int x, int y, int width, + int height) +{ + int screen_num; + + if (!m_bInit) + return false; + + CloseXImage(); + + m_imagemutex.Lock(); + + m_display = XOpenDisplay(NULL); + screen_num = DefaultScreen(m_display); + + m_win = XCreateSimpleWindow(m_display, parent, x, y, width, height, 0, + BlackPixel(m_display, screen_num), 65535 / 20); + + XMapWindow(m_display, m_win); + m_gc = DefaultGC(m_display, screen_num); + + m_d = RootWindow(m_display, screen_num); + + m_image = XGetImage(m_display, m_d, 0, 0, m_width, m_height, AllPlanes, + ZPixmap); + if (!m_image) + { + printf("error\n"); + m_imagemutex.Unlock(); + return false; + } + + m_imagemutex.Unlock(); + m_parent = parent; + return true; +} + +void CSDecoder::CloseXImage() +{ + if (!m_bInit) + return; + + m_imagemutex.Lock(); + if (m_image) + { + XDestroyImage( m_image); + m_image = 0; + } + + if (m_display) + { + if (m_win) + { + XUnmapWindow(m_display, m_win); + XClearWindow(m_display, m_win); + m_win = 0; + } + + if (m_d) + { + XClearWindow(m_display, m_d); + m_d = 0; + } + + XCloseDisplay( m_display); + m_display = 0; + + } + + m_imagemutex.Unlock(); + +} + +void CSDecoder::CloseCodec() +{ + m_bInit = false; + + if (m_pOutFrame) + { + free( m_pOutFrame); + m_pOutFrame = 0; + } + if (m_pCodecCtx) + { + if (m_pCodecCtx->extradata) + { + free(m_pCodecCtx->extradata); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + } + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + +} +bool CSDecoder::ResetCodec(const int width, const int height) +{ + CodecID nCodecID = m_pCodecCtx->codec_id; + CloseCodec(); + m_bInit = false; + + m_width = width; + m_height = height; + + // find the video decoder + m_pCodec = avcodec_find_decoder(nCodecID); + if (!m_pCodec) + { + PErrorText("Codec not found"); + return false; + } + + if (m_pOutFrame) + { + free( m_pOutFrame); + m_pOutFrame = 0; + } + m_pOutFrame = avcodec_alloc_frame(); + + if (m_pCodecCtx) + { + if (m_pCodecCtx->extradata) + { + free(m_pCodecCtx->extradata); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + } + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + m_pCodecCtx = avcodec_alloc_context(); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + + // put sample parameters + /* resolution must be a multiple of two */ + m_pCodecCtx->width = m_width; + m_pCodecCtx->height = m_height; + /* frames per second */ + m_pCodecCtx->frame_rate = CSEncoder::S_CODEC_framerate; + m_pCodecCtx->frame_rate_base = CSEncoder::S_CODEC_frame_rate_base; + m_pCodecCtx->gop_size = CSEncoder::S_CODEC_gop_size; /* emit one intra frame every ten frames */ + + m_pCodecCtx->bit_rate = 512 * 1024; + m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P; + m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO; + + m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; + m_pCodecCtx->extradata = malloc(S_De_ExtraHeaderSize); + if (m_pCodecCtx->extradata == 0) + { + return false; + } + m_pCodecCtx->extradata_size = S_De_ExtraHeaderSize / 8; + + // we dont send complete frames + if (m_pCodec->capabilities & CODEC_CAP_TRUNCATED) + m_pCodecCtx->flags |= CODEC_FLAG_TRUNCATED; + + // open it + if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) + { + PErrorText("could not open codec"); + return false; + } + + if (m_image) + { + XDestroyImage( m_image); + m_image = 0; + } + + m_image = XGetImage(m_display, m_parent, 0, 0, m_width, m_height, + AllPlanes, ZPixmap); + if (!m_image) + { + PErrorText("GetImage error"); + m_imagemutex.Unlock(); + return false; + } + + m_bInit = true; + return true; + +} + +bool CSDecoder::Init(int width, int height, enum CodecID nCodecID) +{ + + if (m_bInit) + return true; + + avcodec_init(); + avcodec_register_all(); + + if (!m_imagemutex.IsInitialized()) + { + if (m_imagemutex.Init() < 0) + return false; + } + + m_width = width; + m_height = height; + + // find the video decoder + m_pCodec = avcodec_find_decoder(nCodecID); + if (!m_pCodec) + { + PErrorText("Codec not found"); + return false; + } + + if (m_pOutFrame) + { + free( m_pOutFrame); + m_pOutFrame = 0; + } + m_pOutFrame = avcodec_alloc_frame(); + + if (m_pCodecCtx) + { + if (m_pCodecCtx->extradata) + { + free(m_pCodecCtx->extradata); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + } + avcodec_close( m_pCodecCtx); + m_pCodecCtx = 0; + } + m_pCodecCtx = avcodec_alloc_context(); + m_pCodecCtx->extradata = 0; + m_pCodecCtx->extradata_size = 0; + + // put sample parameters + /* resolution must be a multiple of two */ + m_pCodecCtx->width = m_width; + m_pCodecCtx->height = m_height; + /* frames per second */ + m_pCodecCtx->frame_rate = CSEncoder::S_CODEC_framerate; + m_pCodecCtx->frame_rate_base = CSEncoder::S_CODEC_frame_rate_base; + m_pCodecCtx->gop_size = CSEncoder::S_CODEC_gop_size; /* emit one intra frame every ten frames */ + + m_pCodecCtx->bit_rate = 512 * 1024; + m_pCodecCtx->pix_fmt = PIX_FMT_YUV420P; + m_pCodecCtx->codec_type = CODEC_TYPE_VIDEO; + + m_pCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER; + m_pCodecCtx->extradata = malloc(S_De_ExtraHeaderSize); + if (m_pCodecCtx->extradata == 0) + { + return false; + } + m_pCodecCtx->extradata_size = S_De_ExtraHeaderSize / 8; + + // we dont send complete frames + if (m_pCodec->capabilities & CODEC_CAP_TRUNCATED) + m_pCodecCtx->flags |= CODEC_FLAG_TRUNCATED; + + // open it + if (avcodec_open(m_pCodecCtx, m_pCodec) < 0) + { + PErrorText("could not open codec"); + return false; + } + + // m_bIsFirstKeyFrame = false; + m_bInit = true; + return true; +} + +int CSDecoder::DecodeProcess(uint8_t *encodeddata_v, + const int encodeddatasize_v) +{ + bool isPaintPic; + int realsize, i; + int got_picture; + if (!m_bInit) + { + return -1; + } + + // int ngot = 0; + int left = 0; + int len; + m_imagemutex.Lock(); + for (i = 0;; i++) + { + if (encodeddatasize_v - i * S_De_INBUF_SIZE >= S_De_INBUF_SIZE) + realsize = S_De_INBUF_SIZE; + else + realsize = encodeddatasize_v - i * S_De_INBUF_SIZE; + + if (realsize <= 0) + break; + + left = 0; + isPaintPic = false; + while (realsize > 0) + { + m_pCodecCtx->width = m_width; + m_pCodecCtx->height = m_height; + len = avcodec_decode_video(m_pCodecCtx, m_pOutFrame, &got_picture, + (encodeddata_v + i * S_De_INBUF_SIZE + left), realsize); + + if (len < 0) + { + PErrorText("Error while decoding"); + m_imagemutex.Unlock(); + return -2; + } + + if (m_image != 0) + { + + m_encoder.GetColorInfo(m_image, &c_info); + switch (m_image->bits_per_pixel) + { + case 8: + input_pixfmt = PIX_FMT_PAL8; + break; + case 16: + if (m_image->red_mask == 0xF800 && m_image->green_mask + == 0x07E0 && m_image->blue_mask == 0x1F) + { + input_pixfmt = PIX_FMT_RGB565; + } + else if (m_image->red_mask == 0x7C00 && m_image->green_mask + == 0x03E0 && m_image->blue_mask == 0x1F) + { + input_pixfmt = PIX_FMT_RGB555; + } + else + { + fprintf( + stderr, + "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth %i not supported ... aborting\n", + m_image->bits_per_pixel); + fprintf( + stderr, + "xtoffmpeg.XImageToFFMPEG(): color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n", + m_image->red_mask, m_image->green_mask, + m_image->blue_mask); + } + break; + case 24: + if (m_image->red_mask == 0xFF0000 && m_image->green_mask + == 0xFF00 && m_image->blue_mask == 0xFF) + { + input_pixfmt = PIX_FMT_BGR24; + } + else if (m_image->red_mask == 0xFF && m_image->green_mask + == 0xFF00 && m_image->blue_mask == 0xFF0000) + { + input_pixfmt = PIX_FMT_RGB24; + } + else + { + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): rgb ordering at image depth not supported ... aborting"); + PErrorText("xtoffmpeg.XImageToFFMPEG(): color masks"); + return false; + } + break; + case 32: + if (c_info.alpha_mask == 0xFF000000 && m_image->green_mask + == 0xFF00) + { + + input_pixfmt = PIX_FMT_RGBA32; + } + else + { + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting\n"); + return false; + } + break; + default: + PErrorText( + "xtoffmpeg.XImageToFFMPEG(): image depth not supported ... aborting\n"); + return false; + } + } + + if (got_picture) + { + if (!isPaintPic) + { + if (m_display && m_image && m_win) + { + avpicture_fill(&pic_rgb, (uint8_t*) m_image->data, + input_pixfmt, m_width, m_height); + + if (img_convert(&pic_rgb, input_pixfmt, + (AVPicture*) m_pOutFrame, PIX_FMT_YUV420P, + m_width, m_height) < 0) + { + PErrorText("Error pixel format conversion"); + m_imagemutex.Unlock(); + return -3; + } + + XPutImage(m_display, m_win, m_gc, m_image, 0, 0, 0, 0, + m_width, m_height); + } + } + isPaintPic = true; + + } + realsize -= len; + left += len; + } + } + + m_imagemutex.Unlock(); + return 0; +} + +//CScreenSender class. +CScreenSender::CScreenSender() : + m_sendthread(SendBufSize) +{ + stop = false; + m_bIsRecord = false; + m_bInit = 0; + + m_hFile = 0; + +} + +CScreenSender::~CScreenSender() +{ + //first stop thread, because m_pOutBuf is being used by Thread(); + Stop(); + + //close file. + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + //free buffer. + if (m_pOutBuf != 0) + free( m_pOutBuf); +} + +bool CScreenSender::Init(int nPort) +{ + if (m_bInit) + return true; + + //init sendthread. + if (!m_sendthread.Init(nPort)) + return false; + + if (m_pOutBuf == 0) + { + m_pOutBuf = (uint8_t*) malloc(CSEncoder::S_En_OutBufSize); + if (m_pOutBuf == 0) + { + return false; + } + + } + + //Init sencoder. + if (!m_sencoder.Init(CODEC_ID_MPEG4)) + { + return false; + } + + m_bInit = true; + return m_bInit; +} + +int CScreenSender::Start(char* szFile /* =0 */, bool bIsRecord /* =false */) +{ + if (!m_bInit) + return -1; + + if (JThread::IsRunning()) + return 0; + + if (!stopmutex.IsInitialized()) + { + if (stopmutex.Init() < 0) + return -2; + } + + stop = false; + + if (!m_recordmutex.IsInitialized()) + { + if (m_recordmutex.Init() < 0) + return -2; + } + + m_bIsRecord = bIsRecord; + + if (bIsRecord && szFile != 0) + { + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + m_hFile = fopen(szFile, "wb"); + if (m_hFile == 0) + { + return -3; + } + + } + + if (m_sendthread.Start() < 0) + { + return -6; + } + + if (JThread::Start() < 0) + { + return -6; + } + + return 0; +} + +void CScreenSender::Stop() +{ + if (!IsRunning()) + return; + + stopmutex.Lock(); + stop = true; + stopmutex.Unlock(); + + int count = 0; + while (1) + { + if (count >= 100) + { + if (JThread::IsRunning()) + { + JThread::Kill(); + } + break; + } + + if (JThread::IsRunning()) + { + count++; + usleep(10000); + continue; + } + + break; + } + + stop = false; + + //close file. + if (m_hFile) + { + fclose( m_hFile); + m_hFile = 0; + } + + m_bIsRecord = false; + + m_sendthread.Stop(); + +} + +void CScreenSender::Record(bool bInRecord /* =true */) +{ + if (!m_bInit) + return; + + m_recordmutex.Lock(); + m_bIsRecord = bInRecord; + m_recordmutex.Unlock(); + +} + +void *CScreenSender::Thread() +{ + XImage * pImage; + int OutBufSzie; + + JThread::ThreadStarted(); + + bool stopthread; + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + + bool isrecord; + m_recordmutex.Lock(); + isrecord = m_bIsRecord; + m_recordmutex.Unlock(); + + int status; + + int64_t pre_time, cur_time; + useconds_t delay, delay1; + + if (m_sencoder.m_pCodecCtx->frame_rate != 0) + { + if (m_sencoder.m_pCodecCtx->frame_rate_base != 0) + delay1 = 1000000 * m_sencoder.m_pCodecCtx->frame_rate_base + / m_sencoder.m_pCodecCtx->frame_rate; + else + delay1 = 1000000 / m_sencoder.m_pCodecCtx->frame_rate; + } + else + { + delay1 = 1000000; + } + + // sleep for sync + if (delay_time > 0) + { + sleep( delay_time); + } + + // for Utiltiy rate of CPU + cur_time = av_gettime(); + pre_time = cur_time - delay1; + + // for compensate. + int64_t nFrame = 0; + int64_t rec_time = 0; + int64_t rec_start; + rec_start = av_gettime(); + + while (!stopthread) + { + delay = cur_time - pre_time; + if (delay < delay1) + { + usleep(delay1 - delay); + } + pre_time = av_gettime(); + + if ((status = m_sencoder.Capture(&pImage)) < 0) + { + stopthread = true; + continue; + } + else + { + OutBufSzie = CSEncoder::S_En_OutBufSize; + if ((status = m_sencoder.EncodeProcess(pImage, m_pOutBuf, + OutBufSzie)) < 0) + { + stopthread = true; + continue; + } + else + { + if (status > 0) + { + //static int iiii=0; + m_sendthread.SendData(m_pOutBuf, status); + + if (m_hFile != 0 && isrecord) + { + fwrite(m_pOutBuf + sizeof(ScreenHeader), status + - sizeof(ScreenHeader), 1, m_hFile); + nFrame++; + + //add up rec_time; + rec_time = av_gettime() - rec_start; + int i; + for (i = 0; rec_time > nFrame * delay1; nFrame++, i++) + { + printf("\nScreen Frame=%d\n", nFrame); + if ((status = m_sencoder.EncodeProcess(pImage, + m_pOutBuf, OutBufSzie)) < 0) + { + printf("\nscreen: encode vital error."); + stopthread = true; + printf( + "\nscreen capture thread stoped by EncodeProcess error!\n"); + return 0; + } + if (status > 0) + fwrite(m_pOutBuf + sizeof(ScreenHeader), status + - sizeof(ScreenHeader), 1, m_hFile); + } + + } + else + { + rec_start = av_gettime(); + nFrame = 0; + } + + } + + } + } + + m_recordmutex.Lock(); + isrecord = m_bIsRecord; + m_recordmutex.Unlock(); + + stopmutex.Lock(); + stopthread = stop; + stopmutex.Unlock(); + + cur_time = av_gettime(); + + } + + printf("\nscreen capture thread stoped!\n"); + return 0; +} + +bool CScreenSender::AddDestination(const RTPIPv4Address &des) +{ + if (!m_bInit) + return false; + if (m_sendthread.AddDestination(des) < 0) + return false; + + return true; +} +void CScreenSender::ClearDestinations() +{ + if (!m_bInit) + return; + m_sendthread.ClearDestinations(); +} + +//CScreenReceiver class. + +CScreenReceiver::CScreenReceiver() +{ + m_bInit = false; + m_ScreenInit = false; +} + +CScreenReceiver::~CScreenReceiver() +{ + +} +bool CScreenReceiver::Init() +{ + if (m_bInit) + return m_bInit; + + //init video decoder. + if (!m_sdecoder.Init(800, 600, CODEC_ID_MPEG4)) + { + return false; + } + + m_bInit = true; + return m_bInit; + +} +bool CScreenReceiver::CreateXImage(Drawable parent, int x, int y, int width, + int height) +{ + bool ret; + ret = m_sdecoder.CreateXImage(parent, x, y, width, height); + + return ret; +} + +void CScreenReceiver::CloseXImage() +{ + m_sdecoder.CloseXImage(); +} + +#define MAX_PACKET_SIZE 10240 + +int CScreenReceiver::Start(int nPort) +{ + + if (IsActive()) + return 0; + + //init rtpsession. + RTPSessionParams sessParams1; + sessParams1.SetOwnTimestampUnit(1.0 / 30.0); //30 video frames per second + sessParams1.SetUsePollThread(1); + //background thread to call virtual callbacks - set by default, but just to be sure + sessParams1.SetMaximumPacketSize(MAX_PACKET_SIZE); + //setup transmission parameters + RTPUDPv4TransmissionParams transParams1; + transParams1.SetPortbase(nPort); + //CREATE THE SESSION + int status1 = Create(sessParams1, &transParams1); + if (status1) + { + return -2; + } + + return 0; +} + +void CScreenReceiver::Stop() +{ + Destroy(); +} + +void CScreenReceiver::ProcessFrame(unsigned char* framedata, int framelen) +{ + pScreen = (ScreenHeader*) framedata; + + if (pScreen->width != m_sdecoder.m_width || pScreen->height + != m_sdecoder.m_height) + { + m_sdecoder.ResetCodec(pScreen->width, pScreen->height); + } + m_sdecoder.DecodeProcess(framedata + sizeof(ScreenHeader), framelen + - sizeof(ScreenHeader)); + +}