Step 2 - 부산대학교 홈페이지
Transcription
Step 2 - 부산대학교 홈페이지
개요 Windows 기반 멀티미디어 통신 응용 개발 MS-Windows 환경에서 간단한 멀티미디어 통신 응용 개발 { 개발 기술 요구 사항 y Windows Multimedia 프로그래밍 기술 y 예제 소스는 Legacy Windows Multimedia API인 VFW를 사용하고 있음 y Directshow 등 최신 Windows Media Technology를 활용하는 것이 바람직하나 기술 이해 및 소스 준비 등에 소요되는 시간 등의 문제로 Legacy 기반으로 설명 부산대학교 정보컴퓨터공학부 y 김종덕 ([email protected]) (kimjd@pusan ac kr) { Windows Network 프로그래밍 기술 y 지금까지 배운 Windows Socket Programming 기술 이용 y 예제 소스는 MFC의 의 CAsyncSocket Class를 를 활용하고 있음 관련 기술에 대한 이해 y 멀티미디어 압축의 기본 개념 y Streaming, VoIP 관련 표준 프로토콜, 기술 및 동향 Windows 기반 멀티미디어 통신 응용 개발 2 Windows 기반 멀티미디어 통신 응용 개발 4 Video Capture & Compression Simple Video Capture & Compression Program 응용 구현 내용 응용구현 1 : VidCap 기본 목표 { VFW Video Capture 기술의 획득 - AVICap { VFW Video 재생 기술의 획득 - DrawDib { VFW Video Vid 압축 기술의 획득 - VCM 필요한 것 { Video Capture 장치 : USB형, 카드형, 1394 { Capture p 장비를 이용할 수 있는 Programming g g Interface y Video For Windows Windows 기반 멀티미디어 통신 응용 개발 제어판에서 장치 확인 구현 순서 Step 0 : 프로젝트 준비 { App/Class Wizard, Resource Editor { Modaless Dialog 생성 Step 1 : Simple Capture { 7 Capture Window 생성, Driver 연결, Preview Step 2 : 사용자 제어 추가 { Windows 기반 멀티미디어 통신 응용 개발 6 Source, Format Dialog, Rate 변경 St 3 : C Step Callback llb k Function의 F ti 의 지정 Step 4 : DrawDib을 이용한 재생 Step 5 : Overlay 등 기타 작업 Step p 6 : Video Compression p & VCM Windows 기반 멀티미디어 통신 응용 개발 8 Step 0 : 프로젝트 준비 Dialog Based Application { Step 0 - Resource 편집 IDD_VIDCAP_DIALOG Project Name : VidCap IDC_BUTTON_CAPTURE IDC BUTTON CAPTURE IDCANCEL Scenario { 주 Dialog에 Capture라는 버튼이 있고 이 버튼이 눌러지면 Capture를 위 한 Modaless Dialog 생성 { Capture Dialog는 Capture 장비에 Connect하고 Capture 시작 { Capture Dialog => CCapDlg Class 생성 IDD_CAPTURE_DIALOG Windows 기반 멀티미디어 통신 응용 개발 9 Step 0 - CW 이용, 변수/함수 추가 생성할 Modaless Dialog, 즉 CCapDlg를 위한 Pointer Member 변수 CVidCapDlg 에 추가 IDD CAPTURE DIALOG IDD_CAPTURE_DIALOG CVidCapDlg 변경 { CCapDlg *m_pCapDlg Member 변수 { Constructor에서 초기화 { OnButtonCapture에서 Create { OnClose에서 Destroy { y { IDC_BUTTON_CAPTURE : m_btnCapture Member 함수 y WM_CLOSE : OnClose y ON_IDC_BUTTON_CAPTURE:BN_CLICKED : OnButtonCapture Windows 기반 멀티미디어 통신 응용 개발 10 Step 0 - Modaless Dialog 생성 CCapDlg 생성 { Windows 기반 멀티미디어 통신 응용 개발 CVidCapDlg::CVidCapDlg(CWnd* p g p g( pParent /*=NULL*/)) p : CDialog(CVidCapDlg::IDD, pParent) { m_pCapDlg = NULL; //{{AFX DATA INIT(CVidCapDlg) //{{AFX_DATA_INIT(CVidCapDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon pp m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } 11 Windows 기반 멀티미디어 통신 응용 개발 12 void CVidCapDlg::OnButtonCapture() { // TODO TODO: Add your control t l notification tifi ti h handler dl code d here h if (!m_pCapDlg) { m_pCapDlg = new CCapDlg(); if (!m_pCapDlg->Create(CCapDlg::IDD, (! C Dl C t (CC Dl IDD this)) thi )) { delete m_pCapDlg; m_pCapDlg = NULL; } else { p m_btnCapture.EnableWindow(FALSE); } } } Step 1 : Simple Capture void id CVidCapDlg::OnClose() CVidC Dl O Cl s () { // TODO: Add your message handler code here and/or call default if (m_pCapDlg) { m_pCapDlg->DestroyWindow(); C Dl D t Wi d () delete m_pCapDlg; m_pCapDlg = NULL; } CDialog::OnClose(); D l l () } Windows 기반 멀티미디어 통신 응용 개발 13 Video Capture: A Minimal Approach Step 1 – Capture Preview Capture of video and audio input to a file named CAPTURE.AVI. p continues until one of the following g events occurs: Capture { The user presses the ESC key or a mouse button. { Your application stops or aborts capture operation. operation { The disk becomes full hWndC = capCreateCaptureWindow ( "My Own Capture Window", WS_CHILD | WS_VISIBLE , Capture API 사용 순서 { capture Window 생성 : capCreateCaptureWindow { capture 장치에 연결 : capDriverConnect { capturing i 정보 획득 : capGetVideoFormat, G Vid F ... { capture rate 설정 : capPreviewRate { capture 결과 Preview (생성한 capture Window에 capture 한 이미지 Display) : capPreview 0, 0, 160, 120, hwndParent, nID); capDriverConnect D i C t (hWndC, (hW dC 0); 0) capCaptureSequence (hWndC); Windows 기반 멀티미디어 통신 응용 개발 15 Windows 기반 멀티미디어 통신 응용 개발 16 CCapDlg 수정 CCapDlg 초기화 과정에서 Capture API 구현 { BOOL CCapDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here _ p = capCreateCaptureWindow((LPSTR)"Simple p p (( ) p Capture p Screen",, m_hCapWnd WS_CHILD | WS_VISIBLE, 5,5,300,240, m_hWnd, 0); CCapDlg의 OnInitDialog Override(C. Override(C W 이용 : ON_WM_INITDIALOG) ON WM INITDIALOG) 생성되는 capture window의 handle을 저장하기 위한 capDriverConnect(m hCapWnd 0); capDriverConnect(m_hCapWnd,0); Member 변수 추가 { HWND BITMAPINFO bminfo; p ( p &bminfo, sizeof(BITMAPINFO)); ( )) capGetVideoFormat(m_hCapWnd, m hCapWnd m_hCapWnd SetWindowPos(::AfxGetMainWnd(), 0, 0, bminfo.bmiHeader.biWidth+20, bminfo bmiHeader biHeight+40 bminfo.bmiHeader.biHeight+40, SWP_NOMOVE | SWP_NOZORDER); capture API 사용하기 위한 작업 { #include <vfw.h> { Project Setting , Link : vfw32.lib p p 100); capPreviewRate(m_hCapWnd, capPreview(m_hCapWnd,TRUE); } Windows 기반 멀티미디어 통신 응용 개발 17 사후 처리 코드 Windows 기반 멀티미디어 통신 응용 개발 끊는다. 끊는다 Preview Rate와 화질과의 관계 { C.W 이용 OnDestroy Override (WM_DESTROY) { capDriverDisconnect 18 중간 결과 점검 Capture Dialog가 Destroy 될 때 capture 장치와의 연결을 { return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE Preview Rate == Capture Rate ? 화면 크기 조정 ? { 각종 Control ? void id CCapDlg::OnDestroy() CC pDl ::OnD st () { CDialog::OnDestroy(); } // TODO: Add your message handler code here capDriverDisconnect(m_hCapWnd); Windows 기반 멀티미디어 통신 응용 개발 19 Windows 기반 멀티미디어 통신 응용 개발 20 Step 2 - 사용자 제어의 추가 Step 2 : 사용자 제어 추가 Preview Rate 설정 지원 C t Capture D Driver i 지원 Dialog Di l 이용 { Video Source { Video Format IDC_EDIT_RATE : UINT m_uiRate (1-30) IDC_BUTTON_RATE : CButton m_btnRate IDC_BUTTON_VIDEO_FORMAT m_btnVFormat IDC_BUTTON_VIDEO_SOURCE m_btnVSource Windows 기반 멀티미디어 통신 응용 개발 Button Update BN_CLICKED 처리 void CVidCapDlg::UpdateButton() { BOOL bOff = (m_pCapDlg==NULL); m btnCapture EnableWindow(bOff); m_btnCapture.EnableWindow(bOff); m_btnRate.EnableWindow(!bOff); m_btnVFormat.EnableWindow(!bOff); m_btnVSource.EnableWindow(!bOff); } void CVidCapDlg::OnButtonRate() { your control notification handler code here // TODO: Add y if (m_pCapDlg) { UpdateData(); m_pCapDlg->SetRate(m_uiRate); } } void CVidCapDlg::OnButtonVideoFormat() { // TODO: Add your control notification handler code here if (m_pCapDlg) { m_pCapDlg->SetupVideoFormat(); } } void CVidCapDlg::OnButtonVideoSource() { // TODO: Add your control notification handler code here if (m_pCapDlg) { m_pCapDlg->SetupVideoSource(); } } BOOL CVidCapDlg::OnInitDialog() { // 생략 // TODO: Add extra initialization here UpdateButton(); return TRUE; // return TRUE unless you set the focus to a control } void CVidCapDlg::OnButtonCapture() { // 생략 if (!m_pCapDlg->Create(CCapDlg::IDD, this)) { // 생략 } else { UpdateButton(); } // 생략 } Windows 기반 멀티미디어 통신 응용 개발 22 23 Windows 기반 멀티미디어 통신 응용 개발 24 Capture Rate CCapDlg SetRate() 함수 현재 Rate를 저장할 Member 변수 추가 { UINT m_uiFrameRate { Constructor에서 초기화 : 10 The capture rate is the number of frames that are captured each second of a capture session. You can retrieve the current capture rate by using the WM_CAP_GET_SEQUENCE_SETUP message (or the capCaptureGetSetup macro). The current capture rate is stored in the dwRequestMicroSecPerFrame member of the CAPTUREPARMS structure. SetRate() => Public 함수 You can set the capture rate by specifying the number of microseconds between successive frames as the value of this member, then sending the updated CAPTUREPARMS structure to the capture window by using void CCapDlg::SetRate(UINT pFrameperSec) { m_uiFrameRate = pFrameperSec; capPreview(m_hCapWnd, FALSE); capPreviewRate(m hCapWnd 1000/m_uiFrameRate); capPreviewRate(m_hCapWnd, 1000/m uiFrameRate); capPreview(m_hCapWnd, TRUE); } Windows 기반 멀티미디어 통신 응용 개발 the WM_CAP_SET_SEQUENCE_SETUP message (or the capCaptureSetSetup macro). The default value of d R dwRequestMicroSecPerFrame Mi S P F i 66667 is 66667, which hi h corresponds d to 15 fframes per second. 25 CCapDlg SetupVideoFormat() if (CapDriverCaps.fHasDlgVideoSource) { capDlgVideoFormat(m_hCapWnd); BITMAPINFO bminfo; capGetVideoFormat(m_hCapWnd, &bminfo, sizeof(BITMAPINFO)); } 26 CCapDlg SetupVideoSource() void CCapDlg::SetupVideoFormat() { p p CAPDRIVERCAPS CapDriverCaps; capDriverGetCaps(m_hCapWnd, &CapDriverCaps, sizeof(CAPDRIVERCAPS)); } else Windows 기반 멀티미디어 통신 응용 개발 void CCapDlg::SetupVideoSource() { CAPDRIVERCAPS CapDriverCaps; capDriverGetCaps(m_hCapWnd, &CapDriverCaps, sizeof(CAPDRIVERCAPS)); } if (CapDriverCaps.fHasDlgVideoSource) capDlgVideoSource(m_hCapWnd); else MessageBox("Video MessageBox( Video Source Dialog Not Supported Supported","VidCap"); VidCap ); SetWindowPos(::AfxGetMainWnd(), 0, 0, bminfo bmiHeader biWidth+20 bminfo.bmiHeader.biWidth+20, bminfo.bmiHeader.biHeight+40, SWP_NOMOVE | SWP_NOZORDER); MessageBox("Video Format Dialog Not Supported", "VidCap"); Windows 기반 멀티미디어 통신 응용 개발 27 Windows 기반 멀티미디어 통신 응용 개발 28 Step 2 결과 Test Step 3 : Callback Function 지정 Windows 기반 멀티미디어 통신 응용 개발 29 Step 3 - Capture Data 직접 이용 Capture한 Frame 정보를 어떻게 Access 할 것인가 ? { AVICap Callback Function 의 이용 { Your application can register callback functions with a capture window to have 1) Window 생성 App Wnd 3) 이벤트 발생 it notify your application when the status changes, when errors occur, when video frame and audio buffers become available, and to yield during streaming Capture Device Di Driver capture. Callback 의 종류 { CapWnd 2) Callback Function 설정 Precise Capture Control, Error, Frame, Status, VideoStream, WaveStream, Yield, Disabling { Frame : A capture window uses frame callback notification messages to notify Callback Function your application li ti when h a new video id fframe iis available. il bl Th The capture t window i d 4) Callback Function 호출 Frame Callback 인자 예) HWND - CapWnd LPVIDEOHDR enables these callback notifications only if the preview rate is nonzero and g capture p is not in p progress g streaming Windows 기반 멀티미디어 통신 응용 개발 31 Windows 기반 멀티미디어 통신 응용 개발 32 Step 3 - Frame Callback 함수 구현 Global 함수 { Member 함수가 될 수 없음 { C-Style 함수 { 형식이 정해져 있음 y CVidCapDlg에 새로운 Edit Control 추가 { IDC_EDIT_FRAME { UINT m_uiCurFrame { Disabled 속성 LRESULT PASCAL FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr) y Step 3 – 구현 시나리오 함수 이름만 변경 가능 시지 핸들러는 capSetCallbackOnFrame이용 함수 설정 capSetCallbackOnError, ... { UM CAPTURE FRAME 메 UM_CAPTURE_FRAME Frame Callback은 호출될 m_uiCurFrame 값을 1 증 때 마다 사용자 메시지 가 시키고 그 결과 반영 UM_CAPTURE_FRAME을 CVidCapDlg에 전달 Windows 기반 멀티미디어 통신 응용 개발 33 Frame Callback 함수와 그 설정 Windows 기반 멀티미디어 통신 응용 개발 BOOL CCapDlg::OnInitDialog() { CDialog::OnInitDialog(); // VidCap.h : main header file for the VIDCAP application #define UM_CAPTURE_FRAME (WM_USER+10) // TODO: Add extra initialization here _ p = capCreateCaptureWindow((LPSTR)"Simple p p (( ) p Capture p Screen",, m_hCapWnd WS_CHILD | WS_VISIBLE, 5,5,300,240, m_hWnd, 0); // CapDlg.cpp : implementation file // 생략 LRESULT PASCAL FrameCallbackProc(HWND F C llb kP (HWND hW hWnd, d LPVIDEOHDR lpVHdr) l VHd ) { ::AfxGetMainWnd()->PostMessage(UM_CAPTURE_FRAME, ,(L )p ); 0,(LPARAM)lpVHdr); } capDriverConnect(m hCapWnd 0); capDriverConnect(m_hCapWnd,0); BITMAPINFO bminfo; p ( p &bminfo, sizeof(BITMAPINFO)); ( )) capGetVideoFormat(m_hCapWnd, SetWindowPos(::AfxGetMainWnd(), 0, 0, bminfo.bmiHeader.biWidth+20, bminfo bmiHeader biHeight+40 bminfo.bmiHeader.biHeight+40, SWP_NOMOVE | SWP_NOZORDER); return (LRESULT) TRUE ; long CVidCapDlg::OnFrameCapture(WPARAM wp, LPARAM lp) { _ ; m_uiCurFrame++; UpdateData(FALSE); return 0l; } Windows 기반 멀티미디어 통신 응용 개발 34 p p 100); capPreviewRate(m_hCapWnd, capSetCallbackOnFrame(m_hCapWnd, FrameCallbackProc); capPreview(m_hCapWnd,TRUE); 35 } return tu n TRUE; // return tu n TRUE unl unless ss you u ssett th the f focus cus tto a control c nt l // EXCEPTION: OCX Property Pages should return FALSE Windows 기반 멀티미디어 통신 응용 개발 36 Step 3 중간 결과와 VIDEOHDR Step 4 : DrawDib을 이 용한 재생 FrameCallback F C llb k 함수의 인자 LPVIDEOHDR ? VFW H 참조 VFW.H typedef struct videohdr_tag { LPBYTE lpData; /* pointer to locked data buffer */ DWORD d dwBufferLength; B ff L th /* L Length th of fd data t b buffer ff */ DWORD dwBytesUsed; /* Bytes actually used */ DWORD dwTimeCaptured; /* Milliseconds from start of stream */ DWORD dwUser; /* for client's / client s use */ / DWORD dwFlags; /* assorted flags (see defines) */ DWORD dwReserved[4]; /* reserved for driver */ } VIDEOHDR, NEAR *PVIDEOHDR, FAR * LPVIDEOHDR; Windows 기반 멀티미디어 통신 응용 개발 37 Step 4 - DrawDib Capture한 Bitmap 이미지(lpData )를 화면에 Draw GDI를 이용한 BITMAP Draw의 문제점 : 느리다 The DrawDib functions provide high performance image-drawing BITMAP의 구조 typedef struct tagBITMAPINFO { // bmi BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; typedef struct tagBITMAPINFOHEADER{ // bmih DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; capabilities biliti ffor d device-independent i i d d t bitmaps bit (DIBs). (DIB ) DrawDib D Dib functions support DIBs of 8-bit, 16-bit, 24-bit, and 32-bit image depths. DrawDib functions write directly to video memory. They do not rely on functions of the graphics device interface (GDI). DIB,, DDB Windows 기반 멀티미디어 통신 응용 개발 39 Windows 기반 멀티미디어 통신 응용 개발 40 Step 4 - 구현 시나리오 Display를 위한 별도의 Modaless Dialog 객체 생성 { CCapDlg와 구현방법이 유사 { CVidCapDlg와 연결 고리 필요 y UM_CAPT TURE_FRA AME (CDispDlg) (Step : 4-1) 4 1) CDispDlg * m_pDispDlg : Member 변수 추가 C Capture Dl Dlg CDispDlg에서 DrawDib을 이용, Capture 한 이미지를 Draw (Step 4-3) Callback Function CapWnd DrawDib을 이용하여 Bitmap Data를 Draw하기 위해서는 해당 Bitmap의 BITMAPINFOHEADER가 필요하다. (Step 4- Capture D i Driver Device Di 2) Windows 기반 멀티미디어 통신 응용 개발 41 Step 4-1 : CDispDlg 생성 HDD Frame Done Video Memory y Windows 기반 멀티미디어 통신 응용 개발 42 Step 4-1 : CVidCapDlg 수정 IDD_DISPLAY_DIALOG { Display Dlg Caption을 제외하고 CCapDlg와 속성 일치 C.W 이용 { OnDestroy, OnInitDialog 함수 추가 Display p y Dialog g 생성 명령을 위한 Display p y 버튼 추가 { IDC_BUTTON_DISPLAY, OnButtonDisplay { Cbutton m_btnDisplay; m btnDisplay; CDispDlg * m_pDispDlg 추가 { Windows 기반 멀티미디어 통신 응용 개발 43 알맞은 초기화 및 해제 코드 UpdateButton의 수정 Windows 기반 멀티미디어 통신 응용 개발 44 void CVidCapDlg::UpdateButton() { BOOL bCapOff = (m (m_pCapDlg==NULL); pCapDlg==NULL); BOOL bDispOff = (m_pDispDlg==NULL); CVidCapDlg::CVidCapDlg(CWnd* pParent /*=NULL*/) : CDialog(CVidCapDlg::IDD, CDialog(CVidCapDlg::IDD pParent) { m_pCapDlg = NULL; p p g = NULL; m_pDispDlg // 생략 } void CVidCapDlg::OnClose() { // TODO: Add your message handler code here and/or call default if (m_pCapDlg) { m_pCapDlg->DestroyWindow(); C Dl D t Wi d () delete m_pCapDlg; m_pCapDlg = NULL; } if (m_pDispDlg) { m_pDispDlg->DestroyWindow(); delete m_pDispDlg; m_pDispDlg Di Dl = NULL; NULL } } } CDialog OnClose(); CDialog::OnClose(); Windows 기반 멀티미디어 통신 응용 개발 45 Step 4-2 : BITMAPINFO 전달 void CVidCapDlg::OnButtonDisplay() { // TODO: Add your control notification handler code here if (!m_pDispDlg) { m_pDispDlg = new CDispDlg(); if (!m_pDispDlg->Create(CDispDlg::IDD, this)) { delete m_pDispDlg; m pDispDlg = NULL; m_pDispDlg } else { UpdateButton(); } } } Windows 기반 멀티미디어 통신 응용 개발 46 Step 4-2 : CCapDlg 수정 CCapDlg에 BITMAPINFO 저장할 Member 변수 추 가, 이 값을 얻어 올 GetVideoFormat() 함수 추가 m_btnCapture.EnableWindow(bCapOff); m_btnRate.EnableWindow(!bCapOff); m_btnVFormat.EnableWindow(!bCapOff); m_btnVSource.EnableWindow(!bCapOff); m btnDisplay EnableWindow(!bCapOff && bDispOff); m_btnDisplay.EnableWindow(!bCapOff { BITMAPINFO m_bminfo m bminfo { void GetVideoFormat(BITMAPINFO *pbm) //BITMAPINFO bminfo; capGetVideoFormat(m_hCapWnd, capGetVideoFormat(m hCapWnd &m_bminfo, &m bminfo sizeof(BITMAPINFO)); SetWindowPos(::AfxGetMainWnd(), 0, 0, m_bminfo.bmiHeader.biWidth+20, m_bminfo.bmiHeader.biHeight+40, SWP_NOMOVE | SWP_NOZORDER); CDispDlg에 BITMAPINFO Member 변수 추가, SetVideoFormat() 함수 추가 { BITMAPINFO m_bminfo m bminfo { void SetVideoFormat(BITMAPINFO *pbm) Windows 기반 멀티미디어 통신 응용 개발 //CapDlg.cpp - OnInitDialog, SetupVideoFormat void CCapDlg::GetVideoFormat(BITMAPINFO *pbm) { memcpy((LPVOID)pbm (const void *)&m_bminfo, memcpy((LPVOID)pbm, *)&m bminfo sizeof(BITMAPINFO)); } 47 Windows 기반 멀티미디어 통신 응용 개발 48 Step 4-2 : CDispDlg 수정 Step 4-2 : CVidCapDlg 수정 void CVidCapDlg::OnButtonDisplay() { p p g if (!m_pDispDlg) { m_pDispDlg = new CDispDlg(); if (!m_pDispDlg->Create(CDispDlg::IDD, this)) { delete m_pDispDlg; m_pDispDlg = NULL; } else { if (m_pCapDlg) { BITMAPINFO bminfo; m_pCapDlg->GetVideoFormat(&bminfo); m_pDispDlg->SetVideoFormat(&bminfo); } UpdateButton(); } } } void CDispDlg::SetVideoFormat(BITMAPINFO *pbm) { memcpy((LPVOID)&m_bminfo, (const void *)pbm, sizeof(BITMAPINFO)); SetWindowPos(::AfxGetMainWnd(), 0, 0, m_bminfo.bmiHeader.biWidth+20, m bminfo.bmiHeader.biHeight+40, m_bminfo.bmiHeader.biHeight 40, SWP_NOMOVE | SWP_NOZORDER); } Windows 기반 멀티미디어 통신 응용 개발 49 Windows 기반 멀티미디어 통신 응용 개발 50 Step 4-3 : DrawDib 함수 개요 void CVidCapDlg::OnButtonVideoFormat() { // TODO: D Add dd your controll notification f handler h dl code d here h if (m_pCapDlg) { m_pCapDlg->SetupVideoFormat(); } } { { if (m_pDispDlg) { BITMAPINFO bminfo; m_pCapDlg->GetVideoFormat(&bminfo); m_pDispDlg->SetVideoFormat(&bminfo); } Windows 기반 멀티미디어 통신 응용 개발 DrawDibOpen()을 호출하여 DrawDibDC를 얻는다. DrawDibBegin 51 This function Thi f ti prepares to t draw d a DIB specified ifi d b by llpbi bi tto th the DC DC. BITMAPINFOHEADER가 변경될 때 마다 호출 DrawDibDraw DrawDibClose() Windows 기반 멀티미디어 통신 응용 개발 52 CDispDlg에서 DrawDib 구현 CDispDlg 수정 void CDispDlg::OnInitDialog() { CDialog::OnInitDialog(); DrawDib DC를 저장할 Member 변수 추가 { HDRAWDIB m hDD m_hDD { 초기화 : OnInitDialog에서 DrawDibOpen { 해제 : OnDestroy에서 O D 에서 DrawDibClose D DibCl // TODO: Add extra initialization here m_hDD hDD = DrawDibOpen(); D DibO () return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE Frame 정보를 재생할 Member 함수 추가 { void DrawFrame(LPVOID lpdata) { BITMAP 정 정보는 는 이미 가지 가지고 있음 y m_bmInfo y m_bmInfo가 _ 바뀔 때 마다 DrawDibBegin g 호출 } void CDispDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: D Add your y message m g handler code here DrawDibClose(m_hDD); } Windows 기반 멀티미디어 통신 응용 개발 53 CDispDlg 수정 Windows 기반 멀티미디어 통신 응용 개발 CDispDlg 수정 void CDispDlg::SetVideoFormat(BITMAPINFO *pbm) { memcpy((LPVOID)&m_bminfo, (const void *)pbm, sizeof(BITMAPINFO)); void CDispDlg::DrawFrame(LPVOID l ( lpdata) l ) { CDC *pDC = GetDC(); DrawDibBegin(m_hDD, NULL, -1, -1, (LPBITMAPINFOHEADER)&m_bminfo, -1, -1, 0); DrawDibBegin(m_hDD, NULL, -1, -1, ((LPBITMAPINFOHEADER)&m_bminfo, ) _ , -1,, -1,, 0); ) DrawDibDraw(m_hDD, pDC->m_hDC, 5, 5, m_bminfo.bmiHeader.biWidth, m_bminfo.bmiHeader.biHeight, (LPBITMAPINFOHEADER)&m bminfo lpdata (LPBITMAPINFOHEADER)&m_bminfo, lpdata, 0 0, 0 0, m_bminfo.bmiHeader.biWidth, m_bminfo.bmiHeader.biHeight, DDF_SAME_HDC); SetWindowPos(::AfxGetMainWnd(), 0, 0, m_bminfo.bmiHeader.biWidth+20, m_bminfo.bmiHeader.biHeight+40, SWP NOMOVE | SWP SWP_NOMOVE SWP_NOZORDER); NOZORDER) } } Windows 기반 멀티미디어 통신 응용 개발 54 55 ReleaseDC(pDC); Windows 기반 멀티미디어 통신 응용 개발 56 CVidCapDlg OnFrameCapture Step 4 중간 결과 Test long CVidCapDlg::OnFrameCapture(WPARAM wp, LPARAM lp) { m_uiCurFrame++; UpdateData(FALSE); } if (m_pDispDlg) { m_pDispDlg->DrawFrame(((LPVIDEOHDR) lp)->lpData); } return 0l; Windows 기반 멀티미디어 통신 응용 개발 57 Windows 기반 멀티미디어 통신 응용 개발 58 기타 문제점 해결 및 개선 Step 5 : Overlay 및 기 타 문제점 제점 Capture Dialog, Display Dialog가 Enter/ESC에 의해 Close 될 경우 { OnOK,, OnCancel override { UM_CLIENT_CLOSE 메시지 전달 현재 Frame 표시의 UpdateData { Frame Rate 변경 불가 { SetDlgItemInt() 이용 { 추가로 Capture된 Frame의 데이터 크기 표시 Overlay 기능의 이용 (CCapDlg) { BOOL m_bOverlay 추가 { capOverlay Windows 기반 멀티미디어 통신 응용 개발 60 Client Dlg Close ON MESSAGE(UM CLIENT CLOSE OnClientClose) ON_MESSAGE(UM_CLIENT_CLOSE, #define #define UM_CAPTURE_FRAME UM_CLIENT_CLOSE (WM_USER+10) (WM_USER+11) #define #define CLIENT_CAPDLG CLIENT_DISPDLG 1 2 long CVidCapDlg::OnClientClose(WPARAM client, LPARAM lp) { switch(client) { case CLIENT_CAPDLG : delete m_pCapDlg; m pCapDlg = NULL; m_pCapDlg break; void CCapDlg::OnOK() {} void CCapDlg::OnCancel() { ::AfxGetMainWnd()->PostMessage(UM_CLIENT_CLOSE, CLIENT_CAPDLG); } _ : case CLIENT_DISPDLG delete m_pDispDlg; m_pDispDlg = NULL; break; void CDispDlg::OnOK() {} default : break; } UpdateButton(); p g () void CDispDlg::OnCancel() { ::AfxGetMainWnd()->PostMessage(UM_CLIENT_CLOSE, CLIENT_DISPDLG); } } 61 Windows 기반 멀티미디어 통신 응용 개발 CVidCapDlg UpdateData Windows 기반 멀티미디어 통신 응용 개발 62 Preview & Overlay Mode A capture driver can implement two methods for viewing an incoming video stream: preview mode and overlay mode. If a capture driver i l implements ts both b th methods, th ds th the user s can choose h s which hi h method th d to t use. s Preview mode transfers digitized frames from the capture hardware to system memory and then displays the digitized frames in the capture window by using graphics device interface (GDI) functions. Applications might decrease the preview rate when the parent window loses focus, and increase the preview rate when the parent window gains focus. focus This action improves general system responsiveness because the preview operation is processor intensive. IDC_EDIT_FSIZE UINT m_uiFrameSize long CVidCapDlg::OnFrameCapture(WPARAM wp, LPARAM lp) { SetDlgItemInt(IDC_EDIT_FRAME, m_uiCurFrame++); m_uiFrameSize = ((LPVIDEOHDR) lp)->dwBytesUsed; SetDlgItemInt(IDC_EDIT_FSIZE, m_uiFrameSize); // UpdateData(FALSE); if (m_pDispDlg) { m_pDispDlg->DrawFrame(((LPVIDEOHDR) lp)->lpData); } return 0l; } Windows 기반 멀티미디어 통신 응용 개발 return 0l; Overlay mode is a hardware function that displays the contents of the h capture buffer b ff on the h monitor i without i h using i CPU resources. You Y can enable and disable overlay mode by sending the WM_CAP_SET_OVERLAY message (or the capOverlay macro) to a capture t window. i d E Enabling bli overlay l mode d automatically t ti ll dis disables bl s preview mode. 63 Windows 기반 멀티미디어 통신 응용 개발 64 Overlay 기능의 추가 void CCapDlg::SetRate(UINT pFrameperSec) { m uiFrameRate = pFrameperSec; m_uiFrameRate if (m_bOverlay) capOverlay(m_hCapWnd, FALSE); else capPreview(m_hCapWnd, FALSE); capPreviewRate(m_hCapWnd, 1000/m_uiFrameRate); BOOL CCapDlg::OnInitDialog() { g g CDialog::OnInitDialog(); m_hCapWnd = capCreateCaptureWindow((LPSTR)"Simple Capture Screen", // 생략 capPreviewRate(m_hCapWnd, 1000/m_uiFrameRate); capSetCallbackOnFrame(m hCapWnd FrameCallbackProc); capSetCallbackOnFrame(m_hCapWnd, CAPDRIVERCAPS CapDriverCaps; p p p &CapDriverCaps, p p sizeof(CAPDRIVERCAPS)); capDriverGetCaps(m_hCapWnd, if (CapDriverCaps.fHasOverlay) { if (IDYES == MessageBox("Overlay 기능을 사용하시겠습니까 ?", "Capture Capability", MB_YESNO | MB_ICONQUESTION)) m bOverlay = TRUE; m_bOverlay } if (m_bOverlay) capOverlay(m_hCapWnd, TRUE); else capPreview(m_hCapWnd, TRUE); } if (m_bOverlay) capOverlay(m_hCapWnd, TRUE); else capPreview(m_hCapWnd,TRUE); } return TRUE; 65 Windows 기반 멀티미디어 통신 응용 개발 Windows 기반 멀티미디어 통신 응용 개발 66 압축의 필요 Step 6 : Video Compression Video Compression Technique 비디오 정보의 표현과 크기 ? { 이미지를 Digital로 표시하는 방법? Pixel ? { 160 * 120 * 16 bit = ? { 1초에 몇 Frame ? { 일반 Ethernet Card의 대역폭은 ? { Bottleneck ? { 압축의 필요 : CODEC ? (Coder/Decoder) y & Video Compression Manager y { 중복성의 제거 y 색신호간 중복성 : YUV (YCrCb, cf) RGB) y 공간적 중복성 : DCT 및 양자화 y 통계적 중복성 : 가변길이 부호화 y 시간적 중복성 : I Frame, P Frame, B Frame 대표적 디지탈 압축 기술 - MPEG, H.261, H.263, H.264, RA 이용하고 있는 캡쳐 장치의 H/W 압축 지원 여부 확인 Windows 기반 멀티미디어 통신 응용 개발 68 Audio Format MIDI - Musical Instrument Digital Interface { 디지털 악기를 위한 디지털 정보 송,수신 송 수신 인터페이스 표준 { 음표 정보를 보낸다(?) { 음원 모듈과 일반 사운드카드의 구분 y Waveform Audio PCM (P (Pulse l C Coded d dM Modulation) d l ti ) { 대표적 음성 코딩 방법 { Frequency / Amplitude { 사람의 가청 주파수 대역 ? Waveform (Digital) Audio { 아날로그 신호를 디지털화하거나 그 역의 과정 수행 { Coding/Decoding - CODEC y { 69 { { 양자화(Quantization) (Q ) 수준 ? { Mono/Stereo … { Data Size ? a time sequence of two-dimensional frames sequence - frame - field - row(line) - pixel - color component - bit Entropy coding(Variable-length coding) { The more frequently frequently, the shorter codeword { Huffman coding, Lempel-Ziv coding { ex)) 2 bits bi per sample l -> 1.6 1 6 bi bits per sample l Sender { { In p u t c o d e w o rd encoding - bit rate control information segmentation and framing 71 F re q u e n c y (P ro b .) O u tp u t c o d e w o rd 0 0 0 .6 0 0 1 0 .1 5 1 0 0 1 0 0 .2 11 11 0 .0 5 1 0 1 Run-length coding { Windows 기반 멀티미디어 통신 응용 개발 70 Windows 기반 멀티미디어 통신 응용 개발 3 dimensional signal 3-dimensional y CD 음질/ 라디오 음질 / 전화 음질? Representation Video in digital { 20 - 20,000 Hz Sampling Rate ? y Digital Video 압축 기술 Nyquist Sampling Theory SoundFont 지원 사운드카드 ? Windows 기반 멀티미디어 통신 응용 개발 ex)) 000000001122222 ==> (0 (0;8)(1;2)(2;5) 8)(1 2)(2 5) Windows 기반 멀티미디어 통신 응용 개발 72 Quantization JPEG Encoding Reduce the precision { reduce # of bits required Value Quantized _ Value = Quantum Windows 기반 멀티미디어 통신 응용 개발 73 Discrete Cosine Transform For the reduction of spatial redundancy convertt the th spatial ti l representation t ti off an 8*8 iimage tto Procedure { Block preparation (Decomposition (Decomposition, RGB to YIQ) { DCT to each block { Q Quantization i i { Reduce the (0, 0) value of each block { Run-length encoding (zigzag scanning) { Huffman encoding 74 Windows 기반 멀티미디어 통신 응용 개발 Example the frequency domain DCT (i, j ) = pixel ( x, y ) = 7 7 1 (2 x + 1)iπ (2 y + 1) jπ C (i )C ( j )∑∑ pixel ( x, y ) cos[ ] cos[ ] 4 16 16 x =0 y =0 8*8 Image Block After DCT 1 7 7 (2 x + 1)iπ (2 y + 1) jπ C (i )C ( j ) DCT (i, j ) cos[ ] cos[ ] ∑∑ 4 i =0 j =0 16 16 where ⎧ 1 x=0 ⎪ C ( x) = ⎨ 2 ⎪1 otherwise ⎩ Windows 기반 멀티미디어 통신 응용 개발 Quantization Coefficient table 75 Windows 기반 멀티미디어 통신 응용 개발 After Quantization 76 MPEG Encoding Temporal Redundancy Reduction { GOP format Prediction Spatial Redundancy Reduction { DCT(Discrete Cosine Transform) Prediction { Transformation { Quantizing { Entropy py encoding g Windows 기반 멀티미디어 통신 응용 개발 77 Motion Compensation transformed without using prediction { restarting point for prediction { random d access point i P frame unidirectional prediction B frame { bidirectional prediction { not used for predicting other frames Windows 기반 멀티미디어 통신 응용 개발 MPEG-1 { 배경은 고정, 고정 물체가 하나 움직인다고 봄 { 1.2 Mbps, p , over twisted p pair lines for modest distances { 따라서 움직이는 물체의 이동 위치만을 기술 { storing movies on CD-ROM in CD-I and CD-Video format 구현 MPEG 2 MPEG-2 { 보통 8*8의 block으로 나눈 후 각 구역이 앞의 그림의 어느 block과 비슷한 지를 찾는다. 압축이 복원보다 힘들고 오래 걸린다. 4 to 6 Mbps, broadcasting, HDTV MPEG-4 { 특징 { 78 Types of MPEG and MPEG Systems 기본 개념 { { { Procedure { I frame 64 kbps, videoconference, BUT …. MPEG System { 동영상을 구성하는 미디어 스트림을 다중화시키고 이들의 재생 시 동기화 를 맞출 수 있도록 부가적 정보를 추가하는 것 { Windows 기반 멀티미디어 통신 응용 개발 79 MPEG 2 TS (Transport Stream) MPEG-2 Stream), PS (Program Stream) Windows 기반 멀티미디어 통신 응용 개발 80 VCM Architecture VCM is an intermediary between an application and compression and decompression drivers. The compression and decompression drivers compress and decompress individual frames of data. When an application makes a call to VCM, VCM translates the call into a message. The message is sent by using the ICSendMessage function to the appropriate compressor or decompressor, which compresses or decompresses the data. VCM receives the return value from the compression or decompression driver and then returns control to the application. If a macro is defined for a message, the macro expands to an ICSendMessage function call supplying appropriate parameters for that message. If a macro is defined for a message, your application should use it rather than the message. In this overview, these macros follow messages in parentheses. Windows 기반 멀티미디어 통신 응용 개발 81 Windows 기반 멀티미디어 통신 응용 개발 82 System Entries for Compressors, Decompressors, and Renderers The system uses entries in the registry to find VCM drivers. These When opening a VCM driver, an application specifies the type of driver and entries are in the form of two four-character codes separated by a the type of data handler it needs. Typically, this information comes from period. The first four-character code is defined by the system and can the stream header. The system tries to open the specified data handler, but be one of the following: if it fails, the system searches the registry for a driver that has the required Four-character code(FOURCC) : Description handler. When searching for the driver, the system tries to match the four-character { VIDC : Identifies compressors and decompressors. { VIDS : Identifies video-stream renderers. codes specified for the driver type and data handler with those specified in { TXTS : Identifies text-stream renderers. the driver entry. For example, if an application specifies the compressor { AUDS : Identifies audio-stream audio stream handlers. handlers MSSQ, the system searches the registry for the driver entry VIDC.MSSQ. If it Custom renderers can define their own four-character codes. Th second The d four-character f h t code d iis d defined fi d b by the th d driver. i T Typically, i ll th the and locates one that can handle the type of data your application specifies. second four-character code corresponds to the type of data the driver In the previous example, if the system could not find VIDC.MSSQ, it would can handle. handle open all drivers with the "VIDC" four-character code and locate one that can Windows 기반 멀티미디어 통신 응용 개발 cannot find a match, it opens each driver corresponding to the driver type 83 handle the data. Windows 기반 멀티미디어 통신 응용 개발 84 FOURCC: AUR2: AURA: CHAM: CVID: CYUV: DXT1: DXT2: DXT3: DXT4: 4 DXT5: FVF1: IF09: IV31: JPEG: MJPG: MRLE: MSVC: PHMO: RT21: ULTI: V422: V655: VDCT VDCT: VIDS: YU92: YUV8: YUV9: YUYV: ZPEG: Company: Technology Name AuraVision Corporation:AuraVision Aura 2: YUV 422 AuraVision Corporation:AuraVision Aura 1: YUV 411 Winnov, Inc.:MM_WINNOV_CAVIARA_CHAMPAGNE Supermac:Cinepak by Supermac Creative Labs, Inc:Creative Labs YUV Microsoft Corporation:DirectX Texture Compression format 1 Microsoft Corporation:DirectX Texture Compression format 2 Microsoft Corporation:DirectX Texture Compression format 3 Microsoft f Corporation:DirectX Texture Compression format f 4 Microsoft Corporation:DirectX Texture Compression format 5 Iterated Systems, Inc.:Fractal Video Frame Intel Corporation:Intel Intermediate YUV9 p 3.1 Intel Corporation:Indeo Microsoft Corporation:Still Image JPEG DIB Microsoft Corporation:Motion JPEG Dib Format Microsoft Corporation:Run Length Encoding Microsoft Corporation:Video 1 IBM Corporation:Photomotion Intel Corporation:Indeo 2.1 IBM Corporation:Ultimotion Vitec Multimedia:24 bit YUV 4:2:2 Vitec Multimedia:16 bit YUV 4:2:2 Vi Vitec M l i di Vid Maker Multimedia:Video M k Pro P DIB Vitec Multimedia:YUV 4:2:2 CCIR 601 for V422 Intel Corporation:YUV Winnov, Inc.:MM_WINNOV_CAVIAR_YUV8 p Intel Corporation:YUV9 Canopus, Co., Ltd.:BI_YUYV, Canopus Metheus:Video Zipper Windows 기반 멀티미디어 통신 응용 개발 85 Windows 기반 멀티미디어 통신 응용 개발 86 87 Windows 기반 멀티미디어 통신 응용 개발 88 VCM API VCM은 윈도우즈 3.1에서는 ICM (Installble Compression Manager)로 불렸기 때문에 API 이름은 IC로 시작된다. 시작된다 압축기 열기 { Open, Locate { ICLocate () : 특정한 비 비트맵을 맵을 압축/복원하기 위한 구동기를 연다 { ICOpen() : VCM 구동기를 연다. Windows 기반 멀티미디어 통신 응용 개발 VCM API 압축기의 선택 { 환경 설정 ICCompressorChoose() : 시스템에 설치된 여러 압축기 { 압축기의 상태를 얻거나 설정하는데 필요한 함수들 들의 Option을 p 결정하고 압축기를 선택한다. { ICQueryConfigure() ICGetStateSize() ICQueryConfigure(), ICGetStateSize(), ICGetState() ICGetState(), ICSetState() 압축기의 닫기 { VCM API ICClose() 압축기의 설치와 제거 정보 얻기 { 압축기의 정보를 얻기 위한 함수 { 응용 프로그램이 사용할 수 있는 압축기를 새로 설치 { KeyFrame의 수, 압축 품질 등을 얻는다. { ICInstall(), ICRemove(), ICOpenFunction() { ICGetInfo(), ICGetDefaultKeyFrameRate(), ICGetDefaultQuality() Windows 기반 멀티미디어 통신 응용 개발 89 90 Windows 기반 멀티미디어 통신 응용 개발 Image Compression/Decompression HANDLE hDIB; BITMAPINFO biIn; M NF HE DE biOut; u ; BITMAPINFOHEADER BYTE *lpData, *bimapIn, *bimapout; LONG lQuality, lSize; Single-Image Compression/Decompression { You can use the ICImageCompress/ICImageDecompress function to compress/decompress a single image. This function returns a handle of the compressed/decompressed deviceindependent bitmap (DIB). Image Data Compression/Decompression Image-Data { hDIB Your application can use a series of ICCompress functions and macros to compress data. The functions and macros can help you perform the following tasks: { y Determine the compression format to use for a specified input format. y Prepare the compressor. y Compress the data. data y End compression. Your application uses a series of ICDecompressEx functions to control the decompressor. The functions can help you perform the following tasks: y Select a decompressor. Prepare the decompressor. Decompress the data. y End decompression Windows 기반 멀티미디어 통신 응용 개발 = ICImageCompress( hVCM, 0, &biIn, bitmapIn, NULL, lQuality, &l &lSize) ) // Handle of VCM // flag (must 0) // 입력 데이터 포맷 // 입력데이터 // 출력데이터 포맷 // 압축 품질 // 압축된 Bitmap B 크기 lpData = ::GlobalLock(hDIB); memcpy(&biOut, (&biO t lpData, l D t sizeof(BITMAPINFOHEADER)); i f(BITMAPINFOHEADER)) memcpy(&bitmapOut, (lpData+sizeof(BITMAPINFOHEADER)), lSize); GlobalFree(hDIB); 91 Windows 기반 멀티미디어 통신 응용 개발 92 Sequence Compression/Decompression DWORD DWORD LONG dwCkID; dwCompFlags, dwQuality=10000; lNumFrames=900, lFrameNum; { if (ICCompressBegin (hVCM, lpbiIn, lpbiOut) == ICERR_OK) { for (lFrameNum = 0; lFrameNum < lNumFrames; lFrameNum++) { if (ICCompress(hVCM, (ICCompress(hVCM 0, 0 lpbiOut, lpbiOut lpOut, lpOut lpbiIn, lpbiIn lpIn, lpIn &dwCkID, &dwCompFlags, lFrameNum, 0, dwQuality, NULL, NULL) == ICERR_OK) { // Write Compressed Data to the AVI file } else { // Handle Compressor Error } } ICCompressEnd(hVCM); } else { // Handle the Eroor identifying the unsupported format } Your application can use the ICSeqCompressFrame, ICSeqCompressFrame ICSeqCompressFrameStart, and ICSeqCompressFrameEnd functions to compress a sequence of frames frames. These functions use the data stored in the COMPVARS structure. Applications use the ICCompressorChoose function to allow the user to select a compressor, open it, and set the compression parameters in the COMPVARS structure; however, pp can set the p parameters in the structure manually… y applications { ICSeqCompressFrame(), ICSeqCompressFrameStart(), ICCompressFree(), CS qC p (), ICSeqCompressFrameEnd(), { ICDecompressEx(), ICDecompressExBegin(), ICDecompressExEnd(), ICDecompressQuery 93 Windows 기반 멀티미디어 통신 응용 개발 Sequence Compression/Decompression 94 Windows 기반 멀티미디어 통신 응용 개발 User Interface Step 6 구현 Microsoft MPEG-4 CODEC을 이용 한 압축 및 재생 Read Only Windows 기반 멀티미디어 통신 응용 개발 96 Step 6 : VidCapDlg의 변화 Step 6 : VidCapDlg의 변화 추가된 멤버 함수 { { VIDC.MP43 CODEC의 Open y MPEG-4 CODEC의 확인 CButton m_chkMPEG4, UINT { void OpenCompressor(); y 추가된 멤버 변수 y { HIC m_vcmMPEG4_Compressor, m_vcmMPEG4_DeCompressor { BOOL m_bMPEG4; { LPBITMAPINFO y void MatchVideoFormat(BOOL bNewFormat); y y { 출력 Video Format 구조의 초기화 또는 설정 OnCheckMpeg4 y y VCM 장치에 대한 핸들; MPEG 4 Compressor가 제대로 Open되었는지의 여부 m_lpbiIn, m_lpbiMid, m_lpbiOut; Capture한 이미지, Compress한 이미지, Decompress한 이미지를 위한 BITMAPINFO 구조체에 대한 Pointer (동적 메모리 할당) MPEG4 CODEC 적용 여부 UINT m_nbiMidSize, m_nbiOutSize; { y y m lpDataMid m_lpDataOut; m_lpDataMid, m lpDataOut; Compress 이미지, Decompress 이미지를 저장할 메모리 버퍼 (동적 메모리 할당) UINT m_nDataMidSize, m_nDataOutSize; { y 97 할당한 메모리 크기 LPBYTE { Windows 기반 멀티미디어 통신 응용 개발 m_uiCompressedSize; 추가된 Control과 Binding된 변수들, Class Wizard 사용 할당한 메모리 크기 Windows 기반 멀티미디어 통신 응용 개발 98 void CVidCapDlg::OpenCompressor() { long CVidCapDlg::OnFrameCapture(WPARAM wp, LPARAM lp) // { ICTYPE_VIDEO : equivalent to the "VIDC" FOURCC // The mmioFOURCC macro converts four characters SetDlgItemInt(IDC_EDIT_FRAME, m_uiCurFrame++); // m_uiFrameSize = ((LPVIDEOHDR) lp)->dwBytesUsed; into a four-character code. m_vcmMPEG4_Compressor = SetDlgItemInt(IDC_EDIT_FSIZE, m_uiFrameSize); ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','P','4','3'), ICMODE_FASTCOMPRESS); if (m_pDispDlg) ( Di Dl ) { m_vcmMPEG4_DeCompressor = LPBYTE lpDataIn = ((LPVIDEOHDR) lp)->lpData; ICOpen(ICTYPE_VIDEO, mmioFOURCC('M','P','4','3'), ICMODE_FASTDECOMPRESS); if (m_chkMPEG4.GetCheck()) { m bMPEG4 = m m_bMPEG4 m_vcmMPEG4_Compressor vcmMPEG4 Compressor && m_vcmMPEG4_DeCompressor; m vcmMPEG4 DeCompressor; DWORD dwCkID; m_chkMPEG4.EnableWindow(m_bMPEG4); DWORD dwCompFlags; } DWORD dwQuality = 8000; void CVidCapDlg::MatchVideoFormat(BOOL bNewFormat) { if (ICCompress(m_vcmMPEG4_Compressor, 0, if (bNewFormat) (LPBITMAPINFOHEADER)m_lpbiMid, m_lpDataMid, { (LPBITMAPINFOHEADER)m_lpbiIn, lpDataIn, if (!m_lpbiIn) &dwCkID &dwCompFlags, &dwCkID, &dwCompFlags m_uiCurFrame, m uiCurFrame 0, 0 dwQuality, dwQuality NULL, NULL NULL) == ICERR ICERR_OK) OK) m_lpbiIn = (LPBITMAPINFO) malloc(sizeof(BITMAPINFO)); { m_pCapDlg->GetVideoFormat(m_lpbiIn); SetDlgItemInt(IDC_EDIT_CSIZE, m_lpbiMid->bmiHeader.biSizeImage); if (m_bMPEG4) if (ICDecompress(m_vcmMPEG4_DeCompressor, 0, { (LPBITMAPINFOHEADER) l biMid m_lpDataMid, (LPBITMAPINFOHEADER)m_lpbiMid, l D Mid DWORD dwformatsize = ICCompressGetFormatSize(m_vcmMPEG4_Compressor, m_lpbiIn);; (LPBITMAPINFOHEADER)m_lpbiOut, m_lpDataOut) == ICERR_OK) if (dwformatsize > m_nbiMidSize) m_pDispDlg->DrawFrame(m_lpDataOut); { } if (m (m_lpbiMid) lpbiMid) free(m free(m_lpbiMid); lpbiMid); } Windows 기반 멀티미디어 통신 응용 개발 m_lpbiMid = (LPBITMAPINFO) malloc(dwformatsize); 99 m_nbiMidSize = dwformatsize; Windows 기반 멀티미디어} 통신 응용 개발 100 Display Dialog의 변화 ICCompressGetFormat(m_vcmMPEG4_Compressor, m_lpbiIn, m_lpbiMid); // Find the worst-case buffer size. DWORD dwBufferSize = ICCompressGetSize(m_vcmMPEG4_Compressor, m_lpbiIn, m_lpbiMid); if (dwBufferSize > m_nDataMidSize) { if (m_lpDataMid) free(m_lpDataMid); m_lpDataMid = (LPBYTE) malloc(dwBufferSize); m_nDataMidSize = dwBufferSize; } ICCompressBegin(m_vcmMPEG4_Compressor, m_lpbiIn, m_lpbiMid); VideoFormat Size가 가변적일 수 있다…. { BITMAPINFO 구조체 동적으로 할당 { 추가한 멤버 변수 dwformatsize = ICDecompressGetFormatSize(m_vcmMPEG4_DeCompressor, m_lpbiMid); if (dwformatsize > m_nbiOutSize) { if ((m_lpbiOut) l biO t) free(m_lpbiOut); f ( l biO t) { m_lpbiOut = (LPBITMAPINFO) malloc(dwformatsize); y LPBITMAPINFO m_lpbminfo; l b i f y m_bminfo는 더 이상 사용되지 않음 S tVid F SetVideoFormat() t() 함수의 수정 m_nbiOutSize = dwformatsize; } ICDecompressGetFormat(m_vcmMPEG4_DeCompressor, m_lpbiMid, m_lpbiOut); dwBufferSize = ICCompressGetSize(m_vcmMPEG4_DeCompressor, m_lpbiMid, m_lpbiOut); if (dwBufferSize > m_nDataOutSize) { if (m_lpDataOut) free(m_lpDataOut); m_lpDataOut = (LPBYTE) malloc(dwBufferSize); m_nDataOutSize = dwBufferSize; } ICDecompressBegin(m_vcmMPEG4_DeCompressor, m_lpbiMid, m_lpbiOut); } Windows } 기반 멀티미디어 통신 응용 개발 101 Windows 기반 멀티미디어 통신 응용 개발 VidCap 최종 모습 Wave Capture/Play/ Compression Simple Wave Capture & Compression Program Windows 기반 멀티미디어 통신 응용 개발 103 102 Waveform Audio API 주요 구조체와 Handle의 Type Device Identifier와 Device Handle { Device Identifier : 여러 개의 장치가 있을 때 구분 { Device Handle : 여러 프로세스에서 하나의 물리적 장치를 이용할 때 구분 y HWAVEOUT, HWAVEIN { WAVEFORMATEX waveInOpen(), I O () waveOutOpen()에 O tO ()에 의해 구해짐 { { Device Identifier를 인자로 이용하는 함수 예 y { Device Handle을 인자로 하는 함수 예 y waveInDevCaps(), I D C () waveOutDevCaps(), O D C () ... waveIn, waveOut { Waveform Audio의 형식 지정에 쓰이는 구조체 WAVEHDR { waveInStart(), waveOutWrite(), ... Waveform Audio의 출력 및 입력 장치에 대한 핸들 입출력에 사용되는 헤더로 쓰이는 구조체 WAVEOUTCAPS, WAVEINCAPS { 출력 및 입력 장치의 기능(Capabilities) 질의에 이용되는 구조체 동시에 In/Out을 열 수 있을까 ? Windows 기반 멀티미디어 통신 응용 개발 105 Windows 기반 멀티미디어 통신 응용 개발 106 Format 관련 구조체 typedef struct { WORD wFormatTag; // Wave 형식 WORD nChannels; // 1=Mono 1=Mono, 2=Stereo DWORD nSamplePerSec; // 1초당 Sample 수 DWORD nAvgBytesPerSec; // 1초당 필요한 Byte 수 WORD nBlockAlign; //Alignment 단위 // PCM의 경우 nChannels * wBitsPerSample/8과 같다 WORD wBitsPerSample; // Sample 당 Bit 수 WORD cbSize; // 추가 정보를 위해 할당할 // 메모리 크기 } WAVEFORMATEX WAVEFORMAT { 모든 Waveform Audio 형식에 공통된 정보만 포함 { 추가적 정보가 필요할 때 이 구조체가 다른 구조체의 첫번째 Member가 될 수 있다. 있다 { WAVEFORMATEX에서 wBitsPerSample, cbSize 멤버가 없다. WAVEFORMATEX { WAVEFORMAT의 확장 { 일반적으로 가장 많이 사용됨 전화음질 PCM(8Khz, 8bits, Mono)을 위해 위 구조체를 채운다면 ? PCMWAVEFORMAT { typedef struct { WAVEFORMAT wf; // WAVEFORMAT 구조체 WORD wbitsPerSample; // Sample당 Bit 수 } PCMWAVEFORMAT; PCM 형태의 파형 오디오에서만 사용 Windows 기반 멀티미디어 통신 응용 개발 107 Windows 기반 멀티미디어 통신 응용 개발 108 Waveform Audio DataBlock APP 녹음이나 재생시 필요한 데이터의 저장을 위해 미리 데이터 블록을 할당하고 장치에 이를 전달하여야 한다. 한다 HWOUT HWIN 하나의 데이터 블록에는 이를 사용하기 위한 정보를 저장하 는 데이터 헤더가 필요하며 이것은 데이터 블록의 사용적에 HDR 미리 준비되어야 한다. 한다 데이터 블록 헤더에는 WAVEHDR 구조체를 사용한다. Device Driver가 데이터 블록의 사용을 완료하고 리턴하는 Data Block l HDR Device Driver Out 경우 할당된 데이터 블록을 해제하기 전에 데이터 헤더를 경우, Data Block l In Device 먼저 해제해야 한다. 109 Windows 기반 멀티미디어 통신 응용 개발 WAVEHDR typedef struct { LPSTR lpData; DWORD dwBufferLength; DWORD dwBytesRecorded; DWORD dwUser; DWORD dwFlags; DWORD dwLoops; p struct wavehdr_tag * lpNext; DWORD reserved; } WAVEHDR; 110 Waveform Audio DataBlock WAVEHDR 구조체 HDR Windows 기반 멀티미디어 통신 응용 개발 // 데이터 블록에 대한 Pointer // 데이터 블록의 크기 // 녹음된 Bytes 량 // 응용 개발자용 // Flag Wavehdr의 준비와 해제에 사용하는 함수 { waveInPrepareHeader { waveInUnprepareHeader { waveOutPrepareHeader O P H d { waveOutUnprepareHeader Device Driver에게 데이터 블록을 넘겨 주는 함수 { waveInAddBuffer,, waveOutWrite Data Block Windows 기반 멀티미디어 통신 응용 개발 111 Windows 기반 멀티미디어 통신 응용 개발 112 Waveform Audio DataBlock Messages Device Driver가 주어진 데이터 블록 처리를 끝냈을 때 어 떻게 ? { { waveOutClose() () / waveInClose() () 함수에 의해 장 장치가 닫혔을 혔 때 보내지는 메시지 CallBack Window MM WOM OPEN / MM_WIM_OPEN MM_WOM_OPEN MM WIM OPEN { Event 발생시 실행할 함수를 지정 y { { Event 발생시 메시지를 받는 윈도우 지정 y MM_WOM_CLOSE/ MM_WIM_CLOSE Callback Function 각 데이터 블록의 헤더인 WAVEHDR 구조체의 dwFlags의 WHDR_DONE 비 waveOutOpen() / waveInOpen() 함수에 의해 장치가 MM WOM DONE MM_WOM_DONE { waveOutWrite() 함수에 의해 Device Driver가 데이터 블록을 하는것이 끝 났을 때 보내는 메시지 트를 Polling MM_WIM_DATA { waveInStart()함수에 의해 녹음이 시작된 후 데이터 블록의 버퍼가 채워졌 을 때 보내는 메시지 Windows 기반 멀티미디어 통신 응용 개발 113 Waveform 재생의 개략적 순서 Windows 기반 멀티미디어 통신 응용 개발 Waveform 녹음의 개략적 순서 waveOutOpen 이용 출력 장치를 열고 핸들을 구한다. waveInOpen 데이터 블록을 위한 메모리를 할당한다. 할당한다 녹음을 위한 데이터 블록 메모리 할당 waveInPrepareHeader waveInAddBuffer { 데이터 블록으로 재생할 오디오 정보를 Copy waveOutPrepareHeader 이용 데이터 블록 준비(초기화) { waveOutWrite O tW it MM_WOM_DONE _ _ - 재생이 끝나면 받음 waveOutUnprepareHeader 이용 데이터 블록 해제 waveOutReset, waveOutClose Windows 기반 멀티미디어 통신 응용 개발 114 waveInStart { 115 데이터 블록 전달 (녹음 되지는 않음) 녹음 시작, 데이터 블록에 정보가 쓰여짐 MM_WIM_DATA waveInUnprepareHeader waveInStop waveInReset, waveInClose Windows 기반 멀티미디어 통신 응용 개발 116 WaveEcho 응용구현 2: WaveEcho Wave API를 이용하여 자신의 목소리를 녹음하고 바로 재생 한다. 한다 { 일반 H/W적 Loopback과 구별 Buffer Delay의 의미를 이해한다. y ((Deca, Hecto), ) Kilo, Mega, g Giga, g Tera y (deci, centi), milli, micro, nano, pico y bps (bit per second) (Bit & Byte) y Hz y 2^10 = ? Windows 기반 멀티미디어 통신 응용 개발 Step 0 : Project 준비 Windows 기반 멀티미디어 통신 응용 개발 119 118 Step 0 Resource 편집 Dialog-Based Application { Project Name : WaveEcho Windows 기반 멀티미디어 통신 응용 개발 121 ClassWizard 이용 Dialog 편집 Windows 기반 멀티미디어 통신 응용 개발 Edit Control 2개 { IDC_EDIT_BUFFERSIZE { IDC EDIT LOG (SendStringTest 참조) IDC_EDIT_LOG Button Control 2개 (IDCANCEL 제외) { IDC_BUTTON_START { IDC_BUTTON_STOP ICON Windows 기반 멀티미디어 통신 응용 개발 122 ClassWizard 이용 Dialog 편집 123 Windows 기반 멀티미디어 통신 응용 개발 124 Step 0 Code Utility Code 작성 SendStringTest 참조 { void CWaveEchoDlg::UpdateButton() { m_btnStart.EnableWindow(!m_bOn); m btnStop EnableWindow(m bOn); m_btnStop.EnableWindow(m_bOn); } LogStatus Member 함수 추가 Button Control을 추가한 이유는 Button Enable/Disable 을 위한 것이다. { CButton Class 참 참조 { 현재 상황을 표현하기 위한 BOOL Variable 추가 & 초기화 y CWaveEchoDlg::CWaveEchoDlg(CWnd* pParent /*=NULL*/) : CDialog(CWaveEchoDlg::IDD, pParent) { m_bOn = FALSE; //{{AFX_DATA_INIT(CWaveEchoDlg) m_uiBufSize = 1000; //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } BOOL m_bOn m bOn = FALSE; { Start/Stop 버튼 서로 Toggle { void UpdateButton() Member 함수 추가 Windows 기반 멀티미디어 통신 응용 개발 125 Windows 기반 멀티미디어 통신 응용 개발 BOOL CWaveEchoDlg::OnInitDialog() { g g() CDialog::OnInitDialog(); Step 1 Simple Recording/Playing // Set the icon for this dialog. The framework does this … // when the application's main window is not a dialog SetIcon(m hIcon TRUE); SetIcon(m_hIcon, // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon } // TODO: Add extra initialization here UpdateButton(); return TRUE; // return TRUE unless you set the focus to… void CWaveEchoDlg::OnButtonStart() { your control notification handler code here // TODO: Add y m_bOn = TRUE; UpdateButton(); } void CWaveEchoDlg::OnButtonStop() { // TODO: Add your control notification handler code here m_bOn = FALSE; UpdateButton(); } Windows 기반 멀티미디어 통신 응용 개발 127 126 Step 1 Step 1 사용자가 입력한 크기만큼의 버퍼(Audio Datablock)를 동 OnButtonStart 적으로 할당하여 waveIn을 이용하여 그 버퍼가 찰 때까지 { waveInOpen waveOutOpen 이용 장치 Open waveInOpen, 녹음을 한다. { 이미 열려 있을 경우 먼저 닫아야 한다. 녹음한 데이터 블록을 waveOut을 통하여 재생한다. { 녹음을 위해 버퍼를 동적으로 할당한다. 재생과 녹음의 개략적 순서 참조 { WaveHdr를 알맞게 설정하고 준비한다. y { Step 1에서 Interface 중 Start Button만 고려 Windows 기반 멀티미디어 통신 응용 개발 129 Step 1 waveInPrepareHeader waveInAddBuffer waveInStart : 녹음 개시 waveInAddBuffer, 버퍼가 차면 MM_WIM_DATA 메시지 수신 { 메시지 Handler 추가 { OnMMWimData Windows 기반 멀티미디어 통신 응용 개발 Step 1 OnMMWimData OnMMWomDone { Parameter 분석 : Reference 참조 { 데이터 블록을 해제 { 녹음된 버퍼를 waveIn에서 해제 { waveOutUnprepareHeader { 출력 장치 Reset R : waveOutReset O R y { { waveInUnprepareHeader 녹음을 멈춘다. y waveInStop, waveInReset 재생을 위해 데이터 블록을 초기화 y OnButtonStop { 할당한 Audio Buffer를 해제 { waveOutClose,, waveInClose 이용 장치를 닫음 waveoutPrepareHeader { waveOutWrite O tW it 이용 재생 시작 { 재생이 끝나면 MM_WOM_DONE 메시지 수신 y 130 OnMMWomDone Windows 기반 멀티미디어 통신 응용 개발 131 Windows 기반 멀티미디어 통신 응용 개발 132 Step 1 : 장치 열기 OnButtonStart Data Block HDR waveInAddBuffer waveInStart M b 변수 추가 Member class CWaveEchoDlg : public CDialog { // Construction // 중간 생략 DECLARE MESSAGE MAP() DECLARE_MESSAGE_MAP() private: HWAVEIN m_hWaveIn; // WaveIn 장치에 대한 Handle HWAVEOUT m_hWaveOut; m hWaveOut; // WaveOut 장치에 대한 Handle WAVEFORMATEX m_wFormat; // WaveFormat void UpdateButton(); void vo d LogStatus(LPCTSTR LogStatus(L S R pszFormat, ...); BOOL m_bOn; }; HWIN O MMW D OnMMWomDone MM_WIM_DATA OnMMWimData MM_WOM_DONE waveOutWrite HDR Data Block HWOUT Windows 기반 멀티미디어 통신 응용 개발 133 CWaveEchoDlg::CWaveEchoDlg(CWnd* g g pParent p /*=NULL*/) : CDialog(CWaveEchoDlg::IDD, pParent) { m_hWaveIn = NULL; m_hWaveOut = NULL; } m_wFormat.wFormatTag = WAVE_FORMAT_PCM; m_wFormat.nChannels F t Ch l = 1; 1 m_wFormat.nSamplesPerSec = 8000; m_wFormat.nAvgBytesPerSec = 8000; m wFormat nBlockAlign = 1; m_wFormat.nBlockAlign m_wFormat.wBitsPerSample = 8; m_wFormat.cbSize = 0; // TODO: Add your message handler code here CloseAllWaveDevice(); void CWaveEchoDlg::CloseAllWaveDevice() //추가 함수 : 장치 닫음 { if (m_hWaveIn) { waveInStop(m_hWaveIn); waveInReset(m_hWaveIn); waveInClose(m_hWaveIn); m_hWaveIn = NULL; } m_bOn = FALSE; //{{AFX_DATA_INIT(CWaveEchoDlg) m uiBufSize = 1000; m_uiBufSize //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent ... m hIcon = AfxGetApp() m_hIcon AfxGetApp()->LoadIcon(IDR LoadIcon(IDR_MAINFRAME); MAINFRAME); Windows 기반 멀티미디어 통신 응용 개발 134 최종 정리 void CWaveEchoDlg::OnDestroy() { CDialog::OnDestroy(); 초기화 코드 } Windows 기반 멀티미디어 통신 응용 개발 if (m_hWaveOut) ( hW O ) { waveOutReset(m_hWaveOut); waveOutClose(m_hWaveOut); m hW m_hWaveOut O t = NULL; } 135 Windows 기반 }멀티미디어 통신 응용 개발 136 Callback Function/Window MMRESULT waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, // Out : WaveIn 핸들을 저장할 변수 Ptr // In : Open할 WaveIn Device ID // WAVE_MAPPER LPWAVEFORMATEX pwfx, // In : Wave Open Format 구조의 Ptr DWORD dwCallback, // In : Callback 객체의 주소 DWORD dwCallbackInstance, // In : User Instance Data DWORD fd O fdwOpen // Open O Option O i ); MMRESULT waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID,, LPWAVEFORMATEX pwfx, DWORD dwCallback, DWORD dwCallbackInstance, DWORD fdwOpen ); App FUN 137 138 Windows 기반 멀티미디어 통신 응용 개발 Step 1 - Audio Block 준비 void d CWaveEchoDlg::OnButtonStart() CW E h Dl O B () { // TODO: Add your control notification handler code here m_bOn bO = TRUE TRUE; UpdateButton(); CloseAllWaveDevice(); waveInOpen(&m_hWaveIn, WAVE_MAPPER, &m_wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); waveOutOpen(&m hWaveOut WAVE waveOutOpen(&m_hWaveOut, WAVE_MAPPER, MAPPER &m &m_wFormat, wFormat (DWORD)m_hWnd, 0, CALLBACK_WINDOW); void CWaveEchoDlg::OnButtonStop() { // TODO: ODO Add dd your control not notification f cat on handler code here m_bOn = FALSE; UpdateButton(); () CloseAllWaveDevice(); } Windows 기반 멀티미디어 통신 응용 개발 MSG Device Driver 주의 : Error Handling Code 없음 } App FUN WaveInOpen과 사용 방법 같음 Windows 기반 멀티미디어 통신 응용 개발 N MSG No Device Driver WAVEHDR와 Buffer { Buffer는 사용자 입력 값을 바탕으로 동적으로 할당 { WAVEHDR와 Buffer를 연속된 메모리로 할당 y { { Memory 할당을 위해 GlobalAlloc(), GlobalLock()을 사용한다. y 이를 관리하기 위한 Member M b 변수추가 y HANDLE y LPWAVEHDR m_hAudioBlock; m_lpwHdr; l Hd Buffer Size와 녹음 시간과의 관계 ? y 139 할당 메모리 사이즈 = sizeof(WAVEHDR) i f(WAVEHDR) + 사용자 입력 버퍼 사이즈 1000b t 버퍼로 얼마나 녹음할 수 있나 ? 1000byte Windows 기반 멀티미디어 통신 응용 개발 140 CWaveEchoDlg::CWaveEchoDlg(CWnd* pParent /*=NULL*/) : CDialog(CWaveEchoDlg::IDD, pParent) { // 중간 생략 m_hAudioBlock = NULL; m lpwHdr = NULL; m_lpwHdr // 이하 생략 } void CWaveEchoDlg::OnButtonStart() { // TODO: Add your control notification handler code here UpdateData(); m_bOn = TRUE; UpdateButton(); class CWaveEchoDlg : public CDialog { // 중간 생략 private: void ReleaseMemory(); BOOL AllocateMemory(); void id CloseAllWaveDevice(); Cl AllW D i () HANDLE m_hAudioBlock; // 동적으로 할당한 메모리에 대한 Handle LPWAVEHDR m_lpwHdr; l Hd // AudioBlock A di Bl k Header에 H d 에 대한 Pointer P i t HWAVEIN m_hWaveIn; // WaveIn 장치에 대한 Handle HWAVEOUT m_hWaveOut; m hWaveOut; // WaveOut 장치에 대한 Handle WAVEFORMATEX m_wFormat; // WaveFormat void UpdateButton(); void LogStatus(LPCTSTR pszFormat, pszFormat ...); ); BOOL m_bOn; CloseAllWaveDevice(); waveInOpen(&m_hWaveIn, WAVE_MAPPER, &m_wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); }; Windows 기반 멀티미디어 통신 응용 개발 141 } Windows 기반 멀티미디어 통신 응용 개발 m lpwHdr->dwBufferLength = (DWORD) m_uiBufSize; m_lpwHdr->dwBufferLength m uiBufSize; void id CWaveEchoDlg::OnDestroy() CW E h Dl O D t () { CDialog::OnDestroy(); m_lpwHdr->lpData = (LPSTR) (((BYTE *)m )m_lpwHdr) lpwHdr) + sizeof(WAVEHDR)); // TODO: Add your message handler code here CloseAllWaveDevice(); ReleaseMemory(); Windows 기반 멀티미디어 통신 응용 개발 142 BOOL CW CWaveEchoDlg::AllocateMemory() E h Dl ll M () { ReleaseMemory(); if (m_hAudioBlock ( hA di Bl k = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)(sizeof(WAVEHDR) + m_uiBufSize)) ) { m_lpwHdr = (LPWAVEHDR)GlobalLock(m_hAudioBlock); void CWaveEchoDlg::OnButtonStop() { // TODO: Add your control notification handler code here m_bOn = FALSE; UpdateButton(); CloseAllWaveDevice(); ReleaseMemory(); l () } } AllocateMemory(); ll () m_lpwHdr->dwFlags = 0L; m lpwHdr->dwLoops m_lpwHdr dwLoops = 0L; 143 } return TRUE; } return FALSE; Windows 기반 멀티미디어 통신 응용 개발 144 Step 1 : 녹음 void CWaveEchoDlg::ReleaseMemory() { if (m_hAudioBlock) (m hAudioBlock) { GlobalUnlock(m_hAudioBlock); GlobalFree(m hAudioBlock); GlobalFree(m_hAudioBlock); m_hAudioBlock = NULL; m_lpwHdr = NULL; } } Windows 기반 멀티미디어 통신 응용 개발 기화하고 waveInAddBuffer를 통해 waveInDevice에 넘김 145 Windows 기반 멀티미디어 통신 응용 개발 146 MM_WIM_DATA Msg Handler 추가 { if (m_hWaveIn && m_hWaveOut && AllocateMemory()) { m bOn = TRUE; m_bOn LogStatus("장치 Open 및 메모리 할당이 성공적으로 ...\r\n"); waveInPrepareHeader(m_hWaveIn, m_lpwHdr, sizeof(WAVEHDR)); waveInAddBuffer(m_hWaveIn, I AddB ff ( hW I m_lpwHdr, l Hd sizeof(WAVEHDR)); waveInStart(m_hWaveIn); } else { m_bOn = FALSE; LogStatus("장치 Open 또는 메모리 할당에 문제가 있습니다\r\n"); } UpdateButton(); Windows 기반 멀티미디어 통신 응용 개발 waveInStart() 호출하여 녹음시작 Step 1 MM_WIM_DATA 처리 void CWaveEchoDlg::OnButtonStart() { // TODO TODO: Add your control t l notification tifi ti h handler dl code d here h UpdateData(); CloseAllWaveDevice(); waveInOpen(&m hWaveIn, WAVE_MAPPER, waveInOpen(&m_hWaveIn, WAVE MAPPER, &m &m_wFormat, wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); } 할당된 Audio Block을 waveInPrepareHeader를 이용 초 MCIWndTest 참조 OnMMWimData { WPARAM : hInputDev y { Handle of the waveform-audio input device that received the data. LPARAM : (LONG) lpwvhdr y Address of a WAVEHDR structure that identifies the buffer containing the data. 147 Audio Block을 재생 Windows 기반 멀티미디어 통신 응용 개발 148 Step 1 MM_WOM_DONE 처리 long g CWaveEchoDlg::OnMMWimData(WPARAM W E Dg W mD (W wp, p, LPARAM L lp) p) { LogStatus("현재 Audio Block에 대한 녹음이 끝났습니다.\r\n"); p p (( ) p ((LPWAVEHDR)) lp, p waveInUnprepareHeader((HWAVEIN)wp, sizeof(WAVEHDR)); //waveInUnprepareHeader(m_hWaveIn, m_lpwHdr, // sizeof(WAVEHDR); MM_WOM_DONE Msg Handler 추가 O MMW D OnMMWomDone { WPARAM, LPARAM의 의미, MM_WIM_DATA와 유사 waveInReset((HWAVEIN)wp); waveInStop((HWAVEIN)wp); ((LPWAVEHDR) lp)->dwFlags = 0L; ((LPWAVEHDR) lp)->dwLoops = 0L; waveOutPrepareHeader(m_hWaveOut, (LPWAVEHDR) lp, sizeof(WAVEHDR)); waveOutWrite(m hWaveOut (LPWAVEHDR) lp, waveOutWrite(m_hWaveOut, lp sizeof(WAVEHDR)); } return 0l; Windows 기반 멀티미디어 통신 응용 개발 149 Windows 기반 멀티미디어 통신 응용 개발 150 Step 1 long CWaveEchoDlg::OnMMWomDone(WPARAM wp, LPARAM lp) { g ( Audio Block에 대한 재생이 끝났습니다.\r\n"); ) LogStatus("현재 waveOutUnprepareHeader((HWAVEOUT)wp, (LPWAVEHDR) lp, sizeof(WAVEHDR)); //waveOutUnprepareHeader(m_hWaveOut, m_lpwHdr, // sizeof(WAVEHDR); waveOutReset((HWAVEOUT)wp); } return 0l; Windows 기반 멀티미디어 통신 응용 개발 151 녹음과 재생의 반복 ? Windows 기반 멀티미디어 통신 응용 개발 152 Step 1-1 멈춤을 누를 때 까지 녹음과 재생을 반복 O MMW D OnMMWomDone에서 에서 Audio A di Bl Block을 k을 단순히 해제하지 말 OnButtonStart waveInAddBuffer waveInStart Data Block HDR 고 녹음을 위해 다시 WaveIn에 넘긴다. OnMMWomDone waveInAddBuffer waveInStart HWIN MM_WIM_DATA OnMMWimData MM_WOM_DONE waveOutWrite HDR Windows 기반 멀티미디어 통신 응용 개발 153 long CWaveEchoDlg::OnMMWomDone(WPARAM wp, LPARAM lp) { LogStatus("현재 Audio Block에 대한 재생이 끝났습니다.\r\n"); waveOutUnprepareHeader((HWAVEOUT)wp, O tU H d ((HWAVEOUT) (LPWAVEHDR) lp, l sizeof(WAVEHDR)); //waveOutUnprepareHeader(m_hWaveOut, m_lpwHdr, // sizeof(WAVEHDR); waveOutReset((HWAVEOUT)wp); waveInPrepareHeader(m_hWaveIn, (LPWAVEHDR) lp, sizeof(WAVEHDR)); waveInAddBuffer(m hWaveIn, (LPWAVEHDR) lp, waveInAddBuffer(m_hWaveIn, sizeof(WAVEHDR)); waveInStart(m_hWaveIn); return 0l; Windows 기반 멀티미디어 통신 응용 개발 HWOUT Windows 기반 멀티미디어 통신 응용 개발 Step 2 - Ring Buffer ((LPWAVEHDR) lp)->dwFlags = 0L; ((LPWAVEHDR) lp)->dwLoops lp) >dwLoops = 0L; } Data Block 155 154 Step 2 Step 2 Step 1의 문제점 { Audio Block 하나만을 이용할 경우 녹음을 하는 동안엔 재생을 재생을 하 있다. 있다 는 경우엔 녹음을 할 수 없는 문제점이 있다. { waveIn, waveOut에게 하나 이상의 Audio Block을 보낼 수 { Audio Block 2개를 만들어 하나는 녹음에 하나는 재생에 사용 ? y 블록에 대하여 녹음/재생이 끝났을 때 Linked List 상에서 그 다음 블록이 MM_WIM_DATA : 다른 블록이 Available 한지를 살피고 가능할 경우 녹음에 이 있을 경우 그 블록에 대해 이어 녹음/재생을 수행한다. 용 { y MM_WOM_DONE : 다른 블록이 Available 한지를 살피고 가능할 경우 재생에 하나의 블록에 대한 처리가 끝날 때 마다 MM_WIM_DATA 또는 MM_WOM_DONE 메시지를 발생시킨다. 이용 y 장치구동기는 Audio Block을 내부적으로 Linked List로 관리하여 하나의 Synchronization 문제점, 녹음과 재생이 끊어짐 157 Windows 기반 멀티미디어 통신 응용 개발 Windows 기반 멀티미디어 통신 응용 개발 158 Step 2 Device Driver HDR Data Block HDR Data Block HDR Data Block Step 1에서 이미 하나의 Audio Block을 이용 생산자 (WaveIn)/소비자(WaveOut) 개념에 의한 Loop을 구성하고 있다. MM_WIM_DATA MM_WOM_DONE HDR Data Block 여러 번의 WaveInAddBuffer() 한 번의 WaveInStart() Audio Block의 개수를 N개(>2)로 늘여 생산자/소비자 Loop을 구성한다. 구성한다 여러 번의 WaveOutWrite() OnMMWomDone에 의해 Audio Block이 재사용되므로 Ring Buffer의 개념이 사용되는 것이다. Windows 기반 멀티미디어 통신 응용 개발 159 Windows 기반 멀티미디어 통신 응용 개발 160 Step 2 OnButtonStart waveInAddBuffer waveInStart Audio Block을 위한 Member 변수를 단일 변수에서 Array 변수로 수정한다. 수정한다 Data HDR Data Block HDR Data Block HDR Block OnMMWomDone waveInAddBuffer waveInStart HWIN MM_WIM_DATA OnMMWimData y HANDLE m_hAudioBlock[RINGBUFFER_SIZE]; y LPWAVEHDR P A DR m_lpwHdr[RINGBUFFER_SIZE]; l d [R GB R S ] 관련한 함수도 이에 맞게 수정한다. { Constructor의 초기화 부분 { AllocateMemory, y, ReleaseMemoryy MM_WOM_DONE waveOutWrite Data HDR Data Bllock k HDR Data D tB Block HDR Block HWOUT Windows 기반 멀티미디어 통신 응용 개발 161 Windows 기반 멀티미디어 통신 응용 개발 162 163 CWaveEchoDlg::CWaveEchoDlg(CWnd* pParent /*=NULL*/) : CDialog(CWaveEchoDlg::IDD, g( g ,p pParent)) { // 중간 생략 for (int i=0; i < RINGBUFFER_SIZE; i++) { m_hAudioBlock[i] = NULL; m_lpwHdr[i] = NULL; } // 이하 생략 } void CWaveEchoDlg::ReleaseMemory() { for (int i=0; i < RINGBUFFER_SIZE; i++) { if (m_hAudioBlock[i]) (m hA di Bl k[i]) { GlobalUnlock(m_hAudioBlock[i]); GlobalFree(m hAudioBlock[i]); GlobalFree(m_hAudioBlock[i]); m_hAudioBlock[i] = NULL; m_lpwHdr[i] = NULL; } } } Windows 기반 멀티미디어 통신 응용 개발 164 #define RINGBUFFER_SIZE RINGBUFFER SIZE 8 class CWaveEchoDlg : public CDialog { // 중간 생략 private: void ReleaseMemory(); BOOL AllocateMemory(); void CloseAllWaveDevice(); [ _SIZE]; ]; HANDLE m_hAudioBlock[RINGBUFFER // 동적으로 할당한 메모리에 대한 Handle LPWAVEHDR m_lpwHdr[RINGBUFFER_SIZE]; // AudioBlock Header에 대한 Pointer HWAVEIN m_hWaveIn; // WaveIn 장치에 대한 Handle HWAVEOUT m_hWaveOut; // WaveOut 장치에 대한 Handle WAVEFORMATEX m_wFormat; // WaveFormat void UpdateButton(); void LogStatus(LPCTSTR pszFormat, ...); BOOL m_bOn; }; Windows 기반 멀티미디어 통신 응용 개발 BOOL CWaveEchoDlg::AllocateMemory() { y() ReleaseMemory(); Step 2 BOOL fError = FALSE; for (int i=0; i < RINGBUFFER_SIZE; i++) { if (m_hAudioBlock[i] = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)(sizeof(WAVEHDR) + m_uiBufSize)) ) { m_lpwHdr[i] = (LPWAVEHDR)GlobalLock(m_hAudioBlock[i]); m_lpwHdr[i]->dwBufferLength = (DWORD) m_uiBufSize; m lpwHdr[i] >lpData = m_lpwHdr[i]->lpData (LPSTR) (((BYTE *)m_lpwHdr[i]) + sizeof(WAVEHDR)); m_lpwHdr[i]->dwFlags = 0L; p p = 0L; m_lpwHdr[i]->dwLoops } else { fError = TRUE; ReleaseMemory(); break; } 녹음을 시작(waveInStart)하기 전에 할당한 N개의 Audio Block을 모두 waveInAddBuffer를 통해 waveIn에 넘긴다. 넘긴다 waveInStart가 호출되면 waveIn은 Audio Block들에 대하 여 순차적으로 녹음을 수행한다. 블록마다 녹음이 끝나면 MM_WIM_DATA MM WIM DATA 발생 OnMMWimData에서는 녹음이 끝난 Block을 waveOutWrite()를 통해 재생 { I d 값 관리할 필요 없음 (LPARAM 참조) Index값 } return !fError; } 기반 멀티미디어 통신 응용 개발 Windows 165 void CWaveEchoDlg::OnButtonStart() { your control notification handler code here // TODO: Add y UpdateData(); CloseAllWaveDevice(); waveInOpen(&m_hWaveIn, WAVE_MAPPER, &m_wFormat, (DWORD)m hWnd 0, (DWORD)m_hWnd, 0 CALLBACK CALLBACK_WINDOW); WINDOW); waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_wFormat, (DWORD)m_hWnd, 0, CALLBACK_WINDOW); if (m_hWaveIn && m_hWaveOut && AllocateMemory()) { m_bOn = TRUE; LogStatus("장치 LogStatus( 장치 Open 및 메모리 할당이 성공적으로 이루어졌습니다.\r\n 이루어졌습니다 \r\n"); ); for (int i=0; i < RINGBUFFER_SIZE; i++) { waveInPrepareHeader(m_hWaveIn, m_lpwHdr[i], sizeof(WAVEHDR)); waveInAddBuffer(m_hWaveIn, m_lpwHdr[i], sizeof(WAVEHDR)); } waveInStart(m_hWaveIn); } else { m_bOn = FALSE; LogStatus("장치 Open 또는 메모리 할당에 문제가 있습니다\r\n"); } UpdateButton(); } 기반 멀티미디어 통신 응용 개발 Windows 167 Windows 기반 멀티미디어 통신 응용 개발 166 long CWaveEchoDlg::OnMMWimData(WPARAM wp, wp LPARAM lp) { //LogStatus("현재 Audio Block에 대한 녹음이 끝났습니다.\r\n"); waveInUnprepareHeader((HWAVEIN)wp (LPWAVEHDR) lp, waveInUnprepareHeader((HWAVEIN)wp, lp sizeof(WAVEHDR)); //waveInUnprepareHeader(m_hWaveIn, m_lpwHdr, // sizeof(WAVEHDR); //waveInReset((HWAVEIN)wp); //waveInStop((HWAVEIN)wp); p(( ) p) ((LPWAVEHDR) lp)->dwFlags = 0L; ((LPWAVEHDR) lp)->dwLoops p p = 0L; waveOutPrepareHeader(m_hWaveOut, (LPWAVEHDR) lp, sizeof(WAVEHDR)); waveOutWrite(m_hWaveOut, (LPWAVEHDR) lp, sizeof(WAVEHDR)); } return t 0l 0l; Windows 기반 멀티미디어 통신 응용 개발 168 long g CWaveEchoDlg::OnMMWomDone(WPARAM g wp, p LPARAM lp) p { //LogStatus("현재 Audio Block에 대한 재생이 끝났습니다.\r\n"); waveOutUnprepareHeader((HWAVEOUT)wp, (LPWAVEHDR) lp, sizeof(WAVEHDR)); ( E )) //waveOutUnprepareHeader(m_hWaveOut, m_lpwHdr, // sizeof(WAVEHDR); Step 2 종료시의 Error 발생 D b : Memory Debug M Access A Vi Violation l ti { 해제된 메모리에 접근 ((LPWAVEHDR) lp)->dwFlags = 0L; ((LPWAVEHDR) lp)->dwLoops = 0L; //waveOutReset((HWAVEOUT)wp); waveInPrepareHeader(m_hWaveIn, waveInPrepareHeader(m hWaveIn (LPWAVEHDR) lp, lp sizeof(WAVEHDR)); waveInAddBuffer(m_hWaveIn, (LPWAVEHDR) lp, sizeof(WAVEHDR)); waveInStart(m_hWaveIn); } return 0l; Windows 기반 멀티미디어 통신 응용 개발 169 Windows 기반 멀티미디어 통신 응용 개발 170 Step 2 waveInReset, waveOutReset은 현재 장치에 할당된 모든 Audio Block들에 대하여 수행이 끝난 것으로 처리한다. 처리한다 그 결과 해당 Block들에 대하여 OnMMWimData, OnMMWomDone이 호출된다. 그러나 이전에 ReleaseMemory()가 호출되어 Audio Block 들은 이미 해제된 후이다. (Dangling Reference Problem) 그런데도 이 블록들을 다시 녹음 및 재생에 이용하려 하므 로 Violation 에러가 발생한다. 발생한다 Windows 기반 멀티미디어 통신 응용 개발 171 llong CWaveEchoDlg::OnMMWimData(WPARAM CW E h Dl O MMWi D t (WPARAM wp, LPARAM lp) l ) { if (wp && lp && m_bOn) { //LogStatus("현재 Audio Block에 대한 녹음이 끝났습니다.\r\n"); //중간생략 waveOutWrite(m hWaveOut (LPWAVEHDR) lp, waveOutWrite(m_hWaveOut, lp sizeof(WAVEHDR)); } return 0l; } long CWaveEchoDlg::OnMMWomDone(WPARAM wp, LPARAM lp) { if (wp && lp && m_bOn) { g ( Audio Block에 대한 재생이 끝났습니다.\r\n"); ) //LogStatus("현재 // 중간생략 waveInStart(m_hWaveIn); } return 0l; } Windows 기반 멀티미디어 통신 응용 개발 172 Step 2 Step 3 : ACM의 적용과 Volume Control BufferSize에 따른 음질 변화 { Quality 척도 : Delay { Frame Delay y 계산 방법 ? y 1000Byte Frame의 Frame Delay ? { F Frame Delay를 D l 를 줄이는 방법 ? { TradeOff Windows 기반 멀티미디어 통신 응용 개발 Microsoft G.723.1 CODEC의 적용 173 G.723.1 Microsoft G.723.1 CODEC 이용 8000Hz, 16bit Linear PCM => G.723.1 30ms마다 하나의 Frame ACM 이용 F Frame Delay D l ? Frame Size ? Windows 기반 멀티미디어 통신 응용 개발 175 { 24 bytes { 16 bit Linear PCM 30ms => ? 480bytes Windows 기반 멀티미디어 통신 응용 개발 176 ACM Open ACM Encode WAVEFORMATEX Raw_wFormat = { WAVE_FORMAT_PCM, 1, 8000, 16000, 2, 16, 0}; static stat c const struct { WAVEFORMATEX wf; BYTE extra[10]; } G7231_Format = { {66 1, {66, 1 8000, 8000 800, 800 24 24, 0 0, 10} 10}, {2, 0, 0xce, 0x9a, 0x32, 0xf7, 0xa2, 0xae, 0xde, 0xac } }; LPWAVEHDR waveInUnprepareHeader(hwi, wHdr, sizeof(WAVEHDR)); wHdr->dwFlags = 0l; wHdr->dwLoops = 0l; ACMSTREAMHEADER if (acmStreamOpen(&g_hAcmEncoder, NULL, &Raw_wFormat, (LPWAVEFORMATEX)&G7231_Format, NULL, NULL, 0, 0)) return t n -1; 1; // En Encoder d Op Open n Error E acmStreamPrepareHeader(g_hAcmEncoder, &acmheader, 0); acmStreamConvert(g_hAcmEncoder, &acmheader, 0); acmStreamUnprepareHeader(g_hAcmEncoder, &acmheader, 0); 177 ACM Decode ACMSTREAMHEADER Windows 기반 멀티미디어 통신 응용 개발 178 ACM Close acmheader; acmStreamClose(g_hAcmEncoder, 0); acmStreamClose(g_hAcmDecoder, 0); memset(&acmheader, 0, sizeof(acmheader)); acmheader.cbStruct = sizeof(acmheader); acmheader.pbSrc = (BYTE *)buf; acmheader.cbSrcLength = size; acmheader.pbDst = decoded_buffer; acmheader.cbDstLength h d bD tL th = 480; 480 acmStreamPrepareHeader(g_hAcmDecoder, &acmheader, 0); if (acmStreamConvert(g_hAcmDecoder, &acmheader, 0)) return -1; 1; acmStreamUnprepareHeader(g_hAcmDecoder, &acmheader, 0); Windows 기반 멀티미디어 통신 응용 개발 acmheader; memset(&acmheader, 0, sizeof(acmheader)); acmheader.cbStruct = sizeof(acmheader); acmheader.pbSrc = (BYTE *)wHdr->lpData; acmheader.cbSrcLength h h = wHdr->dwBytesRecorded; acmheader.pbDst = (unsigned char *)g_buffer; acmheader.cbDstLength = 24; if (acmStreamOpen(&g_hAcmDecoder, NULL, ( (LPWAVEFORMATEX)&G7231_Format, ) _ , &Raw_wFormat, NULL, NULL, 0, 0)) return -1; // Decoder Open Error Windows 기반 멀티미디어 통신 응용 개발 wHdr = (LPWAVEHDR) dwParam1; 179 Windows 기반 멀티미디어 통신 응용 개발 180 Mixer Control 기타 Volume Control waveOutSetVolume((HWAVEOUT)WAVE_MAPPER, newvol); waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, &vol Mixer 의 이용 Windows 기반 멀티미디어 통신 응용 개발 181 182 Windows 기반 멀티미디어 통신 응용 개발 BabyChat 설계 응용구현 3 : BabyChat 생성, 호출 CLoginDlg CBabyC ChatApp Port 정보 데이터수신 UserID 정보 생성 CDataSocket 생성 호출 생성, Windows 기반 멀티미디어 통신 응용 개발 목적지 주소 전송 데이터 CBabyChatDlg (Main Dlg) 184 Step 0 Step 0 : CLoginDlg 생성 Dialog Based { BabyChat { App Wizard Step 2 : WinSock Support 반드시 설정 { R Resource 편집 - 2개의 Dialog Di l y Login Dialog, Main Dialog y L i Di Login Dialog를 l 를 위해 새로운 Dialog Di l R Resource 추가 y 2개의 Edit Control C t l - IDC_EDIT_PORT - IDC_EDIT_USERID 1개의 Button Control - IDOK IDD_BABYCHAT_LOGIN Windows 기반 멀티미디어 통신 응용 개발 185 Step 0 - CLoginDlg Class 편집 186 Windows 기반 멀티미디어 통신 응용 개발 Step 0 - MainDlg Resource 편집 IDD BABYCHAT DIALOG IDD_BABYCHAT_DIALOG IDC_EDIT_IP IDC EDIT PORT IDC_EDIT_PORT IDC_EDIT_MSG IDCANCEL IDC_BUTTON_SEND : Default Button IDC_EDIT_LOG 이전 Project 참조 Windows 기반 멀티미디어 통신 응용 개발 187 Windows 기반 멀티미디어 통신 응용 개발 188 Step 0 : MainDlg Message Map Step 0 - MainDlg 멤버변수 추가 Windows 기반 멀티미디어 통신 응용 개발 189 Step-0 : CDataSocket 객체 생성 Windows 기반 멀티미디어 통신 응용 개발 Windows 기반 멀티미디어 통신 응용 개발 190 OnReceive Member 함수 추가 191 Windows 기반 멀티미디어 통신 응용 개발 192 Step 1 - CLoginDlg & MainDlg Step 1 - CLoginDlg 구현 CBabyChatApp의 InitInstance() 부분을 수정 { CBabyChatDlg 생성 전에 생성하도록 한다. 한다 CLoginDlg 정보를 MainDlg로 넘겨 줘야 한다. { y #include “LoginDlg.h” BOOL CBabyChatApp::InitInstance() { // 생략 CLoginDlg login_dlg; if (login_dlg.DoModal() (l i dl D M d l() == IDOK) { CBabyChatDlg dlg; m_pMainWnd = &dlg; i t nResponse int R = dlg.DoModal(); dl D M d l() if (nResponse == IDOK) { // 생략 ... } } return FALSE; } Windows 기반 멀티미디어 통신 응용 개발 PUBLIC : CString m_csUserID BOOL CBabyChatApp::InitInstance() CB b Ch tA I itI t () { // 생략 CLoginDlg login_dlg; if (login_dlg.DoModal() (l i dl D M d l() == IDOK) { CBabyChatDlg dlg; m_pMainWnd = &dlg; dlg.m_csUserID l = login_dlg.m_csUserID; l l int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // 생략 ... } } return FALSE; } 193 Step 1 - Socket Create Windows 기반 멀티미디어 통신 응용 개발 194 Step 2 : MainDlg & CDataSocket #include #i l d “Datasocket.H” “D k H” BOOL CBabyChatApp::InitInstance() { // 생략 CLoginDlg login_dlg; if (login_dlg.DoModal() == IDOK) { CD t S k t dataSocket; CDataSocket d t S k t if (dataSocket.Create(login_dlg.m_uiPort, SOCK_DGRAM)) { CBabyChatDlg dlg; m_pMainWnd = &dlg; dlg.m_csUserID = login_dlg.m_csUserID; int nResponse = dlg.DoModal(); if f (nResponse ( == IDOK)) { // 생략 ... } dataSocket.Close(); } return FALSE; } Windows 기반 멀티미디어 통신 응용 개발 UserID 정보를 저장할 Member 변수를 MainDlg에 추가 CDataSocket은 다음을 이용 CMainDlg Access 가능 { CWnd* AfxGetMainWnd( ); CWnd { m_pMainWnd MainDlg가 CDataSocket을 이용할 수 있도록 이 객체의 주 소 정보를 저장할 Member 변수를 추가 { 195 생성자를 수정하여 CDataSocket Pointer를 받도록 한다. Windows 기반 멀티미디어 통신 응용 개발 196 CBabyChatDlg 수정 Member 변수 추가 (#include “datasocket.h”) { CDataSocket * m_pDataSocket m pDataSocket 생성자 수정 (선언과 구현 모두) { CBabyChatDlg(CWnd *pParent) => CBabyChatDlg(CDataSocket *pSocket, CWnd *pParent) CBabyChatDlg::CBabyChatDlg(CDataSocket *pSocket, CWnd* pParent /*=NULL*/) : CDialog(CMainDlg::IDD, pParent) { m_pDataSocket = pSocket; //{{AFX_DATA_INIT(CMainDlg) m csIP = _T( m_csIP T(""); ); m_csMsg = _T(""); m_uiPort = 0; //}}AFX_DATA_INIT } Windows 기반 멀티미디어 통신 응용 개발 197 #include “Datasocket.H” y pp () BOOL CBabyChatApp::InitInstance() { // 생략 CLoginDlg login_dlg; if (login_dlg.DoModal() == IDOK) { CDataSocket dataSocket; if (dataSocket.Create(login_dlg.m_uiPort, (d t S k t C t (l i dl iP t SOCK_DGRAM)) SOCK DGRAM)) { CBabyChatDlg dlg(&dataSocket); m pMainWnd = &dlg; m_pMainWnd dlg.m_csUserID = login_dlg.m_csUserID; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // 생략 ... } dataSocket.Close(); } return FALSE; } Windows 기반 멀티미디어 통신 응용 개발 198 Step 3 : 데이터 전송 OnButtonSend() 구현 자신이 입력한 내용을 Log L 창에 표시 LogStatus() g () 함수 추가 : { void CBabyChatDlg::OnButtonSend() { // TODO: Add your control notification handler code here UpdateData(); LogStatus("%s\r\n",(LPCTSTR)m g ( \ \ ,( )m_csMsg); g); 이전 Project 참조 CString vcsMsg = m_csUserID + " : " + m_csMsg; SOCK DGRAM : UDP SOCK_DGRAM { Connectionless, SendTo() 를 이용 { 목적지 주소와 IP 필요 입력한 메시지 앞에 사용자 ID를 첨가 } Windows 기반 멀티미디어 통신 응용 개발 199 if (m_pDataSocket->SendTo((LPCTSTR)vcsMsg, vcsMsg.GetLength(), m_uiPort, m_csIP)==SOCKET_ERROR) LogStatus("%s\r\n","데이터 전송에 실패했습니다"); else l { m_csMsg=""; UpdateData(FALSE); } Windows 기반 멀티미디어 통신 응용 개발 200 Step 4 - 데이터 수신 Step 4 - CDataSocket 수정 CDataSocket이 데이터를 수신하면 사용자 정의 메시지를 // DataSocket.h #define UM_SOCKET_RECEIVED(WM_USER+10) class l CD CDataSocket k : public bl CAsyncSocket C k { // 생략... 이용하여 MainDlg에 Notify { OnReceive() 수정 { 사용자 정의 메시지 y void CDataSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call UM_SOCKET_RECEIVED { AfxGetMainWnd() 함수 호출을 통해 MainDlg의 CWnd *를 알 수 있다. { SendMessage() / PostMessage()를 이용하여 Notify ::AfxGetMainWnd()->SendMessage(UM_SOCKET_RECEIVED); MainDlg는 앞에서 정의한 사용자 정의 메시지를 처리할 수 CAsyncSocket::OnReceive(nErrorCode); } 있는 메시지 핸들러 구현 Windows 기반 멀티미디어 통신 응용 개발 201 Windows 기반 멀티미디어 통신 응용 개발 202 Step 4 - CMainDlg 수정 MAX_DATA_SIZE 상수 정의는 수신 시 이용할 버퍼 할당을 위해 필요한 값 #define MAX_DATA_SIZE 256 class CBabyChatDlg : public CDialog { // 생략 //{{AFX_MSG(CBabyChatDlg) // 생략 afx_msg f l long OnDataReceived(WPARAM D R d( P R wp, LPARAM LP R l ) lp); //}}AFX_MSG // 생략 } ((nReceived = m_pDataSocket->ReceiveFrom(buffer, p ( if (( sizeof(buffer),NULL, NULL)) == SOCKET_ERROR) LogStatus("%s\r\n","데이터 수신에 실패했습니다"); else { buffer[nReceived]='\0'; L LogStatus("%s\r\n",buffer); ("% \ \ " b ff ) } BEGIN_MESSAGE_MAP(CBabyChatDlg, CDialog) //{{AFX_MSG_MAP(CBabyChatDlg) // 생략 ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend) ON_MESSAGE(UM_SOCKET_RECEIVED, OnDataReceived) //}}AFX_MSG_MAP END END_MESSAGE_MAP() E GE P() Windows 기반 멀티미디어 통신 응용 개발 long CBabyChatDlg::OnDataReceived(WPARAM wp, LPARAM lp) { uff [M X_D DATA_SIZE]; E]; char buffer[MAX int nReceived; } 203 return t 0l 0l; Windows 기반 멀티미디어 통신 응용 개발 204 BabyChat Test 응용구현 4 : IPhone 205 Windows 기반 멀티미디어 통신 응용 개발 Step 0 IPhone 설계 생성, 호출 CIP PhoneAppp 생성 CLoginDlg Port : UserID CDataSocket Port BabyChat과 WaveEcho의 단순 합성 B b Ch t 확장 또는 코드 재사용 BabyChat Character Data CAudioSocket Port+1 { Manual Reuse : File, Resource Code Copy, 수정 { CLoginDlg, CDataSocket 그대로 재사용 { CIPhoneDlg가 CBabyChatDlg의 내용을 포함하게 함. y WaveEcho의 코드 내용을 덧붙임 분산되어 있는 상수정의 Iphone.H에 Iphone H에 통합 CIPhoneDlg 생성, 호출 Windows 기반 멀티미디어 통신 응용 개발 Audio Data WaveIn WaveOut 207 Windows 기반 멀티미디어 통신 응용 개발 208 Step 0 - CIPhoneDlg Resource Step 0 - Member Variable IDC_EDIT_FRAMESIZE IDC_AUDIO_START IDC_AUDIO_STOP 209 Windows 기반 멀티미디어 통신 응용 개발 Step 0 - Member Variables Step 0 - Member Variables m_uiPort, m_csIP, m_csMsg, : Resource,, BabyChat에서 y 이용 m_uiFrameSize, m_btnAudio* : Resource, WaveEcho에서 이용 m ecLog m_ecLog : 로그창 m_pDataSocket : Data Socket Ptr, Ptr (BabyChat) m_wFormat, m_hAudioBlock, m_lpwHdr, m_hWave* : 음성 녹음 관련 변수 (WaveEcho) (W E h ) m_bOn : Audio 버튼 Flag (WaveEcho) m_hICon : AppWizard에 의해 자동생성 Windows 기반 멀티미디어 통신 응용 개발 210 Windows 기반 멀티미디어 통신 응용 개발 OnButtonSend, O B tt S d O OnDataReceived D t R i d : (BabyChat) OnAudioStart, OnAudioStop, OnMMWimData, OnMMWonDone, AllocateMemory, ReleaseMemory, CloseAllWaveDevice, UpdateButton, OnDestroy : (WaveEcho) ogS a us LogStatus : Log 창 출력 CIPhoneDlg, DoDataExchange, OnInitDialog OnPaint, OnInitDialog, OnPaint OnQueryDragIcon : AppWizard 생성 211 Windows 기반 멀티미디어 통신 응용 개발 212 Step 0 - 중간 결과물 Test Step 1 - Audio 정보 Network 전송 Audio 정보 전송을 위한 Socket이 필요 { CAudioSocket Class 생성 y { { OnMMWimData y Local 재생하게 하지말고 Socket을 통해 전송 y 목적지 주소는 Data Socket과 동일하게 CAudioSocket의 OnReceive y 213 Windows 기반 멀티미디어 통신 응용 개발 음성 녹음 및 전송 설계 BabyChat의 CDataSocket 생성 참조 수신한 Audio A di 정보를 WaveOut W O t 이용 재생 214 Windows 기반 멀티미디어 통신 응용 개발 음성 수신 및 재생 설계 OnButtonStart Network waveInAddBuffer waveInStart D t Data HDR Data Block HDR Data Block HDR Block HWIN MM_WIM_DATA OnMMWimData AudioSocket.SendTo Aud oSocket.Send o Windows 기반 멀티미디어 통신 응용 개발 Sock UM_SOCKET_RECEIVED AudioSocket.ReceiveFrom Data HDR Data Block HDR Data Block HDR Block waveInAddBuffer HDR Data Block waveOutWrite Data HDR Data Block HDR Block MM_WOM_DONE HDR Data Block HWOUT Sock Network 215 Windows 기반 멀티미디어 통신 응용 개발 216 Step 1 - CAudioSocket 생성 버퍼 설계 // New Constants Definition => Iphone.H #define TYPE_DATA 0 #define TYPE_AUDIO TYPE AUDIO 1 녹음 및 전송, 수신 및 재생을 위한 링 버퍼를 별도로 두고 관리 Frame 크기 { 설정 가능한 최대 FrameSize는 10000으로 고정 { 녹음 및 전송용은 사용자 입력값 입력값으로 버퍼 할당 { 수신 및 재생용은 미리 지정된 최대 FrameSize로 할당 CAsyncSocket::OnReceive(nErrorCode); } void CDataSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class ::AfxGetMainWnd()->SendMessage(UM_SOCKET_RECEIVED,TYPE_DATA); 전송 시 Header를 H d 를 제외한 데이터만 전송 { 수신 시 Header 재구성 필요 y void CAudioSocket::OnReceive(int nErrorCode) { // TODO: Add your specialized code here and/or call the base class ::AfxGetMainWnd()->SendMessage(UM_SOCKET_RECEIVED,TYPE_AUDIO); dwBytesRecorded } CAsyncSocket::OnReceive(nErrorCode); 녹음 형식 녹 형식은 PCM으로 고정 정 Windows 기반 멀티미디어 통신 응용 개발 217 #include “AudioSocket.H” y pp () BOOL CBabyChatApp::InitInstance() { // 생략 CLoginDlg login_dlg; if (login (login_dlg.DoModal() dlg DoModal() == IDOK) { CDataSocket dataSocket; CAudioSocket audioSocket; if (dataSocket.Create(login_dlg.m_uiPort, SOCK_DGRAM) && audioSocket.Create(login_dlg.m_uiPort+1, SOCK_DGRAM)) { CBabyChatDlg dlg(&dataSocket, dlg(&dataSocket &audioSocket); m_pMainWnd = &dlg; dlg.m_csUserID = login_dlg.m_csUserID; p = dlg.DoModal(); g int nResponse if (nResponse == IDOK) { // 생략 ... } dataSocket.Close(); audioSocket.Close(); } return FALSE; } Windows 기반 멀티미디어 통신 응용 개발 219 218 Windows 기반 멀티미디어 통신 응용 개발 Step 1 : CIPhoneDlg 수정 CAudioSocket을 위한 Pointer 변수 추가 { CAudioSocket * m_pAudioSocket; m pAudioSocket; { Constructor 변경 : CAudioSocket 변수 포함 OnDataReceived에서 WPARAM 고려 { TYPE_DATA { TYPE_AUDIO CIPhoneDlg::CIPhoneDlg(CDataSocket pSocket, CIPhoneDlg::CIPhoneDlg(CDataSocket* pSocket CAudioSocket *pAudSocket pAudSocket, CWnd* pParent /*=NULL*/) : CDialog(CIPhoneDlg::IDD, pParent) { // 생략 m_pDataSocket = pSocket; m_pAudioSocket = pAudSocket; // 생략 } Windows 기반 멀티미디어 통신 응용 개발 220 Step 2 - 버퍼 구현 long CIPhoneDlg::OnDataReceived(WPARAM wp, LPARAM lp) { int nReceived; switch (wp) { case TYPE_DATA : char h buffer[MAX_DATA_SIZE]; b ff [MAX DATA SIZE] if ((nReceived = m_pDataSocket->ReceiveFrom(buffer, sizeof(buffer),NULL, NULL)) SOCKET ERROR) == SOCKET_ERROR) LogStatus("%s\r\n","데이터 수신에 실패했습니다"); else { b ff [ R buffer[nReceived]='\0'; i d] '\0' LogStatus("%s\r\n",buffer); } break; case TYPE_AUDIO : // Add Audio Data Processing Routine break; d f lt : default LogStatus("%s\r\n","정의되지 않은 데이터를 수신하였습니다"); break; } // End of Sw Switch tch return 0l; Windows } 기반 멀티미디어 통신 응용 개발 221 } m_lpOutwHdr[i]->dwBufferLength l O Hd [i] d B ff L h = MAX_FRAME_SIZE; MAX FRAME SIZE m_lpOutwHdr[i]->lpData = (LPSTR) (((BYTE *)m_lpOutwHdr[i]) + sizeof(WAVEHDR)); m_lpOutwHdr[i]->dwFlags = 0L; m lpOutwHdr[i]->dwLoops m_lpOutwHdr[i] >dwLoops = 0L; fError = TRUE; ReleaseMemory(); l () break; } } m nOutIndex = 0; m_nOutIndex return !fError; Windows 기반 멀티미디어 통신 응용 개발 버퍼 관련 Member 변수 추가 { 기존 변수는 녹음 및 전송용으로 이용 { 수신 및 재생을 위해 새 변수 추가 { 수신 및 재생용 Ring Ri B Buffer는 ff 는 관리를 위한 Index I d 변수가 필요함. 필요함 #define MAX_FRAME_SIZE 10000 // 동적으로 할당한 메모리에 대한 Handle HANDLE m_hAudioBlock[RINGBUFFER_SIZE]; HANDLE m_hOutAudioBlock[RINGBUFFER_SIZE]; // AudioBlock Header에 대한 Pointer LPWAVEHDR m_lpwHdr[RINGBUFFER_SIZE]; LPWAVEHDR m m_lpOutwHdr[RINGBUFFER_SIZE]; lpOutwHdr[RINGBUFFER SIZE]; UINT m_nOutIndex; Windows 기반 멀티미디어 통신 응용 개발 222 void CIPhoneDlg::ReleaseMemory() { for (int i=0; i < RINGBUFFER_SIZE; i++) { if (m_hAudioBlock[i]) { //생략 } if (m_hOutAudioBlock[i]) (m hOutAudi Bl ck[i]) { GlobalUnlock(m_hOutAudioBlock[i]); GlobalFree(m_hOutAudioBlock[i]); m hOutAudioBlock[i] = NULL; m_hOutAudioBlock[i] m_lpOutwHdr[i] = NULL; } } } BOOL CIPhoneDlg::AllocateMemory() { // 생략 for (int ii=0; 0; i < RINGBUFFER_SIZE; RINGBUFFER SIZE; ii++)) { if (m_hAudioBlock[i] = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)(sizeof(WAVEHDR) + m_uiFrameSize)) ) { // 생략 } else { // 생략 } if (m_hOutAudioBlock[i] (m hOutAudioBlock[i] = GlobalAlloc(GMEM_MOVEABLE GlobalAlloc(GMEM MOVEABLE | GMEM GMEM_SHARE, SHARE (DWORD)(sizeof(WAVEHDR) + MAX_FRAME_SIZE)) ) { m_lpOutwHdr[i] = (LPWAVEHDR)GlobalLock(m_hOutAudioBlock[i]); } else { 223 CIPhoneDlg::CIPhoneDlg(CDataSocket* pSocket, CAudioSocket *pAudSocket, CWnd* pParent /*=NULL*/) : CDialog(CIPhoneDlg::IDD, pParent) { // 생략 for (int i=0; i < RINGBUFFER_SIZE; i++) { m_hAudioBlock[i] = NULL; m_lpwHdr[i] = NULL; m_hOutAudioBlock[i] = NULL; m_lpOutwHdr[i] = NULL; } m_nOutIndex = 0; // 생략 } Windows 기반 멀티미디어 통신 응용 개발 224 Step 3 - 녹음 및 전송 { long CIPhoneDlg::OnMMWimData(WPARAM wp, wp LPARAM lp) { if (wp && lp && m_bOn) { LPWAVEHDR lpwh = (LPWAVEHDR) lp; OnAudioStart 변화 없음 장치 열기, 열기 메모리 할당, 할당 녹음 시작 OnMMWimData { Audio 소켓을 통해 녹음된 데이터 전송 { 보내는 정보의 크기는 dwBytesRecorded { 목적지는 가장 최근에 UpdateData()된 결과 { SendTo 호출 출 후 데이터 블록을 다시 WaveIn에 에 Add waveInUnprepareHeader((HWAVEIN)wp, lpwh, sizeof(WAVEHDR)); lpwh->dwFlags = 0L; lpwh->dwLoops = 0L; } } Windows 기반 멀티미디어 통신 응용 개발 225 if (m_pAudioSocket->SendTo(lpwh->lpData, lpwh->dwBytesRecorded, ) _ERROR)) m_uiPort+1,, m_csIP)==SOCKET LogStatus("%s\r\n", "Audio 전송에 실패했습니다"); waveInPrepareHeader(m_hWaveIn, lpwh, sizeof(WAVEHDR)); waveInAddBuffer(m hWaveIn lpwh, waveInAddBuffer(m_hWaveIn, lpwh sizeof(WAVEHDR)); return 0l; Windows 기반 멀티미디어 통신 응용 개발 226 Step 3 - 수신 및 재생 case TYPE_AUDIO _ : // Add Audio Data Processing Routine if (m_bOn) { LPWAVEHDR lpwh = m_lpOutwHdr[m_nOutIndex]; m lpOutwHdr[m nOutIndex]; if (++m_nOutIndex == RINGBUFFER_SIZE) m_nOutIndex = 0; OnDataReceived의 Audio Handling Routine 구현 { 수신한 데이터를 미리 할당한 OutBuffer에 저장 { Index 관리 필요 { 헤더 값 설정 { 음성 장치 Open 이전에 수신한 경우 데이터만 받아들이고 아무 작업도 하 지 않음 if ((nReceived = m_pAudioSocket->ReceiveFrom(lpwh->lpData, lpwh->dwBufferLength, NULL,NULL)) )) == SOCKET_ERROR) E E ) LogStatus("%s\r\n", "Audio 수신에 실패했습니다"); else { p g = nReceived;; lpwh->dwBufferLength lpwh->dwBytesRecorded = nReceived; lpwh->dwFlags = 0L; lpwh->dwLoops = 0L; waveOutPrepareHeader(m_hWaveOut, lpwh, sizeof(WAVEHDR)); waveOutWrite(m_hWaveOut, lpwh, sizeof(WAVEHDR)); } } else { char audio_buffer[MAX_FRAME_SIZE]; m_pAudioSocket->ReceiveFrom(audio_buffer, sizeof(audio_buffer),NULL,NULL); } break; Windows 기반 멀티미디어 통신 응용 개발 227 Windows 기반 멀티미디어 통신 응용 개발 228 Step 4 : IPhone Test llong CIPhoneDlg::OnMMWomDone(WPARAM CIPh Dl O MMW D (WPARAM wp, LPARAM lp) l ) { if (wp && lp && m_bOn) { waveOutUnprepareHeader((HWAVEOUT)wp, (LPWAVEHDR)lp, sizeof(WAVEHDR)); } } return 0l; Windows 기반 멀티미디어 통신 응용 개발 229 Windows 기반 멀티미디어 통신 응용 개발 230 Contents Networked Multimedia 주요 이론/기술/표준 Streaming Ad ti St Adaptive Streaming i Streaming g Format RTP/RTCP VoIP Windows 기반 멀티미디어 통신 응용 개발 232 Introduction to Streaming Streaming vs. Downloading What is Streaming ? 구분 Streaming Downloading A/V 미디어의 특성 D Download l d N No Y Yes 초기 버퍼링 수초 No Preview Random Access Yes No 에러 및 음질 저하 Yes No 생방송 Yes No 전송 프로토콜 UDP RTP UDP, RTP, RTSP TCP HTTP TCP, 저작권 문제 No Yes St Streaming i Server S Y Yes N No { y { 재생시점에 필요한 데이터만 유효 . Streaming y 재생시점에 필요한 데이터만 네트워크를 통해서 수신 . y 재생한 데이터 스트림은 저장할 필요 없음 . y 네크워크의 지터(Jitter)와 지연시간 처리 y 초기 버퍼링 y 적응형 전송률 제어 y 에러 제어 Windows 기반 멀티미디어 통신 응용 개발 233 Streaming Tools MS Windows Media Technologies R lN t RealNetworks k RealPlayer R lPl Apple pp Quick Q Time Windows 기반 멀티미디어 통신 응용 개발 Windows 기반 멀티미디어 통신 응용 개발 234 Streaming Component 235 Windows 기반 멀티미디어 통신 응용 개발 236 Streaming Component The Video Source { The Video Streaming Server { is typically one or more streams of analogue video. It can come from cameras, DVD players or VCRs. These Microsoft Windows Media Technologies. The bandwidth connection to the Video Streaming Server must accommodate broadcasts to connect the cameras to video production and editing equipment, before being passed on to the total bandwidth of all the requests for a video stream, unlike the Encoding station, which must only the Encoding Station. accommodate one copy of each. As a result, the Video Streaming Server usually has a direct connection to a very Th Encoding The E di Station St ti { high bandwidth line. For example, if there were 100 requests for a video stream compressed at 28.8 Kbps, the server would require at least a 3 Mbps connection. The Encoding Station and the Video Streaming Server can be one single is a computer workstation that captures and, typically, encodes both the audio and video. The most system. However, unless hardware encoding is used, this would typically be for a situation requiring limited common systems used for encoding are NT or UNIX workstations equipped with audio and video capture performance (e.g. a single input stream and a small number of viewer requests). Even so, it would still require a cards. These systems must have the computational power to encode one or more audio and video streams fairly high-performance system. It is much more common to have two separate systems. either in software or via a hardware code. Both the Osprey-100 video capture card and the new Osprey-200 audio/video capture card encode in software. The Osprey-500WM/DV was designed specifically to support The Web Server { the Windows Media Format and decodes DV video in hardware before passing it directly to the Windows for video streaming is in not much different from other Web Servers. Servers The web site merely contains a URL link to the Video Streaming Server - one for every available video stream. Typically this is an icon on the web page to be Media Encoder for streaming. { is responsible for delivering compressed video to each individual request for a particular video stream. This is usually handled by one of the commercial streaming media software packages such as Real Networks Real System or video sources will have an analogue video connection to the Encoding Station. Station It is common for live selected. A Video Player application is required to decode the specific video stream received by the system The Encoding Station which needs to be near the Video Source, sends the compressed audio/video streams requesting the stream over the Internet (or corporate Intranet). The most popular current video streaming on to the Video Streaming Server (typically via a LAN using UDP/TCP protocol). Individual compressed applications are Real Networks Real System and Microsoft Windows Media Technologies. Both of these require streams can vary from 20 Kbps (Kilobits/second) to 500 Kbps or more. The connection between the Encoding downloading a corresponding Video Player application such as Real Player or Media Player; but both of these are free. Station and the Video Streaming Server must be able to accommodate the total of the bandwidths of the There are other video streaming applications that are implemented in such a way as to include the player in the i di id l streams individual t and d mustt b be a clear l and d reliable li bl connection. ti stream and d no download d l d is i required. i d Windows 기반 멀티미디어 통신 응용 개발 237 Windows 기반 멀티미디어 통신 응용 개발 238 A/V Streaming Service Delivery Techniques: { On-demand A/V Streaming There are two key streaming delivery techniques: unicast and multicast. Unicast refers to networking in which computers establish two-way, point-to-point connections. Most networks operate in this fashion, users request a file, and a server sends the file to those { AOD/VOD Streaming Service. Service { 시간적 제약 없음 . { 사용자의 선택권이 우선 . y When streaming g multimedia over a network, the advantage g to unicast is that clients only. the client computer can communicate with the computer supplying the multimedia stream. The disadvantage of unicast is that each client that connects to the server receives a separate stream, stream which rapidly uses up network bandwidth.Unlike bandwidth Unlike a broadcast, broadcast routers can control where a multicast travels on the network. When streaming multimedia over the network, the advantage to multicasting is that only a single copy of the data is sent across the network, which preserves network bandwidth. The disadvantage to multicasting is that Live A/V Streaming { Internet Radio, Internet Broadcasting { 컨텐츠 제공자의 스케줄링이 컨텐 케줄링이 우선 . it is connectionless; clients have no control over the streams they receive. To use IP multicast on a network, the network routers must support the IP Multicast protocol. Most routers now handle multicast. Windows 기반 멀티미디어 통신 응용 개발 239 Windows 기반 멀티미디어 통신 응용 개발 240 Fundamental Design Issues for Multimedia Services over the Internet Adaptive Streaming Characteristic of Multimedia Services { Current Internet { real time real-time Best Effort Service Model Solutions { Upgrade Network ? (extend service model) y { I tS IntServ, DiffS DiffServ Make adaptive applications ? 242 Windows 기반 멀티미디어 통신 응용 개발 Adaptive Streaming General Architecture Server Bandwidth Negotiation { [28 8K] [56K] [ISDN] [LAN] [28.8K] { Stream Thinning { M l i l Rate Multiple R / Multiple M l i l Fil Files Q factor Buffer Encoder Dynamic Adaptation { Real System G2 : SureStream { Media Technologies g 3.0 : Intelligent g Streaming g { One file for all connection rate Windows 기반 멀티미디어 통신 응용 개발 rate controller Video source 243 Congestion Detection Control Algorithm Rate Adjustment Windows 기반 멀티미디어 통신 응용 개발 Internet Client Feedback Information 244 Congestion Detection Measure { Receiving Rate Rate, Loss Ratio Ratio, End End-to-End to End Delay, Delay Delay Jitter TCP-Friendly Rate Control TCP Performance P f Model M d l Estimate Network Conditions { { λTCP = loss at receiver y RED Gateway { p : loss probability { C : depends on ACK Strategy (Every/Delayed) & Loss Derivation (Periodic/Random) Disseminate information to decision makers { MSS C RTT p cf) TCP Congestion Control Mechanism ECN(Explicit Congestion Notification) y Rate Control Algorithm RTCP RR tto source, ACK/NACK Windows 기반 멀티미디어 통신 응용 개발 245 Rate Adjustment 246 Windows 기반 멀티미디어 통신 응용 개발 Rate Adjustment (2) Intra-frame coding Scalable Video Compression Techniques SNR Adaptation DCT Raw Video { DCT based Filtering Methods DCT-based y { { VDONet, Vxtreme Real Video { I Image SSegmentation t ti and d Obj Object-based t b d Vid Video C Coding di y Spectral Filtering y F t l Vid Fractal Video C Coding di y { H.261,H.263, MPEG-1,MPEG-2 Subband/Wavelet Coding y { { { 247 Inter-frame coding F.B C DCT-1 Q-1 discards a range of DCT coefficients y discards a given # of high precision bits y increase quantizer Color Reduction C l tto M Color Monochrome, h Dith Dithering, i g DC C Color l Movement Detection y Windows 기반 멀티미디어 통신 응용 개발 Q M.D Quantization Filtering y MPEG-4 + i increase movementt d detection t ti th threshold h ld Windows 기반 멀티미디어 통신 응용 개발 248 Rate Adjustment (3) Displayed Frame Rate Adaptation { frame rate 2.5 5.0 0 10.0 15.0 20 0 20.0 30.0 y { Streaming Format frame dropping send pattern I I I P I P I P P P I P P P I PB P PB I PB P PB I BP BP BP BI BP BP BP B IBBPBBPBBPBBIBBPBBPBBPBB macroblock filtering playback dilation y intentionally reduce the playback rate at the receiver Windows 기반 멀티미디어 통신 응용 개발 249 SMIL Language/Format for Multimedia Synchronization SMIL { Synchronized Multimedia Integration Language { W3C, RealNetwork ASF { Active Streaming Format { Microsoft XML-based Language allow control over the what, where, and when off media di elements l iin a multimedia presentation clear markup language M1 SMIL File M2 M3 similar to HTML M4 Windows 기반 멀티미디어 통신 응용 개발 251 Windows 기반 멀티미디어 통신 응용 개발 252 Example <seq> <!-- This img tag displays the title screen --> <text src="title.rt” type="text/html” region="title” dur="20s"/> <smil> <head> <layout> l <root-layout height="425” width="450" background-color="black"/> <region id="title” left="50" top="150" width="350" height="200"/> <region i id="full" id "f ll" left="0" l ft "0" ttop="0" "0" h height="425" i ht "425" width="450" idth "450" background-color="#602030"/> <region id="video” left="200” top="200” height="180” width="240” z index="1"/> z-index= 1 /> </layout> </head> <!-- This section displays the animated map with an audio soundtrack --> <par> <audio src= src="map map_narration.ra narration ra"/> /> <img src="map.rp” region="full” fill="freeze"/> </par> <!-- This section contains the video-annotated slideshow --> <par> img src src="slideshow.rp” slideshow.rp region region="full” full fill fill="freeze"/> freeze / <img <seq> <video src="slide_narration_video1.rm” region="video"/> <audio src="slide_narration_audio1.ra"/> _ _ <video src="slide_narration_video2.rm” region="video"/> </seq> </par> </seq> <body> ……….See Next Page……. </body> </smil> 253 Windows 기반 멀티미디어 통신 응용 개발 254 Windows 기반 멀티미디어 통신 응용 개발 ASF Improves Manageability, application-level bandwidth RTP & RTCP reservation { Proportional Mix of data from the object within the stream MPEG A di D Audio Data t H.261 ASF File M1 M2 M3 M4 RTP UDP IP Network Technology 255 Windows 기반 멀티미디어 통신 응용 개발 Introduction RTP { End to end network transport functions for real-time End-to-end real time data { Suitable framework for any encoding C Complete l t P Protocol t l : RTP fframework k + payload l d fformatt y { RTP Used with RTCP optionally RTCP { Monitoring of data delivery { Minimal control and identification functionality 257 Windows 기반 멀티미디어 통신 응용 개발 Mixer & Translator { Payload type identification { Sequence numbering { Time stamping { Deliver monitoring Delivery RTP over UDP/IP { Multiplexing { Checksum { Multicasting RTP does NOT provide { Timely delivery { Guaranteed QoS delivery { Out-of-order delivery prevention An intermediate system Translator { y receives RTP packets from one or more sources y possibly changes the data format An intermediate system y forwards RTP packets with their SSRC id intact y e g) e.g) y combines the packets in some manner y forwards a new RTP packet y convert encoding without mixing timing adjustment among several streams and generate its own timing y replicator from multicast to unicast y application-level filters in firewalls y y mixer becomes SSRC for the new combined packet Each source generates 64Kbit/s of Audio traffic Each source generates 1Mbit/s of Video traffic SSRC : A SSRC : A Windows 기반 멀티미디어 통신 응용 개발 SSRC : C Mixer E combines all three into a single 64Kbit/s stream 259 SSRC : B Frame Relay SSRC : A SSRC : B SSRC : C SSRC : E CSRC : A, B, C SSRC : B 258 Windows 기반 멀티미디어 통신 응용 개발 Translator Mixer { Services SSRC : C Windows 기반 멀티미디어 통신 응용 개발 converts each to a lower q quality, y, 256Kbit/s stream 260 Example of Translator & Mixer RTP Data Transfer Protocol E6 : 15 E1 : 17 M1 M1 : 48 (1, 17) M1 : 48 ((1,, 17)) T1 E2 : 1 E2 31 0 E6 E1 RTP fixed header fields T2 E4 : 47 IP Header E6 : 15 M1 : 48 (1 (1, 17) E4 : 47 M3 : 89 (64, 45) E7 UDP Header V P X E4 : 47 CC M3 : 89 (64, 45) E4 E5 : 45 M2 2 E5 E : End system M : Mixer T : Translator …….. Application Data source : SSRC (CSRCs) 261 RTP Header Extension PT 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 variable length header extension is appended to the RTP header variable-length first 16-bits of header extension are left open for distinguishing ID or parameters for profile length counts the # of 32-bit 32 bit words in the extension 15 0 defined by profile 31 length Header extension Windows 기반 멀티미디어 통신 응용 개발 262 Windows 기반 멀티미디어 통신 응용 개발 RTP Payload Types if X bit is set { (fisrt) Contributing Source ID V : version (2bit) paddingg (1bit) ( ) P:p X : Extension (1bit) CC : Contributor Count(4bit) M : Marker (1bit) PT : Payload P l d Type(7bit) T (7bit) (last) Contributing Source ID Windows 기반 멀티미디어 통신 응용 개발 Sequence Number Synchronization Source ID M2 : 12 (64) E33 PT Timestamp M3 E3 : 64 M 263 Payload PT PCMU audio 16-22 1016 audio 23 G721 audio 24 GSM audio 25 Unassigned audio 26 DV14 audio(8Khz) 27 DV14 audio(16Khz) 28 LPC audio 29 PCMA audio 30 G722 audio 31 L16 audio(stereo) 32 L16 audio(mono) 33 TPS0 audio 34-71 VSC audio di 72 76 72-76 MPA audio 77-95 G728 audio 96-127 Windows 기반 멀티미디어 통신 응용 개발 Payload unassigned g audio RGB8 video HDCC video CelB video JPEG video CUSM video nv video PicW video CPV video H261 video MPV video MP2T video unassigned video reserved d unassigned dynamic 264 Port Assignment RTP data { use even UDP port number RTCP packets { RTCP use the next higher(odd) UDP port number Default port numbers { RTP Control Protocol { Monitors QoS { Convey participants’ information Uses same distribution mechanism as RTP { 5004, 5005 such as multicasted UDP Periodically transmitted to all participants of the session. i Windows 기반 멀티미디어 통신 응용 개발 265 Windows 기반 멀티미디어 통신 응용 개발 RTCP Packet SR :Sender Report { Bytes sent ->rate >rate estimation { Timestamp ->Synchronization RR :Receiver Report { Voice over IP Loss,Jitter,RTT SDES :Source DEScription { CNAME (user@host),Phone,Location ( h t) Ph L ti … BYE :End of participation APP :Application specific functions Windows 기반 멀티미디어 통신 응용 개발 267 266 Introduction 망 진화 예상도 패킷교환망을 통하여 음성서비스를 제공하는 기술 및 시스 템 Internet 의 활성화와 함께 , 패킷망이 통신망의 주류를 형 성 패킷망에 음성신호를 전달함으로써 , 통신비용절감 인터넷폰 ((PC-to-PC)의 ) 등장 PC-to-Phone, Phone-to-Phone 의 개념으로 확장 Windows 기반 멀티미디어 통신 응용 개발 269 Media Adaptation and Transfer { Speech Coding : 음성압축 , 묵음검출 { Serialization (Packetization) : IP 패킷의 크기 , 헤더의 오버헤드 { Multiplexing, Trunking Bearer Call Signaling { Intelligent Network Call Processing H.323 defines { System level characteristics of terminals, System-level terminals gateways, gateways gatekeepers gatekeepers, and MCUs Signaling { Service and Management { Call signaling procedures (phases A-E) A E) { Refers to H.225 and H.245 specs H.225 defines (Call Control) { Supplementary and Multimedia Service { Packetization and use of RTP/RTCP { Authentication, Mobility and Directory Service { Use of Q.931/2 and RAS messages { GSMP (General Switch Management Protocol) Switching and Control Architecture { MSMP (Multi Service Multi Plug-In) { Soft Switching Windows 기반 멀티미디어 통신 응용 개발 270 H.323 Standard Scopes VoIP 기술 분류 Windows 기반 멀티미디어 통신 응용 개발 H 245 defines (Channel Control) H.245 { 271 Procedures for use of Control Protocol MSGs H.332 Multicasting to Large Groups (MCU) Windows 기반 멀티미디어 통신 응용 개발 272 H.323 Protocol & Call Setup H.323 Zone Terminal GateKeeper Gateway Router Terminal Terminal Terminal Router Terminal Terminal Control Data Audio Video A/V Cntl Control Gatekeeper G.7xx H.26x H.225.0 H.245 RTCP T.120 RTP TCP MCU Reg, Adm, Status (RAS) UDP IP 273 Windows 기반 멀티미디어 통신 응용 개발 SIP H.323 vs SIP Application Level Control H.323 Protocol Modular Architecture { SDP, SAP { RTP, RTCP, RTSP Roughly the same M di T Media Transportt E i l t (RTP, Equivalent (RTP identical id ti l codecs) d ) SIP Call setup delay 6-7 RTT 1.5RTT Complexity High : ASN, use of several different protocols Adequate : HTTP-like protocol Extensibility 비표준 인자의 지원이 어려움 Open to new protocol feature Codec Support ITU registered codecs Any IANA registered codecs Third party call control none Yes Identical to HTTP/1.1 Architecture Monolithic Modular Server state-ful/less stateless stateful Conference Control Centralized (MCU) Distributed Multicast capable signaling No Yes Addressing Host, gatekeeper-resolved alias, E.164 Any URL including E-mail, h.323. Transport Protocol Reliable protocol required Any (udp allowed Web-Integration ? Integration with other internet services, click-to-dial feature Inter-domain user location weak Byy existing g internet services (DNS, LDAP) SIP : [email protected] Domain Based User Lookup Redirect / Proxy y Server Transport Independent { Set of supported Services Text Protocol, Message Syntax { Windows 기반 멀티미디어 통신 응용 개발 274 Windows 기반 멀티미디어 통신 응용 개발 UDP 사용 가능 User Mobility 275 Windows 기반 멀티미디어 통신 응용 개발 276 GCP 기존 Gateway 구조의 문제 { Call Agent MG Controller Decomposed Architecture { Location Server LDAP Signaling과 Media Control의 Coupling SIP H.323 MGCP Megaco Soft Switch (Call Agent) Call Agent MG Controller SIP H.323 Overall Scenario TCAP / ISUP over SIGTRAN MGCP Megaco Signalling GW ISUP/SS7 RGW Signalling Gateway TCAP/ ISUP over SCTP Media Gateway Controller (Call Agent) SIP RTP Internet MGCP Megaco H.323 TGW RTP PSTN MGCP/ Megaco MGCP/ Megaco Media Gateway Windows 기반 멀티미디어 통신 응용 개발 Bearer (Streams) RGW Media di Gateway SIP / H.323 Terminal Bearer (Streams) 277 Windows 기반 멀티미디어 통신 응용 개발 DirectShow Windows 기반 멀티미디어 통신 응용 개발 279 278 Directshow Basics(1) Directshow Basics (2) Filters Pins { The basic building block block, Component { Objects associated with a filter { generally performs a single operation on a multimedia stream { 2 Category : Input, Output { receive i iinput and d produce d output { T Type Negotiation N i i { 3 Category : Source, Transform, Renderer Graphs { Filter Graph Manager { A set of connected filters is called a filter An Object that manages (the creation of) a filter graph Media Sample { Contains the Data being passed from filter to filter through the filter graph. { Windows 기반 멀티미디어 통신 응용 개발 281 Data + Information (type, size, time-stamp) Windows 기반 멀티미디어 통신 응용 개발 Directshow Basics (3) Allocators { An object, object usually created by an input pin, pin that creates a buffer suited for the data type being negotiated between pins { This buffer is used to queue up media samples and feeds one or more of them when a filter is ready to process { Filters often reuse re se upstream pstream buffers b ffers and do not always al a s require req ire cop copying ing the multimedia data into another buffer Clocks { Used to synchronize sub-stream of the multimedia stream { Each Filter in the graph shares the same clock, which is used to timestamp the media sample Windows 기반 멀티미디어 통신 응용 개발 283 GraphEdit Utility Program 282 GraphEdit Using GraphEdit Graph Editing Utility Adding a Filter Manually { GraphEdit exe No Source Code GraphEdit.exe, Connecting Filters { Allows to simulate automatic and manual graph building visually Viewing Filter & Pin Information Deleting Connection/Filter Rendering a Pin Saving a Filter Graph Simple Test { Rendering a Media File (File – Render Media File) Windows 기반 멀티미디어 통신 응용 개발 285 Windows 기반 멀티미디어 통신 응용 개발 Quiz GraphEdit을 이용하여 어떠한(임의의) AVI File을 읽어 들 여 포함되어 있는 비디오 스트림을 Mpeg4로 Encoding한 후 파일로 (다른 파일 AVI) 저장하는 Graph를 구성하라 Windows 기반 멀티미디어 통신 응용 개발 287 Playback Applications 286 Writing a Directshow Application Playback a Multimedia File A typical DirectShow application performs three basic Playing a file using DirectShow is a four-step process: steps as illustrated in the following diagram steps, Create an instance of the filter graph manager. Use the filter graph manager to create a filter graph. Use the filter graph manager to run the filter graph. Wait for playback to complete. To accomplish this, you need to use the following COM interfaces: Windows 기반 멀티미디어 통신 응용 개발 289 Filter Graph Manager Interfaces IGraphBuilder – The basic unautomated graph interface IFilterGraph – The Filter Graph Manager Interface IMediaControl – The Media Streaming Interface These interfaces provide different levels of control or automation IMediaEvent – Exposes events occurring within the graph IMediaPosition – Controls the position of the media stream playback IMediaSeeking – An improvement over the IMediaPosition interfaces IVideoWindow – Determines various settings about the output of the video window IBasicAudio – Determines the audio settings IBasicVideo – Determines the video setting IVideoFrameStep – Allows you to step through a video Windows 기반 멀티미디어 통신 응용 개발 291 { IGraphBuilder: p Constructs the filter g graph. p { IMediaControl: Handles media streaming in the filter graph. { IMediaEvent: Handles filter graph events. { The filter graph manager implements all of these interfaces. Windows 기반 멀티미디어 통신 응용 개발 290