검색결과 리스트
C/C++에 해당되는 글 83건
- 2014.08.10 [C++] chilkatsoft
- 2014.07.25 [C++] Crypto++
- 2014.01.03 [WinDBG] 사용시 참고할만한 사이트
- 2014.01.03 [FFmpeg] 인코딩 과정 정리
- 2013.12.06 [FFmpeg] FFmpeg x264EncodingGuide
- 2013.08.15 [FFmpeg] 동영상 정보 확인 하는 프로그램
- 2013.08.07 [VC++] dependency walker
- 2013.06.29 [FFmpeg] Water Mark
- 2013.06.13 [VC++] Device Info
- 2013.06.12 [VC++] Getting the PropertyData of ManagementObject in C++
- 2013.06.11 [FFmpeg] 옵션
- 2013.05.31 [VC++] 윈도우 OS Bit 판별하기
- 2013.05.31 [VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법
- 2013.05.31 [VC++] DevCon 사용법
- 2013.05.31 [MFC] Dialog 베이스로 시작시 숨기기
- 2013.05.30 [VC++] Detecting Hardware Insertion and/or Removal
- 2013.05.24 [ATL] ATL Com Programming
- 2013.05.24 [COM] Com Event Handling
- 2013.05.21 [VC++] IOCP 프로그래밍 1
- 2013.05.16 [FFmpeg] 동영상의 기본적인 이해
- 2013.05.02 [FFmpeg] library document
- 2013.05.01 [VC++] Visual Studio Predefine Macro
- 2013.04.29 [FFmpeg] thumbnail 추출
- 2013.04.28 [FFmpeg] FFMpeg 윈도우 컴파일
- 2013.04.28 [FFmpeg] FFmpeg을 이용한 동영상 인코딩
- 2013.04.26 [VC++] Tray Icon Animation
- 2013.03.14 [VC++] Design Specifications and Guidelines - Visual Design
- 2013.03.08 [VC++] 모듈 정의 파일(.def)을 이용해서 EXPORTS 시키기
- 2013.02.17 [FFmpeg] FFmpeg 동영상 변환
- 2013.01.29 [C++] C++11
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[C++] Crypto++ (0) | 2014.07.25 |
---|---|
[WinDBG] 사용시 참고할만한 사이트 (0) | 2014.01.03 |
[VC++] dependency walker (0) | 2013.08.07 |
[VC++] Device Info (0) | 2013.06.13 |
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[C++] chilkatsoft (0) | 2014.08.10 |
---|---|
[WinDBG] 사용시 참고할만한 사이트 (0) | 2014.01.03 |
[VC++] dependency walker (0) | 2013.08.07 |
[VC++] Device Info (0) | 2013.06.13 |
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[C++] chilkatsoft (0) | 2014.08.10 |
---|---|
[C++] Crypto++ (0) | 2014.07.25 |
[VC++] dependency walker (0) | 2013.08.07 |
[VC++] Device Info (0) | 2013.06.13 |
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
트랙백
댓글
글
1. 디먹싱 (Demuxing)
: 파일(DCF)에서 비디오, 오디오 데이터 스트림을 추출
2. 디코딩 (Deconding)
: 특정 동영상 코덱을 사용하여 원본 영상 데이터를 얻는 것
3. 인코딩 (Encoding)
: 원본 영상 데이터로부터 특정 동영상 코덱으로 변환하는 것
2. 먹싱 (Muxing)
: 변환한 데이터(오디오, 비디오)를 파일(DCF)에 담는 것을 먹싱
* DCF (Digital Container Format)
동영상/오디오 코덱을 이용하여 데이터를 저장하는 방식과 재생 동기화 정보등의 부가 정보를 담고 있는 파일 형식
결국 H.264로 변환한다는건
디먹싱 디코딩 인코딩 먹싱
.wmv
.asf ------> 비트스트림 데이터 추출 ------> 원본 데이터 (동영상,오디오) ------> 특정 동영상 코텍(H.264)으로 변환 ------> .mp4
.avi
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] FFmpeg x264EncodingGuide (0) | 2013.12.06 |
---|---|
[FFmpeg] 동영상 정보 확인 하는 프로그램 (0) | 2013.08.15 |
[FFmpeg] Water Mark (0) | 2013.06.29 |
[FFmpeg] 옵션 (0) | 2013.06.11 |
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 인코딩 과정 정리 (0) | 2014.01.03 |
---|---|
[FFmpeg] 동영상 정보 확인 하는 프로그램 (0) | 2013.08.15 |
[FFmpeg] Water Mark (0) | 2013.06.29 |
[FFmpeg] 옵션 (0) | 2013.06.11 |
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 인코딩 과정 정리 (0) | 2014.01.03 |
---|---|
[FFmpeg] FFmpeg x264EncodingGuide (0) | 2013.12.06 |
[FFmpeg] Water Mark (0) | 2013.06.29 |
[FFmpeg] 옵션 (0) | 2013.06.11 |
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[C++] Crypto++ (0) | 2014.07.25 |
---|---|
[WinDBG] 사용시 참고할만한 사이트 (0) | 2014.01.03 |
[VC++] Device Info (0) | 2013.06.13 |
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
[VC++] 윈도우 OS Bit 판별하기 (0) | 2013.05.31 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] FFmpeg x264EncodingGuide (0) | 2013.12.06 |
---|---|
[FFmpeg] 동영상 정보 확인 하는 프로그램 (0) | 2013.08.15 |
[FFmpeg] 옵션 (0) | 2013.06.11 |
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
[FFmpeg] library document (0) | 2013.05.02 |
트랙백
댓글
글
장치관리자 Device Tree: http://www.codeproject.com/Articles/6597/CDeviceTree
Enumerate Properties: http://www.codeproject.com/Articles/6866/Enumerate-Properties-of-an-Installed-Device
장치 열거하기 (한글) : http://blog.naver.com/cra2yboy?Redirect=Log&logNo=90165203152
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[WinDBG] 사용시 참고할만한 사이트 (0) | 2014.01.03 |
---|---|
[VC++] dependency walker (0) | 2013.08.07 |
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
[VC++] 윈도우 OS Bit 판별하기 (0) | 2013.05.31 |
[VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법 (0) | 2013.05.31 |
트랙백
댓글
글
링크 : http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/1ba183a5-71bb-4601-beb6-73ba20b087cd/
IWbemService Interface : http://msdn.microsoft.com/en-us/library/aa392093(v=vs.85).aspx
MSDN 예제 : http://msdn.microsoft.com/en-us/library/aa390425(v=VS.85).aspx
Query : http://msdn.microsoft.com/en-us/library/aa392902(v=vs.85).aspx
WMI 데이터판독기 작업 : http://sqlmvp.kr/140163038957
WMI를 이용한 프로세스 감시 : http://blog.naver.com/adsloader?Redirect=Log&logNo=50142012166
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] dependency walker (0) | 2013.08.07 |
---|---|
[VC++] Device Info (0) | 2013.06.13 |
[VC++] 윈도우 OS Bit 판별하기 (0) | 2013.05.31 |
[VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법 (0) | 2013.05.31 |
[VC++] DevCon 사용법 (0) | 2013.05.31 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 동영상 정보 확인 하는 프로그램 (0) | 2013.08.15 |
---|---|
[FFmpeg] Water Mark (0) | 2013.06.29 |
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
트랙백
댓글
글
현재 윈도우가 x86인지 x64인지 확인하는 방법
링크 : http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139(v=vs.85).aspx
#include <windows.h>
#include <tchar.h>typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL IsWow64()
{
BOOL bIsWow64 = FALSE;//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
GetModuleHandle(TEXT("kernel32")),"IsWow64Process");if(NULL != fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
{
//handle error
}
}
return bIsWow64;
}int main( void )
{
if(IsWow64())
_tprintf(TEXT("The process is running under WOW64.\n"));
else
_tprintf(TEXT("The process is not running under WOW64.\n"));return 0;
}
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Device Info (0) | 2013.06.13 |
---|---|
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
[VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법 (0) | 2013.05.31 |
[VC++] DevCon 사용법 (0) | 2013.05.31 |
[MFC] Dialog 베이스로 시작시 숨기기 (0) | 2013.05.31 |
트랙백
댓글
글
링크 : http://support.microsoft.com/kb/190351/ko
한마디로 자식 프로세스를 생성해서 Input, Output으로 주고 받는 방법이다.
참고 : http://www.tipssoft.com/bulletin/board.php?bo_table=update&wr_id=941
팁스소프트의 좋은 예제
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Getting the PropertyData of ManagementObject in C++ (0) | 2013.06.12 |
---|---|
[VC++] 윈도우 OS Bit 판별하기 (0) | 2013.05.31 |
[VC++] DevCon 사용법 (0) | 2013.05.31 |
[MFC] Dialog 베이스로 시작시 숨기기 (0) | 2013.05.31 |
[VC++] Detecting Hardware Insertion and/or Removal (0) | 2013.05.30 |
트랙백
댓글
글
링크 : http://ct_starter.blog.me/130163495738
windows 7 x64 용 : http://www.diskool.com/pcman_tip/1225619
* 네트웍 장비 검사
#네트웍 장비 검사
devcon listclass net
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] 윈도우 OS Bit 판별하기 (0) | 2013.05.31 |
---|---|
[VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법 (0) | 2013.05.31 |
[MFC] Dialog 베이스로 시작시 숨기기 (0) | 2013.05.31 |
[VC++] Detecting Hardware Insertion and/or Removal (0) | 2013.05.30 |
[ATL] ATL Com Programming (0) | 2013.05.24 |
트랙백
댓글
글
링크 1 : http://bobmoore.mvps.org/Win32/w32tip26.htm
링크 2 : http://november11.tistory.com/55
링크 1은 프레임워크를 조금 수정해서 모달리스로 만드는 방법이고
링크 2는 WindowPosChanging을 이용한 방법이다.
둘다 테스트 해본결과 링크 2번이 구조도 덜 바꾸고 편했다.
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] 콘솔 프로세스의 리디렉션된 표준핸들이 생성되는 방법 (0) | 2013.05.31 |
---|---|
[VC++] DevCon 사용법 (0) | 2013.05.31 |
[VC++] Detecting Hardware Insertion and/or Removal (0) | 2013.05.30 |
[ATL] ATL Com Programming (0) | 2013.05.24 |
[COM] Com Event Handling (0) | 2013.05.24 |
트랙백
댓글
글
링크 : http://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal
링크 : http://msdn.microsoft.com/en-us/library/windows/desktop/aa363432(v=vs.85).aspx
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] DevCon 사용법 (0) | 2013.05.31 |
---|---|
[MFC] Dialog 베이스로 시작시 숨기기 (0) | 2013.05.31 |
[ATL] ATL Com Programming (0) | 2013.05.24 |
[COM] Com Event Handling (0) | 2013.05.24 |
[VC++] IOCP 프로그래밍 (1) | 2013.05.21 |
트랙백
댓글
글
너무 정리가 잘되어 있는곳 : http://codecrue.egloos.com/category/ATL%2FActiveX
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[MFC] Dialog 베이스로 시작시 숨기기 (0) | 2013.05.31 |
---|---|
[VC++] Detecting Hardware Insertion and/or Removal (0) | 2013.05.30 |
[COM] Com Event Handling (0) | 2013.05.24 |
[VC++] IOCP 프로그래밍 (1) | 2013.05.21 |
[VC++] Visual Studio Predefine Macro (0) | 2013.05.01 |
트랙백
댓글
글
http://www.codeproject.com/Articles/9014/Understanding-COM-Event-Handling
http://www.codeproject.com/Articles/3541/COM-Connection-Points
XMLHttpRequest onStatusChange Event Handling : http://www.ookii.org/Blog/using_ixmlhttprequestonreadystatechange_from_c
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Detecting Hardware Insertion and/or Removal (0) | 2013.05.30 |
---|---|
[ATL] ATL Com Programming (0) | 2013.05.24 |
[VC++] IOCP 프로그래밍 (1) | 2013.05.21 |
[VC++] Visual Studio Predefine Macro (0) | 2013.05.01 |
[VC++] Tray Icon Animation (0) | 2013.04.26 |
트랙백
댓글
글
참고소스 : http://blog.daum.net/aswip/2580198
출처 : http://blog.naver.com/sonmg?Redirect=Log&logNo=20000462755
IOCP- 윈속 프로그래밍 | 2002년 08월 21일 | 03시 05분 |
|
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[ATL] ATL Com Programming (0) | 2013.05.24 |
---|---|
[COM] Com Event Handling (0) | 2013.05.24 |
[VC++] Visual Studio Predefine Macro (0) | 2013.05.01 |
[VC++] Tray Icon Animation (0) | 2013.04.26 |
[VC++] Design Specifications and Guidelines - Visual Design (0) | 2013.03.14 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] Water Mark (0) | 2013.06.29 |
---|---|
[FFmpeg] 옵션 (0) | 2013.06.11 |
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
[FFmpeg] FFMpeg 윈도우 컴파일 (0) | 2013.04.28 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 옵션 (0) | 2013.06.11 |
---|---|
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
[FFmpeg] FFMpeg 윈도우 컴파일 (0) | 2013.04.28 |
[FFmpeg] FFmpeg을 이용한 동영상 인코딩 (0) | 2013.04.28 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[COM] Com Event Handling (0) | 2013.05.24 |
---|---|
[VC++] IOCP 프로그래밍 (1) | 2013.05.21 |
[VC++] Tray Icon Animation (0) | 2013.04.26 |
[VC++] Design Specifications and Guidelines - Visual Design (0) | 2013.03.14 |
[VC++] 모듈 정의 파일(.def)을 이용해서 EXPORTS 시키기 (0) | 2013.03.08 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
---|---|
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] FFMpeg 윈도우 컴파일 (0) | 2013.04.28 |
[FFmpeg] FFmpeg을 이용한 동영상 인코딩 (0) | 2013.04.28 |
[FFmpeg] FFmpeg 동영상 변환 (0) | 2013.02.17 |
트랙백
댓글
글
VS 2010 컴파일 출처 : http://blog.naver.com/PostView.nhn?blogId=bsh0128&logNo=80162582453
Windows ffmpeg : http://ffmpeg.zeranoe.com/builds/
이전 버전
==============================================================================================================================
출처 : http://blog.naver.com/meteoros21/130084661358
아래 다운로드 안됨 : http://dev.naver.com/projects/npdf/download/note/777
1. 컴파일 환경을 위한 파일 준비
2. MinGW 설치
설치 옵션에서 gcc 모듈 설치
설치 위치 c:\MinGW
C:\MinGW\bin 을 환경변수 PATH에 추가
3. MSYS 설치
설치 위치 C:\MSYS
C:\MSYS\bin 을 환경변수 PATH에 추가
VC++ 환경을 위해 C:\MSYS\msys.bat 파일 적당한 곳에 다음 라인 추가
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" 추가
4. coreutils 설치
압축을 푼 다음, bin 디렉터리에 존재하는 모든 파일을 C:\MSYS\bin 에 복사
동일한 파일들이 존재하는데 덮어 쓰지말고 스킵
5. ffmpeg 소스 준비
http://ffmpeg.arrozcru.org/autobuilds/ 에서 32bit shared 최신 버전 다운
압축을 풀어서 C:\MSYS\ffmpeg 디렉터리로 복사
6. 컴파일
msys.bat 실행하여 콘솔로 들어간다.
$cd /ffmpeg
$./configure --enable-shared --enable-memalign-hack
$make
$make install
오류가 없다면 /local/bin 에 *.lib, *.dll 파일이, /local/include 아래에 *.h 파일이
생성된다. 가져다가 윈도우 어플리케이션 개발 시 사용하면 된다.
coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
---|---|
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
[FFmpeg] FFmpeg을 이용한 동영상 인코딩 (0) | 2013.04.28 |
[FFmpeg] FFmpeg 동영상 변환 (0) | 2013.02.17 |
트랙백
댓글
글
링크 : http://helloworld.naver.com/helloworld/8794
NHN 동영상서비스개발2팀 김대웅
Android는 오픈 플랫폼이어서 단말기가 제공하는 동영상 플레이어의 기능과 지원하는 포맷이 제조사마다 다릅니다. 그래서 더 효율적으로 동영상 서비스를 제공하려면 독자적인 동영상 플레이어가 있는 것이 좋습니다. 이 글에서는 오픈 소스인 FFmpeg의 레퍼런스 프로젝트인 FFPlay로 Android용 동영상 플레이어를 제작하기까지의 고민과 과정을 소개합니다.
Android 동영상 플레이어를 왜 만들어야 하는가?
Android는 오픈 플랫폼이어서 다양한 제조사가 다양한 기기를 만들고 있다. 이러한 다양성은 소비자에게는 기기 선택의 폭을 넓혀 줄 수 있지만, NHN 같은 서비스 제공자 입장에서는 다양한 종류의 단말기에서 동일한 사용자 경험을 제공하려면 추가적인 노력을 들여야 한다. Android 단말기에서 기본으로 제공하는 동영상 플레이어마다 기능이 다르고, 지원하는 동영상 포맷도 다르기 때문이다.
그래서 Android 동영상 서비스를 위해서는 독자적인 동영상 플레이어를 갖추고 있는 것이 좋다. 이를 위해 오픈 소스인 FFmpeg(http://www.ffmpeg.org/)을 이용해 Android 동영상 플레이어를 만들었다.
동영상 플레이어에 대한 배경 지식
코덱, 컨테이너 그리고 플레이어
일반적인 사용자 입장에서 생각한다면 동영상(비디오)에는 오디오가 포함되어 있지만, 전문적인 개발자 입장에서는 동영상과 오디오는 서로 다른 영역이다. MP3나 Vorbis와 같은 오디오 압축 코덱이 소리를 담당하고, 동영상을 담당하는 동영상 압축 코덱은 MPEG, MPEG-4 AVC(H.264), WMV9 등이다. 동영상 압축 코덱은 동영상 정보를 압축하는 알고리즘 종류를 지칭하는 것으로 이해하는 것이 좋다. 동영상이란 정지 영상(동영상 프레임)을 초당 수 개에서 수십 개까지 빠르게 보여 주는 것을 말하는 것이고, 압축 동영상이란 최소한의 정지 영상 정보만으로 완전한 동영상 정보를 만들어 내어 이를 재생해낼 수 있도록 하는 것이다.
우리가 알고 있는 .mp4, .wmv, .asf, .3gpp 등의 파일은 Digital Container Format이라고 부르는 것이다. 엄밀히 말해 이들은 코덱이 아니다. Digital Container Format은 동영상/오디오 코덱을 이용하여 데이터를 저장하는 방식과 재생 동기화 정보 등의 부가 정보를 담고 있는 파일 형식을 말한다. 그리고 동영상 플레이어는 이 Digital Container Format을 읽어 동영상/오디오를 재생하는 프로그램이다.
원본 영상 데이터로부터 특정 동영상 코덱으로 변환하는 것을 인코딩이라 하고, 변환한 데이터를 파일에 담는 것을 먹싱(muxing)이라고 한다. 동영상을 재생하려면 역순으로 해야 한다. 이때 동영상 파일로부터 비트스트림(bit-stream) 데이터를 추출하는 과정을 디먹싱(demuxing)이라고 한다. 이렇게 디먹싱하면 어떤 코덱으로 인코딩되었는지 알 수 있게 된다. 그리하여 적합한 코덱으로 디코딩하면 원본 데이터 영상을 얻을 수 있다.
FFmpeg
FFmpeg은 크로스 플랫폼을 지원하는 오픈소스 멀티미디어 프레임워크이다. FFmpeg을 이용해 인코딩/디코딩, 트랜스코딩(transcode), 먹싱/디먹싱, 스트림(stream)은 물론 '재생'까지 멀티미디어와 관련한 거의 모든 기능을 다 갖추고 있다.
FFmpeg의 라이선스는 GPL과 LGPL이다. FFmpeg에는 다음과 같은 여러 세부 라이브러리가 있다.
- libavcodec: 오디오/비디오의 인코더/디코더
- libavformat: 오디오/비디어 컨테이너 포맷의 muxer/demuxer
- libavutil: FFmpeg 개발 시 필요한 다양한 유틸리티
- libpostproc: video post-processing
- libswscale: 비디오의 image scaling, color-space, pixel-format 변환
- libavfilter: 인코더와 디코더 사이에서 오디오/비디오를 변경하고 검사
- libswresample: 오디오 리샘플링(audio resampling)
FFmpeg을 이용하여 동영상 파일을 읽어 원본 데이터를 추출하는 과정은 다음 그림과 같다.
그림 1 FFmpeg을 이용한 demux/디코딩
가장 먼저 libavformat을 이용하여 디먹싱을 한다. 이렇게 디먹싱하면 비트스트림 데이터를 얻는데, 이 것으로 어떤 코덱을 사용했는지 파악할 수 있다. 그 다음으로 libavcodec을 이용하여 디코딩을 한다. libavcodec은 추출한 코덱 정보를 바탕으로 적합한 디코더로 비트스트림에서 원본 데이터를 추출한다.
Android NDK
Android NDK(Native Development Kit)는 C/C++와 같은 네이티브 언어로 개발한 라이브러리를 Android 앱에서 사용할 수 있게 하는 개발 도구이다. Android NDK의 구성 사항은 다음과 같다.
- Cross-toolchains(compiler, linker 등)
- Android Platform을 이용하기 위한 헤더 파일과 라이브러리
- 문서와 샘플 코드
현재 Android NDK가 지원하는 ARM instruction set은 다음과 같다.
- ARMv5TE
- ARMv7-A
- X86 instructions
ARMv5TE machine code는 모든 ARM 기반의 Android 기기에서 동작한다. ARMv7-A는 호환되는 CPU가 탑재된 기기에서만 동작한다. 두 instruction set의 주요한 차이점은 ARMv7-A만 H/W FPU, Thumb-2, NEON instructions를 지원한다는 데 있다. Android NDK로 개발할 때에 두 instruction set 모두를 지원하거나 둘 중 하나만 지원하도록 할 수 있다.
FFmpeg 포팅
FFmpeg은 C로 작성되었기 때문에 Android에서 동작시키려면 NDK를 이용해야 한다. 동영상 플레이어를 개발할 때에는 FFmpeg의 모든 library가 다 필요한 것은 아니기 때문에 필요한 libavformat과 libavcodec, libswscale만 NDK에서 빌드했다. NDK를 이용한 FFmpeg의 빌드 과정은 다음과 같다.
각 과정의 자세한 설명은 아래의 링크를 참고하기 바란다.
- Android NDK FFmpeg 컴파일 강좌 (1/4)
- Android NDK FFmpeg 컴파일 강좌 (2/4)
- Android NDK FFmpeg 컴파일 강좌 (3/4)
- Android NDK FFmpeg 컴파일 강좌 (4/4)
Android 동영상 플레이어
Android용으로 빌드한 FFmpeg 라이브러리로 동영상 플레이어를 개발하는 방법에는 크게 두 가지가 있다.
첫 번째로 플레이어에 필요한 기능을 직접 개발하는 방법이다. 관련 지식을 쌓을 수 있고, 필요한 기능을 요구에 맞게 개발할 수 있는 장점이 있지만 데이터 큐(data queue), 스트림 싱크(stream sync) 등 많은 기능을 직접 모두 구현해야 하기 때문에 오랜 개발 기간이 필요하다는 단점이 있다.
두 번째는 FFmpeg에서 레퍼런스로 제공하는 FFPlay를 Android용으로 포팅하는 방법이다. FFPlay는 FFMpeg 프로젝트의 일부로, SDL(Simple DirectMedia Layer)을 이용한 동영상 플레이어이다. SDL은 여러 그래픽, 사운드, 입력 디바이스에 대한 레이어 인터페이스를 제공하는 크로스 플랫폼 중 하나이다. Android용 SDL이 없기 때문에 동영상(비디오)/오디오 렌더링을 위해 FFPlay에서 SDL을 사용하는 부분을 수정해서 개발해야 하는 문제가 있다. 하지만 FFPlay에는 필요한 기능들이 이미 상당수가 있기 때문에 FFPlay의 Android 포팅 버전을 개발하는 것이 전체적으로 개발 시간을 줄일 수 있는 방법이다. 또한 FFPlay가 FFmpeg의 레퍼런스 프로젝트이기 때문에 FFmpeg 사용법을 잘 습득할 수 있는 기회가 될 수 있다.
그래서 FFPlay를 Android 용으로 포팅하는 방식을 선택했다.
그림 2 FFPlay의 구조
Android에서 오디오 재생
Android에서 PCM 데이터를 재생하기 위해 AudioTrack 클래스를 이용했다.
AudioTrack 클래스는 PCM 데이터를 전달하면 JNI를 통해 AudioFlinger에 접근하여 오디오 디바이스로 소리를 출력해 준다. SDL에서는 오디오 재생(Audio rendering)에 콜백 인터페이스를 사용한다. 즉 오디오 디바이스에 출력할 데이터가 필요하면 콜백 함수가 호출되고, 필요한 만큼의 데이터를 디코딩하여 전달하는 방식이다. 하지만 AudioTrack은 콜백 인터페이스 기반이 아니기 때문에 지속적으로 데이터를 전달해 주어야 한다. 이를 위해 FFPlay에서 Audio Decoder 부분을 별도의 스레드로 동작시키고 지속적으로 PCM 데이터를 AudioTrack에 넘겨주도록 수정했다.
그림 3 Audio Rendering
Android에서 동영상(비디오) 렌더링
Android에서 픽셀 데이터를 화면에 출력하기 위해 OpenGL을 이용했다.
Android에서는 OpenGL을 이용하여 화면에 출력하려면 GLSurfaceView 클래스를 이용해야 한다. SDL에서는 화면을 그려야 할 때에 SDL에 픽셀 데이터를 넘겨 주도록 되어 있다. 그리고 Android에서 OpenGL을 이용할 때는 꼭 OpenGL 스레드에서 GLSurfaceView.Renderer.onDraw() 함수가 호출되어 화면을 출력하도록 해야 한다. 이를 위하여 기존의 Video Refresher가 스레드로 수행되면서 필요한 시점에 화면을 그렸던 방식에서, Video Refresher가 스레드로 수행되면서 필요한 시점에 GLSurfaceView 클래스에 요청(GLSurfaceView.requestRender() 함수 호출)을 보내어 GLSurfaceView.Renderer.onDraw() 함수를 호출하고 함수 내에서 픽셀 데이터를 가져와 화면에 그리는 방식으로 구조를 변경했다.
그림 4 Video Rendering
OpenGL ES를 이용하여 화면을 그리는 과정은 다음 그림과 같다. 동영상 프레임(Video frame)을 디코딩하여 나온 결과인 픽셀 데이터는 원본 동영상 프레임보다 더 넓다(이것은 처리 성능을 향상시키기 위한 방법이고, 이렇게 넓어진 너비를 line-size라고 한다). 이렇게 나온 픽셀 데이터의 크기를 기준으로 해당 크기보다 큰 텍스처(texture)를 준비한다. 그 다음 텍스처에 픽셀 데이터를 그대로 복사하고, 원래의 동영상 프레임 크기만큼의 텍스처만 화면(screen)에 입힌다.
그림 5 OpenGL ES를 이용한 동영상 프레임 렌더링
Android 동영상 플레이어 최종 모습
Android 동영상 플레이어의 개략적인 구조는 다음 그리과 같다.
그림 6 Android 동영상 플레이어의 구조
FFPlay와 기본적인 구조는 동일하지만 앞서 설명한 대로 오디오와 비디오의 렌더링은 SDL을 이용하는 방식에서 AudioTrack과 OpenGL을 이용하는 방식으로 바꾼 것이 가장 큰 차이다.
또 하나의 차이는 스레드 사용이다. 원래의 FFPlay는 SDL 스레드를 사용하는데, 이는 내부적으로 pthread를 사용하는 것이다. Android에서도 pthread를 이용할 수는 있지만 네이티브 코드에서 생성한 pthread의 존재를 JavaVM이 모르고 있기 때문에 여러 가지 예상치 못한 오류가 발생할 수 있고 JNI를 호출할(call) 수 없다.
참조
JNI와 pthread에 대한 자세한 내용은 "JNI Tips" 문서를 참조한다.
이러한 문제점을 피하고 NDK에서 스레드를 사용하기 위해서는 생성된 pthread를 AttachCurrentThread() 함수를 사용하여 JavaVM에게 알려주거나, Java 스레드를 생성한 후 해당 스레드에서 수행하려하는 함수를 JNI를 이용하여 실행하도록 하는 방법이 있다. Android 동영상 플레이어는 개발 과정의 디버깅 편의성 등을 고려하여 Java 스레드를 이용하여 개발했다.
성능 개선
FFmpeg을 이용해 디코딩하여 나온 픽셀 데이터는 YUV 픽셀 데이터이다. 하지만 OpenGL을 이용해 렌더링을 하려면 RGB 픽셀 데이터가 필요하다. FFmpeg에서는 다음 그림과 같이 libswscale을 이용해 YUV 픽셀 데이터를 RGB 픽셀 데이터로 변환하는 색공간 변환 작업을 할 수 있다.
그림 7 libswscale을 이용한 픽셀 데이터 변환
하지만 libswscale은 CPU를 이용하여 변환 작업을 진행하기 때문에, 비록 변환 계산은 단순해도 변환해야 할 데이터의 양이 많아 수행 성능이 좋지 않다. 이를 개선하기 위하여 Shader를 사용했다. Shader는 CPU가 아닌 GPU를 사용한다. Shader에는 vertex를 변환하는 vertex shader와 픽셀을 변환하는 fragment shader가 있다. 색 공간의 변환은 픽셀 단위로 이루어지기 때문에 fragment shader를 이용했다. 관련 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | uniform sampler2D sampler0; uniform sampler2D sampler1; uniform sampler2D sampler2; varying highp vec2 _texcoord; void main() { highp float y = texture2D(sampler0, _texcoord).r; highp float u = texture2D(sampler1, _texcoord).r; highp float v = texture2D(sampler2, _texcoord).r; y = 1.1643 * (y - 0.0625 ); u = u - 0.5 ; v = v - 0.5 ; highp float r = y + 1.5958 * v; highp float g = y - 0.39173 * u - 0.81290 * v; highp float b = y + 2.017 * u; gl_FragColor = vec4(r, g, b, 1.0 ); } |
Shader를 이용하여 색 공간을 변환하면 다음 그림과 같은 구조가 된다. GPU는 CPU와 달리 단순 반복 연산에서 더욱 좋은 성능을 내기 때문에 좀 더 빠른 변환이 가능하다. 또한 변환 과정 중 CPU는 다른 작업을 수행하도록 할 수 있는 장점이 있다. 그 결과 동영상 플레이어 재생 능력이 libswscale을 썼을 때보다 더 향상되었다.
그림 8 OpenGL ES의 shader를 이용한 pixel data 변환
마치며
더 나은 동영상 서비스를 준비하기 위하여 모바일 동영상 플레이어를 자체 개발할 필요가 있다고 판단했고, FFmpeg을 이용해 Android 동영상 플레이어를 개발했다. 동영상 플레이어를 개발하는 과정에서는 FFmpeg을 비롯한 많은 오픈 소스의 도움을 받았기 때문에 개발 과정을 공개하는 것이 좋다고 생각했다. 비록 이 글을 읽는 독자 분들이 하는 일이 동영상이나 모바일과는 크게 관계가 없어도, 사용한 기술과 의사 결정 과정 등이 다른 분야의 업무에도 도움이 될 수 있을 것이라 생각한다.
앞으로도 개발 경험이나 새로운 기술에 대한 내용을 공유할 수 있는 기회가 더 있으면 한다. 궁금한 내용은 언제든 문의해 주기를 바란다.
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
---|---|
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
[FFmpeg] FFMpeg 윈도우 컴파일 (0) | 2013.04.28 |
[FFmpeg] FFmpeg 동영상 변환 (0) | 2013.02.17 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] IOCP 프로그래밍 (1) | 2013.05.21 |
---|---|
[VC++] Visual Studio Predefine Macro (0) | 2013.05.01 |
[VC++] Design Specifications and Guidelines - Visual Design (0) | 2013.03.14 |
[VC++] 모듈 정의 파일(.def)을 이용해서 EXPORTS 시키기 (0) | 2013.03.08 |
[C++] C++11 (0) | 2013.01.29 |
트랙백
댓글
글
링크 : http://msdn.microsoft.com/en-us/library/ms997619.aspx
Design Specifications and Guidelines - Visual Design
Layout
Size, spacing, and placement of information are critical in creating a visually consistent and predictable environment. Visual structure is also important for communicating the purpose of the elements displayed in a window. In general, follow the layout conventions for how information is read. In Western countries, this means left-to-right, top-to-bottom, with the most important information located in the upper left corner.
The system defines the size and location of user interface elements in a window based on dialog units (DLUs), not pixels. A dialog unit is the device-independent measure to use for layout. One horizontal dialog unit is equal to one-fourth of the average character width for the current system font. One vertical dialog unit is equal to one-eighth of an average character height for the current system font. The default height for most single-line controls is 14 DLUs. Be careful if you use a pixel-based drawing program, because it may not provide an accurate representation when you translate your design into dialog units. If you do use a pixel-based drawing tool, you may want to take screen snapshots from a development tool that supports dialog units and use those images.
More Information
Your application can retrieve the number of pixels per base unit for the current display using the GetDialogBaseUnits function. For more information about this function, see the Microsoft Platform SDK on the MSDN Online Web site.
Size
The following table lists the typical height and width of common dialog box controls.
Size of Common Dialog Box Controls | ||
---|---|---|
Control | Height (DLUs) | Width (DLUs) |
Dialog boxes and property sheets | 263 max. (for 640 x 480 screen resolution) 218 215 188 | 263 max. (for 640 x 480 screen resolution) 252 227 212 |
(For property sheets, heights include 25 DLUs for property sheet button bars.) | ||
Command buttons | 14 | 50 |
Check boxes | 10 | As wide as needed |
Drop-down combo box and drop-down list | 10 | Size to match other drop-down combo boxes and text boxes |
Option buttons | 10 | As wide as needed |
Text boxes | 14 | Size to match other drop-down combo boxes and text boxes |
Text labels | 8 per line of text | As wide as needed |
Other screen text | 8 per line of text | As wide as needed |
More Information
To support localization, you should make controls wider than just enough to display the labels. For more information, see Chapter 15, "Special Design Considerations."
Toolbars and their buttons use pixels instead of dialog units for their measurement. The recommended sizes are shown in the following table.
Size of Toolbars and Toolbar Buttons | ||
---|---|---|
Control | Height (pixels) | Width (pixels) |
Toolbars in small button mode | 23 | Width of toolbar area or window |
Toolbars in large button mode | 28 | Width of toolbar area or window |
Small toolbar buttons | 21 | Depends on content; 22 if the button includes only an image |
Large toolbar buttons | 26 | Depends on content; 28 if the button includes only an image |
When you cannot reasonably apply the size guidelines for secondary windows, try to maintain a width within a task. This can provide a smooth transition, making it easier for a user to focus on the task. Also, always check to make sure that the window will fit in the minimum screen resolution set by your application's users. Typically, this means using a 640 x 480 resolution screen to ensure that it fits completely. You must also take into account the possible space taken up by the task bar and other desktop toolbars.
Make buttons a consistent length for readability. However, if maintaining this consistency greatly expands the space required for a set of buttons, it may be reasonable to have one button larger than the rest.
Similarly, if you use tabs, try to maintain a consistent width for all tabs in the same window (and in the same dimension). However, if a particular tab's label makes this unworkable, size it larger and maintain a smaller, consistent size for the other tabs. If a tab's label contains variable text, you can size the tab to fit the label, up to some reasonable maximum, after which you truncate the text and add an ellipsis.
Try to maintain a consistent width between text boxes and the list boxes they appear near, using only one or two different widths per group or window. If you localize your application, you should extend text, option button labels, and check box labels to be as wide as the group or window, where possible. This will reduce the work necessary to localize your interface.
Spacing and Positioning
Maintain a consistent margin from the edge of the window seven dialog units is recommended. Use spacing between groups within the window, as shown in Figure 14.27.
Figure 14.27 Recommended layout and spacing of controls and text (click to enlarge image)
The following table lists the typical items found in an interface and the recommended spacing between them.
Spacing Between Interface Items | ||
---|---|---|
Interface items | Use this spacing (DLUs) | |
Dialog box margins | 7 on all sides | |
Between paragraphs of text | 7 | |
Between text labels and their associated controls (for example, text boxes and list boxes) | 3 | |
Between related controls | 4 | |
Between unrelated controls | 7 | |
First control in a group box | 11 down from the top of the group box; align vertically to the group box title | |
Between controls in a group box | 4; align vertically to the group box title | |
Between horizontally or vertically arranged buttons | 4; align vertically to the group box title | |
From the left edge of a group box | 9; if the group box is left-aligned, controls are 16 from the left edge of the dialog box or property page | |
Last control in a group box | 7 above the bottom of the group box | |
Smallest space between controls | 2 | |
Text label beside a button | 3 down from the top of the button | |
Check box, list box, or option button beside a button | 2 down from the top of the button | |
Toolbars and their buttons use pixels instead of DLUs. The following table provides spacing for toolbar buttons.
Spacing for toolbar buttons | ||
---|---|---|
Button Size | Spacing | |
Small (16 x 16 pixel image) toolbar buttons | 3 pixels between a button and its text label 2 pixels above the toolbar image 3 pixels below the toolbar image | |
Large (20 x 20 pixel image) toolbar buttons | 3 pixels between a button and its text label 2 pixels above the toolbar image 2 pixels below the toolbar image | |
In general, for controls that do not contain their own labels, place the label to the left or above the related control. This makes it easier for users to associate the label with the corresponding control.
When a text box is the first item in the group box, use a smaller measurement so the visual spacing above and to the right looks equal. In cases where there are controls below a group box, align the controls to the edge of the group box above and use seven DLUs between the bottom edge of the group box and the control (or text), as shown in Figure 14.28.
Figure 14.28 Example of group box spacing (click to enlarge image)
Position controls in a toolbar so that there is at least a window's border width from the edges of the toolbar, as shown below.
Use at least 4 DLUs between controls, except for between a set of related toolbar buttons. There should be no space between adjacent toolbar buttons, such as a set of related option buttons.
For wizard design, Figure 14.29 shows suggested positioning and spacing.
Figure 14.29 Positioning and spacing in a wizard (click to enlarge image)
Grouping
Group related components you can use group box controls, separator lines, or spacing. Although you can also use color to visually group objects, it is not a common convention and could result in undesirable effects if the user changes color schemes.
A group box provides a strong visual element for related items. However, avoid using a group box when you have only one set of related items or where the group box may take too much space or add visual clutter rather than structure. Instead, consider using separators to group related items. Property sheets for files and folders are a good illustration of the use of separators rather than group boxes.
Stack the main command buttons in a secondary window in the upper right corner or in a row along the bottom, as shown in Figure 14.30. If there is a default button, it is typically the first button in the set. Place OK and Cancel buttons next to each other. If there is no OKbutton but there are command buttons that initiate action, place the Cancel button at the end of the buttons but before a Help button. If a particular command button applies only to a particular field, group it with that field.
More Information
For more information about button placement in secondary windows, see Chapter 9, "Secondary Windows."
Figure 14.30 Layout of buttons (click to enlarge image)
Group controls so that their location helps users understand the associated context or scope. For tabbed pages, follow these guidelines:
- When command buttons and other controls apply only to that page, place them within the border of the tabbed page.
- When command buttons and other controls apply to the entire window, place them outside the tabbed page.
Alignment
When information is positioned vertically, align fields by their left edges (in western countries). This usually makes it easier for the user to scan the information. Text labels are usually left-aligned and placed above or to the left of the areas to which they apply. When placing text labels to the left of text box controls, align the top of the text with text displayed in the text box.
In group boxes, controls should be left-aligned with the text label of the group. However, command buttons in the group should be right-aligned.
Align command buttons in most secondary windows at the top right or right-align them with the bottom. The exception is for message boxes, where command buttons should be centered. In toolbar arrangements, buttons and other controls are typically left- or top-aligned, depending on the layout of the area.
Required and Optional Input
For input form design, you may want to require certain input fields or controls and make others optional. To help users distinguish required input from optional input, provide some form of visual differentiation. The best way to do this is to separate the two sets of input into separate windows, panes, or groups and label the fields accordingly. However, this may not always work with the type of information you are presenting. The next best way is to label the individual fields with the words "required" or "optional" in parentheses. You can also use fonts, symbols, or graphics; however, such conventions require the user to learn the convention in order to use the application effectively. In scenarios where you cannot rely on training the user, use a more obvious form of identification. Do not use color unless you are using some other form of feedback as well. Color may attract the user's attention, but the perception of color can vary. Therefore, do not rely on it as the only means of identification.
Preview and Sample Boxes
In some situations, you may want to provide an area for a visual example of changes a user is making to an item, as shown in Figure 14.31.
Figure 14.31 Preview or sample box (click to enlarge image)
A sample is a representation of what might show up on screen, but it does not show the actual data that the user is working on. In contrast, a preview shows the user's actual data.
Include text, graphics, or both in your preview or sample boxes. The preview can be illustrative and interactive. If the preview is interactive, include instructions or some visual cue to let the user know that it is interactive.
Include a label for your preview or sample box, and keep the wording for the label brief. A one- or two-word label (often Preview or Sample) is usually sufficient unless the user needs to interact with the preview to update it. Use sentence-style capitalization for the label, but do not include ending punctuation unless the user can interact with the preview, in which case end the label with a colon.
Fundamentals of Designing User Interaction
Windows Interface Components
Design Specifications and Guidelines
Appendixes and References
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Visual Studio Predefine Macro (0) | 2013.05.01 |
---|---|
[VC++] Tray Icon Animation (0) | 2013.04.26 |
[VC++] 모듈 정의 파일(.def)을 이용해서 EXPORTS 시키기 (0) | 2013.03.08 |
[C++] C++11 (0) | 2013.01.29 |
[COM] WebBrowser Customization (0) | 2012.12.29 |
트랙백
댓글
글
외부 프로그램과 연동하는 dll을 만들어야 했는데 .h, .lib를 같이 배포했기 때문에 __declspec을 사용했었습니다.
다른 방법으로는 모듈 정의 파일을 이용하는 방법도 있습니다.
프로젝트 속성 -> 구성속성 -> 링커 -> 입력 -> 모듈 정의 파일
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Tray Icon Animation (0) | 2013.04.26 |
---|---|
[VC++] Design Specifications and Guidelines - Visual Design (0) | 2013.03.14 |
[C++] C++11 (0) | 2013.01.29 |
[COM] WebBrowser Customization (0) | 2012.12.29 |
[VC++] visual studio 2008 Excel Automation "\excel.tlh(1219) : error C2371: 'FontPtr' : redefinition; different basic types" (0) | 2011.08.05 |
트랙백
댓글
글
'C/C++ > FFmpeg' 카테고리의 다른 글
[FFmpeg] 동영상의 기본적인 이해 (0) | 2013.05.16 |
---|---|
[FFmpeg] library document (0) | 2013.05.02 |
[FFmpeg] thumbnail 추출 (0) | 2013.04.29 |
[FFmpeg] FFMpeg 윈도우 컴파일 (0) | 2013.04.28 |
[FFmpeg] FFmpeg을 이용한 동영상 인코딩 (0) | 2013.04.28 |
트랙백
댓글
글
'C/C++ > VC++ / MFC' 카테고리의 다른 글
[VC++] Design Specifications and Guidelines - Visual Design (0) | 2013.03.14 |
---|---|
[VC++] 모듈 정의 파일(.def)을 이용해서 EXPORTS 시키기 (0) | 2013.03.08 |
[COM] WebBrowser Customization (0) | 2012.12.29 |
[VC++] visual studio 2008 Excel Automation "\excel.tlh(1219) : error C2371: 'FontPtr' : redefinition; different basic types" (0) | 2011.08.05 |
[MFC] MFC에서 Token 분리 (0) | 2011.07.21 |
RECENT COMMENT