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