ffmpeg 천줄로 비디오플레이어 만들기
http://www.dranger.com/ffmpeg/ffmpeg.html

http://hybridego.net/entry/천줄로-비디오플레이어-만들기
http://hybridego.net/entry/千-Line-으로-비디오플레이어-만들기-1
http://hybridego.net/entry/千-Line-으로-비디오플레이어-만들기-2
http://hybridego.net/entry/千-Line-으로-비디오플레이어-만들기-3
http://hybridego.net/entry/千-Line-으로-비디오플레이어-만들기-4
http://hybridego.net/entry/千-Line-으로-비디오플레이어-만들기-5
http://hybridego.net/entry/千-Line으로-비디오플레이어-만들기-6
http://hybridego.net/entry/千-Line으로-비디오플레이어-만들기-7
http://hybridego.net/entry/千-Line으로-비디오플레이어-만들기-8
http://hybridego.net/entry/千-Line으로-비디오플레이어-만들기-마무리
별로 중요하지 않은 부분중 생략된 부분이 있고 의역이 많이 있습니다.
군데군데 틀린 번역이 있을수 있습니다. (영어가 후달려서)

하지만 소스코드 설명 부분은 틀리지 않도록 노력했습니다.

위의 원문을 번역한 것입니다.
잘못된 부분이 있을지도 모르겠습니다.
혹시 잘못된 부분을 발견하시면 댓글로 알려주시면 감사하겠습니다.



Tutorial 02: Outputting to the Screen

SDL and Video

우리는 스크린에 그림을 그리기 위해서 SDL 을 사용할 것입니다.
SDL 은 Simple Direct Layer 표준이고 멀티미디어, Cross-Platform 등을 위한 훌륭한 라이브러리 입니다.
SDL the official website  에서 개발 패키지를 다운 받으실 수 있습니다.
이번 Tutorial을 컴파일 하기 위해서는 SDL 라이브러리가 꼮 있어야 하니까 설치해 두셔야 합니다.

SDL은 스크린에 그림을 그리기 위한 많은 메소드를 갖고 있고, 이것으로 비디오를 출력할 수도 있습니다. 이걸 YUV 오버레이 라고 부릅니다.

YUV (technically not YUV but YCbCr) 는 RGB같은 RAW 이미지 데이타를 저장하는 방법입니다.
개략적으로 말하면 Y는 밝기, U와 V는 색상을 나타냅니다. (이것은 RGB보다 좀더 복잡한데 몇몇 색깔정보는 버려지고, Y요소 2개당 U,V 요소는 1개씩 들어가기 때문입니다.) SDL의 YUV 오버레이는 YUV 테이터의 RAW 배열을 갖고 있고 이것을 디스플레이 합니다. 4가지 종류의 YUV포맷이 사용 가능하지만 YV12가 가장 빠릅니다. YUV420P이라는 다른 YUV포맷이 있는데 이것은 YV12에서 U랑 V가 바뀐것 빼고는 똑같습니다.
Subsample 된 420 이라는 것은 4:2:0의 비율을 나타내는데 Y성분이 4개면 U,V성분은 1개가 있다는 뜻입니다.
이런 방법은 bandwidth를 저장하는데 매우 효율적입니다. 사람의 눈은 이런 변환을 잘 구분하지 못하기 때문이지요.
이름에 있는 P는 포맷이 planar 라는 뜻입니다. -이것은 YUV요소가 연속적 배열이라는 의미 입니다.
fmpeg는 이미지를 YUV420P로 변환할 수 있고, 그것을 다른 비디오 포맷으로 쉽게 변환 할 수 있습니다.

이제 우리는 Tutorial1의 SaveFrame() 함수를 대체하고, 출력을 우리 화면에 해보도록 합시다.
아! 그전에 SDL Library를 어떻게 사용해야 하는지를 먼저 봐야 겠군요
일단 라이브러리를 Include하고 SDL을 초기화해볼까요?
SDL_Init()는 우리가 SDL을 사용하려고 할때 꼭 써야하는 함수 입니다.
SDL_GetError()는 디버깅 함수이구요


Creating a Display

이젠 이미지를 디스플레이 할곳이 필요한데 이 SDL에서는 이 장소를 Surface라고 부릅니다.
화면의 가로, 세로를 설정합니다. 그 다음 옵션은 스크린의 depth 인데요 0으로 하면 현재 디스플레이와 같은 depth로 설정하는 것입니다.

이번엔 우리가 만든 screen에 YUV overay를 만들어 video를 올릴것입니다.
가로, 세로, YV12를, screen 에~


Displaying the Image

이젠 이미지를 디스플레이 하기만 하면 됩니다. 마지막 프레임까지 쭈욱~
우리는 RGB프레임을 위해 갖고 있던것들을 제거할 수 있습니다. 그리고 SaveFrame()과 디스플레이 코드를 바꿀것입니다.
이미지를 디스플레이 하기 위해서 AVPicture struct 를 만들고 TUV에 쓸 데이타 포인터와 라인싸이즈를 설정합니다.
SDL_LockYUVOverlay(), img_convert(), SDL_UnlockYUVOverlay()
overlay를 써야하기 때문에 일단 lock을 걸어줍니다. lock을 거는것을 습관하 하세요 그래야 나중에 뒷탈이 없습니다.
전에 봤던 AVPicture struct는 하나의 data pointer를 갖고 있는데 이것은 4개의 pointer의 array 입니다.
YUV420P를 다루기 때문에 우리는 3개의 channel을 갖고 있고 그래서 4개중에 3개만 세팅 합니다.
다른 포맷들은 아마 Alpha channel까지 해서 네개의 포인터를 갖고 있을지도 모릅니다.
linesize는 사운드 같은것 입니다.
YUV overlay에 있는 비슷한 구조들은 다양한 pixel과 pitch 입니다. ("pitches" 는 주어진 데이타 라인의 넓이를 알기 위해 사용되는 SDL용어 입니다.)

pict에 쓸때 overlay에 pict.data의 세개 배열을 지정한다. 우리는 사실 overlay에 기록하는 것입니다.
비슷하게, overlay로부터 직접 linesize 정보를 얻기도 합니다. 바꾼 포맷을 PIX_FMT_YUV420P로 바꾸고, 방금 전처럼 img_convert 를 사용합니다.


Drawing the Image


이제 그리면 됩니다. 이 함수에는 비디오의 가로, 세로 싸이즈를 지정하면 크기를 변환해준다. SDL은 graphic processor를 이용해 빠른 Scaling 을 해줍니다.


Now our video is displayed!

이번에는 SDL의 다른 기능을 살펴봅시다.
SDL은 event system 입니다. 여러분이 버튼을 누르거나 마우스를 움직이거나 어떤 Signal을 줄때 event가 일어납니다.
여러분의 프로그램에서 이 event들을 감지할 수 있습니다. 그리고 여러분의 프로그램에서 event를 발생시킬 수도 있습니다.
이런 기능은 SDL로 Multithread 프로그램을 돌릴때 유용하게 쓸수 있습니다.
지금 이 프로그램에서는 packet processing이 끝나자 마자 이벤트를 감시할 것입니다.
SDL_QUIT 이벤트를 이용해서 우리 프로그램을 종료 하도록 합시다.

이제 컴파일을 해봅시다.
여러분이 리눅스를 쓰신다면 다음이 SDL lib 을 사용한 가장 좋은 컴파일 방법입니다.

gcc -o tutorial02 tutorial02.c -lavutil -lavformat -lavcodec -lz -lm \
`sdl-config --cflags --libs`

sdl-config는 gcc에다가 SDL libraries 를 include 할수 있는 적당한 flag를 출력해 줍니다.
여러분이 만약 여러분 시스템의 컴파일을 위해 약간 다른 설정을 해야 한다면 SDL Documentation을 참고 하세요.
자! 이제 컴파일을 하고 실행을 시켜 봅시다.

어떤일이 일어나나요? 비디오가 미친거 같죠? ㅋㅋ 사실 우리는 비디오 파일에서 추출할 수 있는 한 최대속도로 비디오는 디스플레이 합니다. 우리는 지금 언제 비디오를 디스플레이 해야하는지를 coding 하지 않았어요. sync가 전혀 안되고 있습니다.
우리는 video syncing을 해야하고요.... 아차! 일단 Sound 플레이를 해야겠군요!
Posted by Real_G