동영상 압축 과정 중 압축률을 결정하는 부분을 양자화(Quantization)라고 합니다.

주파수 변환된 계수들의 크기를 줄이거나 제거하는 과정인데 쉽게 말하면 다음과 같은 계수들이 있다고 했을 때

63, 127, 133, 33, 11, 5, 2


모든 계수들을 30으로 나누고 나머지는 버린다면 다음과 같은 결과가 나오겠죠.

2, 4, 4, 1, 0, 0, 0


이런식으로 계수들의 크기를 줄이거나 없애는(0) 과정입니다.

이 과정에서 계수들을 나누는데 사용된 30이 양자화의 정도를 결정하는데 이 값이 클수록 더 많은 계수들이 없어지거나 줄어들겠죠.

H.264(x264)에서는 QP(Quantization Parameter)가 이와 비슷한 개념입니다.


양자화된 계수들을 복원(디코딩)할 때에는 다시 30을 곱해줍니다.

60, 120, 120, 30, 0, 0, 0


그러면 위와 같은 결과가 나오는데 원래의 계수들(63, 127, 133, 33, 11, 5, 2)과 비슷하긴 하지만 어느정도의 차이가 발생합니다.

즉 양자화 과정을 거치면서 데이터의 손실이 발생한다는 말이고 이 손실은 되돌릴 수 없는 것이죠.


H.264(x264)에서도 대략적으로는 위와 비슷한 방식으로 양자화가 진행되고(훨씬 복잡한 과정이죠.) 그 정도를 결정하는 수치가 바로 QP입니다.

QP가 높을수록 더 많은 데이터가 손실되고 비트레이트는 낮아지는 것이죠.

즉 "비트(레이트)를 어떻게 배분할 것인가"라는 말은 다시 말해서 "QP를 어떻게 조절할 것인가"와 같은 말입니다.




x264의 비트 배분 방식은 CRF, ABR 등이 있지만 더 넓게 보면 MB-tree와 qcomp로 나눌 수 있습니다.

MB-tree 또는 qcomp 방식 중 하나를 기반으로 해서 CRF, ABR 등을 추가로 선택할 수 있는 것이죠.

기본적으로 x264는 MB-tree 방식을 사용하지만 설명을 간단히 하기 위해 qcomp 방식을 기준으로 정리해 보겠습니다.


x264의 비트 배분 방식에는 CQP, CRF, 1패스 ABR, 2패스 ABR과 VBV 등이 있습니다.

(CBR과 같이 VBV를 사용하는 비트 배분 방식은 나중에 따로 정리해 보겠습니다.)

앞서 설명드린대로 비트를 배분한다는 말은 QP를 조절한다는 말이기 때문에 각각의 배분 방식 또한 QP를 조절하는 방법에 따라 나눠집니다.


CQP(Constant QP)는 말 그대로 일정한 QP를 사용하는 방식입니다.

따로 QP를 조절하지 않고 사용자가 입력한 QP를 그대로 사용하는 것이죠.

다만 프레임의 종류에 따라서(I, P, B, b) 약간씩의 차이가 있을 뿐입니다.

(I프레임의 화질은 이후의 프레임들에도 영향을 주기 때문에 다른 프레임들보다 낮은 QP가 사용되고 마찬가지 원리가 P, B, b 프레임 등에 적용되는데

이것은 CQP 뿐만 아니라 모든 비트 배분 방식에 적용되는 기본 원리입니다.)

QP가 일정하기 때문에 화면이 복잡하거나 움직임이 많으면 비트레이트가 높아지고 화면이 단순하고 움직임이 적으면 비트레이트가 낮아집니다.

따라서 CQP를 사용하면 영상 전체적으로 비슷한 화질을 갖게 됩니다.


그런데 모든 장면에서 똑같은 QP를 사용하는 것(CQP)보다는 상황에 맞게 QP를 조절하는 것이 보통은 더 효율적이라고 봅니다.

움직임이 많고 복잡한 장면에서는 상대적으로 화질 저하를 눈치채기 힘들기 때문에 QP를 높여서 비트레이트를 낮추고

그렇게 해서 남는 여유분을 움직임이 적고 단순한 장면에 사용하면 화질이 더 좋아진 것처럼 보이기 때문이죠.

(게다가 움직임이 적은 장면에서는 움직임 예측의 효율도 높아지기 때문에 투입된 비트 대비 효과도 커집니다.)

수치적으로도, 복잡한 구간에서 QP를 높이면 단순한 구간에서는 그 높인 만큼보다 더 낮은 QP를 사용할 수 있습니다.

복잡한 구간에서는 비트레이트가 높기 때문에 QP가 변할 때 그에 해당하는 비트레이트 변동폭도 크기 때문입니다.

즉 이런식으로 비트를 배분하면 동일한 파일사이즈(비트레이트)에서도 전체적인 QP를 낮출 수 있다는 말이 됩니다.

CQP를 제외한 CRF, ABR 등은 모두 이렇게 영상의 복잡한 정도에 따라서 QP를 조절합니다.


2패스 ABR

2패스 ABR은 첫 번째 패스를 통해서 영상의 복잡도를 계산합니다.

첫 번째 패스는 영상의 전반적인 모습을 파악하는 것이 목적이기 때문에 인코딩 옵션은 크게 중요하지 않습니다.

(옵션이 어떻게 됐든 상관없이 영상의 복잡도는 거의 비슷하게 추정되기 때문이죠. 다시 말해서 영상의 복잡도는 복잡한 구간과 단순한 구간의

상대적인 비율이 중요한 것이지 절대적인 크기는 아무래도 상관없다는 뜻입니다)

이렇게 계산된 복잡도는 예를 들면 CQP로 인코딩했을 때의 비트레이트와 비슷합니다.

일정한 QP로 인코딩하면 영상의 복잡도에 따라서 비트레이트가 변할 테니까 이것을 그 영상의 복잡도라고 생각할 수 있는 것이죠.

따라서 첫 번째 패스의 결과 아래와 같은 비트레이트가 얻어졌다면 이것을 그 영상의 복잡도로 설정하고

이 복잡도를 기준으로 두 번째 패스에서 어떻게 비트를 배분할지 결정하게 됩니다.


두 번째 패스에서 구간별로 배분할 비트를 구하는 공식은 복잡도^0.6입니다.

0.6은 어디서 많이 보던 숫자죠..바로 x264 --qcomp 옵션의 기본값입니다.

이 0.6의 의미를 생각해보면..값이 점점 커져서 1이 되면 복잡도^1 = 복잡도가 되겠죠. 즉 비트레이트=복잡도 인 CQP와 비슷한 결과가 나오게 됩니다.

반대로 점점 작아지다가 0이 되면 복잡도^0 = 1이 되겠죠. 즉 복잡도와 관계없이 비트레이트가 일정한 CBR과 비슷한 결과가 나옵니다.

기본값인 0.6을 사용하면 아래와 같이 복잡도가 높은 구간에서는 비트를 낮추고 복잡도가 낮은 구간에서는 비트를 높이게 되겠죠.

앞서 설명드린대로 복잡한 구간에서는 비트를 낮추고 단순한 구간에서는 비트를 높이는 것이 효율적이기 때문에 기본값을 0.6으로 설정한 것입니다.

(그리고 아래 그래프에서는 복잡도(CQP)복잡도^0.6이 같은 위치에 그려져 있지만 원래대로라면 복잡도(CQP)는 훨씬 위에 위치해야겠죠.)


하지만 이렇게 두 번째 패스에서 배분될 비트를 구하는 과정은 입력 비트레이트와는 관계없이 진행된다는 것을 알 수 있습니다.

따라서 입력된 비트레이트와 동일한 비트레이트를 얻기 위해서는 복잡도^0.6을 적절히 스케일링해서 비트를 배분해야 합니다.

예를 들어 복잡도^0.6으로 얻어진 파란색 그래프의 평균 비트레이트는 3000이고 입력된 비트레이트가 2000이라면

이 파란색 그래프에 2/3를 곱한(스케일링) 다음 그 결과에 따라 비트를 배분해서 평균 비트레이트가 2000이 되도록 인코딩하는 것입니다.

또한 첫 번째 패스에서 구해진 복잡도의 부정확성을 보충하기 위해 두 번째 패스에서는 약간의 보정이 필요합니다.

(첫 번째 패스에서는 두 번째 패스보다 가벼운 옵션을 사용하기 때문입니다. 이 부정확성을 최소화하려면 --slow-firstpass 옵션을 사용해야겠죠.)

첫 번째 패스에서 구해진 복잡도(비트)와 이를 토대로 한 두 번째 패스의 실제 인코딩 결과가 완벽히 일치하기는 어렵기 때문에

인코딩 과정 중에 QP를 끊임없이 재조정하는 것이죠. 이 때 얼마나 정확하게 입력된 비트레이트를 맞출지 정해주는 옵션이 --ratetol 입니다.

1패스 ABR 인코딩에서도 마찬가지로 입력된 비트레이트를 얼마나 정확하게 맞출지 조절하는 데에 사용되는 옵션입니다.


1패스 ABR

1패스 ABR에서는 첫 번째, 두 번째 패스라는 개념이 없기 때문에 영상의 전체적인 모양(복잡도)을 미리 알 수가 없습니다.

그래서 인코딩이 시작되면 일정 구간까지만 영상을 분석한 다음 복잡도^0.6을 계산하고 이를 스케일링해서 비트를 배분하는 식으로 진행됩니다.

(1패스 ABR, CRF 등의 1패스 인코딩에서는 복잡도를 계산할 때 2패스 인코딩과는 약간 다른 수치를 사용합니다.)

하지만 2패스 ABR과는 달리 복잡도가 어떻게 변할지 모르기 때문에 복잡도^0.6을 스케일링하는 데에 제약이 있을 수밖에 없습니다.

예를 들어 위 그래프의 복잡도가 가장 높은 부분을 비트레이트=3000으로 인코딩한다고 가정해보면 x264가 계산한 복잡도^0.6은 그림처럼 파란색

그래프가 있는 지점이겠죠. 하지만 입력된 비트레이트=3000을 맞추기 위해서는 파란색 그래프 만큼의 비트를 배분할 수가 없습니다.

앞으로 이 정도의 복잡도가 계속될지 아니면 복잡도가 낮아질지 모르기 때문이죠. 따라서 파란색 그래프보다 낮은 비트를 배분할 수밖에 없습니다.

마찬가지로 복잡도가 가장 낮은 부분에서도 입력된 비트레이트=3000을 맞추기 위해 파란색 그래프보다 높은 비트를 배분하게 됩니다.

이처럼 1패스 ABR은 영상의 전반적인 복잡도를 알지 못하는 상태에서 정해진 비트레이트를 맞춰야 한다는 제약이 있기 때문에

2패스 ABR에 비하면 비트 배분의 효율이 약간 떨어지게 됩니다.


CRF

CRF는 2패스 ABR과 비트 배분 방식이 동일합니다.

인코딩이 시작되면 1패스 ABR과 마찬가지로 일정 구간까지만 복잡도^0.6을 계산하고 그 결과를 주어진 CRF로 스케일링 해서 비트를 배분합니다.

이 작업을 인코딩이 끝날 때까지 반복하는데 정해진 비트레이트를 맞추지 않아도 되기 때문에 결국 2패스 ABR 인코딩과 똑같은 결과를 얻게 되겠죠.

(그리고 정해진 비트레이트가 없기 때문에 인코딩 진행 중에 QP를 재조정하는 작업도 필요없게 됩니다.)

다만 차이점이 있다면 2패스 ABR에서는 입력된 비트레이트에 따라서 복잡도^0.6을 스케일링하지만 CRF에서는 비트레이트와 관계없이

일정한 수치(CRF)로 복잡도^0.6을 스케일링한다는 것입니다.

따라서 어떤 영상을 CRF=20으로 인코딩했을 때 평균 비트레이트가 2000이었다면, 이 CRF 인코딩과 2패스 ABR(비트레이트=2000) 인코딩의

비트 배분 결과는 거의 같다고 할 수 있습니다. (완전히 동일하다고는 할 수는 없지만 비트 배분 상의 차이는 거의 없다고 할 수 있습니다.)

즉 2패스 ABR 인코딩은 입력된 비트레이트와 동일한 비트레이트가 나오는 CRF 수치를 찾는 과정이라고도 볼 수 있는 것이죠.



여기까지가 qcomp 방식을 기준으로 한 ABR, CRF, 2패스 인코딩의 비트 배분 방식들에 대한 설명입니다.

하지만 앞서 말씀드린대로 요즘은 x264의 비트 배분 방식이 MB-tree를 기본값으로 하고 있죠.

MB-tree도 기본적으로는 qcomp 방식과 비슷합니다. 다만 비트 배분을 위해 복잡도를 사용하지 않고 참조율을 사용한다는 차이점이 있죠.

영상의 복잡한 정도에 따라서 복잡도를 계산하는 것이 아니라 인터 코딩시 참조율을 분석해서 자주 참조되는 부분과 덜 참조되는 부분을

구별한 다음 참조율이 높은 곳에는 많은 비트를 배분하고 낮은 곳에는 적은 비트를 배분하는 것입니다.

그리고 MB-tree는 qcomp와 다르게 비트 배분의 기본 단위(참조율 분석 단위)를 프레임이 아닌 매크로블럭 레벨로 확장하고 있습니다.

따라서 프레임 단위의 참조율 뿐만 아니라 블럭 단위의 참조율까지 고려해서 비트를 배분하기 때문에 더 효율적인 비트 배분이 가능합니다.

쉽게 말해서 지금까지 설명드린 qcomp 방식의 복잡도라는 개념을 참조율로 대체하면 MB-tree의 비트 배분 방식이 되는 것이죠.

게다가 참조율의 분석 단위가 프레임이 아닌 매크로블럭까지로 확장된다고 보시면 됩니다.

(x264의 --qcomp 옵션도 동일하게 작동합니다. 1에 가까워지면 MB-tree의 작동이 최소화되면서 CQP와 비슷하게 되고, 0에 가까워지면 MB-tree의

작동이 최대화되면서 참조율에 따른 비트 배분 상의 차이가 없어지게 됩니다.)




Posted by 김코덱
,