DlgAudioVideo.cpp
上传用户:gnaf34
上传日期:2022-04-22
资源大小:1657k
文件大小:15k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * DlgAudioVideo.cxx
  3.  *
  4.  * Implementation file
  5.  *
  6.  * Copyright (c) ITEC-Ohio, 2002.
  7.  *
  8.  * The contents of this file are subject to the Mozilla Public License
  9.  * Version 1.0 (the "License"); you may not use this file except in
  10.  * compliance with the License. You may obtain a copy of the License at
  11.  * http://www.mozilla.org/MPL/
  12.  *
  13.  * Software distributed under the License is distributed on an "AS IS"
  14.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  15.  * the License for the specific language governing rights and limitations
  16.  * under the License.
  17.  *
  18.  * The Original Code is Open H323 Library available at http://www.openh323.org
  19.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  20.  *
  21.  */
  22. #include "stdafx.h"
  23. #include <iostream.h>
  24. #include <fstream.h>
  25. #include <ptlib.h>
  26. #include "main.h"
  27. #include "gsmcodec.h"
  28. #include "lpc10codec.h"
  29. #include "mscodecs.h"
  30. #include "h261codec.h"
  31. #include "h323.h"
  32. //#include "videoio.h"
  33. #include "h323pdu.h"
  34. #include "BeaconClient.h"
  35. #include "DlgAudioVideo.h"
  36. #ifdef _DEBUG
  37. #define new DEBUG_NEW
  38. #undef THIS_FILE
  39. static char THIS_FILE[] = __FILE__;
  40. #endif
  41. #define  IDT_TIMER_1  WM_USER + 200 
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CDlgAudioVideo dialog
  44. HBITMAP hGroupBmp;
  45. extern BeaconClient* globalInstance;
  46. extern const char* globalEndReason;
  47. extern BeaconClient* globalInstance;
  48. extern const char* globalEndReason;
  49. extern PString TokenCurrentCall;
  50. extern H323VideoCodec * videoCodecDlgAudioVideo;
  51. UINT    TimerVal;
  52. extern int FlagEndPoint;
  53. int TimerRecordCount = 0;
  54. extern CString consoleStr;
  55. CDlgAudioVideo::CDlgAudioVideo(CWnd* pParent /*=NULL*/)
  56. : CDialog(CDlgAudioVideo::IDD, pParent)
  57. {
  58. //{{AFX_DATA_INIT(CDlgAudioVideo)
  59. //}}AFX_DATA_INIT
  60. }
  61. void CDlgAudioVideo::DoDataExchange(CDataExchange* pDX)
  62. {
  63. CDialog::DoDataExchange(pDX);
  64. //{{AFX_DATA_MAP(CDlgAudioVideo)
  65. DDX_Control(pDX, IDC_STATIC1, m_audioVideo);
  66. //DDX_Control(pDX, IDC_DIRECTANIMATIONWINDOWEDINTEGRATEDMEDIACONTROL1, m_audioVideo);
  67. //}}AFX_DATA_MAP
  68. }
  69. BEGIN_MESSAGE_MAP(CDlgAudioVideo, CDialog)
  70. //{{AFX_MSG_MAP(CDlgAudioVideo)
  71. ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay)
  72. ON_WM_PAINT()
  73. ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
  74. ON_BN_CLICKED(IDC_BUTTON_RECORD, OnButtonRecord)
  75. ON_WM_TIMER()
  76. //}}AFX_MSG_MAP
  77. END_MESSAGE_MAP()
  78. /////////////////////////////////////////////////////////////////////////////
  79. // CDlgAudioVideo message handlers
  80. void CDlgAudioVideo::OnButtonPlay() 
  81. {
  82. consoleStr += "rnCommand to playback recorded audio sent to the H.323 Beacon Server...";
  83. // TODO: Add your control notification handler code here
  84. //PVideoChannel   * channelTmp;
  85. //H323VideoDevice * displaydevice;
  86. //displayDevice = new NullVideoOutputDevice;
  87. //CDlgAudioVideo::KillTimer(TimerVal);
  88. TRY {
  89.  H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall);
  90.          if (connection == NULL)
  91.           return;
  92.          //connection->SendUserInput(tone);
  93.  //channelTmp = OpenVideoChannel(*((H323Connection *)connection), TRUE, *((H323VideoCodec *)videoCodecDlgAudioVideo));
  94.  // How to convert m_AudioVideo to displayDevice ?
  95.  //CDeviceVideoAudio::PlayButton(channelTmp);
  96.  //CDeviceVideoAudio::AttachVideoReader(channelTmp, displayDevice);
  97.  
  98.  connection->SendUserInput(3);
  99.          connection->Unlock();
  100.   
  101.  GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE);
  102.  GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);
  103.  GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(FALSE);
  104.  
  105. }
  106. CATCH_ALL(e){
  107. // Put some delay here
  108. }
  109. END_CATCH_ALL
  110. }
  111. void CDlgAudioVideo::OnPaint() 
  112. {
  113. CPaintDC dc(this); // device context for painting
  114. // TODO: Add your message handler code here
  115. HBITMAP hGroupBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 
  116.                                         MAKEINTRESOURCE(IDB_BITMAP2),
  117.                                         IMAGE_BITMAP, 
  118.                                         180,180, 
  119.                                         LR_DEFAULTCOLOR);
  120. m_audioVideo.SetBitmap(hGroupBmp);
  121. // Do not call CDialog::OnPaint() for painting messages
  122. }
  123. void CDlgAudioVideo::OnButtonStop() 
  124. {
  125. consoleStr += "rnCommand to stop recording sent to the H.323 Beacon Server...";
  126. // TODO: Add your control notification handler code here
  127. TRY {
  128.  H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall);
  129.          if (connection == NULL)
  130. return;
  131.  
  132.  connection->SendUserInput(2);
  133.          connection->Unlock();
  134.  GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE);
  135.  GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);
  136.  GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(TRUE);
  137.  CDlgAudioVideo::KillTimer(TimerVal);
  138.  TimerVal = 0;
  139.  // TODO: Add your control notification handler code here
  140. if (DeleteObject(hGroupBmp) == TRUE){
  141. // Do Nothing
  142. m_audioVideo.SetBitmap(NULL);
  143. CDlgAudioVideo::UpdateWindow();
  144. }
  145. else{
  146. }
  147. }
  148. CATCH_ALL(e){
  149. // Put some delay here
  150. }
  151. END_CATCH_ALL
  152. }
  153. void CDlgAudioVideo::OnButtonRecord() 
  154. {
  155. consoleStr += "rnCommand to record audio stream sent to the H.323 Beacon Server...";
  156. // TODO: Add your control notification handler code here
  157. TRY {
  158. TimerVal = CDlgAudioVideo::SetTimer(IDT_TIMER_1,1000,NULL);
  159. if (TimerVal == 0){
  160.                 MessageBox ("Unable to obtain timer","IDT_TIMER_1",MB_OK |MB_SYSTEMMODAL);
  161.         }
  162. H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall);
  163.         if (connection == NULL)
  164.           return;
  165.  
  166. connection->SendUserInput(1);
  167.         connection->Unlock();
  168. GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(TRUE);
  169. GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);  
  170.  
  171. }
  172. CATCH_ALL(e){
  173. // Put some delay here
  174. }
  175. END_CATCH_ALL
  176. }
  177. PVideoChannel *CDlgAudioVideo::OpenVideoChannel(H323Connection & connection,
  178.                                      BOOL isEncoding,
  179.                                      H323VideoCodec & codec)           
  180. {
  181.   PVideoChannel   * channel = new PVideoChannel;
  182.   
  183.   if (isEncoding) {
  184.     PConfig config;
  185.     
  186.     //codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,1));
  187. //codecSetTxQualityLevel(1); //**Quality of the transmitted video. 1 is good, 31 is poor.
  188.     //codec.SetBackgroundFill(2);
  189.     //Create grabber.
  190.     PVideoInputDevice * grabber = new PVideoInputDevice();
  191.     PStringList devices = grabber->GetDeviceNames();
  192.     PString deviceName;
  193. // Modified, so it just use whatever the "FIRST" available video hardware
  194.     if (devices.IsEmpty())
  195.       deviceName = "Frame test N.0 - Moving line";
  196.     else
  197.       deviceName = grabber->GetDeviceNames()[0];
  198.     //deviceName = config.GetString(VideoDeviceConfigKey, deviceName);
  199. // Modified, so it does not use any config files
  200.     //if (!grabber->Open(deviceName, FALSE) ||
  201.     //    !grabber->SetVideoFormat((PVideoDevice::VideoFormat)config.GetInteger(VideoFormatConfigKey, PVideoDevice::Auto)) ||
  202.     //    !grabber->SetChannel(config.GetInteger(VideoSourceConfigKey,1)) ||
  203.     //   !grabber->SetColourFormatConverter("YUV420P") ||
  204.     //    !grabber->SetFrameSize(videoWidth, videoHeight) ||
  205.     //    !grabber->SetVFlipState(localFlip)) 
  206. // If videosize = CIF then videoWidh = 352, videoHeight = 288
  207. // If videosize = QCIF then videoWidh = 176, videoHeight = 144
  208. // If videosize = Auto then videoWidh = 50, videoHeight = 50
  209.   if (!grabber->Open(deviceName, FALSE)  ||
  210.   !grabber->SetVideoFormat(PVideoDevice::Auto) ||  // Set Video Format to be Auto
  211.   !grabber->SetChannel(0) ||  // Set Channel to be 1
  212.   !grabber->SetColourFormatConverter("YUV420P") ||
  213.   !grabber->SetFrameSize(176, 144)  ||  // videoWidth = 180, videoHeight = 180 // To be fit in Dialog Audio Video
  214.   !grabber->SetVFlipState(TRUE)) 
  215.   
  216. {
  217.       //PTRACE(1, "Failed to open or configure the video device "" << deviceName << '"');
  218.   MessageBox("Failed to open or configure the video device","H.323 Beacon Client",MB_OK);
  219.       delete grabber;
  220.       grabber = new PFakeVideoInputDevice();
  221.       grabber->SetColourFormat("YUV420P");
  222.       grabber->SetVideoFormat(PVideoDevice::PAL);
  223.       grabber->SetFrameSize(180, 180);
  224.       grabber->SetVFlipState(FALSE);
  225.       grabber->SetChannel(atoi(&deviceName[13]));
  226.     }
  227.     else
  228. {
  229. MessageBox("Opening is a success","H.323 Beacon Client",MB_OK);
  230.     grabber->Start();
  231.     channel->AttachVideoReader(grabber);
  232. }
  233. return channel;
  234. // Always play it in Dialog Audio Video Window
  235.    //a if (localVideo)
  236. //a {
  237. // Replace this, so it can play on Beacon Client Video
  238.       //adisplayDevice = new VideoDevice(mainWindow, TRUE, connection.GetLocalPartyName(), FALSE);
  239. //a }
  240.     //a else
  241. //a {
  242.      //a displayDevice = new NullVideoOutputDevice;
  243. //a }
  244.   }
  245.   else
  246.     // Replace this, so it can play on Beacon Client Video
  247. //displayDevice = new VideoDevice(mainWindow, FALSE, connection.GetRemotePartyName(), remoteFlip);
  248.   // a displayDevice->SetFrameSize(180, 180);  // videowidth = 180, videoheight = 180
  249.  
  250.   //Give the video window (which plays video) to the channel.
  251.   // a channel->AttachVideoPlayer(displayDevice);
  252.   //return codec.AttachChannel(channel,TRUE);
  253.   return channel;
  254. }
  255. void CDeviceVideoAudio::PlayButton(PVideoChannel   * channelTmp)
  256. {
  257. H323VideoDevice * displayDevice;
  258. displayDevice = new PPMVideoOutputDevice(99);
  259. /*
  260. MainWindow *mainWindow = new MainWindow();
  261. displayDevice = new VideoDevice(mainWindow,TRUE,"REMOTE",FALSE);
  262. */
  263. AttachVideoReader(channelTmp,displayDevice);
  264. }
  265. void CDeviceVideoAudio::StopButton()
  266. {
  267. }
  268. void CDeviceVideoAudio::AttachVideoReader(PVideoChannel * channel, H323VideoDevice * displayDevice)
  269. {
  270. channel->AttachVideoPlayer(displayDevice);
  271. }
  272. ///////////////////////////////////////////////////////////////////////////////
  273. /*
  274. VideoWindow::VideoWindow(PInteractor * parent, VideoDevice * dev, BOOL local)
  275.   : PFloatingDialog(parent)
  276. {
  277.   device = dev;
  278.   localVideo = local;
  279.   canvas = NULL;
  280. }
  281. VideoWindow::~VideoWindow()
  282. {
  283.   // Release the mutex and request it again, this guarantees that if the video
  284.   // thread happens to be in the mutex wait in WriteLineSegment() it is executed
  285.   // and exited from that function before continuing out of the shutdown procedure.
  286.   mutex.Wait();
  287.   delete canvas;
  288. }
  289. void VideoWindow::OnClose()
  290. {
  291.   Shutdown();
  292.   PConfig config;
  293.   PPoint pos = GetPosition(PixelCoords);
  294.   /*
  295.   config.SetInteger(localVideo ? LocalVideoWindowLeftConfigKey
  296.                                : RemoteVideoWindowLeftConfigKey, pos.X());
  297.   config.SetInteger(localVideo ? LocalVideoWindowTopConfigKey
  298.                                : RemoteVideoWindowTopConfigKey, pos.Y());
  299.   
  300.   PFloatingDialog::OnClose();
  301. }
  302. void VideoWindow::OnCancel()
  303. {
  304.   Shutdown();
  305.   Close();
  306. }
  307. void VideoWindow::OnRedraw(PCanvas & redrawCanvas)
  308. {
  309.   if (!image.IsNULL())
  310.     redrawCanvas.DrawPixels(0, 0, image);
  311.   // We create canvas in here as under Win32 we must have the construction AND
  312.   // destruction of a canvas in the "GUI" thread.
  313.   if (canvas == NULL) {
  314.     canvas = new PDrawCanvas(this);
  315.     canvas->SetViewportRect(canvas->GetMappingRect());
  316.   }
  317. }
  318. void VideoWindow::SetVideoSize(int width, int height)
  319. {
  320.   SetDimensions(width, height, PixelCoords);
  321.   if (image.IsNULL() ||
  322.       image->Width() != (PDIMENSION)width ||
  323.       image->Height() != (PDIMENSION)height) {
  324.     mutex.Wait();
  325.     image = PPixelImage(width, height, 24);
  326.     raster = PPixelImage(width, 1, 24);
  327.     mutex.Signal();
  328.   }
  329.   PConfig config;
  330.   /*
  331.   PORDINATE x = config.GetInteger(localVideo ? LocalVideoWindowLeftConfigKey
  332.                                              : RemoteVideoWindowLeftConfigKey,
  333.                                   localVideo ? 0 : 300);
  334.   PORDINATE y = config.GetInteger(localVideo ? LocalVideoWindowTopConfigKey
  335.                                              : RemoteVideoWindowTopConfigKey,
  336.                                   GetParent()->GetDimensions(PixelCoords).Height());
  337. PORDINATE x = 50;
  338. PORDINATE y = 50;
  339.   SetPosition(x, y, TopLeftPixels, TopLeftPixels);
  340.   Show();
  341. }
  342. BOOL VideoWindow::WriteLineSegment(int x, int y, unsigned len, const BYTE * data)
  343. {
  344.   PWaitAndSignal wait(mutex);
  345.   if (device == NULL || image.IsNULL())
  346.     return FALSE;
  347.   memcpy(image->GetRasterDataPtr(y)+x*3, data, len*3);
  348.   if (canvas == NULL)
  349.     Invalidate();
  350.   else {
  351.     memcpy(raster->GetRasterDataPtr(0), image->GetRasterDataPtr(y), image->GetDimensions().Width()*3);
  352.     canvas->DrawPixels(0, y, raster);
  353.   }
  354.   return TRUE;
  355. }
  356. void VideoWindow::Shutdown()
  357. {
  358.   mutex.Wait();
  359.   if (device != NULL) {
  360.     device->windowOpen = FALSE;
  361.     device = NULL;
  362.   }
  363.   mutex.Signal();
  364. }
  365. ///////////////////////////////////////////////////////////////////////////////
  366. VideoDevice::VideoDevice(MainWindow * mainWindow,
  367.                          BOOL local,
  368.                          const PString & title,
  369.                          BOOL flipIt)
  370. {
  371.   window = new VideoWindow(mainWindow, this, local);
  372.   window->SetTitle(title);
  373.   windowOpen = TRUE;
  374.   rgbReverseOrder = TRUE;
  375.   flip = flipIt;
  376. }
  377. VideoDevice::~VideoDevice()
  378. {
  379.   if (windowOpen)
  380.     window->OnCancel();
  381. }
  382. BOOL VideoDevice::SetFrameSize(unsigned w, unsigned h)
  383. {
  384.   unsigned old_w, old_h;
  385.   H323VideoDevice::GetFrameSize(old_w, old_h);
  386.   if (old_w != w || old_h != h) {
  387.     if (!H323VideoDevice::SetFrameSize(w, h))
  388.       return FALSE;
  389.     if (windowOpen)
  390.       window->SetVideoSize(w, h);
  391.   }
  392.   return TRUE;
  393. }
  394. BOOL VideoDevice::WriteLineSegment(int x, int y, unsigned len, const BYTE * data)
  395. {
  396.   if (!windowOpen)
  397.     return FALSE;
  398.   if (flip)
  399.     y = (frameHeight-1) - y;
  400.   return window->WriteLineSegment(x, y, len, data);
  401. }
  402. */
  403. ///////////////////////////////////////////////////////////////////////////////
  404. void CDlgAudioVideo::OnTimer(UINT nIDEvent) 
  405. {
  406. // TODO: Add your message handler code here and/or call default
  407. CDialog::OnTimer(nIDEvent);
  408. if (TimerRecordCount == 30 && FlagEndPoint == 0){
  409. CDlgAudioVideo::KillTimer(TimerVal);
  410. TimerVal = 0;
  411. //CWnd::KillTimer(TimerVal);
  412. /*if(CWnd::KillTimer(TimerVal) == 0)
  413. MessageBox("Cleared...3","H.323 Beacon Client", MB_OK);
  414. else
  415. MessageBox("Not Cleared...3","H.323 Beacon Client", MB_OK);*/
  416.  MessageBox("Maximum Record Time is 30 seconds ... Recording Stopped !","H323 Beacon Client",MB_OK |MB_SYSTEMMODAL);
  417.  GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE);
  418.  GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);
  419.  GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(TRUE);
  420.  TimerRecordCount = 0;
  421.  
  422.  if (FlagEndPoint == 0){
  423.   if (globalInstance->endpoint !=NULL){
  424. TRY {
  425. H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall);
  426. if (connection == NULL)
  427. return;
  428.  
  429. connection->SendUserInput(2);
  430. connection->Unlock();
  431. }
  432.  CATCH_ALL(e){
  433.  }
  434.  END_CATCH_ALL
  435.   }
  436. }
  437.              
  438. }
  439. else{
  440. TimerRecordCount++;
  441. }
  442. }