SlideShare a Scribd company logo
Android Camrea Basics..
2015.10
이철혁
MSQL@NAVER.COM
이 문서는 나눔글꼴로 작성되었습니다. 설치하기
1. Camera
2. Color Space
3. Camera API
4. Surface
5. Texture
6. OpenGL
7. Case Study
목차
참고 : 이 PT를 바탕으로 강의를 통해 설명을 하기 위해 만들어 졌
던 자료이기에 PT만으로 이해가 안가는 부분이 있을 수 있음.
참고한 소스는 아래와 같다.
https://android.googlesource.com/
https://github.com/google/grafika
https://github.com/CyberAgent/android-gpuimage
1.Camera
1. Camera
3 / 14
Android 에서 가장 인기 있는 앱, 서비스는 카메라 기반 서비스들이 많다.
카메라 앱은 멀티미디어 서비스의 결정체이기도 기본적으로 알아야 할 것들이 많다.
카메라 앱을 만들기 위한 기초에 대해서 간략히 정리하는 것이 이 PT의 목표이다.
Android에서는 5.0 Lollipop 부터 기존의 Camera API를 대체할 수 있는 강력한 Camera2 API를 제공하고 있
지만, 다양한 버전을 모두 서비스 해야하는 환경에서 Camera2 API는 아직 전폭적으로 사용되고 있지 못하다.
심지어 5.0, 5.1 일부 단말기에서도 제대로 지원을 못하는 상황이 있어 제조사, 단말기, Android 버전에 따른 파
편화 관리가 어렵기에 당분간은 Camera API를 그대로 사용할 것 같다.
따라서 현재 모든 내용은 Camera API를 기반으로 설명된다.
1.Camera 4 / 14
Android system architecture
간단히 Java API 로 제공되는
android.hardware.Camera API를 사용하면,
물리적인 카메라가 어떤 단계를 거쳐 오는지 생각 못할
수 있는데, Android system architecture를 보면 정말
많은 단계를 통해 개발자에게 Camera의 정보가 오는
것을 확인할 수 있다.
출처 :
https://developer.android.com/guide/platform/in
dex.html?hl=ko
1.Camera 5 / 14
Camera architecture
Camera 만 다시 한번 보면
좀 더 자세히 확인할 수 있다.
출처 :
https://source.android.com/devices/camera/
1.Camera 6 / 14
Kernel driver
실제 카메라 하드웨어와 HAL과 상호 작용을 하는 단계로, 카메라와 드라이버는 YV12, NV21 이미지 형식을
지원해야만 카메라의 미리보기와 비디오 녹화가 가능하다.
YV12, NV21에 대해서는 뒤의 색공간에서 다시 한번 소개한다.
HAL
실제 카메라 하드웨어를 제어하는 Kernel driver를 카메라 서비스가 직접 다루지 않고 중간 층인
HAL( Hardware Abstraction Layer )을 통해 접근하도록 정의된 표준 인터페이스 이다.
출처 : https://source.android.com/devices/camera/
1.Camera 7 / 14
Camera service
안드로이드 프레임워크 frameworks/av/services/camera/libcameraservice/CameraService.cpp 에 위치하
여 HAL과 통신하는 실제 코드이다.
출처 : https://source.android.com/devices/camera/
1.Camera 8 / 14
Binder IPC proxies
frameworks/av/camera 에 위치한 3가지 바인더 클래스가 존재한다.
- ICameraService
- ICamera
- ICameraClient
출처 : https://source.android.com/devices/camera/
1.Camera 9 / 14
Native framework, JNI, Application framework
frameworks/av/camera/Camera.cpp는 우리가 어플리케이션에서 사용하는 android.hardware.Camera
API에 대응되는 native code이다.
android.hardware.Camera API에서는 JIN를 통해 Camera Service는 IPC binder proxies를 이용하여 접근
한다.
출처 : https://source.android.com/devices/camera/
1.Camera 10 / 14
Camera Pipeline
Raw Bayer Input 은 Camera Sensor를 통해 전달된
이미지를 의미한다. 현재 대부분의 폰에서 사용되는
Camera sensor는 한 개의 소자가 모든 색을 받아들이
는 구조가 아니라 R,G,B 각각의 색에 반응하는 소자들
을 조합하여 사용한다. 따라서 우리가 보는 RGB이미지
로 보기 위한 변환이 필요하다.
출처 :
https://source.android.com/devices/camera/came
ra3_requests_hal
http://www.cis.upenn.edu/~danielkh/files/2013_
2014_demosaicing/2013_RTF_demosaicing_1.pdf
1.Camera 11 / 14
Camera Pipeline
Android 에서는 Camera Sensor의 이미지를 그대로
전달하는게 아니라, 생각보다 많은 보정 단계를 거친후
에 전달된다.
기본적으로 사용되는 3A Algorithms 은 아래의 3가지
의 앞 글자를 따온 것이다.
- Auto-focus
- Auto-exposure
- Auto-whitebalance
1.Camera 12 / 14
Hot Pixel Correction
Hot Pixel은 모든 것이 검은 환경에서도 발생하는 흰색
의 픽셀을 의미한다. 이는 카메라 센서에서 노이즈와 과
부하등으로 발생하기도 하기에 제일 처음 처리하는 이
미지 단계가 이를 보정하는 것이다.
주변 픽셀들등의 정보를 이용해 보간법(interpolation)
으로 수정한다.
1.Camera 13 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
1.Camera 14 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
Bayer filter samples
Red Green Blue
Reconstructed
1.Camera 15 / 14
Demosaic
앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이
미지로 복원하는 과정을 의미한다.
1.Camera 16 / 14
Noise Reduction
DSLR과 같은 전문 카메라와 달리 카메라 센서의 크기가
제한적이고, 렌즈의 밝기도 어두운 경우가 많아 저조도
환경(어두운 환경), 확대한 환경 등에서 품질이 떨어지
기에 이를 보완하기 위한 방법이다.
1.Camera 17 / 14
Shading Correction
잘못된 그림자를 보정하는 부분이다.
1.Camera 18 / 14
Edge Enhancement
이미지의 엣지부분의 대비(contrast)를 높혀서 선명하
게 보이도록 하는 작업이다.
1.Camera 19 / 14
Output
Camera에서 제공하는 Output은 3가지 이다.
- RAW
- JPEG
- YUV
1.Camera 20 / 14
Raw
Camera2 API 부터 지원한다.
Raw 이미지는 앞서 거치는 Image Processing을 거치
지 않은 Camera Sensor의 결과물이다.
따라서 전문적으로 다른 Image Processing을 거치면
다른 JPEG을 만들어 낼 수 있다. 그래서 주로 전문가들
이 사용한다.
1.Camera 21 / 14
JPEG
Camera API의 takePicture 메서드를 이용하면 받을 수
있는 결과물로 폰의 Camera가 지원하는 최고의 해상도,
퀄리티의 이미지를 받아 볼 수 있다.
해당 포맷은 Preview로 제공되지 않고, takePicture 메
서드로만 받을 수 있다.
1.Camera 22 / 14
YUV
Camera API의 startPreview를 한 이후에 제공되는
preview(실시간의 Camera Sensor에 전달되는 이미지
들…)는 해당 포맷으로 제공된다.
JPEG에 비해 해상도가 떨어진다.
대부분의 폰에서 폰의 Display 해상도 ( QHD, FHD,
HD 정도)의 해상도 이하로 제공된다.
2. Color Space
2. Color Space
23 / 14
색, 색 공간(色空間, color space)
색 공간에 대한 이해는 필수이다.
동영상 쪽을 전혀 해보지 않았으면,
색공간 == RGB 인줄 알지만, 카메라에서 주로 쓰이는 색공간은 RGB가 아니다.
따라서 혼동이 많이 발생하기에, 색공간에 대한 이해를 정확히 해야 한다.
2.Color Space 24 / 14
색 (Color)
사전적 정의 :
가시광선의 명암과 분광 조성에 대한 시감각 또는 색감각, 색감각을 일으키는
빛 또는 색자극, 색자극을 일으키는 물체의 특성.
사람은 약 107,000가지의 색을 구별할 수 있음.
2.Color Space 25 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
색상(hue)
색깔의 질로도 표현하는데, 우리가 쉽게 색이라고 하면 생각하는 가장 중요한 색의 성질이다.
보면 안다.
2.Color Space 26 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
명도(lightness)
눈이 느끼는 밝기의 차이.
먼셀표색계에서는 흰색을 명도 10, 검정색을 0으로 하고
그 사이의 단계를 10단계 등분하여 번호를 매겨 사용한다.
같은 단계의 명도라 하더라도 색상에 따라
더 밝게, 어둡게 보일 수 있다.
2.Color Space 27 / 14
색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma)
채도(Chroma, Saturation)
색이 보다 선명할수록 채도가 높다고 말하며
회색이나 흰색 또는 검정과 같은 무채색에 가까울수록 채도가 낮다고 말한다.
채도가 높은 색을 말할 때는 흔히 '짙다'고 표현하고,
반대로 채도가 낮은 색을 말할 때는 흔히 '흐리다'는 표현을 사용한다.
예를 들어 짙은 노랑, 흐린 노랑과 같이 표현할 수 있다.
2.Color Space 28 / 14
Color space(색공간)
색 공간(色空間, color space)은 색 표시계(color system)를 3차원으로 표현한 공간 개념이라고
사전적으로 정의한다. 3차원인 이유는?
앞에서 설명한 색의 3가지 속성인 색상(hue), 명도(lightness), 채도(chroma)을 각각의 축으로
3차원 공간으로 표현한 것이다. 미술시간에 많이 봤을 먼셀 색입체를 보면 이해가 쉽다.
2.Color Space 29 / 14
RGB
RGB 색 공간은 색을 혼합하면 명도가 올라가는 가산 혼합 방식으로 색을 표현한다.
( 빛은 더할수록 명도가 올라가서 모든 색을 다 섞으면 흰색이 된다는 것을 초등학교에서 배웠을 것이다. )
RGB 가산혼합의 삼원색은 빨강(Red), 녹색(Green), 파랑(Blue)을 뜻한다.
RGBA은 RGB와 동일하며, 알파(Alpha)라는 투명도(투과도)를 추가한 것.
RGB 색 공간은 삼원색에 해당하는 세 가지 채널의 밝기를 기준으로 색을 지정한다.
RGB 색 공간은 웹 색상 표현의 기본 원리이다.
2.Color Space 30 / 14
CMYK
CMYK 색 공간은 인쇄과정에서 쓰이는 감산 혼합 방식으로,
(실제 미술시간에 빛과 달리 물감을 섞으면 섞을수록 검정색이 되는 것을 경험해봤을 것이다. )
흰 바탕에 네 가지 잉크의 조합으로 색을 나타내는 것을 말한다.
색을 혼합하면 명도가 낮아지기에 감산 혼합이라고 한다.
CMYK는 인쇄에 쓰이는 4가지 색은 옥색(Cyan), 자청색(Magenta), 노랑(Yellow), 검정(Black)을 뜻한다.
2.Color Space 31 / 14
HSV
HSV 색 공간은 색상(Hue), 채도(Saturation), 명도(value)를 기준으로 색을 구성하는 방식이다.
감산 혼합이나 가산 혼합보다 색상의 지정이 직관적이기 때문에 시각 예술에서 자주 쓰인다.
2.Color Space 32 / 14
Color space (색 공간)
모든 색 공간이 표현하는 색이 같은데, 방법이 다른게 아니라 색 공간에 따라 표현하는 색의 범위가 다르다.
이 점을 반드시 이해해야 한다. ( 아래의 면적이 클수록 표현할 수 있는 색이 많은 색 공간이다. )
2.Color Space 33 / 14
YUV (=YCbCr)
흑백TV시절의 방송 인프라를 사용하여, 한 방송으로 컬러TV와 흑백TV를 다 볼 수 있도록 고안되었다.
흑백TV에서 이용되던 정보에 부수적으로 컬러정보를 추가하여 사용하여, 인프라의 큰 교체없이 컬러TV를 볼
수 있게 되었다.
2.Color Space 34 / 14
YUV (=YCbCr)
실제 적용 예를 보면, 원래 컬러인 이미지가 흑백인 Y와 추가적인 컬러 정보 UV로 구성되어 있다.
Original Y’
U V
2.Color Space 35 / 14
YUV (=YCbCr)
자연상에서 가장 많은 색인 Green에 더 많은 공간을 두어서
모든 색이 동일한 범위를 갖는 것에 비해 효율적인 구조를 만듦.
UV
U : Ranges from Red to Yellow
V : Ranges from Blue to Yellow
2.Color Space 36 / 14
YUV (=YCbCr)
YUV는 밝기(Luminance)인 Y성분과 색상(Chrominance)인
U(Cb)와 V(Cr) 성분으로 구성하여 픽셀을 표현하는 방식.
일반적인 RGB 방식에 비하여 작은 용량(대역폭)으로 전송이 가능
1 pixel 표시 크기 비교
ARGB = 32bits ( 4bytes )
YUV411 = Y : 8 bit + U : 2 bit + V : 2 bit = 12bits
극단적으로 ARGB를 사용해 1 pixel을 32bits 로 전송하는 것을 12bits로 전송할 수 있으니 62.5%의 적어 지
금까지도 많은 곳에서 사용 되는 것이다.
2.Color Space 37 / 14
YUV (=YCbCr)
이렇게 극단적으로 적은 정보로 전송할 수 있는 이유는?
흑백의 명암을 나타내는 Y정보에 데이터의 절반을 사용하는 이유는 사람의 눈은 밝기 변화를 느끼는 간상세포
는 9천만 개 이상 존재하는데 비하여 색상을 인식하는 원추세포는 약 600만 개 정도에 불과하기 때문이다.
따라서, 사람의 시각은 밝기의 변화에 비하여 색상의 변화에는 둔감하다는 특성을 보이게 된다.
이에 따라 많은 영상 시스템은 밝기 정보와 색상의 정보를 분리하여 별도로 부호화 하도록 하여 필요에 따라 압
축 효율을 높인다.
원추세포는 3가지
L 원추세포(ρ세포) : 빨간색
M 원추세포(Г세포) : 청녹색과 노란색
S 원추세포(β세포) : 파란색
각각 원추세포의 비율이 다르다.
빨강 40 : 녹색 20 : 파랑 1
2.Color Space 38 / 14
YUV (=YCbCr)
YUV는 YUV422, YUV420, YUV411 등의 포맷이 있는데,
이러한 표현은 아래와 같이 각 구성값의 비트 할당수에서 비롯한다.
즉 YUV422은 Y:U:V = 4:2:2 이다.
YUV는 RGB 처럼 한 개의 픽셀 개념으로 이해하면 안됨!
2.Color Space 39 / 14
YUV (=YCbCr)
YUV는 한 개의 픽셀 개념으로 이해하면 안되며, 기존 TV의 주사방식을 생각해보면 이해하기 쉬움
기존 TV 주사방식: 비월 주사 방식(Interlace scanning)
하나의 영상을 홀수와 짝수 가로줄로 나뉜 것을 번갈아가며 표시하는 영상의 표시 방식이다.
2.Color Space 40 / 14
YUV (=YCbCr)
U V
Y
2.Color Space 41 / 14
YUV (=YCbCr)
각 구성값의 비트 할당수로도 구분되지만, YUV를 어떤 순서로 배열해서 사용하는지에 따라도 구분된다.
YUV422 : YUV를 아래와 같은 순서로 사용한다.
YUV420 : 구성요소 별로 모아 놓았다.
2.Color Space 42 / 14
YUV (=YCbCr)
YUV420 : 구성요소 별로 모아 놓았다.
2.Color Space 43 / 14
YUV (=YCbCr)
Single Frame YUV420 : 16 Bits per pixel
IMC1 IMC3
2.Color Space 44 / 14
YUV (=YCbCr)
Single Frame YUV420 : 12 Bits per pixel
IMC2 IMC4
2.Color Space 45 / 14
YUV (=YCbCr)
Single Frame YUV420 : 12 Bits per pixel
YV12 NV12
2.Color Space 46 / 14
NV12/NV21
NV12 : YUV420 과 비슷한 개념이나, 표현 방식이 다름
For 1 NV12 pixel: YYYYYYYY UVUV
For a 2-pixel NV12 frame: YYYYYYYYYYYYYYYY UVUVUVUV
For a 50-pixel NV12 frame: Y*8*50 (UV)*2*50
For a n-pixel NV12 frame: Y*8*n (UV)*2*n
NV21 : NV12와 비슷하나 UV의 순서가 바뀌어 VU로 출력됨
2.Color Space 47 / 14
RGB <-> YUV 변환
문제는 우리가 주로 쓰는 색공간은 결국 RGB이고,
픽셀단위로 조작이 필요하거나 후처리를 위해 변환이 필요한 경우가 발생한다.
RGB <-> YUV는 색공간이 다르기에 정확히 1대1 대응이 되지 않는다.
수많은 방법들이 있으나, 아래와 같은 수학식으로도 변환이 될 수 있다.
From RGB to YUV
Y = 0.299R + 0.587G + 0.114B
U = 0.492 (B-Y)
V = 0.877 (R-Y)
It can also be represented as:
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
From YUV to RGB
R = Y + 1.140V
G = Y - 0.395U - 0.581V
B = Y + 2.032U
2.Color Space 48 / 14
RGB <-> YUV 변환
이를 코드로 보면 아래와 같다.
이 코드는 실제로 사용되면 안된다. (엄밀히 말하면, YUV-> RGB 변환이 CPU에서 실행되면 안된다.)
RGB와 YUV를 변환하는 것이 얼마나 큰 비용의 연산인지 감을 잡기위해 작성한 코드이다.
void YUVfromRGB(double& Y, double& U, double& V, const double R, const double G, const double
B) {
Y = 0.257 * R + 0.504 * G + 0.098 * B + 16;
U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
V = 0.439 * R - 0.368 * G - 0.071 * B + 128;
}
void RGBfromYUV(double& R, double& G, double& B, double Y, double U, double V)
{
Y -= 16;
U -= 128;
V -= 128;
R = 1.164 * Y + 1.596 * V;
G = 1.164 * Y - 0.392 * U - 0.813 * V;
B = 1.164 * Y + 2.017 * U;
}
2.Color Space 49 / 14
색공간을 이용한 코드
RGB, YUV는 필수적으로 사용되는 건 알겠는데,
다른 색공간이 필요한 경우가 있을까?
앱에 기능 중 ColorPicker에서 색을 선택 후
수직이나 수평으로 드래그하면
명도와 채도를 변화하는 코드가 있다.
이를 RGB에서 구현하고자 하면 상당히 복잡하다.
가장 빠르고 단순하게 해결하는 방법은
다른 색공간을 이용하는 것이다.
앞에서 말했듯,
물론 색공간을 변화하면 일부 색이 손실되지만,
여기서는 큰 문제가 아니었기에
사용할 수 있는 방법이다.
2.Color Space 50 / 14
색공간을 이용한 코드
HSV를 이용하면 쉽게 채도와 명도를 바꿀 수 있다.
이를 이용해 명도, 채도는 HSV공간안에서 변경 후에 최종 선택이 완료되면 다시 RGB로 변경해 최종 선택된
색을 넘기게 된다.
// 채도 ( width : Saturation : [1])
// 명도 ( height : bright : [2])
int red = Color.red(pixelColor);
int blue = Color.blue(pixelColor);
int green = Color.green(pixelColor);
if (mIsTouchDown) {
red = Color.red(mPreviousColor);
blue = Color.blue(mPreviousColor);
green = Color.green(mPreviousColor);
}
float[] colorHSV = new float[3];
Color.RGBToHSV(red, green, blue, colorHSV);
float saturation = (float) rawY / mHeightPixels;
float bright = (float) rawX / mWidthPixels;
colorHSV[1] = 2.0f * saturation;
colorHSV[2] = 2.0f - 2.0f * bright;
if (mOnColorPickedListener != null) {
mOnColorPickedListener.onColorPicked(Color.HSVToColor(colorHSV));
}
3.Camera API
3. Camera API
51 / 14
Camera API 는 API level 21부터 deprecated 되었다.
하지만 앞서 말했듯 다양한 버전을 모두 서비스하는 환경에서
우리는 Camera API를 사용해야 한다.
3.Camera API 52 / 14
Camera Class가 하는 일
1) Set image capture settings : 이미지를 가져오기 위한 설정을 함 ( LED Flash 키는 것도 포함 )
2) Start/Stop preview : 미리보기(preview)를 켜고 끔
3) Snap pictures : 실제 사진을 찍음
4) Retrieve frames for encoding for video : 비디오 녹화를 위해 동영상을 제공함
3.Camera API 53 / 14
권한 추가 필요
3.Camera API 54 / 14
사진을 찍기 위한 단계
1. Obtain an instance of Camera from open(int).
: 카메라 인스턴스를 얻기 위해 open 메소드를 이용한다.
매개변수인 int는 카메라 id로 보통의 경우 전, 후면 카메라이다.
2. Get existing (default) settings with getParameters().
: getParameters() 메소드를 이용해 현재 카메라의 세팅을 가져온다.
3. If necessary, modify the returned Camera.Parameters object and call setParameters(Camera.Parameters).
: 카메라의 파라미터, 세팅을 변경이 필요하면 setParameters()를 이용해 세팅한다.
4. If desired, call setDisplayOrientation(int).
: 전달되는 영상의 출력 방향을 결정한다.
5. Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder).
Without a surface, the camera will be unable to start the preview.
: setPreviewDisplay를 통해 카메라 preview가 보여질 surfaceholder가 초기화 되어 전달되어야 한다. (뒤에 상세히 설명)
6. Important: Call startPreview() to start updating the preview surface.
Preview must be started before you can take a picture.
: startPreview()를 통해 preview를 시작하는데, 사진을 찍기전에 startPreview()는 무조건 실행되어야 한다.
3.Camera API 55 / 14
사진을 찍기 위한 단계
7. When you want, call takePicture (Camera.ShutterCallback, Camera.PictureCallback)
to capture a photo. Wait for the callbacks to provide the actual image data.
: 사진을 찍을때 takePicture메소드를 실행하는데, Camera.PictureCallback을 통해 실제 이미지가 전달된다.
(실제 사용할일은 없다. 우리는 실제로 사진을 찍는 것이 아니라 Preview만을 이용하기 때문 )
8. After taking a picture, preview display will have stopped.
To take more photos, call startPreview() again first.
: 사진을 찍은 후에는 preview가 멈추기 때문에 다시 사진을 찍기 위해서는 startPreview()를 다시 실행해야만 한다.
( takePicture를 사용하지 않기에 발생하지 않는 단계 )
9. Call stopPreview() to stop updating the preview surface.
: stopPreview()는 실행하면 더 이상 preview를 갱신하지 않는다.
10. Important: Call release() to release the camera for use by other applications.
Applications should release the camera immediately
in onPause() (and re-open() it in onResume()).
: Camera 객체의 Life Cycle관리는 매우 중요하다.
Camera 객체는 시스템에서 하나밖에 사용하지 못하게 되어 있으므로,
앱의 Life Cycle에 맞춰서 release()를 해주지 않으면, 다른 앱에서 카메라를 사용할 수 없게 된다.
onPause()에서는 release()를 onResume()에서 open()을 하도록 작성해야 한다.
3.Camera API 56 / 14
Android camera preview workflow
앞서 살펴본 단계를 생각해보면,
Camera 클래스의 open 메서드를 호출한다고 하면,
하드웨어 레벨까지 전달되고 다시 Application API 레벨까지 올라오는 것을 그릴 수 있어야 한다.
Android
Application
Android
Framework
Android
Runtime(JNI)
Client
Camera
Server
CameraService
Hardware
CameraHardwareStu
b
Open Camera
open native_setup connect connect HAL_openCameraHardWare
CameraHardWareStub instanceCamera instance
Binder(IPC)
3.Camera API 57 / 14
Android camera preview workflow
다른 메서드 들도 같다고 생각하면 된다..
3.Camera API 58 / 14
CameraManager.java
3.Camera API 59 / 14
CameraTextureView.java
3.Camera API 60 / 14
Camera.CameraInfo
3.Camera API 61 / 14
Camera.CameraInfo
3.Camera API 62 / 14
Camera.CameraInfo
3.Camera API 63 / 14
Camera.CameraInfo
3.Camera API 64 / 14
setDisplayOrientation
3.Camera API 65 / 14
setDisplayOrientation
주의 : orientaion은 setParameter 이후 제일 마지막에 있어야 함.
3.Camera API 66 / 14
setPreviewTexture
3.Camera API 67 / 14
startPreview
3.Camera API 68 / 14
startPreviewDisplay
3.Camera API 69 / 14
startPreview()
3.Camera API 70 / 14
startPreview()
3.Camera API 71 / 14
Camera.PreviewCallback
3.Camera API 72 / 14
Camera.PreviewCallback
3.Camera API 73 / 14
Camera.PreviewCallback
3.Camera API 74 / 14
previewCallbackWithBuffer 사용 예
3.Camera API 75 / 14
previewCallbackWithBuffer 사용 예
3.Camera API 76 / 14
GPU Image 사용 예
3.Camera API 77 / 14
GPU Image 사용 예
3.Camera API 78 / 14
takePicture
고화질의 JPEG을 받아야 할 경우만 사용함.
3.Camera API 79 / 14
stopPreview
3.Camera API 80 / 14
release
4.Surface
4. Surface
81 / 14
Surface, SurfaceHolder, SurfaceView, GLSurfaceView, SurfaceTexture,
Surface Flinger, OpenGL, EGL…
Surface와 관련된 내용이 이것 저것 많이 나온다.
혼돈하지 말자. 의외로 간단하다.
Surface는 raw buffer이고,
SurfaceHolder는 말 그대로 Surface를 얻을 수 있게 해준다.
SurfaceView는 View계층 구조가 복잡해 빠른 반응속도가 필요한 게임, 동영상에서 쓰기 위해 만들어진 고속도
로(펀칭홀)라고 생각하자.
나머지는 이 후에 설명될 것이다.
4.Surface 82 / 14
Surface
4.Surface 83 / 14
SurfaceHolder
4.Surface 84 / 14
서피스 플링어 서비스
서피스 플링어 서비스는 여러 개의 Surface를 하나로 만들기 위해 서피스의
개념에 Z-order를 추가한 레이어개념으로 서피스를 관리
가장 큰 Z-order 값을 가장 먼저 그림
4.Surface 85 / 14
EGL
서피스 플링어 서비스가 디스플레이 초기화 과정에서 EGL을 사용하고,
합성과정에서 OpenGL ES API를 사용. (OpenGL ES는 Embedded Systems의 약어로 임베디드에서 쓰이기 위한 OpenGL API
의 서브셋이다.)
뒤에 설명되는 OpenGL은 플랫폼에 독립적이다. 따라서 OpenGL의 명령에 따라 실제 각 디바이스에 그려줄 밑 부분이 필요한데,
그 역할을 EGL이 한다.
OpenGL ES
EGL
Native Window System
4.Surface 86 / 14
4.Surface 87 / 14
4.Surface 88 / 14
SurfaceView란?
SurfaceView는 다른 View들과는 달리 직접 SurfaceView가 컨텐츠를 표시하지 않습니다.
일반적인 View는 화면에 뷰를 표시하는 연산과 기타 연산,
사용자와의 상호작용 처리 등이 모두 하나의 쓰레드에서 처리됩니다.
SurfaceView는 화면 업데이트를 백그라운드 쓰레드로 수행하여
어플리케이션의 자원을 잠식하지 않고 원활하게 뷰를 업데이트해줍니다.
SurfaceView는 OpenGL을 통한 가속이 지원되어 원활한 3D그래픽 표현도 가능합니다.
(GLSurfaceView)
4.Surface 89 / 14
SurfaceView란?
4.Surface 90 / 14
SurfaceView란?
4.Surface 91 / 14
GLSurfaceView
4.Surface 92 / 14
GLSurfaceView
4.Surface 93 / 14
GLSurfaceView 이용하기
4.Surface 94 / 14
GLSurfaceView 이용하기
4.Surface 95 / 14
GLSurfaceView 이용하기
4.Surface 96 / 14
GLSurfaceView 이용하기
4.Surface 97 / 14
GLSurfaceView 이용하기
4.Surface 98 / 14
GLSurfaceView 이용하기
4.Surface 99 / 14
4.Surface 100 / 14
4.Surface 101 / 14
GLSurfaceView 이용하기
4.Surface 102 / 14
GLSurfaceView 이용하기
4.Surface 103 / 14
GLSurfaceView 이용하기
4.Surface 104 / 14
4.Surface 105 / 14
4.Surface 106 / 14
5.Texture
5. Texture
107 / 14
5.Texture 108 / 14
5.Texture 109 / 14
Texture는 같은 이미지 포맷의 이미지를 한 개 혹은 그 이상을 포함하는 OpenGL 오브젝
트이다.
5.Texture 110 / 14
Texture 사용예
귤을 예를 들어 실제 처럼 보이게 하기 위해
1. 색상을 추가하고
2. 빛을 추가 한 후에
3. 실제 귤의 이미지를 입히면
더욱 귤 같이 보일 것이다.
이때 귤의 이미지를 Texture라고 하고 실제 Object에 입히는 것을 mapping이라고 한다.
5.Texture 111 / 14
5.Texture 112 / 14
5.Texture 113 / 14
5.Texture 114 / 14
4.Surface 115 / 14
6.OpenGL
6. OpenGL
116 / 14
정리된 글 출처
OpenGL은 게임에서 이용하는 것이라고 생각할 수 있다.
하지만 카메라 앱을 만들기 위해서 OpenGL은 필수이다.
안드로이드에서 Native 프로그래밍을 하지 않고 GPU를 이용하기 위해서는 OpenGL을 이용하거나
Renderscript를 이용하는 방법 밖에 없기 때문이다.
자세한 내용은 이 곳을 참고하면 된다.
http://soen.kr/lecture/library/opengl/opengl-1.htm
4.Surface 117 / 14
OpenGL 특징
OpenGL의 특징은 이름에 포함된 Open이라는 단어에서 대부분 유추할 수 있다.
개방되어 있고 무료이며 이식성이 뛰어나다.
① 그래픽 라이브러리는 구체성을 기준으로 고수준과 저수준으로 분류되는데 OpenGL은 저수준 라이브러리이다.
VRML같은 고수준 라이브러리는 물체간의 관계를 정의함으로써 장면을 그려낸다.
이에 비해 저수준 라이브러리는 모델링보다는 랜더링 기능이 주이며 세부적인 명령을 일일이 전달함으로써 물체의 가장 기본적인
요소를 그린다.
사용 방법이 훨씬 더 어렵지만 세세한 부분까지 그릴 수 있다.
② 개방된 표준이므로 플랫폼에 독립적이다.
운영체제와 연관된 부분이 없고 디바이스 드라이버를 통해 하드웨어를 직접 제어하므로 드라이버만 존재하면 모든 하드웨어 환경
에서 실행할 수 있다.
대부분의 데스크탑 환경, 모바일 환경은 물론이고 PlayStation, Nintendo 등의 게임기 등에도 광범위하게 이식되어 있다.
4.Surface 118 / 14
OpenGL 특징
③ 간단한 함수들로 구성되어 있으므로 개발 언어에도 독립적이다.
C/C++, C#, 자바, 파이썬 등 대부분의 언어에서 사용 가능하다.
함수 기반이므로 C 언어가 가장 적합하되 객체 지향의 이점까지 고려하면 C++이 가장 유리하다.
무엇보다 문서와 예제가 풍부하고 재사용한 코드를 쉽게 구할 수 있다는 것이 큰 이점이다.
또 그래픽 프로그램이 요구하는 속도를 충분히 만족한다.
④ 하드웨어의 가속 기능을 최대한 활용하여 효율적으로 동작한다.
하드웨어가 지원하지 않는 기능은 소프트웨어로 흉내낼 수도 있으므로 느려지거나 품질이 나빠지더라도 최소한 그려내기는 한다.
4.Surface 119 / 14
OpenGL 특징
OpenGL 함수들은 일반 함수와 구분하기 위해 예외없이 접두어가 붙는다.
gl 라이브러리의 함수는 gl 접두어로 시작하고 glu의 라이브러리는 glu로 시작한다.
마찬가지로 glut 소속의 함수는 glut 접두가 붙는다.
접두어만으로도 OpenGL 함수임을 쉽게 알 수 있다.
OpenGL은 C 수준의 함수들로 구성되어 있으므로 객체 지향과는 거리가 멀다.
그래서 함수 오버로딩(Overloading)을 지원하지 않으며 인수의 개수와 타입이 다른 동명 함수를 작성할 수 없다.
동일한 동작을 하되 인수 목록이 다르면 함수의 이름도 매번 달라져야 한다.
4.Surface 120 / 14
OpenGL 특징
그래픽 출력에는 좌표뿐만 아니라 아주 많은 요소들이 개입된다.
색상, 굵기, 모양, 조명, 각종 모드 등등 여러 가지 정보들이 필요하다.
그리기 함수들은 도형 출력을 위해 이 모든 정보들을 참조하지만 그렇다고 해서 이 정보들을 모두 함수의 인수로 전달할 수는 없다.
그렇게 하다가는 인수 목록이 한없이 길어질 것이며 잘 바뀌지도 않는 값을 매번 전달하는 것도 낭비이다.
그래서 OpenGL은 그리기에 필요한 여러 가지 정보들을 상태 머신(State Machine)에 저장한다.
상태 머신이란 상태를 저장하는 장소이며 그리기에 영향을 미치는 여러 변수값들이 집합이다.
배경 색상은 GL_COLOR_CLEAR_VALUE 상태 변수에 저장되며 현재 정점의 색상은 GL_CURRENT_COLOR 상태 변수에 저장된
다
7.Case Study
7. Case Study
121 / 14
총정리
지금까지 배운 기술을 바탕으로 실제 카메라의 Preview로 넘어온 영상을 동영상으로 저장하는 프로세스를 경험
해 보자.
실제코드는 https://github.com/google/grafika 를 참고하기 바란다.
4.Surface 122 / 14
Camera Preview
GLSurfaceView
setEGLContextClientVersion(2);
Renderer
setRenderer();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
4.Surface 123 / 14
Camera Preview
Renderer
onSurfaceCreated
1) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성
GLES20.glGenTextures
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES
2) 해당 Texture로 SurfaceTexture 생성
mSurfaceTexture = new SurfaceTexture(textureId)
3) vertexShader, fragmentShader 정의
4) 생성된 SurfaceTexture의 OnFrameAvailableListener 지정
SurfaceTexture에 새로운 이미지프레임이 왔을 때 불리는 callback
mSurfaceTexture.setOnFrameAvailableListener(this);
5) 생성된 SurfaceTexture 로 setPreviewTexture
camera.setPreviewTexture(surfaceTexture);
6) 카메라 preview 시작
camera.startPreview();
4.Surface 124 / 14
Camera Preview
Renderer
onFrameAvailable
1) SurfaceTexture는 새로운 프레임이 있다는 신호를 받는
용도로 사용되고, requestRender는 어느 쓰레드에서도
호출 할 수 있다.
이 결과로 Renderer의 onDrawFrame이 실행됨.
glSurfaceView.requestRender();
4.Surface 125 / 14
Camera Preview
Renderer
onDrawFrame
1) updateTexImage()를 실행하여, 이미지 스트림으로부터 가장
최신의 프레임으로 texture 이미지를 업데이트한다.
만약 최신 프레임이 없으면 기존 이미지를 재사용함.
mSurfaceTexture.updateTexImage();
2) TransformMatrix에서 사용할 Matrix 지정.
TransformMatrix는 기본 좌표계의 버텍스가 이 행렬에 곱해져서
새로운 좌표계로 변환된 버텍스를 얻기 위해 사용되는 행렬
( 회전, 이동, 크키 )
updateTexImage()를 사용할때 마다 사용할 Matrix가 달라질 수
있으므로 매번 새롭게 지정해줘야 함.
mSurfaceTexture.getTransformMatrix(mSTMatrix);
4.Surface 126 / 14
Camera Preview
Renderer
onDrawFrame
3) OpenGL vertex shader, fragment shader 실행
4) 렌더링 실행
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
5) GL 명령어 실행
GLES20.glFlush();
4.Surface 127 / 14
Camera Preview
GLSurfaceView
Renderer
Camera
2) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성
해당 Texture로 SurfaceTexture 생성
SurfaceTexture
3) setPreviewTexture
(surfaceTexture);
4) preview 갱신
5) onFrameAvailable
- requestRenderer(); 호출
6) onDrawFrame
SurfaceTexture.updateTexImage();
7) GL rendering
1) setRenderer
8) eglSwapBuffers
mEgl.eglSwapBuffers(mEglDisplay,
mEglSurface);
4.Surface 128 / 14
Camera Preview
GLSurfaceView
EGL setup
1) EGL10 mEgl =
(EGL10) EGLContext.getEGL();
2) EGLDisplay mEglDisplay =
mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
3) EGLConfig mEglConfig =
view.mEGLConfigChooser.chooseConfig
(mEgl, mEglDisplay);
4) EGLSurface mEglSurface =
view.mEGLWindowSurfaceFactory.createWindowSurface
(mEgl,mEglDisplay, mEglConfig, view.getHolder());
4.Surface 129 / 14
Camera Preview
GLSurfaceView
EGL setup
1) EGL10 mEgl =
(EGL10) EGLContext.getEGL();
참고 : EGLContext는 인자로 전달받기보다 TLS를 통해 접근함.
4.Surface 130 / 14
Camera Preview
4.Surface 131 / 14
Camera Preview
4.Surface 132 / 14
Camera Preview
GLSurfaceView
EGL setup
2) EGLDisplay mEglDisplay =
mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
4.Surface 133 / 14
Camera Preview
GLSurfaceView
EGL setup
2) EGLDisplay mEglDisplay =
mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
4.Surface 134 / 14
Camera Preview
GLSurfaceView
EGL setup
2) EGLDisplay mEglDisplay =
mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
4.Surface 135 / 14
Camera Preview
GLSurfaceView
EGL setup
3) EGLConfig mEglConfig =
view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
4.Surface 136 / 14
Camera Preview
4.Surface 137 / 14
Camera Preview
GLSurfaceView
EGL setup
3) EGLConfig mEglConfig =
view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
4.Surface 138 / 14
Camera Preview
GLSurfaceView
EGL setup
3) EGLConfig mEglConfig =
view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
4.Surface 139 / 14
Camera Preview
4.Surface 140 / 14
Camera Preview
GLSurfaceView
EGL setup
4) EGLSurface mEglSurface =
view.mEGLWindowSurfaceFactory.createWindowSurface
(mEgl,mEglDisplay, mEglConfig, view.getHolder());
4.Surface 141 / 14
Camera Preview
GLSurfaceView
EGL setup
4) EGLSurface mEglSurface =
view.mEGLWindowSurfaceFactory.createWindowSurface
(mEgl,mEglDisplay, mEglConfig, view.getHolder());
4.Surface 142 / 14
Camera Preview
GLSurfaceView
EGL setup
4) EGLSurface mEglSurface =
view.mEGLWindowSurfaceFactory.createWindowSurface
(mEgl,mEglDisplay, mEglConfig, view.getHolder());
안드로이드에서 window 객체는
SurfaceView, SurfaceTexture, SurfaceHolder, Surface가 될 수 있다.
4.Surface 143 / 14
Camera Preview
4.Surface 144 / 14
Camera Preview
4.Surface 145 / 14
Camera Preview
GLSurfaceView
eglSwapBuffers
- 현재 버퍼를 전송, 이 함수의 이름은 전면 버퍼와 후면 버퍼를
교체했던 전통 방식에서 유래됐으나, 실제 구현은 이제 다를 수
있다.
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
4.Surface 146 / 14
Camera Preview
4.Surface 147 / 14
Camera Preview
4.Surface 148 / 14
Camera Preview
4.Surface 149 / 14
Camera Preview
queueBuffer
Buffer를 binder IPC로 Surface Flinger로 보냄.
4.Surface 150 / 14
Camera Preview
dequeueBuffer
FramebufferNativeWindow에게 다음에 그릴 buffer요청
4.Surface 151 / 14
Camera Recording
Renderer
Encoder
1. 현재 사용중인 EGLContext 넘김
EGL14.eglGetCurrentContext()
2. TextureID 넘김
1. prepareEncoder
2. OpenGL draw
3. EGL works
4. drainEncoder
5. End of stream
4.Surface 152 / 14
Camera Recording
Encoder
prepareEncoder #1
1) MediaCodec 설정
2) MediaCodec에서 사용할 surface 생성
3) MediaMuxer 설정
4) EGLContext 생성 (eglCreateContext)
5) EGLSurface 생성 (eglCreateWindowSurface)
6) OpenGL vertex shader, fragment shader
4.Surface 153 / 14
Camera Recording
Encoder
prepareEncoder #2
Encode : MediaCodec Mux : MediaMuxer
4.Surface 154 / 14
Camera Recording
Encoder
prepareEncoder #3
1) 버퍼 메타데이터 정보 생성 (코덱의 출력버퍼와 관련된 내용)
mVideoBufferInfo = new MediaCodec.BufferInfo();
2) 인코딩에 사용될 미디어포맷 생성
- String/Value 쌍으로 구성된 미디어 데이터 정보
MediaFormat videoFormat =
MediaFormat.createVideoFormat(
VIDEO_MIME_TYPE, width, height);
public static final MediaFormat createVideoFormat(String mime, int width, int height) {
MediaFormat format = new MediaFormat();
format.setString(KEY_MIME, mime);
format.setInteger(KEY_WIDTH, width);
format.setInteger(KEY_HEIGHT, height);
return format;
}
4.Surface 155 / 14
Camera Recording
Encoder
prepareEncoder #4
2) 인코딩에 사용될 미디어포맷 생성
- String/Value 쌍으로 구성된 미디어 데이터 정보
MediaFormat.KEY_COLOR_FORMAT
사용할 색공간을 지정함.
COLOR_FormatSurface은 GraphicBuffer의 메타데이터 리퍼런스
videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
4.Surface 156 / 14
Camera Recording
Encoder
prepareEncoder #5
3) 미디어 인코더 생성, 설정
mVideoEncoder =
MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
mVideoEncoder.configure(videoFormat, null, null,
MediaCodec.CONFIGURE_FLAG_ENCODE);
4) Encoder가 사용할 surface 생성
mInputSurface = mVideoEncoder.createInputSurface();
4.Surface 157 / 14
Camera Recording
Encoder
prepareEncoder #6
5) 인코더 시작
mVideoEncoder.start();
6) Muxer 생성
mMuxer = new MediaMuxer(outputFile.toString(),
MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
4.Surface 158 / 14
Camera Recording
Encoder
prepareEncoder #7
7) EGLContext 생성 (eglCreateContext)
mEGLDisplay =
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
EGLContext context =
EGL14.eglCreateContext(mEGLDisplay, config,
sharedContext, attrib3_list, 0);
4.Surface 159 / 14
Camera Recording
Encoder
prepareEncoder #8
7) EGLContext 생성 (eglCreateContext)
mEGLDisplay =
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
EGLContext context =
EGL14.eglCreateContext(mEGLDisplay, config,
sharedContext, attrib3_list, 0);
4.Surface 160 / 14
Camera Recording
Encoder
prepareEncoder #9
7) EGLContext 생성 (eglCreateContext)
mEGLDisplay =
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
EGLContext context =
EGL14.eglCreateContext(mEGLDisplay, config,
sharedContext, attrib3_list, 0);
4.Surface 161 / 14
Camera Recording
4.Surface 162 / 14
Camera Recording
Encoder
prepareEncoder #11
8) EGLSurface 생성 (eglCreateWindowSurface)
EGLSurface eglSurface =
EGL14.eglCreateWindowSurface(mEGLDisplay,
mEGLConfig, surface, surfaceAttribs, 0);
여기서 surface는 mVideoEncoder.createInputSurface()
로 생성되었던 surface를 넘김
4.Surface 163 / 14
Camera Recording
4.Surface 164 / 14
Camera Recording
Encoder
prepareEncoder #13
8) EGLSurface 생성 (eglCreateWindowSurface)
EGLSurface eglSurface =
EGL14.eglCreateWindowSurface(mEGLDisplay,
mEGLConfig, surface, surfaceAttribs, 0);
여기서 surface는 mVideoEncoder.createInputSurface()
로 생성되었던 surface를 넘김
4.Surface 165 / 14
Camera Recording
Encoder
prepareEncoder #14
8) EGLSurface 생성 (eglCreateWindowSurface)
EGLSurface eglSurface =
EGL14.eglCreateWindowSurface(mEGLDisplay,
mEGLConfig, surface, surfaceAttribs, 0);
여기서 surface는 mVideoEncoder.createInputSurface()
로 생성되었던 surface를 넘김
4.Surface 166 / 14
Camera Recording
4.Surface 167 / 14
Camera Recording
Encoder
prepareEncoder #16
9) EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface,
mEGLSurface, mEGLContext)
4.Surface 168 / 14
Camera Recording
Encoder
prepareEncoder #17
9) EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface,
mEGLSurface, mEGLContext)
4.Surface 169 / 14
Camera Recording
Encoder
OpenGL draw #1
1) GLES20.glBindTexture(
GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
2) GLES20.glDrawArrays
4.Surface 170 / 14
Camera Recording
Encoder
EGL works #1
1) EGLExt.eglPresentationTimeANDROID
2) EGL14.eglSwapBuffers
4.Surface 171 / 14
Camera Recording
Encoder
End of stream #1
1) MediaCodec signalEndOfInputStream()
2) MediaCodec stop()
3) MediaCodec release()
4) MediaMuxer stop()
5) MediaMuxer release()
6) EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
7) mSurface.release();
4.Surface 172 / 14
Renderer
Encoder
MediaMuxer
Surface1) 현재 사용중인 EGLContext 전달
EGL14.eglGetCurrentContext()
2) 사용중인 TextureID 전달
MediaCodec
3) MediaCodec.create 4) createInputSurface로 생성
5) MediaMuxer 생성
EGLContext
6) eglCreateContext
EGLSurface
7) eglCreateWindowSurface
Thank you…
이 문서는 나눔글꼴로 작성되었습니다. 설치하기

More Related Content

What's hot

2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑
Sukwoo Lee
 
Choi JiHyun NDC2011
Choi JiHyun  NDC2011Choi JiHyun  NDC2011
Choi JiHyun NDC2011
지현 최
 
Metodologia e Linguagem de Programação - Aula 1
Metodologia e Linguagem de Programação - Aula 1Metodologia e Linguagem de Programação - Aula 1
Metodologia e Linguagem de Programação - Aula 1
Thyago Maia
 
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
Tatsuya Iwama
 
UE4でTranslucencyやUnlitに影を落としたい!
UE4でTranslucencyやUnlitに影を落としたい!UE4でTranslucencyやUnlitに影を落としたい!
UE4でTranslucencyやUnlitに影を落としたい!
com044
 
Java Programming | Java Tutorial For Beginners | Java Training | Edureka
Java Programming | Java Tutorial For Beginners | Java Training | EdurekaJava Programming | Java Tutorial For Beginners | Java Training | Edureka
Java Programming | Java Tutorial For Beginners | Java Training | Edureka
Edureka!
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁
KWANGIL KIM
 
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
YEONG-CHEON YOU
 
Visual studio
Visual studioVisual studio
Visual studio
AvinashChunduri2
 
Hybrid application development
Hybrid application developmentHybrid application development
Hybrid application development
Knoldus Inc.
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근MinGeun Park
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅JP Jung
 
이펙트 쉐이더 2강 - 알파 / 블랜딩
이펙트 쉐이더 2강 - 알파 / 블랜딩이펙트 쉐이더 2강 - 알파 / 블랜딩
이펙트 쉐이더 2강 - 알파 / 블랜딩
Jihoo Oh
 
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile GamesUnreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
Epic Games China
 
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
エピック・ゲームズ・ジャパン Epic Games Japan
 
Effekseer勉強会 機能解説など
Effekseer勉強会 機能解説などEffekseer勉強会 機能解説など
Effekseer勉強会 機能解説など
ueshita
 
2.2 turtle graphics
2.2   turtle graphics2.2   turtle graphics
2.2 turtle graphicsallenbailey
 
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
Daehoon Han
 
Flutter
FlutterFlutter
Flutter
Dave Chao
 
Umg ,이벤트 바인딩, Invaidation Box
Umg ,이벤트 바인딩, Invaidation BoxUmg ,이벤트 바인딩, Invaidation Box
Umg ,이벤트 바인딩, Invaidation Box
대영 노
 

What's hot (20)

2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑2018.12.22 깊이 버퍼 그림자 매핑
2018.12.22 깊이 버퍼 그림자 매핑
 
Choi JiHyun NDC2011
Choi JiHyun  NDC2011Choi JiHyun  NDC2011
Choi JiHyun NDC2011
 
Metodologia e Linguagem de Programação - Aula 1
Metodologia e Linguagem de Programação - Aula 1Metodologia e Linguagem de Programação - Aula 1
Metodologia e Linguagem de Programação - Aula 1
 
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
ゲームエンジンの文法【UE4】No.005 Gameplay Frameworkの理解
 
UE4でTranslucencyやUnlitに影を落としたい!
UE4でTranslucencyやUnlitに影を落としたい!UE4でTranslucencyやUnlitに影を落としたい!
UE4でTranslucencyやUnlitに影を落としたい!
 
Java Programming | Java Tutorial For Beginners | Java Training | Edureka
Java Programming | Java Tutorial For Beginners | Java Training | EdurekaJava Programming | Java Tutorial For Beginners | Java Training | Edureka
Java Programming | Java Tutorial For Beginners | Java Training | Edureka
 
190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁190119 unreal engine c++ 입문 및 팁
190119 unreal engine c++ 입문 및 팁
 
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
프레임레이트 향상을 위한 공간분할 및 오브젝트 컬링 기법
 
Visual studio
Visual studioVisual studio
Visual studio
 
Hybrid application development
Hybrid application developmentHybrid application development
Hybrid application development
 
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
[Ndc12] 누구나 알기쉬운 hdr과 톤맵핑 박민근
 
5강 알파와알파소팅
5강 알파와알파소팅5강 알파와알파소팅
5강 알파와알파소팅
 
이펙트 쉐이더 2강 - 알파 / 블랜딩
이펙트 쉐이더 2강 - 알파 / 블랜딩이펙트 쉐이더 2강 - 알파 / 블랜딩
이펙트 쉐이더 2강 - 알파 / 블랜딩
 
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile GamesUnreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
Unreal Open Day 2017 UE4 for Mobile: The Future of High Quality Mobile Games
 
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
初心者向け UE4 映像制作での シーケンサー と Movie Render Queue の使い方
 
Effekseer勉強会 機能解説など
Effekseer勉強会 機能解説などEffekseer勉強会 機能解説など
Effekseer勉強会 機能解説など
 
2.2 turtle graphics
2.2   turtle graphics2.2   turtle graphics
2.2 turtle graphics
 
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
[IGC2017] 오버턴VR 개발기 -1인 개발 3년차 리포트
 
Flutter
FlutterFlutter
Flutter
 
Umg ,이벤트 바인딩, Invaidation Box
Umg ,이벤트 바인딩, Invaidation BoxUmg ,이벤트 바인딩, Invaidation Box
Umg ,이벤트 바인딩, Invaidation Box
 

Similar to Android camera basics

Uncharted4 part1
Uncharted4 part1Uncharted4 part1
Uncharted4 part1
Yong-jun Choi
 
9강 camera advanced light2
9강 camera advanced light29강 camera advanced light2
9강 camera advanced light2JP Jung
 
Devtree lightmapping unity5_2_1stday
Devtree lightmapping unity5_2_1stdayDevtree lightmapping unity5_2_1stday
Devtree lightmapping unity5_2_1stday
SangYun Yi
 
Gamma라고 들어봤니
Gamma라고 들어봤니Gamma라고 들어봤니
Gamma라고 들어봤니
minwoo lee
 
Game Visual Art Technologies
Game Visual Art TechnologiesGame Visual Art Technologies
Game Visual Art Technologies
SangYun Yi
 
Android mediacodec
Android mediacodecAndroid mediacodec
Android mediacodec
Taehwan kwon
 
Ndc11 이창희_hdr
Ndc11 이창희_hdrNdc11 이창희_hdr
Ndc11 이창희_hdr
changehee lee
 
게임 프로그래밍 패턴 8장
게임 프로그래밍 패턴 8장게임 프로그래밍 패턴 8장
게임 프로그래밍 패턴 8장
진화 손
 
동물 홍채인식부터 서버까지
동물 홍채인식부터 서버까지동물 홍채인식부터 서버까지
동물 홍채인식부터 서버까지
진성 정
 
Animal iris recognition
Animal iris recognitionAnimal iris recognition
Animal iris recognition
진성 정
 
06_HDR 소개
06_HDR 소개06_HDR 소개
06_HDR 소개noerror
 
컴퓨터 그래픽스 2015-2019년 출석수업대체시험
컴퓨터 그래픽스 2015-2019년 출석수업대체시험컴퓨터 그래픽스 2015-2019년 출석수업대체시험
컴퓨터 그래픽스 2015-2019년 출석수업대체시험
Lee Sang-Ho
 
About LED Studio Lighting System
About LED Studio Lighting SystemAbout LED Studio Lighting System
About LED Studio Lighting System
jaihyun Jung
 
Display color와 Digital texture format의 이해
Display color와 Digital texture format의 이해Display color와 Digital texture format의 이해
Display color와 Digital texture format의 이해
SangYun Yi
 
[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑
MoonLightMS
 
Devtree illu
Devtree illuDevtree illu
Devtree illu
SangYun Yi
 
입문 Visual SLAM - 5장 카메라와 이미지
입문 Visual SLAM - 5장 카메라와 이미지입문 Visual SLAM - 5장 카메라와 이미지
입문 Visual SLAM - 5장 카메라와 이미지
jdo
 
Unite2015 probelight(150417)
Unite2015 probelight(150417)Unite2015 probelight(150417)
Unite2015 probelight(150417)
SangYun Yi
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012devCAT Studio, NEXON
 

Similar to Android camera basics (20)

Uncharted4 part1
Uncharted4 part1Uncharted4 part1
Uncharted4 part1
 
9강 camera advanced light2
9강 camera advanced light29강 camera advanced light2
9강 camera advanced light2
 
Devtree lightmapping unity5_2_1stday
Devtree lightmapping unity5_2_1stdayDevtree lightmapping unity5_2_1stday
Devtree lightmapping unity5_2_1stday
 
Gamma라고 들어봤니
Gamma라고 들어봤니Gamma라고 들어봤니
Gamma라고 들어봤니
 
Game Visual Art Technologies
Game Visual Art TechnologiesGame Visual Art Technologies
Game Visual Art Technologies
 
Android mediacodec
Android mediacodecAndroid mediacodec
Android mediacodec
 
Ndc11 이창희_hdr
Ndc11 이창희_hdrNdc11 이창희_hdr
Ndc11 이창희_hdr
 
게임 프로그래밍 패턴 8장
게임 프로그래밍 패턴 8장게임 프로그래밍 패턴 8장
게임 프로그래밍 패턴 8장
 
동물 홍채인식부터 서버까지
동물 홍채인식부터 서버까지동물 홍채인식부터 서버까지
동물 홍채인식부터 서버까지
 
Animal iris recognition
Animal iris recognitionAnimal iris recognition
Animal iris recognition
 
06_HDR 소개
06_HDR 소개06_HDR 소개
06_HDR 소개
 
컴퓨터 그래픽스 2015-2019년 출석수업대체시험
컴퓨터 그래픽스 2015-2019년 출석수업대체시험컴퓨터 그래픽스 2015-2019년 출석수업대체시험
컴퓨터 그래픽스 2015-2019년 출석수업대체시험
 
Color Control
Color ControlColor Control
Color Control
 
About LED Studio Lighting System
About LED Studio Lighting SystemAbout LED Studio Lighting System
About LED Studio Lighting System
 
Display color와 Digital texture format의 이해
Display color와 Digital texture format의 이해Display color와 Digital texture format의 이해
Display color와 Digital texture format의 이해
 
[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑[0918 박민수] 범프 매핑
[0918 박민수] 범프 매핑
 
Devtree illu
Devtree illuDevtree illu
Devtree illu
 
입문 Visual SLAM - 5장 카메라와 이미지
입문 Visual SLAM - 5장 카메라와 이미지입문 Visual SLAM - 5장 카메라와 이미지
입문 Visual SLAM - 5장 카메라와 이미지
 
Unite2015 probelight(150417)
Unite2015 probelight(150417)Unite2015 probelight(150417)
Unite2015 probelight(150417)
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 

More from Choulhyouc Lee

Baidu push 연동하기
Baidu push 연동하기Baidu push 연동하기
Baidu push 연동하기
Choulhyouc Lee
 
알고리듬? 알고리즘?
알고리듬? 알고리즘?알고리듬? 알고리즘?
알고리듬? 알고리즘?
Choulhyouc Lee
 
Network 초보자를 위한 Netty
Network 초보자를 위한 NettyNetwork 초보자를 위한 Netty
Network 초보자를 위한 Netty
Choulhyouc Lee
 
2011~2012 소프트웨어 관련도서 추천 리뷰 모음
2011~2012 소프트웨어 관련도서 추천 리뷰 모음2011~2012 소프트웨어 관련도서 추천 리뷰 모음
2011~2012 소프트웨어 관련도서 추천 리뷰 모음
Choulhyouc Lee
 
디자이너를위한Git #1/2
디자이너를위한Git #1/2디자이너를위한Git #1/2
디자이너를위한Git #1/2
Choulhyouc Lee
 
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
Choulhyouc Lee
 

More from Choulhyouc Lee (6)

Baidu push 연동하기
Baidu push 연동하기Baidu push 연동하기
Baidu push 연동하기
 
알고리듬? 알고리즘?
알고리듬? 알고리즘?알고리듬? 알고리즘?
알고리듬? 알고리즘?
 
Network 초보자를 위한 Netty
Network 초보자를 위한 NettyNetwork 초보자를 위한 Netty
Network 초보자를 위한 Netty
 
2011~2012 소프트웨어 관련도서 추천 리뷰 모음
2011~2012 소프트웨어 관련도서 추천 리뷰 모음2011~2012 소프트웨어 관련도서 추천 리뷰 모음
2011~2012 소프트웨어 관련도서 추천 리뷰 모음
 
디자이너를위한Git #1/2
디자이너를위한Git #1/2디자이너를위한Git #1/2
디자이너를위한Git #1/2
 
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
가장 쉬운 안드로이드 앱 개발 방법 앱인벤터
 

Android camera basics

  • 1. Android Camrea Basics.. 2015.10 이철혁 MSQL@NAVER.COM 이 문서는 나눔글꼴로 작성되었습니다. 설치하기
  • 2. 1. Camera 2. Color Space 3. Camera API 4. Surface 5. Texture 6. OpenGL 7. Case Study 목차 참고 : 이 PT를 바탕으로 강의를 통해 설명을 하기 위해 만들어 졌 던 자료이기에 PT만으로 이해가 안가는 부분이 있을 수 있음. 참고한 소스는 아래와 같다. https://android.googlesource.com/ https://github.com/google/grafika https://github.com/CyberAgent/android-gpuimage
  • 3. 1.Camera 1. Camera 3 / 14 Android 에서 가장 인기 있는 앱, 서비스는 카메라 기반 서비스들이 많다. 카메라 앱은 멀티미디어 서비스의 결정체이기도 기본적으로 알아야 할 것들이 많다. 카메라 앱을 만들기 위한 기초에 대해서 간략히 정리하는 것이 이 PT의 목표이다. Android에서는 5.0 Lollipop 부터 기존의 Camera API를 대체할 수 있는 강력한 Camera2 API를 제공하고 있 지만, 다양한 버전을 모두 서비스 해야하는 환경에서 Camera2 API는 아직 전폭적으로 사용되고 있지 못하다. 심지어 5.0, 5.1 일부 단말기에서도 제대로 지원을 못하는 상황이 있어 제조사, 단말기, Android 버전에 따른 파 편화 관리가 어렵기에 당분간은 Camera API를 그대로 사용할 것 같다. 따라서 현재 모든 내용은 Camera API를 기반으로 설명된다.
  • 4. 1.Camera 4 / 14 Android system architecture 간단히 Java API 로 제공되는 android.hardware.Camera API를 사용하면, 물리적인 카메라가 어떤 단계를 거쳐 오는지 생각 못할 수 있는데, Android system architecture를 보면 정말 많은 단계를 통해 개발자에게 Camera의 정보가 오는 것을 확인할 수 있다. 출처 : https://developer.android.com/guide/platform/in dex.html?hl=ko
  • 5. 1.Camera 5 / 14 Camera architecture Camera 만 다시 한번 보면 좀 더 자세히 확인할 수 있다. 출처 : https://source.android.com/devices/camera/
  • 6. 1.Camera 6 / 14 Kernel driver 실제 카메라 하드웨어와 HAL과 상호 작용을 하는 단계로, 카메라와 드라이버는 YV12, NV21 이미지 형식을 지원해야만 카메라의 미리보기와 비디오 녹화가 가능하다. YV12, NV21에 대해서는 뒤의 색공간에서 다시 한번 소개한다. HAL 실제 카메라 하드웨어를 제어하는 Kernel driver를 카메라 서비스가 직접 다루지 않고 중간 층인 HAL( Hardware Abstraction Layer )을 통해 접근하도록 정의된 표준 인터페이스 이다. 출처 : https://source.android.com/devices/camera/
  • 7. 1.Camera 7 / 14 Camera service 안드로이드 프레임워크 frameworks/av/services/camera/libcameraservice/CameraService.cpp 에 위치하 여 HAL과 통신하는 실제 코드이다. 출처 : https://source.android.com/devices/camera/
  • 8. 1.Camera 8 / 14 Binder IPC proxies frameworks/av/camera 에 위치한 3가지 바인더 클래스가 존재한다. - ICameraService - ICamera - ICameraClient 출처 : https://source.android.com/devices/camera/
  • 9. 1.Camera 9 / 14 Native framework, JNI, Application framework frameworks/av/camera/Camera.cpp는 우리가 어플리케이션에서 사용하는 android.hardware.Camera API에 대응되는 native code이다. android.hardware.Camera API에서는 JIN를 통해 Camera Service는 IPC binder proxies를 이용하여 접근 한다. 출처 : https://source.android.com/devices/camera/
  • 10. 1.Camera 10 / 14 Camera Pipeline Raw Bayer Input 은 Camera Sensor를 통해 전달된 이미지를 의미한다. 현재 대부분의 폰에서 사용되는 Camera sensor는 한 개의 소자가 모든 색을 받아들이 는 구조가 아니라 R,G,B 각각의 색에 반응하는 소자들 을 조합하여 사용한다. 따라서 우리가 보는 RGB이미지 로 보기 위한 변환이 필요하다. 출처 : https://source.android.com/devices/camera/came ra3_requests_hal http://www.cis.upenn.edu/~danielkh/files/2013_ 2014_demosaicing/2013_RTF_demosaicing_1.pdf
  • 11. 1.Camera 11 / 14 Camera Pipeline Android 에서는 Camera Sensor의 이미지를 그대로 전달하는게 아니라, 생각보다 많은 보정 단계를 거친후 에 전달된다. 기본적으로 사용되는 3A Algorithms 은 아래의 3가지 의 앞 글자를 따온 것이다. - Auto-focus - Auto-exposure - Auto-whitebalance
  • 12. 1.Camera 12 / 14 Hot Pixel Correction Hot Pixel은 모든 것이 검은 환경에서도 발생하는 흰색 의 픽셀을 의미한다. 이는 카메라 센서에서 노이즈와 과 부하등으로 발생하기도 하기에 제일 처음 처리하는 이 미지 단계가 이를 보정하는 것이다. 주변 픽셀들등의 정보를 이용해 보간법(interpolation) 으로 수정한다.
  • 13. 1.Camera 13 / 14 Demosaic 앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이 미지로 복원하는 과정을 의미한다.
  • 14. 1.Camera 14 / 14 Demosaic 앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이 미지로 복원하는 과정을 의미한다. Bayer filter samples Red Green Blue Reconstructed
  • 15. 1.Camera 15 / 14 Demosaic 앞에서 Raw Bayer Input을 우리가 볼 수 있는 RGB 이 미지로 복원하는 과정을 의미한다.
  • 16. 1.Camera 16 / 14 Noise Reduction DSLR과 같은 전문 카메라와 달리 카메라 센서의 크기가 제한적이고, 렌즈의 밝기도 어두운 경우가 많아 저조도 환경(어두운 환경), 확대한 환경 등에서 품질이 떨어지 기에 이를 보완하기 위한 방법이다.
  • 17. 1.Camera 17 / 14 Shading Correction 잘못된 그림자를 보정하는 부분이다.
  • 18. 1.Camera 18 / 14 Edge Enhancement 이미지의 엣지부분의 대비(contrast)를 높혀서 선명하 게 보이도록 하는 작업이다.
  • 19. 1.Camera 19 / 14 Output Camera에서 제공하는 Output은 3가지 이다. - RAW - JPEG - YUV
  • 20. 1.Camera 20 / 14 Raw Camera2 API 부터 지원한다. Raw 이미지는 앞서 거치는 Image Processing을 거치 지 않은 Camera Sensor의 결과물이다. 따라서 전문적으로 다른 Image Processing을 거치면 다른 JPEG을 만들어 낼 수 있다. 그래서 주로 전문가들 이 사용한다.
  • 21. 1.Camera 21 / 14 JPEG Camera API의 takePicture 메서드를 이용하면 받을 수 있는 결과물로 폰의 Camera가 지원하는 최고의 해상도, 퀄리티의 이미지를 받아 볼 수 있다. 해당 포맷은 Preview로 제공되지 않고, takePicture 메 서드로만 받을 수 있다.
  • 22. 1.Camera 22 / 14 YUV Camera API의 startPreview를 한 이후에 제공되는 preview(실시간의 Camera Sensor에 전달되는 이미지 들…)는 해당 포맷으로 제공된다. JPEG에 비해 해상도가 떨어진다. 대부분의 폰에서 폰의 Display 해상도 ( QHD, FHD, HD 정도)의 해상도 이하로 제공된다.
  • 23. 2. Color Space 2. Color Space 23 / 14 색, 색 공간(色空間, color space) 색 공간에 대한 이해는 필수이다. 동영상 쪽을 전혀 해보지 않았으면, 색공간 == RGB 인줄 알지만, 카메라에서 주로 쓰이는 색공간은 RGB가 아니다. 따라서 혼동이 많이 발생하기에, 색공간에 대한 이해를 정확히 해야 한다.
  • 24. 2.Color Space 24 / 14 색 (Color) 사전적 정의 : 가시광선의 명암과 분광 조성에 대한 시감각 또는 색감각, 색감각을 일으키는 빛 또는 색자극, 색자극을 일으키는 물체의 특성. 사람은 약 107,000가지의 색을 구별할 수 있음.
  • 25. 2.Color Space 25 / 14 색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma) 색상(hue) 색깔의 질로도 표현하는데, 우리가 쉽게 색이라고 하면 생각하는 가장 중요한 색의 성질이다. 보면 안다.
  • 26. 2.Color Space 26 / 14 색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma) 명도(lightness) 눈이 느끼는 밝기의 차이. 먼셀표색계에서는 흰색을 명도 10, 검정색을 0으로 하고 그 사이의 단계를 10단계 등분하여 번호를 매겨 사용한다. 같은 단계의 명도라 하더라도 색상에 따라 더 밝게, 어둡게 보일 수 있다.
  • 27. 2.Color Space 27 / 14 색의 3속성 : 색상(hue), 명도(lightness), 채도(chroma) 채도(Chroma, Saturation) 색이 보다 선명할수록 채도가 높다고 말하며 회색이나 흰색 또는 검정과 같은 무채색에 가까울수록 채도가 낮다고 말한다. 채도가 높은 색을 말할 때는 흔히 '짙다'고 표현하고, 반대로 채도가 낮은 색을 말할 때는 흔히 '흐리다'는 표현을 사용한다. 예를 들어 짙은 노랑, 흐린 노랑과 같이 표현할 수 있다.
  • 28. 2.Color Space 28 / 14 Color space(색공간) 색 공간(色空間, color space)은 색 표시계(color system)를 3차원으로 표현한 공간 개념이라고 사전적으로 정의한다. 3차원인 이유는? 앞에서 설명한 색의 3가지 속성인 색상(hue), 명도(lightness), 채도(chroma)을 각각의 축으로 3차원 공간으로 표현한 것이다. 미술시간에 많이 봤을 먼셀 색입체를 보면 이해가 쉽다.
  • 29. 2.Color Space 29 / 14 RGB RGB 색 공간은 색을 혼합하면 명도가 올라가는 가산 혼합 방식으로 색을 표현한다. ( 빛은 더할수록 명도가 올라가서 모든 색을 다 섞으면 흰색이 된다는 것을 초등학교에서 배웠을 것이다. ) RGB 가산혼합의 삼원색은 빨강(Red), 녹색(Green), 파랑(Blue)을 뜻한다. RGBA은 RGB와 동일하며, 알파(Alpha)라는 투명도(투과도)를 추가한 것. RGB 색 공간은 삼원색에 해당하는 세 가지 채널의 밝기를 기준으로 색을 지정한다. RGB 색 공간은 웹 색상 표현의 기본 원리이다.
  • 30. 2.Color Space 30 / 14 CMYK CMYK 색 공간은 인쇄과정에서 쓰이는 감산 혼합 방식으로, (실제 미술시간에 빛과 달리 물감을 섞으면 섞을수록 검정색이 되는 것을 경험해봤을 것이다. ) 흰 바탕에 네 가지 잉크의 조합으로 색을 나타내는 것을 말한다. 색을 혼합하면 명도가 낮아지기에 감산 혼합이라고 한다. CMYK는 인쇄에 쓰이는 4가지 색은 옥색(Cyan), 자청색(Magenta), 노랑(Yellow), 검정(Black)을 뜻한다.
  • 31. 2.Color Space 31 / 14 HSV HSV 색 공간은 색상(Hue), 채도(Saturation), 명도(value)를 기준으로 색을 구성하는 방식이다. 감산 혼합이나 가산 혼합보다 색상의 지정이 직관적이기 때문에 시각 예술에서 자주 쓰인다.
  • 32. 2.Color Space 32 / 14 Color space (색 공간) 모든 색 공간이 표현하는 색이 같은데, 방법이 다른게 아니라 색 공간에 따라 표현하는 색의 범위가 다르다. 이 점을 반드시 이해해야 한다. ( 아래의 면적이 클수록 표현할 수 있는 색이 많은 색 공간이다. )
  • 33. 2.Color Space 33 / 14 YUV (=YCbCr) 흑백TV시절의 방송 인프라를 사용하여, 한 방송으로 컬러TV와 흑백TV를 다 볼 수 있도록 고안되었다. 흑백TV에서 이용되던 정보에 부수적으로 컬러정보를 추가하여 사용하여, 인프라의 큰 교체없이 컬러TV를 볼 수 있게 되었다.
  • 34. 2.Color Space 34 / 14 YUV (=YCbCr) 실제 적용 예를 보면, 원래 컬러인 이미지가 흑백인 Y와 추가적인 컬러 정보 UV로 구성되어 있다. Original Y’ U V
  • 35. 2.Color Space 35 / 14 YUV (=YCbCr) 자연상에서 가장 많은 색인 Green에 더 많은 공간을 두어서 모든 색이 동일한 범위를 갖는 것에 비해 효율적인 구조를 만듦. UV U : Ranges from Red to Yellow V : Ranges from Blue to Yellow
  • 36. 2.Color Space 36 / 14 YUV (=YCbCr) YUV는 밝기(Luminance)인 Y성분과 색상(Chrominance)인 U(Cb)와 V(Cr) 성분으로 구성하여 픽셀을 표현하는 방식. 일반적인 RGB 방식에 비하여 작은 용량(대역폭)으로 전송이 가능 1 pixel 표시 크기 비교 ARGB = 32bits ( 4bytes ) YUV411 = Y : 8 bit + U : 2 bit + V : 2 bit = 12bits 극단적으로 ARGB를 사용해 1 pixel을 32bits 로 전송하는 것을 12bits로 전송할 수 있으니 62.5%의 적어 지 금까지도 많은 곳에서 사용 되는 것이다.
  • 37. 2.Color Space 37 / 14 YUV (=YCbCr) 이렇게 극단적으로 적은 정보로 전송할 수 있는 이유는? 흑백의 명암을 나타내는 Y정보에 데이터의 절반을 사용하는 이유는 사람의 눈은 밝기 변화를 느끼는 간상세포 는 9천만 개 이상 존재하는데 비하여 색상을 인식하는 원추세포는 약 600만 개 정도에 불과하기 때문이다. 따라서, 사람의 시각은 밝기의 변화에 비하여 색상의 변화에는 둔감하다는 특성을 보이게 된다. 이에 따라 많은 영상 시스템은 밝기 정보와 색상의 정보를 분리하여 별도로 부호화 하도록 하여 필요에 따라 압 축 효율을 높인다. 원추세포는 3가지 L 원추세포(ρ세포) : 빨간색 M 원추세포(Г세포) : 청녹색과 노란색 S 원추세포(β세포) : 파란색 각각 원추세포의 비율이 다르다. 빨강 40 : 녹색 20 : 파랑 1
  • 38. 2.Color Space 38 / 14 YUV (=YCbCr) YUV는 YUV422, YUV420, YUV411 등의 포맷이 있는데, 이러한 표현은 아래와 같이 각 구성값의 비트 할당수에서 비롯한다. 즉 YUV422은 Y:U:V = 4:2:2 이다. YUV는 RGB 처럼 한 개의 픽셀 개념으로 이해하면 안됨!
  • 39. 2.Color Space 39 / 14 YUV (=YCbCr) YUV는 한 개의 픽셀 개념으로 이해하면 안되며, 기존 TV의 주사방식을 생각해보면 이해하기 쉬움 기존 TV 주사방식: 비월 주사 방식(Interlace scanning) 하나의 영상을 홀수와 짝수 가로줄로 나뉜 것을 번갈아가며 표시하는 영상의 표시 방식이다.
  • 40. 2.Color Space 40 / 14 YUV (=YCbCr) U V Y
  • 41. 2.Color Space 41 / 14 YUV (=YCbCr) 각 구성값의 비트 할당수로도 구분되지만, YUV를 어떤 순서로 배열해서 사용하는지에 따라도 구분된다. YUV422 : YUV를 아래와 같은 순서로 사용한다. YUV420 : 구성요소 별로 모아 놓았다.
  • 42. 2.Color Space 42 / 14 YUV (=YCbCr) YUV420 : 구성요소 별로 모아 놓았다.
  • 43. 2.Color Space 43 / 14 YUV (=YCbCr) Single Frame YUV420 : 16 Bits per pixel IMC1 IMC3
  • 44. 2.Color Space 44 / 14 YUV (=YCbCr) Single Frame YUV420 : 12 Bits per pixel IMC2 IMC4
  • 45. 2.Color Space 45 / 14 YUV (=YCbCr) Single Frame YUV420 : 12 Bits per pixel YV12 NV12
  • 46. 2.Color Space 46 / 14 NV12/NV21 NV12 : YUV420 과 비슷한 개념이나, 표현 방식이 다름 For 1 NV12 pixel: YYYYYYYY UVUV For a 2-pixel NV12 frame: YYYYYYYYYYYYYYYY UVUVUVUV For a 50-pixel NV12 frame: Y*8*50 (UV)*2*50 For a n-pixel NV12 frame: Y*8*n (UV)*2*n NV21 : NV12와 비슷하나 UV의 순서가 바뀌어 VU로 출력됨
  • 47. 2.Color Space 47 / 14 RGB <-> YUV 변환 문제는 우리가 주로 쓰는 색공간은 결국 RGB이고, 픽셀단위로 조작이 필요하거나 후처리를 위해 변환이 필요한 경우가 발생한다. RGB <-> YUV는 색공간이 다르기에 정확히 1대1 대응이 되지 않는다. 수많은 방법들이 있으나, 아래와 같은 수학식으로도 변환이 될 수 있다. From RGB to YUV Y = 0.299R + 0.587G + 0.114B U = 0.492 (B-Y) V = 0.877 (R-Y) It can also be represented as: Y = 0.299R + 0.587G + 0.114B U = -0.147R - 0.289G + 0.436B V = 0.615R - 0.515G - 0.100B From YUV to RGB R = Y + 1.140V G = Y - 0.395U - 0.581V B = Y + 2.032U
  • 48. 2.Color Space 48 / 14 RGB <-> YUV 변환 이를 코드로 보면 아래와 같다. 이 코드는 실제로 사용되면 안된다. (엄밀히 말하면, YUV-> RGB 변환이 CPU에서 실행되면 안된다.) RGB와 YUV를 변환하는 것이 얼마나 큰 비용의 연산인지 감을 잡기위해 작성한 코드이다. void YUVfromRGB(double& Y, double& U, double& V, const double R, const double G, const double B) { Y = 0.257 * R + 0.504 * G + 0.098 * B + 16; U = -0.148 * R - 0.291 * G + 0.439 * B + 128; V = 0.439 * R - 0.368 * G - 0.071 * B + 128; } void RGBfromYUV(double& R, double& G, double& B, double Y, double U, double V) { Y -= 16; U -= 128; V -= 128; R = 1.164 * Y + 1.596 * V; G = 1.164 * Y - 0.392 * U - 0.813 * V; B = 1.164 * Y + 2.017 * U; }
  • 49. 2.Color Space 49 / 14 색공간을 이용한 코드 RGB, YUV는 필수적으로 사용되는 건 알겠는데, 다른 색공간이 필요한 경우가 있을까? 앱에 기능 중 ColorPicker에서 색을 선택 후 수직이나 수평으로 드래그하면 명도와 채도를 변화하는 코드가 있다. 이를 RGB에서 구현하고자 하면 상당히 복잡하다. 가장 빠르고 단순하게 해결하는 방법은 다른 색공간을 이용하는 것이다. 앞에서 말했듯, 물론 색공간을 변화하면 일부 색이 손실되지만, 여기서는 큰 문제가 아니었기에 사용할 수 있는 방법이다.
  • 50. 2.Color Space 50 / 14 색공간을 이용한 코드 HSV를 이용하면 쉽게 채도와 명도를 바꿀 수 있다. 이를 이용해 명도, 채도는 HSV공간안에서 변경 후에 최종 선택이 완료되면 다시 RGB로 변경해 최종 선택된 색을 넘기게 된다. // 채도 ( width : Saturation : [1]) // 명도 ( height : bright : [2]) int red = Color.red(pixelColor); int blue = Color.blue(pixelColor); int green = Color.green(pixelColor); if (mIsTouchDown) { red = Color.red(mPreviousColor); blue = Color.blue(mPreviousColor); green = Color.green(mPreviousColor); } float[] colorHSV = new float[3]; Color.RGBToHSV(red, green, blue, colorHSV); float saturation = (float) rawY / mHeightPixels; float bright = (float) rawX / mWidthPixels; colorHSV[1] = 2.0f * saturation; colorHSV[2] = 2.0f - 2.0f * bright; if (mOnColorPickedListener != null) { mOnColorPickedListener.onColorPicked(Color.HSVToColor(colorHSV)); }
  • 51. 3.Camera API 3. Camera API 51 / 14 Camera API 는 API level 21부터 deprecated 되었다. 하지만 앞서 말했듯 다양한 버전을 모두 서비스하는 환경에서 우리는 Camera API를 사용해야 한다.
  • 52. 3.Camera API 52 / 14 Camera Class가 하는 일 1) Set image capture settings : 이미지를 가져오기 위한 설정을 함 ( LED Flash 키는 것도 포함 ) 2) Start/Stop preview : 미리보기(preview)를 켜고 끔 3) Snap pictures : 실제 사진을 찍음 4) Retrieve frames for encoding for video : 비디오 녹화를 위해 동영상을 제공함
  • 53. 3.Camera API 53 / 14 권한 추가 필요
  • 54. 3.Camera API 54 / 14 사진을 찍기 위한 단계 1. Obtain an instance of Camera from open(int). : 카메라 인스턴스를 얻기 위해 open 메소드를 이용한다. 매개변수인 int는 카메라 id로 보통의 경우 전, 후면 카메라이다. 2. Get existing (default) settings with getParameters(). : getParameters() 메소드를 이용해 현재 카메라의 세팅을 가져온다. 3. If necessary, modify the returned Camera.Parameters object and call setParameters(Camera.Parameters). : 카메라의 파라미터, 세팅을 변경이 필요하면 setParameters()를 이용해 세팅한다. 4. If desired, call setDisplayOrientation(int). : 전달되는 영상의 출력 방향을 결정한다. 5. Important: Pass a fully initialized SurfaceHolder to setPreviewDisplay(SurfaceHolder). Without a surface, the camera will be unable to start the preview. : setPreviewDisplay를 통해 카메라 preview가 보여질 surfaceholder가 초기화 되어 전달되어야 한다. (뒤에 상세히 설명) 6. Important: Call startPreview() to start updating the preview surface. Preview must be started before you can take a picture. : startPreview()를 통해 preview를 시작하는데, 사진을 찍기전에 startPreview()는 무조건 실행되어야 한다.
  • 55. 3.Camera API 55 / 14 사진을 찍기 위한 단계 7. When you want, call takePicture (Camera.ShutterCallback, Camera.PictureCallback) to capture a photo. Wait for the callbacks to provide the actual image data. : 사진을 찍을때 takePicture메소드를 실행하는데, Camera.PictureCallback을 통해 실제 이미지가 전달된다. (실제 사용할일은 없다. 우리는 실제로 사진을 찍는 것이 아니라 Preview만을 이용하기 때문 ) 8. After taking a picture, preview display will have stopped. To take more photos, call startPreview() again first. : 사진을 찍은 후에는 preview가 멈추기 때문에 다시 사진을 찍기 위해서는 startPreview()를 다시 실행해야만 한다. ( takePicture를 사용하지 않기에 발생하지 않는 단계 ) 9. Call stopPreview() to stop updating the preview surface. : stopPreview()는 실행하면 더 이상 preview를 갱신하지 않는다. 10. Important: Call release() to release the camera for use by other applications. Applications should release the camera immediately in onPause() (and re-open() it in onResume()). : Camera 객체의 Life Cycle관리는 매우 중요하다. Camera 객체는 시스템에서 하나밖에 사용하지 못하게 되어 있으므로, 앱의 Life Cycle에 맞춰서 release()를 해주지 않으면, 다른 앱에서 카메라를 사용할 수 없게 된다. onPause()에서는 release()를 onResume()에서 open()을 하도록 작성해야 한다.
  • 56. 3.Camera API 56 / 14 Android camera preview workflow 앞서 살펴본 단계를 생각해보면, Camera 클래스의 open 메서드를 호출한다고 하면, 하드웨어 레벨까지 전달되고 다시 Application API 레벨까지 올라오는 것을 그릴 수 있어야 한다. Android Application Android Framework Android Runtime(JNI) Client Camera Server CameraService Hardware CameraHardwareStu b Open Camera open native_setup connect connect HAL_openCameraHardWare CameraHardWareStub instanceCamera instance Binder(IPC)
  • 57. 3.Camera API 57 / 14 Android camera preview workflow 다른 메서드 들도 같다고 생각하면 된다..
  • 58. 3.Camera API 58 / 14 CameraManager.java
  • 59. 3.Camera API 59 / 14 CameraTextureView.java
  • 60. 3.Camera API 60 / 14 Camera.CameraInfo
  • 61. 3.Camera API 61 / 14 Camera.CameraInfo
  • 62. 3.Camera API 62 / 14 Camera.CameraInfo
  • 63. 3.Camera API 63 / 14 Camera.CameraInfo
  • 64. 3.Camera API 64 / 14 setDisplayOrientation
  • 65. 3.Camera API 65 / 14 setDisplayOrientation 주의 : orientaion은 setParameter 이후 제일 마지막에 있어야 함.
  • 66. 3.Camera API 66 / 14 setPreviewTexture
  • 67. 3.Camera API 67 / 14 startPreview
  • 68. 3.Camera API 68 / 14 startPreviewDisplay
  • 69. 3.Camera API 69 / 14 startPreview()
  • 70. 3.Camera API 70 / 14 startPreview()
  • 71. 3.Camera API 71 / 14 Camera.PreviewCallback
  • 72. 3.Camera API 72 / 14 Camera.PreviewCallback
  • 73. 3.Camera API 73 / 14 Camera.PreviewCallback
  • 74. 3.Camera API 74 / 14 previewCallbackWithBuffer 사용 예
  • 75. 3.Camera API 75 / 14 previewCallbackWithBuffer 사용 예
  • 76. 3.Camera API 76 / 14 GPU Image 사용 예
  • 77. 3.Camera API 77 / 14 GPU Image 사용 예
  • 78. 3.Camera API 78 / 14 takePicture 고화질의 JPEG을 받아야 할 경우만 사용함.
  • 79. 3.Camera API 79 / 14 stopPreview
  • 80. 3.Camera API 80 / 14 release
  • 81. 4.Surface 4. Surface 81 / 14 Surface, SurfaceHolder, SurfaceView, GLSurfaceView, SurfaceTexture, Surface Flinger, OpenGL, EGL… Surface와 관련된 내용이 이것 저것 많이 나온다. 혼돈하지 말자. 의외로 간단하다. Surface는 raw buffer이고, SurfaceHolder는 말 그대로 Surface를 얻을 수 있게 해준다. SurfaceView는 View계층 구조가 복잡해 빠른 반응속도가 필요한 게임, 동영상에서 쓰기 위해 만들어진 고속도 로(펀칭홀)라고 생각하자. 나머지는 이 후에 설명될 것이다.
  • 82. 4.Surface 82 / 14 Surface
  • 83. 4.Surface 83 / 14 SurfaceHolder
  • 84. 4.Surface 84 / 14 서피스 플링어 서비스 서피스 플링어 서비스는 여러 개의 Surface를 하나로 만들기 위해 서피스의 개념에 Z-order를 추가한 레이어개념으로 서피스를 관리 가장 큰 Z-order 값을 가장 먼저 그림
  • 85. 4.Surface 85 / 14 EGL 서피스 플링어 서비스가 디스플레이 초기화 과정에서 EGL을 사용하고, 합성과정에서 OpenGL ES API를 사용. (OpenGL ES는 Embedded Systems의 약어로 임베디드에서 쓰이기 위한 OpenGL API 의 서브셋이다.) 뒤에 설명되는 OpenGL은 플랫폼에 독립적이다. 따라서 OpenGL의 명령에 따라 실제 각 디바이스에 그려줄 밑 부분이 필요한데, 그 역할을 EGL이 한다. OpenGL ES EGL Native Window System
  • 88. 4.Surface 88 / 14 SurfaceView란? SurfaceView는 다른 View들과는 달리 직접 SurfaceView가 컨텐츠를 표시하지 않습니다. 일반적인 View는 화면에 뷰를 표시하는 연산과 기타 연산, 사용자와의 상호작용 처리 등이 모두 하나의 쓰레드에서 처리됩니다. SurfaceView는 화면 업데이트를 백그라운드 쓰레드로 수행하여 어플리케이션의 자원을 잠식하지 않고 원활하게 뷰를 업데이트해줍니다. SurfaceView는 OpenGL을 통한 가속이 지원되어 원활한 3D그래픽 표현도 가능합니다. (GLSurfaceView)
  • 89. 4.Surface 89 / 14 SurfaceView란?
  • 90. 4.Surface 90 / 14 SurfaceView란?
  • 91. 4.Surface 91 / 14 GLSurfaceView
  • 92. 4.Surface 92 / 14 GLSurfaceView
  • 93. 4.Surface 93 / 14 GLSurfaceView 이용하기
  • 94. 4.Surface 94 / 14 GLSurfaceView 이용하기
  • 95. 4.Surface 95 / 14 GLSurfaceView 이용하기
  • 96. 4.Surface 96 / 14 GLSurfaceView 이용하기
  • 97. 4.Surface 97 / 14 GLSurfaceView 이용하기
  • 98. 4.Surface 98 / 14 GLSurfaceView 이용하기
  • 101. 4.Surface 101 / 14 GLSurfaceView 이용하기
  • 102. 4.Surface 102 / 14 GLSurfaceView 이용하기
  • 103. 4.Surface 103 / 14 GLSurfaceView 이용하기
  • 109. 5.Texture 109 / 14 Texture는 같은 이미지 포맷의 이미지를 한 개 혹은 그 이상을 포함하는 OpenGL 오브젝 트이다.
  • 110. 5.Texture 110 / 14 Texture 사용예 귤을 예를 들어 실제 처럼 보이게 하기 위해 1. 색상을 추가하고 2. 빛을 추가 한 후에 3. 실제 귤의 이미지를 입히면 더욱 귤 같이 보일 것이다. 이때 귤의 이미지를 Texture라고 하고 실제 Object에 입히는 것을 mapping이라고 한다.
  • 116. 6.OpenGL 6. OpenGL 116 / 14 정리된 글 출처 OpenGL은 게임에서 이용하는 것이라고 생각할 수 있다. 하지만 카메라 앱을 만들기 위해서 OpenGL은 필수이다. 안드로이드에서 Native 프로그래밍을 하지 않고 GPU를 이용하기 위해서는 OpenGL을 이용하거나 Renderscript를 이용하는 방법 밖에 없기 때문이다. 자세한 내용은 이 곳을 참고하면 된다. http://soen.kr/lecture/library/opengl/opengl-1.htm
  • 117. 4.Surface 117 / 14 OpenGL 특징 OpenGL의 특징은 이름에 포함된 Open이라는 단어에서 대부분 유추할 수 있다. 개방되어 있고 무료이며 이식성이 뛰어나다. ① 그래픽 라이브러리는 구체성을 기준으로 고수준과 저수준으로 분류되는데 OpenGL은 저수준 라이브러리이다. VRML같은 고수준 라이브러리는 물체간의 관계를 정의함으로써 장면을 그려낸다. 이에 비해 저수준 라이브러리는 모델링보다는 랜더링 기능이 주이며 세부적인 명령을 일일이 전달함으로써 물체의 가장 기본적인 요소를 그린다. 사용 방법이 훨씬 더 어렵지만 세세한 부분까지 그릴 수 있다. ② 개방된 표준이므로 플랫폼에 독립적이다. 운영체제와 연관된 부분이 없고 디바이스 드라이버를 통해 하드웨어를 직접 제어하므로 드라이버만 존재하면 모든 하드웨어 환경 에서 실행할 수 있다. 대부분의 데스크탑 환경, 모바일 환경은 물론이고 PlayStation, Nintendo 등의 게임기 등에도 광범위하게 이식되어 있다.
  • 118. 4.Surface 118 / 14 OpenGL 특징 ③ 간단한 함수들로 구성되어 있으므로 개발 언어에도 독립적이다. C/C++, C#, 자바, 파이썬 등 대부분의 언어에서 사용 가능하다. 함수 기반이므로 C 언어가 가장 적합하되 객체 지향의 이점까지 고려하면 C++이 가장 유리하다. 무엇보다 문서와 예제가 풍부하고 재사용한 코드를 쉽게 구할 수 있다는 것이 큰 이점이다. 또 그래픽 프로그램이 요구하는 속도를 충분히 만족한다. ④ 하드웨어의 가속 기능을 최대한 활용하여 효율적으로 동작한다. 하드웨어가 지원하지 않는 기능은 소프트웨어로 흉내낼 수도 있으므로 느려지거나 품질이 나빠지더라도 최소한 그려내기는 한다.
  • 119. 4.Surface 119 / 14 OpenGL 특징 OpenGL 함수들은 일반 함수와 구분하기 위해 예외없이 접두어가 붙는다. gl 라이브러리의 함수는 gl 접두어로 시작하고 glu의 라이브러리는 glu로 시작한다. 마찬가지로 glut 소속의 함수는 glut 접두가 붙는다. 접두어만으로도 OpenGL 함수임을 쉽게 알 수 있다. OpenGL은 C 수준의 함수들로 구성되어 있으므로 객체 지향과는 거리가 멀다. 그래서 함수 오버로딩(Overloading)을 지원하지 않으며 인수의 개수와 타입이 다른 동명 함수를 작성할 수 없다. 동일한 동작을 하되 인수 목록이 다르면 함수의 이름도 매번 달라져야 한다.
  • 120. 4.Surface 120 / 14 OpenGL 특징 그래픽 출력에는 좌표뿐만 아니라 아주 많은 요소들이 개입된다. 색상, 굵기, 모양, 조명, 각종 모드 등등 여러 가지 정보들이 필요하다. 그리기 함수들은 도형 출력을 위해 이 모든 정보들을 참조하지만 그렇다고 해서 이 정보들을 모두 함수의 인수로 전달할 수는 없다. 그렇게 하다가는 인수 목록이 한없이 길어질 것이며 잘 바뀌지도 않는 값을 매번 전달하는 것도 낭비이다. 그래서 OpenGL은 그리기에 필요한 여러 가지 정보들을 상태 머신(State Machine)에 저장한다. 상태 머신이란 상태를 저장하는 장소이며 그리기에 영향을 미치는 여러 변수값들이 집합이다. 배경 색상은 GL_COLOR_CLEAR_VALUE 상태 변수에 저장되며 현재 정점의 색상은 GL_CURRENT_COLOR 상태 변수에 저장된 다
  • 121. 7.Case Study 7. Case Study 121 / 14 총정리 지금까지 배운 기술을 바탕으로 실제 카메라의 Preview로 넘어온 영상을 동영상으로 저장하는 프로세스를 경험 해 보자. 실제코드는 https://github.com/google/grafika 를 참고하기 바란다.
  • 122. 4.Surface 122 / 14 Camera Preview GLSurfaceView setEGLContextClientVersion(2); Renderer setRenderer(); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  • 123. 4.Surface 123 / 14 Camera Preview Renderer onSurfaceCreated 1) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성 GLES20.glGenTextures GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES 2) 해당 Texture로 SurfaceTexture 생성 mSurfaceTexture = new SurfaceTexture(textureId) 3) vertexShader, fragmentShader 정의 4) 생성된 SurfaceTexture의 OnFrameAvailableListener 지정 SurfaceTexture에 새로운 이미지프레임이 왔을 때 불리는 callback mSurfaceTexture.setOnFrameAvailableListener(this); 5) 생성된 SurfaceTexture 로 setPreviewTexture camera.setPreviewTexture(surfaceTexture); 6) 카메라 preview 시작 camera.startPreview();
  • 124. 4.Surface 124 / 14 Camera Preview Renderer onFrameAvailable 1) SurfaceTexture는 새로운 프레임이 있다는 신호를 받는 용도로 사용되고, requestRender는 어느 쓰레드에서도 호출 할 수 있다. 이 결과로 Renderer의 onDrawFrame이 실행됨. glSurfaceView.requestRender();
  • 125. 4.Surface 125 / 14 Camera Preview Renderer onDrawFrame 1) updateTexImage()를 실행하여, 이미지 스트림으로부터 가장 최신의 프레임으로 texture 이미지를 업데이트한다. 만약 최신 프레임이 없으면 기존 이미지를 재사용함. mSurfaceTexture.updateTexImage(); 2) TransformMatrix에서 사용할 Matrix 지정. TransformMatrix는 기본 좌표계의 버텍스가 이 행렬에 곱해져서 새로운 좌표계로 변환된 버텍스를 얻기 위해 사용되는 행렬 ( 회전, 이동, 크키 ) updateTexImage()를 사용할때 마다 사용할 Matrix가 달라질 수 있으므로 매번 새롭게 지정해줘야 함. mSurfaceTexture.getTransformMatrix(mSTMatrix);
  • 126. 4.Surface 126 / 14 Camera Preview Renderer onDrawFrame 3) OpenGL vertex shader, fragment shader 실행 4) 렌더링 실행 GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 5) GL 명령어 실행 GLES20.glFlush();
  • 127. 4.Surface 127 / 14 Camera Preview GLSurfaceView Renderer Camera 2) GL_TEXTURE_EXTERNAL_OES영역에 Texture 생성 해당 Texture로 SurfaceTexture 생성 SurfaceTexture 3) setPreviewTexture (surfaceTexture); 4) preview 갱신 5) onFrameAvailable - requestRenderer(); 호출 6) onDrawFrame SurfaceTexture.updateTexImage(); 7) GL rendering 1) setRenderer 8) eglSwapBuffers mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
  • 128. 4.Surface 128 / 14 Camera Preview GLSurfaceView EGL setup 1) EGL10 mEgl = (EGL10) EGLContext.getEGL(); 2) EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 3) EGLConfig mEglConfig = view.mEGLConfigChooser.chooseConfig (mEgl, mEglDisplay); 4) EGLSurface mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface (mEgl,mEglDisplay, mEglConfig, view.getHolder());
  • 129. 4.Surface 129 / 14 Camera Preview GLSurfaceView EGL setup 1) EGL10 mEgl = (EGL10) EGLContext.getEGL(); 참고 : EGLContext는 인자로 전달받기보다 TLS를 통해 접근함.
  • 130. 4.Surface 130 / 14 Camera Preview
  • 131. 4.Surface 131 / 14 Camera Preview
  • 132. 4.Surface 132 / 14 Camera Preview GLSurfaceView EGL setup 2) EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
  • 133. 4.Surface 133 / 14 Camera Preview GLSurfaceView EGL setup 2) EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
  • 134. 4.Surface 134 / 14 Camera Preview GLSurfaceView EGL setup 2) EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
  • 135. 4.Surface 135 / 14 Camera Preview GLSurfaceView EGL setup 3) EGLConfig mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
  • 136. 4.Surface 136 / 14 Camera Preview
  • 137. 4.Surface 137 / 14 Camera Preview GLSurfaceView EGL setup 3) EGLConfig mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
  • 138. 4.Surface 138 / 14 Camera Preview GLSurfaceView EGL setup 3) EGLConfig mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
  • 139. 4.Surface 139 / 14 Camera Preview
  • 140. 4.Surface 140 / 14 Camera Preview GLSurfaceView EGL setup 4) EGLSurface mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface (mEgl,mEglDisplay, mEglConfig, view.getHolder());
  • 141. 4.Surface 141 / 14 Camera Preview GLSurfaceView EGL setup 4) EGLSurface mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface (mEgl,mEglDisplay, mEglConfig, view.getHolder());
  • 142. 4.Surface 142 / 14 Camera Preview GLSurfaceView EGL setup 4) EGLSurface mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface (mEgl,mEglDisplay, mEglConfig, view.getHolder()); 안드로이드에서 window 객체는 SurfaceView, SurfaceTexture, SurfaceHolder, Surface가 될 수 있다.
  • 143. 4.Surface 143 / 14 Camera Preview
  • 144. 4.Surface 144 / 14 Camera Preview
  • 145. 4.Surface 145 / 14 Camera Preview GLSurfaceView eglSwapBuffers - 현재 버퍼를 전송, 이 함수의 이름은 전면 버퍼와 후면 버퍼를 교체했던 전통 방식에서 유래됐으나, 실제 구현은 이제 다를 수 있다. mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
  • 146. 4.Surface 146 / 14 Camera Preview
  • 147. 4.Surface 147 / 14 Camera Preview
  • 148. 4.Surface 148 / 14 Camera Preview
  • 149. 4.Surface 149 / 14 Camera Preview queueBuffer Buffer를 binder IPC로 Surface Flinger로 보냄.
  • 150. 4.Surface 150 / 14 Camera Preview dequeueBuffer FramebufferNativeWindow에게 다음에 그릴 buffer요청
  • 151. 4.Surface 151 / 14 Camera Recording Renderer Encoder 1. 현재 사용중인 EGLContext 넘김 EGL14.eglGetCurrentContext() 2. TextureID 넘김 1. prepareEncoder 2. OpenGL draw 3. EGL works 4. drainEncoder 5. End of stream
  • 152. 4.Surface 152 / 14 Camera Recording Encoder prepareEncoder #1 1) MediaCodec 설정 2) MediaCodec에서 사용할 surface 생성 3) MediaMuxer 설정 4) EGLContext 생성 (eglCreateContext) 5) EGLSurface 생성 (eglCreateWindowSurface) 6) OpenGL vertex shader, fragment shader
  • 153. 4.Surface 153 / 14 Camera Recording Encoder prepareEncoder #2 Encode : MediaCodec Mux : MediaMuxer
  • 154. 4.Surface 154 / 14 Camera Recording Encoder prepareEncoder #3 1) 버퍼 메타데이터 정보 생성 (코덱의 출력버퍼와 관련된 내용) mVideoBufferInfo = new MediaCodec.BufferInfo(); 2) 인코딩에 사용될 미디어포맷 생성 - String/Value 쌍으로 구성된 미디어 데이터 정보 MediaFormat videoFormat = MediaFormat.createVideoFormat( VIDEO_MIME_TYPE, width, height); public static final MediaFormat createVideoFormat(String mime, int width, int height) { MediaFormat format = new MediaFormat(); format.setString(KEY_MIME, mime); format.setInteger(KEY_WIDTH, width); format.setInteger(KEY_HEIGHT, height); return format; }
  • 155. 4.Surface 155 / 14 Camera Recording Encoder prepareEncoder #4 2) 인코딩에 사용될 미디어포맷 생성 - String/Value 쌍으로 구성된 미디어 데이터 정보 MediaFormat.KEY_COLOR_FORMAT 사용할 색공간을 지정함. COLOR_FormatSurface은 GraphicBuffer의 메타데이터 리퍼런스 videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); videoFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate); videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); videoFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
  • 156. 4.Surface 156 / 14 Camera Recording Encoder prepareEncoder #5 3) 미디어 인코더 생성, 설정 mVideoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE); mVideoEncoder.configure(videoFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 4) Encoder가 사용할 surface 생성 mInputSurface = mVideoEncoder.createInputSurface();
  • 157. 4.Surface 157 / 14 Camera Recording Encoder prepareEncoder #6 5) 인코더 시작 mVideoEncoder.start(); 6) Muxer 생성 mMuxer = new MediaMuxer(outputFile.toString(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
  • 158. 4.Surface 158 / 14 Camera Recording Encoder prepareEncoder #7 7) EGLContext 생성 (eglCreateContext) mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0);
  • 159. 4.Surface 159 / 14 Camera Recording Encoder prepareEncoder #8 7) EGLContext 생성 (eglCreateContext) mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0);
  • 160. 4.Surface 160 / 14 Camera Recording Encoder prepareEncoder #9 7) EGLContext 생성 (eglCreateContext) mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); EGLContext context = EGL14.eglCreateContext(mEGLDisplay, config, sharedContext, attrib3_list, 0);
  • 161. 4.Surface 161 / 14 Camera Recording
  • 162. 4.Surface 162 / 14 Camera Recording Encoder prepareEncoder #11 8) EGLSurface 생성 (eglCreateWindowSurface) EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0); 여기서 surface는 mVideoEncoder.createInputSurface() 로 생성되었던 surface를 넘김
  • 163. 4.Surface 163 / 14 Camera Recording
  • 164. 4.Surface 164 / 14 Camera Recording Encoder prepareEncoder #13 8) EGLSurface 생성 (eglCreateWindowSurface) EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0); 여기서 surface는 mVideoEncoder.createInputSurface() 로 생성되었던 surface를 넘김
  • 165. 4.Surface 165 / 14 Camera Recording Encoder prepareEncoder #14 8) EGLSurface 생성 (eglCreateWindowSurface) EGLSurface eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surface, surfaceAttribs, 0); 여기서 surface는 mVideoEncoder.createInputSurface() 로 생성되었던 surface를 넘김
  • 166. 4.Surface 166 / 14 Camera Recording
  • 167. 4.Surface 167 / 14 Camera Recording Encoder prepareEncoder #16 9) EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)
  • 168. 4.Surface 168 / 14 Camera Recording Encoder prepareEncoder #17 9) EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)
  • 169. 4.Surface 169 / 14 Camera Recording Encoder OpenGL draw #1 1) GLES20.glBindTexture( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); 2) GLES20.glDrawArrays
  • 170. 4.Surface 170 / 14 Camera Recording Encoder EGL works #1 1) EGLExt.eglPresentationTimeANDROID 2) EGL14.eglSwapBuffers
  • 171. 4.Surface 171 / 14 Camera Recording Encoder End of stream #1 1) MediaCodec signalEndOfInputStream() 2) MediaCodec stop() 3) MediaCodec release() 4) MediaMuxer stop() 5) MediaMuxer release() 6) EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); 7) mSurface.release();
  • 172. 4.Surface 172 / 14 Renderer Encoder MediaMuxer Surface1) 현재 사용중인 EGLContext 전달 EGL14.eglGetCurrentContext() 2) 사용중인 TextureID 전달 MediaCodec 3) MediaCodec.create 4) createInputSurface로 생성 5) MediaMuxer 생성 EGLContext 6) eglCreateContext EGLSurface 7) eglCreateWindowSurface
  • 173. Thank you… 이 문서는 나눔글꼴로 작성되었습니다. 설치하기