스케일업/번역

FFmpeg as a library (libav) 튜토리얼

gamz 2021. 2. 14. 21:19

빅버니

프로그래머블한 동영상 인코딩 방법을 찾는 중에 발견한 튜토리얼인데 설명이 너무 좋고 쩔어서 클립해두고 종종 찾아보다가 중국어로 번역된 부분이 있길래 나도 기여해보고자하는 마음에 번역을 시작해보고자 한다.

 

번역 작업 자체는 깃헙으로 하고 PR을 올릴터이지만 그 작업 과정 중에 메모해둘만한게 있다면 이곳에 기록해두려고 포스트도 하나 파본다. 번역 완료, PR 올림.

 

후기

- 하루에 1-2시간씩 4일 정도 걸림

- 오래 걸린 부분은 PTS 부분 - 개념은 이해 되는데 원문 내용이랑 잘 매치가 안됨. 따로 다뤄야할 듯

- 단어를 있는 그대로 최대한 번역하려고 하다보니 너무 자연스럽지 않은 직역체였음

- 그래서 마지막에 전체적으로 손보면서 군더더기 같은 것들은 빼고 문체도 조금 다듬었음

- 약간 지루한 느낌인데 다 하고 나니까 보람 참

 

보완

오디오 비디오 동기화 부분에서 PTS 개념 설명 및 예제가 나오는데 설명과 예제가 잘 매치가 안되서 좀 헤맸다. 이 부분을 조금 더 리뷰해보면서 보완해보고자 한다.

 

일단 원문에는 이렇게 설명되어있다.

Therefore we need to introduce some logic to play each frame smoothly. For that matter, each frame has a presentation timestamp (PTS) which is an increasing number factored in a timebase that is a rational number (where the denominator is known as timescale) divisible by the frame rate (fps).

It's easier to understand when we look at some examples, let's simulate some scenarios.
For a fps=60/1 and timebase=1/60000 each PTS will increase timescale / fps = 1000 therefore the PTS real time for each frame could be (supposing it started at 0):

* frame=0, PTS = 0, PTS_TIME = 0
* frame=1, PTS = 1000, PTS_TIME = PTS * timebase = 0.016
* frame=2, PTS = 2000, PTS_TIME = PTS * timebase = 0.033

 

나는 이렇게 번역했는데,

그래서 뭔가 프레임을 원활하게 재생할 수 있는 로직을 소개할 필요가 있습니다. 이 이슈를 위해, 각 프레임은 프리젠테이션 타임스탬프 (PTS)를 갖게 되는데 이것은 프레임속도(fps) 로 나누어지는 타임베이스(timebase) 라고 하는 유리수(분모가 타임스케일(timescale) 로 알려진)로 구성된(factored) 증가하는 숫자입니다.

예제를 좀 본다면 이해가 더 쉬울 것입니다, 몇개의 시나리오를 시뮬레이션해죠.
fps=60/1 이고 timebase=1/60000 라면 각 PTS는 timescale / fps = 1000를 증가할 것 입니다. 그래서 각 프레임의 PTS 실제 시간은 이렇게 됩니다 (0부터 시작한다고 하면):

* frame=0, PTS = 0, PTS_TIME = 0
* frame=1, PTS = 1000, PTS_TIME = PTS * timebase = 0.016
* frame=2, PTS = 2000, PTS_TIME = PTS * timebase = 0.033

 

내가 헷갈렸던 건 이렇다. 그리고 아직까지도 저 설명대로면 예제가 잘 이해가 안된다.

- PTS는 timebase에 따른 증가하는 숫자라고 했는데 PTS와 PTS_TIME을 따로 구분하지

- timebase가 frame rate (fps)로 divisible 이라고 해놓고서 왜 PTS를 구할때 timescale / fps 를 하지 (이건 괄호를 잘 못 친게 아닌가..)

 

그래서 일단 해당 설명을 떠나서 개념 자체를 이해하기 위해 따로 찾아봤다. 이 글이 이해하는데 도움이 되었다.

- 모던 컨테이너에서는 비디오(오디오) 프레임의 시간 관리를 framerate 대신 timestamp를 쓴다고 함 (예전엔 framerate 만으로 컨트롤 했나보다)

- 이 timestamp는 프레임마다 박혀 있게 되는데 이걸 PTS Time 라고 함, 0번째 프레임 0초, 1번째 프레임 0.04초, 2번째 프레임 0.08초.. 이런 식

- 시간 표현의 해상도를 위해서 timebase를 도입했는데 이건 tick을 의미함. 예를들면, timebase가 1/75 일때 one tick은 1/75초를 의미함. 여기서 75가 결국 1초를 75개로 나눈 해상도를 의미하며 timescale이라고 부름. (timebase와 timescale은 역수관계)

- timescale(or timebase)는 보통 fps를 고려한 값이 되는데 원문에서 divisible by fps 라고 한게 그런 맥락으로 보임

 

정리해보면, 초당 표현 가능한 tick의 수가 timescale인데 초당 프레임 수(fps)에 따라 이 timescale 내의 몇 개의 tick을 쓰는지가 나올 것이다. 예를들면, timescale이 75이고 fps가 25면 75개의 tick 중에 25개의 tick이 사용될 것이고 각 프레임은 0, 3rd, 6th, ..., 75th tick으로 매핑될 것이다. 여기서 이 증가한 3이라는 숫자는 timescale / fps 의 값으로 얻어지며, 곧 PTS의 증가치가 된다. 즉, PTS 값은 프레임을 timescale / fps 만큼 증가하는 tick으로 대응한 것이고 PTS Time 값은 여기에 timebase를 곱한 값이다.

 

이런 방식이기 때문에 Transcoding(Re-encoding) 없이 동영상의 framerate를 변경하는 것도 가능하다.