www.pudn.com > H323BeaconClient-v1.4_win_src.zip > DlgAudioVideo.cpp, change:2004-06-22,size:15586b


/* 
 * DlgAudioVideo.cxx 
 * 
 * Implementation file 
 * 
 * Copyright (c) ITEC-Ohio, 2002. 
 * 
 * The contents of this file are subject to the Mozilla Public License 
 * Version 1.0 (the "License"); you may not use this file except in 
 * compliance with the License. You may obtain a copy of the License at 
 * http://www.mozilla.org/MPL/ 
 * 
 * Software distributed under the License is distributed on an "AS IS" 
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific language governing rights and limitations 
 * under the License. 
 * 
 * The Original Code is Open H323 Library available at http://www.openh323.org 
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 
 * 
 */ 
 
#include "stdafx.h" 
#include <iostream.h> 
#include <fstream.h> 
#include <ptlib.h> 
#include "main.h" 
#include "gsmcodec.h" 
#include "lpc10codec.h" 
#include "mscodecs.h" 
#include "h261codec.h" 
#include "h323.h" 
//#include "videoio.h" 
#include "h323pdu.h" 
 
#include "BeaconClient.h" 
#include "DlgAudioVideo.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define  IDT_TIMER_1  WM_USER + 200  
 
///////////////////////////////////////////////////////////////////////////// 
// CDlgAudioVideo dialog 
 
 
HBITMAP hGroupBmp; 
extern BeaconClient* globalInstance; 
extern const char* globalEndReason; 
extern BeaconClient* globalInstance; 
extern const char* globalEndReason; 
extern PString TokenCurrentCall; 
extern H323VideoCodec * videoCodecDlgAudioVideo; 
UINT    TimerVal; 
extern int FlagEndPoint; 
int TimerRecordCount = 0; 
extern CString consoleStr; 
 
CDlgAudioVideo::CDlgAudioVideo(CWnd* pParent /*=NULL*/) 
	: CDialog(CDlgAudioVideo::IDD, pParent) 
{ 
	//{{AFX_DATA_INIT(CDlgAudioVideo) 
	//}}AFX_DATA_INIT 
 
} 
 
 
void CDlgAudioVideo::DoDataExchange(CDataExchange* pDX) 
{ 
	CDialog::DoDataExchange(pDX); 
	//{{AFX_DATA_MAP(CDlgAudioVideo) 
	DDX_Control(pDX, IDC_STATIC1, m_audioVideo); 
	//DDX_Control(pDX, IDC_DIRECTANIMATIONWINDOWEDINTEGRATEDMEDIACONTROL1, m_audioVideo); 
	//}}AFX_DATA_MAP 
} 
 
 
BEGIN_MESSAGE_MAP(CDlgAudioVideo, CDialog) 
	//{{AFX_MSG_MAP(CDlgAudioVideo) 
	ON_BN_CLICKED(IDC_BUTTON_PLAY, OnButtonPlay) 
	ON_WM_PAINT() 
	ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop) 
	ON_BN_CLICKED(IDC_BUTTON_RECORD, OnButtonRecord) 
	ON_WM_TIMER() 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CDlgAudioVideo message handlers 
 
 
void CDlgAudioVideo::OnButtonPlay()  
{ 
	consoleStr += "\r\nCommand to playback recorded audio sent to the H.323 Beacon Server..."; 
	// TODO: Add your control notification handler code here 
 
	//PVideoChannel   * channelTmp; 
	//H323VideoDevice * displaydevice; 
	 
 
	//displayDevice = new NullVideoOutputDevice; 
 
	//CDlgAudioVideo::KillTimer(TimerVal); 
	TRY { 
 
		 
		 H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall); 
 
         if (connection == NULL) 
          return; 
         //connection->SendUserInput(tone); 
		 //channelTmp = OpenVideoChannel(*((H323Connection *)connection), TRUE, *((H323VideoCodec *)videoCodecDlgAudioVideo)); 
		 // How to convert m_AudioVideo to displayDevice ? 
 
		 //CDeviceVideoAudio::PlayButton(channelTmp); 
 
		 //CDeviceVideoAudio::AttachVideoReader(channelTmp, displayDevice); 
		  
		 connection->SendUserInput(3); 
         connection->Unlock(); 
   
		 GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE); 
		 GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);	 
		 GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(FALSE); 
		  
	} 
	CATCH_ALL(e){ 
		// Put some delay here		 
	} 
	END_CATCH_ALL 
	 
} 
 
 
 
 
void CDlgAudioVideo::OnPaint()  
{ 
	CPaintDC dc(this); // device context for painting 
	 
	// TODO: Add your message handler code here 
	 
	HBITMAP hGroupBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),  
                                        MAKEINTRESOURCE(IDB_BITMAP2), 
                                        IMAGE_BITMAP,  
                                        180,180,  
                                        LR_DEFAULTCOLOR); 
	m_audioVideo.SetBitmap(hGroupBmp); 
	// Do not call CDialog::OnPaint() for painting messages 
} 
 
void CDlgAudioVideo::OnButtonStop()  
{ 
	consoleStr += "\r\nCommand to stop recording sent to the H.323 Beacon Server..."; 
	// TODO: Add your control notification handler code here 
	TRY { 
	 
		 H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall); 
 
         if (connection == NULL) 
			return; 
		  
		 connection->SendUserInput(2); 
         connection->Unlock(); 
 
		 GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE); 
		 GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);	 
		 GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(TRUE); 
 
		 CDlgAudioVideo::KillTimer(TimerVal); 
 
		 TimerVal = 0; 
 
		 // TODO: Add your control notification handler code here 
		if (DeleteObject(hGroupBmp) == TRUE){ 
			// Do Nothing 
			m_audioVideo.SetBitmap(NULL); 
			CDlgAudioVideo::UpdateWindow(); 
		} 
		else{ 
		 
		} 
	} 
	CATCH_ALL(e){ 
		// Put some delay here		 
	} 
	END_CATCH_ALL 
} 
 
void CDlgAudioVideo::OnButtonRecord()  
{ 
	consoleStr += "\r\nCommand to record audio stream sent to the H.323 Beacon Server..."; 
	// TODO: Add your control notification handler code here 
	TRY { 
 
		 
		TimerVal = CDlgAudioVideo::SetTimer(IDT_TIMER_1,1000,NULL); 
 
		if (TimerVal == 0){ 
                MessageBox ("Unable to obtain timer","IDT_TIMER_1",MB_OK |MB_SYSTEMMODAL); 
        } 
		 
		H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall); 
 
        if (connection == NULL) 
          return; 
		  
		connection->SendUserInput(1); 
        connection->Unlock(); 
		 
		GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(TRUE); 
		GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);	 	 
		  
	} 
	CATCH_ALL(e){ 
		// Put some delay here		 
	} 
	END_CATCH_ALL 
	 
} 
 
 
 
PVideoChannel *CDlgAudioVideo::OpenVideoChannel(H323Connection & connection, 
                                     BOOL isEncoding, 
                                     H323VideoCodec & codec)            
{ 
  PVideoChannel   * channel = new PVideoChannel; 
   
 
  if (isEncoding) { 
    PConfig config; 
 
	 
     
    //codec.SetTxQualityLevel(config.GetInteger(VideoQualityConfigKey,1)); 
	//codecSetTxQualityLevel(1); //**Quality of the transmitted video. 1 is good, 31 is poor. 
    //codec.SetBackgroundFill(2); 
 
    //Create grabber. 
    PVideoInputDevice * grabber = new PVideoInputDevice(); 
 
    PStringList devices = grabber->GetDeviceNames(); 
    PString deviceName; 
 
	// Modified, so it just use whatever the "FIRST" available video hardware 
    if (devices.IsEmpty()) 
      deviceName = "Frame test N.0 - Moving line"; 
    else 
      deviceName = grabber->GetDeviceNames()[0]; 
    //deviceName = config.GetString(VideoDeviceConfigKey, deviceName); 
 
 
	 
	 
	// Modified, so it does not use any config files 
    //if (!grabber->Open(deviceName, FALSE) || 
    //    !grabber->SetVideoFormat((PVideoDevice::VideoFormat)config.GetInteger(VideoFormatConfigKey, PVideoDevice::Auto)) || 
    //    !grabber->SetChannel(config.GetInteger(VideoSourceConfigKey,1)) || 
    //   !grabber->SetColourFormatConverter("YUV420P") || 
    //    !grabber->SetFrameSize(videoWidth, videoHeight) || 
    //    !grabber->SetVFlipState(localFlip))  
 
 
	// If videosize = CIF then videoWidh = 352, videoHeight = 288 
	// If videosize = QCIF then videoWidh = 176, videoHeight = 144 
	// If videosize = Auto then videoWidh = 50, videoHeight = 50 
 
	  if (!grabber->Open(deviceName, FALSE)  || 
		  !grabber->SetVideoFormat(PVideoDevice::Auto) ||  // Set Video Format to be Auto 
		  !grabber->SetChannel(0) ||  // Set Channel to be 1 
		  !grabber->SetColourFormatConverter("YUV420P") || 
		  !grabber->SetFrameSize(176, 144)  ||  // videoWidth = 180, videoHeight = 180 // To be fit in Dialog Audio Video 
		  !grabber->SetVFlipState(TRUE))  
		   
 
	{ 
      //PTRACE(1, "Failed to open or configure the video device \"" << deviceName << '"'); 
	  MessageBox("Failed to open or configure the video device","H.323 Beacon Client",MB_OK); 
      delete grabber; 
      grabber = new PFakeVideoInputDevice(); 
      grabber->SetColourFormat("YUV420P"); 
      grabber->SetVideoFormat(PVideoDevice::PAL); 
      grabber->SetFrameSize(180, 180); 
      grabber->SetVFlipState(FALSE); 
      grabber->SetChannel(atoi(&deviceName[13])); 
    } 
    else 
	{ 
	 
	MessageBox("Opening is a success","H.323 Beacon Client",MB_OK); 
    grabber->Start(); 
 
    channel->AttachVideoReader(grabber); 
	} 
 
	 
	return channel; 
	// Always play it in Dialog Audio Video Window 
 
   //a if (localVideo) 
	//a { 
		// Replace this, so it can play on Beacon Client Video 
      //adisplayDevice = new VideoDevice(mainWindow, TRUE, connection.GetLocalPartyName(), FALSE); 
	//a } 
    //a else 
	//a { 
     //a displayDevice = new NullVideoOutputDevice; 
	//a } 
 
  } 
  else 
    // Replace this, so it can play on Beacon Client Video 
	//displayDevice = new VideoDevice(mainWindow, FALSE, connection.GetRemotePartyName(), remoteFlip); 
 
  // a displayDevice->SetFrameSize(180, 180);  // videowidth = 180, videoheight = 180 
  
  //Give the video window (which plays video) to the channel. 
  // a channel->AttachVideoPlayer(displayDevice); 
 
  //return codec.AttachChannel(channel,TRUE); 
  return channel; 
} 
 
 
void CDeviceVideoAudio::PlayButton(PVideoChannel   * channelTmp) 
{ 
	H323VideoDevice * displayDevice; 
 
	displayDevice = new PPMVideoOutputDevice(99); 
	/* 
	MainWindow *mainWindow = new MainWindow(); 
 
	displayDevice = new VideoDevice(mainWindow,TRUE,"REMOTE",FALSE); 
	*/ 
	AttachVideoReader(channelTmp,displayDevice); 
} 
 
 
void CDeviceVideoAudio::StopButton() 
{ 
	 
} 
 
 
void CDeviceVideoAudio::AttachVideoReader(PVideoChannel * channel, H323VideoDevice * displayDevice) 
{ 
		channel->AttachVideoPlayer(displayDevice); 
		 
} 
 
 
 
 
/////////////////////////////////////////////////////////////////////////////// 
 
/* 
VideoWindow::VideoWindow(PInteractor * parent, VideoDevice * dev, BOOL local) 
  : PFloatingDialog(parent) 
{ 
  device = dev; 
  localVideo = local; 
  canvas = NULL; 
} 
 
 
VideoWindow::~VideoWindow() 
{ 
  // Release the mutex and request it again, this guarantees that if the video 
  // thread happens to be in the mutex wait in WriteLineSegment() it is executed 
  // and exited from that function before continuing out of the shutdown procedure. 
  mutex.Wait(); 
 
  delete canvas; 
} 
 
 
void VideoWindow::OnClose() 
{ 
  Shutdown(); 
 
  PConfig config; 
 
  PPoint pos = GetPosition(PixelCoords); 
 
  /* 
  config.SetInteger(localVideo ? LocalVideoWindowLeftConfigKey 
                               : RemoteVideoWindowLeftConfigKey, pos.X()); 
  config.SetInteger(localVideo ? LocalVideoWindowTopConfigKey 
                               : RemoteVideoWindowTopConfigKey, pos.Y()); 
 
   
 
  PFloatingDialog::OnClose(); 
} 
 
 
void VideoWindow::OnCancel() 
{ 
  Shutdown(); 
  Close(); 
} 
 
 
void VideoWindow::OnRedraw(PCanvas & redrawCanvas) 
{ 
  if (!image.IsNULL()) 
    redrawCanvas.DrawPixels(0, 0, image); 
 
  // We create canvas in here as under Win32 we must have the construction AND 
  // destruction of a canvas in the "GUI" thread. 
  if (canvas == NULL) { 
    canvas = new PDrawCanvas(this); 
    canvas->SetViewportRect(canvas->GetMappingRect()); 
  } 
} 
 
 
void VideoWindow::SetVideoSize(int width, int height) 
{ 
  SetDimensions(width, height, PixelCoords); 
 
  if (image.IsNULL() || 
      image->Width() != (PDIMENSION)width || 
      image->Height() != (PDIMENSION)height) { 
    mutex.Wait(); 
    image = PPixelImage(width, height, 24); 
    raster = PPixelImage(width, 1, 24); 
    mutex.Signal(); 
  } 
 
  PConfig config; 
  /* 
  PORDINATE x = config.GetInteger(localVideo ? LocalVideoWindowLeftConfigKey 
                                             : RemoteVideoWindowLeftConfigKey, 
                                  localVideo ? 0 : 300); 
  PORDINATE y = config.GetInteger(localVideo ? LocalVideoWindowTopConfigKey 
                                             : RemoteVideoWindowTopConfigKey, 
                                  GetParent()->GetDimensions(PixelCoords).Height()); 
 
 
	PORDINATE x = 50; 
	PORDINATE y = 50; 
 
  SetPosition(x, y, TopLeftPixels, TopLeftPixels); 
 
  Show(); 
} 
 
 
BOOL VideoWindow::WriteLineSegment(int x, int y, unsigned len, const BYTE * data) 
{ 
  PWaitAndSignal wait(mutex); 
 
  if (device == NULL || image.IsNULL()) 
    return FALSE; 
 
  memcpy(image->GetRasterDataPtr(y)+x*3, data, len*3); 
 
  if (canvas == NULL) 
    Invalidate(); 
  else { 
    memcpy(raster->GetRasterDataPtr(0), image->GetRasterDataPtr(y), image->GetDimensions().Width()*3); 
    canvas->DrawPixels(0, y, raster); 
  } 
 
  return TRUE; 
} 
 
 
void VideoWindow::Shutdown() 
{ 
  mutex.Wait(); 
 
  if (device != NULL) { 
    device->windowOpen = FALSE; 
    device = NULL; 
  } 
 
  mutex.Signal(); 
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
 
VideoDevice::VideoDevice(MainWindow * mainWindow, 
                         BOOL local, 
                         const PString & title, 
                         BOOL flipIt) 
{ 
  window = new VideoWindow(mainWindow, this, local); 
  window->SetTitle(title); 
  windowOpen = TRUE; 
  rgbReverseOrder = TRUE; 
  flip = flipIt; 
} 
 
 
VideoDevice::~VideoDevice() 
{ 
  if (windowOpen) 
    window->OnCancel(); 
} 
 
 
BOOL VideoDevice::SetFrameSize(unsigned w, unsigned h) 
{ 
  unsigned old_w, old_h; 
  H323VideoDevice::GetFrameSize(old_w, old_h); 
  if (old_w != w || old_h != h) { 
    if (!H323VideoDevice::SetFrameSize(w, h)) 
      return FALSE; 
 
    if (windowOpen) 
      window->SetVideoSize(w, h); 
  } 
 
  return TRUE; 
} 
 
 
BOOL VideoDevice::WriteLineSegment(int x, int y, unsigned len, const BYTE * data) 
{ 
  if (!windowOpen) 
    return FALSE; 
 
  if (flip) 
    y = (frameHeight-1) - y; 
 
  return window->WriteLineSegment(x, y, len, data); 
} 
 
*/ 
/////////////////////////////////////////////////////////////////////////////// 
 
 
 
void CDlgAudioVideo::OnTimer(UINT nIDEvent)  
{ 
	// TODO: Add your message handler code here and/or call default 
	 
	 
	CDialog::OnTimer(nIDEvent); 
 
	 
 
	if (TimerRecordCount == 30 && FlagEndPoint == 0){ 
		CDlgAudioVideo::KillTimer(TimerVal); 
		TimerVal = 0; 
		//CWnd::KillTimer(TimerVal); 
		/*if(CWnd::KillTimer(TimerVal) == 0) 
			MessageBox("Cleared...3","H.323 Beacon Client", MB_OK); 
		else 
			MessageBox("Not Cleared...3","H.323 Beacon Client", MB_OK);*/ 
 
		 MessageBox("Maximum Record Time is 30 seconds ... Recording Stopped !","H323 Beacon Client",MB_OK |MB_SYSTEMMODAL); 
 
		 
		 GetDlgItem( IDC_BUTTON_STOP )->EnableWindow(FALSE); 
		 GetDlgItem( IDC_BUTTON_RECORD )->EnableWindow(FALSE);	 
		 GetDlgItem( IDC_BUTTON_PLAY )->EnableWindow(TRUE); 
		 TimerRecordCount = 0; 
 
		  
		 if (FlagEndPoint == 0){ 
			  if (globalInstance->endpoint !=NULL){ 
				TRY { 
 
				H323Connection * connection = globalInstance->endpoint->FindConnectionWithLock(TokenCurrentCall); 
 
				if (connection == NULL) 
				return; 
		  
				connection->SendUserInput(2); 
				connection->Unlock(); 
				} 
				 CATCH_ALL(e){ 
				 } 
				 END_CATCH_ALL 
			  } 
		} 
              
	} 
	else{ 
		TimerRecordCount++; 
	} 
	 
}