하드웨어 비디오 코덱과 소프트웨어 비디오 코덱의 하이브리드!

영상을 압축하는 두 가지 코덱

요즘 많은 사람들이 즐기는 주요 엔터테인먼트 중 하나가 멀티미디어 콘텐츠입니다. 사람들은 다양한 기기로 멀티미디어 콘텐츠를 소비하는데요. 그중에서도 스마트폰은 많은 사람들이 이용하는 주요 기기입니다. 하지만 스마트폰의 제한된 컴퓨팅 환경은 고화질의 멀티미디어 콘텐츠를 즐기는 것을 어렵게 만듭니다. 특히 최근에 많은 분들이 즐기는 실시간 멀티미디어 애플리케이션에선 영상을 압축하는 시간까지 제한됩니다. 이런 조건에서 스마트폰의 CPU로는 고화질의 영상을 제시간에 압축하기 어렵습니다.

그럼에도 많은 분들이 실시간으로 HD 화질의 멀티미디어 콘텐츠를 소비할 수 있는 이유는, 영상 압축을 소프트웨어 코덱이 아닌 하드웨어 코덱으로 하기 때문입니다. 많은 스마트폰 제조사들이 하드웨어 비디오 코덱을 제공하는데요. 소프트웨어로 구현된 비디오 코덱과 달리 높은 해상도의 영상을 실시간으로 압축할 수 있을 만큼 성능이 좋아 널리 쓰이고 있습니다.

그렇지만 모든 면에서 하드웨어 코덱이 뛰어난 것은 아닙니다. 하드웨어 코덱은 스마트폰이 제조될 때 만들어진 기능 외에 다른 기능을 구현하는 것이 불가능하지만, 소프트웨어 코덱은 업데이트를 통해 계속 기능을 추가하는 것이 가능합니다. 하드웨어 코덱이 제공하지 않는 많은 기능을 개발자가 직접 추가할 수 있습니다.

두 코덱의 장단점을 간단히 정리하면 다음과 같습니다.

  • 소프트웨어 영상 코덱: 유연성, 안정성, 호환성
  • 하드웨어 영상 코덱: 실시간 성능, CPU와 병렬로 실행

LINE 영상 통화의 품질을 책임지는 VoIP 플랫폼 개발팀에서는 그룹 통화 리팩토링 및 품질 개선 프로젝트인 ‘Constella 프로젝트’를 진행하면서 스케일러블(scalable) 영상 코딩(다양한 해상도를 하나의 데이터 스트림으로 코딩하는 기법)을 구현해야 했는데요. 소프트웨어 코덱으로는 필요한 만큼 성능이 나오지 않고, 하드웨어 코덱은 스케일러블 영상 코딩을 지원하지 않아서 난관에 부딪혔습니다. 그래서 스케일러블 영상 코딩을 위해 두 코덱의 장점을 살린 새로운 코딩 시스템을 개발하기로 결정했습니다.

 

두 코덱의 장점을 합쳐보자!

그룹 영상 통화는 한 사용자의 영상을 다양한 사용자가 다양한 해상도로 볼 수 있기 때문에 스케일러블 영상 코딩이 필요합니다. 스케일러블 영상 코딩을 가장 간단하게 설명하자면, 원본 영상을 HD, VGA, QVGA로 세 번 압축한 뒤, 컴퓨터로 그룹 영상 통화에 참여하는 사용자에겐 HD로 압축한 영상 데이터를 보내주고, 스마트폰으로 참여하는 사용자에겐 VGA, 한 화면에 여러 영상을 보는 사용자에겐 QVGA를 보내주는 것입니다. YouTube를 즐겨보신다면 같은 영상이라도 해상도를 달리 선택할 수 있는 것을 보셨을 텐데요. 그룹 영상 통화의 경우 YouTube와 같은 방송 프로그램 보다 스케일러블 영상 코딩을 더 다양하게 활용할 수 있습니다.

하지만 원본 영상을 각 해상도로 세 번이나 압축하는 것은 여러모로 자원 낭비가 심한 방법입니다. 같은 영상이기 때문에 중복된 정보가 많고, 한 번 압축하는 것보다 더 많은 CPU 자원이 필요하기 때문에 이런 방식으로 스마트폰에서 실시간으로 압축하는 것은 불가능에 가깝습니다. 그래서 그룹 영상 통화에서 스케일러블 영상 코딩을 가능하게 만들기 위해선 새로운 방법이 필요했습니다. 팀원이 다같이 고민한 끝에, 하드웨어 코덱을 활용하고 상위 해상도 영상의 중복된 정보를 제거하는 방법으로 개발해 보기로 결정했습니다.

 

아이디어 1: 중복된 정보 제거하기(엔트로피)

스케일러블 스트림(stream)을 생성하기 위해서 다양한 계층의 해상도로 영상의 크기를 조정합니다. 예를 들어, 원본의 해상도가 HD이고 VGA 해상도로 스케일러블 스트림을 생성할 때, HD 이미지의 크기를 조정해서 VGA 이미지를 만들고 두 영상을 각각 압축할 수 있습니다. 하지만 이렇게 생성된 저해상도 이미지는 고해상도 이미지와 중복된 정보가 많이 있습니다. 이 두 이미지의 차이를 이용하면 낮은 엔트로피의 이미지 정보를 만들 수 있고, 낮은 엔트로피의 이미지 정보를 압축하면 코덱으로 더 좋은 효율을 낼 수 있습니다.

위 그림에서 보이는 바와 같이 같은 장면을 해상도만 바꾼 두 이미지는 거의 유사한 정보를 갖고 있습니다. 그리고 낮은 해상도로 바꾼 PVGA를 다시 높은 해상도로 바꾸면, 원래의 이미지인 PHD에서 정보가 조금 손실된 이미지인 PHD‘가 됩니다. 지금 당장 그림판에서 아무 그림이나 열어서 해상도를 작게 만들었다가 다시 크게 만들어 보세요. 이미지가 원래대로 복구되지 않는 것을 볼 수 있을 겁니다. 여기서 PHD – PHD‘를 구하면, 같은 장면이지만 해상도가 다른 두 이미지 간의 차이 정보를 구할 수 있고, 이 차이 정보는 PHD에 비해서 ‘엔트로피가 낮은 정보’입니다. 그렇다면 여기서 ‘엔트로피가 낮다’는 것은 무엇을 의미하는 걸까요? 엔트로피와 정보의 양에 대해 이해하기 위해선 배경지식이 필요한데요. 간단히 필요한 개념만 설명하겠습니다.

 

엔트로피와 정보

엔트로피는 정보 이론에서 정보의 양을 나타낼 때 쓰는 개념입니다. 이 개념은 정보 이론을 정립한 학자인 Claude E. Shannon이 다음과 같이 정의했습니다.

여기서 X는 확률 변수고, H(X)는 확률 변수 X의 엔트로피를 나타냅니다. 수식으로 표현되어 있어 읽기 어렵지만, 마지막 수식을 아래 예시와 함께 천천히 살펴보면 이해할 수 있을 겁니다.

동전을 던져서 앞면이 나오는 경우와 뒷면이 나오는 경우를 예로 들어 엔트로피를 설명하면 다음과 같습니다.

  • P(xi)는 xi가 발생할 확률입니다. 예시에서는 앞면 또는 뒷면이 나올 확률이 0.5이므로 각각 P(x) = P(x) = 0.5입니다.
  • b는 데이터를 표현할 진법수입니다. 여기서는 0 또는 1로 표현하여 비트(bit) 단위를 쓴다고 가정하겠습니다. b = 2입니다.
  • n은 표현해야 할 데이터의 개수입니다. 앞면 또는 뒷면의 2개이므로 여기서 n = 2입니다.
  • 결국 마지막 수식을 계산하면 이렇습니다. -(0.5 x log2(0.5) + 0.5 x log2(0.5)) = 1. 즉, 엔트로피는 1비트입니다. 해석하면, 동전을 던지는 경우에 관한 모든 정보를 표현하려면 1비트면 충분하다는 뜻입니다.

이와 같이 어떤 확률 변수 X의 엔트로피는 계산할 수 있고, 엔트로피가 클수록 정보의 양이 많다고 할 수 있습니다. 그렇다면 다음의 두 그림 중 엔트로피가 더 큰 그림은 어떤 것일까요?

 

대부분 답을 아시겠지만, 오른쪽 그림이 엔트로피가 더 큰 그림입니다. 하나의 픽셀이 갖는 값의 경우의 수가 왼쪽 그림과 비교해서 더 많고 조밀합니다.

이렇듯 같은 크기의 이미지도 다른 엔트로피를 갖기 때문에, 압축 알고리즘은 이미지의 엔트로피를 더 낮게 만들기 위해 다양한 방법을 사용합니다. 예를 들어, 동영상은 여러 이미지가 연속으로 보이는 것인데요. 앞장과 바로 뒷장의 이미지는 거의 같은 이미지입니다. 60FPS 정도의 동영상에서 두 이미지의 차이를 사람이 구분하는 것은 거의 불가능할 정도로 중복된 정보가 많습니다. 이를 동영상 압축 알고리즘에서는 어떻게 처리할까요? 간단합니다. 두 이미지의 차이값을 이용하여 엔트로피가 낮은 정보를 이용합니다.

이런 특성을 활용하여, 저희 팀에서는 고해상도와 저해상도 이미지의 차이값만 구해서 이를 기존의 영상 코덱으로 압축하는 것으로 더 낮은 엔트로피의 영상을 압축하는 효과를 얻고자 했습니다.

 

아이디어 2: 고해상도는 하드웨어의 도움을 받자!

영상 압축 알고리즘은 해상도가 증가함에 따라 계산 복잡도가 기하급수적으로 증가합니다. 그렇기 때문에 스마트폰의 제한된 컴퓨팅 환경에서 소프트웨어 코덱으로 실시간 HD 영상 통화를 해내는 것은 버겁습니다. 이러한 상황에서 VGA와 QVGA까지 스케일러블 압축을 하는 것은 스마트폰에서는 거의 불가능한 도전이라 스케일러블 영상 압축을 스마트폰에서 실시간으로 하는 경우는 없다고 할 수 있습니다.

하지만 대부분의 스마트폰에 내장되어 있는 하드웨어 코덱을 활용하면 고해상도 영상도 실시간으로 스케일러블 압축할 수 있지 않을까 생각했습니다. 즉, 하나의 영상을 HD와 VGA, QVGA, 이렇게 세 개의 해상도로 압축할 경우라면 HD 영상은 하드웨어 코덱으로 압축하고 나머지 VGA와 QVGA는 소프트웨어 코덱으로 압축하는 것입니다. 그리고 각 해상도 영상의 중복된 정보는 위에서 설명드린 아이디어 1을 활용하여 제거하고 압축하면, 아무런 조작 없이 각각의 해상도를 따로 압축하는 것보다 낮은 비트율로 높은 화질을 달성할 수 있습니다.

아래 그래프는 HD(720p) 30FPS로 녹화된 10초 길이의 영상을 하드웨어 코덱과 소프트웨어 코덱으로 각각 압축하는 데 걸린 시간을 그래프로 그린 것입니다. 차이가 극명하게 나타난 것을 볼 수 있습니다. 소프트웨어 코덱은 50% 이상의 시간을 압축하는 데만 사용해야 하기 때문에, HD 해상도의 영상을 소프트웨어 코덱만을 이용해서 실시간으로 스케일러블 압축하는 것은 거의 불가능한 것을 알 수 있습니다.

하지만 고해상도 영상의 압축을 하드웨어 코덱에 맡기면 소프트웨어 코덱에서 사용한 시간의 20% 정도만 소비해 HD 영상을 압축할 수 있으므로 스케일러블 코딩에 필요한 시간을 충분히 확보할 수 있습니다.

또한 각 해상도 계층에 다른 코덱을 사용하면 압축 시간의 효율 외에도 얻는 이점이 있는데요. 저해상도 계층에 소프트웨어 코덱을 활용, 그 장점을 보여줄 수 있다는 점입니다. 예를 들어 하드웨어 코덱으로는 호환성에 문제가 있는 장치들 사이의 영상 통화도 소프트웨어 코덱으로 저해상도 계층을 압축하면 고해상도 계층은 무시한 채 저해상도로 서로 영상 통화가 가능해집니다.

 

하이브리드 코덱의 설계와 구현

저희는 하드웨어 비디오 코덱과 소프트웨어 비디오 코덱이 각각 다른 계층의 해상도를 압축하는 비디오 코딩 시스템을 만들고 내부적으로 ‘하이브리드 비디오 코딩 시스템’ 또는 ‘하이브리드 코덱’이라고 부르고 있습니다. 이 하이브리드 코덱의 특징은, 독립적인 비디오 코덱이 각각 다른 계층을 압축하고, 상위 해상도 계층 이미지는 하위 해상도 계층 이미지와의 차이값을 독립적인 다른 비디오 코덱에 영상 스트림으로 압축시켜서 중복된 정보를 최대한 제거하면서 스케일러블 스트림을 생성할 수 있다는 것입니다.

아래는 하이브리드 코덱의 구성을 나타낸 그림입니다.

고해상도의 원본 이미지와 해상도를 낮춘 저해상도 이미지를 각각 Encoder 0과 Encoder 1에서 압축합니다. Encoder 0에서 압축한 이미지는 디코딩하고, 디코딩된 이미지와 고해상도 이미지의 차이값을 구해서 Encoder 1에서 압축합니다. 이렇게 Layer 0 stream과 Layer 1 stream을 생성해서 사용자가 Layer 0의 해상도가 필요하면 Layer 0 stream만 전송하고, Layer 1 해상도가 필요하면 Layer 0과 Layer 1 스트림을 모두 전송합니다. 사용자의 단말은 Layer 0 stream을 디코딩한 이미지를 업스케일링(Up-scaling)한 뒤 Layer 1 stream을 디코딩해서 얻은 차이값을 더해서, 원본 이미지와 같은 해상도의 이미지를 얻을 수 있습니다. 여기서 하드웨어 코덱을 계산양이 더 많은 계층의 압축 코덱으로 활용하여 스마트폰과 같이 제한된 컴퓨팅 환경에서도 실시간으로 압축할 수 있습니다.

하지만 하이브리드 코덱을 개발하는 데 있어서 두 가지 문제가 있었습니다.

 

첫 번째 문제: 값의 범위

하이브리드 코덱의 설계를 구현하기 위해서는 계층이 서로 다른 두 이미지의 차이값을 마치 하나의 이미지처럼 만들어서 기존 코덱에 입력으로 주어야 했는데요. 특히 차이값의 범위가 기존 이미지 값의 범위와 달라지는 것이 큰 문제였습니다. 하이브리드 코덱의 차이값은 0 ~ 255가 아닌 -255 ~ 255로 범위가 더 크기 때문에, 1바이트로 한 화소의 차이값을 표현할 수 없습니다.

그렇다면 시간 연속된 이미지의 차이를 구해서 압축을 하는 기존 코덱에선 이 문제를 어떻게 해결하고 있을까 궁금해서 알아본 결과, 하이브리드 코덱에서 쓸 수 있는 방법이 아니었습니다. 아래 그림은 기존 코덱의 방법을 나타낸 그림입니다.

기존 코덱에선 시간적으로 연속된 두 이미지의 차이값을 short 자료형으로 저장해도 어차피 압축 과정에서 변환하고 양자화(quantize)하면서 압축되기 때문에 상관없지만, 하이브리드 코덱에선 기존 코덱을 수정 없이 독립적으로 이용해야 하기 때문에 계수 정보를 활용할 수 없었습니다.

1바이트로 표현할 수 없는 이러한 값 범위의 문제는 차이값을 양자화해서 해결했습니다. -255 ~ 255의 값을 2로 나눠서 양자화하면 -128 ~ 127로 양자화되어 1바이트로 표현할 수 있는 수가 됩니다. 비디오 코덱은 압축하면서 내부적으로 양자화하기 때문에 이렇게 미리 양자화하는 게 최종 압축 이미지의 품질에 끼치는 영향이 제한적이었습니다.

 

두 번째 문제: 2의 보수 표현

또 다른 문제는, 차이값은 2의 보수이며 음수로 표현한다는 점입니다. 그렇기 때문에 0xFF는 -1을 표현해서 0과 차이가 1이지만, 이 값을 그대로 코덱에 넣으면 두 픽셀의 차이를 255로 인식하게 됩니다. 이런 점은 압축 영상의 왜곡을 유발하기 때문에 반드시 해결해야 하는 문제입니다.

아래는 영상 차이값을 유발하는 위 문제를 표현한 그림입니다.

원본 이미지와 하위 계층 이미지를 다시 크게 만들어서 두 이미지의 차이를 구해보면 대부분의 값이 0 근처의 값입니다. 그런데 -1의 경우 2의 보수로 표현하기 때문에 0xFF로 저장되고, 이를 압축하는 코덱은 -1이 아닌 255라고 인식을 해서 압축할 때 왜곡을 발생시킵니다. 다행히 이 문제는 결과 값을 0x80만큼 시프트(shift)연산해서 해결할 수 있었습니다. 0xFF와 0x00을 0x80만큼 시프트 연산하면, 각각 0x79와 0x80이 되어서 차이가 1이 되고 비디오 코덱이 제대로 압축하게 됩니다. 나중에 디코더로 압축을 풀면 0x80을 다시 빼서 본래의 값을 구할 수 있습니다. 결국 시프트 연산하면 아래 그림과 같이 차이값을 구할 수 있습니다.

 

구현 결과 및 성능 평가

하이브리드 코덱은 현재 그룹 통화 리팩토링 및 품질 개선 프로젝트인 Constella 프로젝트에서 구현되어 LINE에 적용, 서비스하고 있습니다. 스마트폰에서 HD 해상도의 영상을 실시간으로 HD, VGA, QVGA를 모두 볼 수 있도록 스케일러블 압축을 합니다. 사용자는 그리드 뷰, 포커스 뷰 등 필요에 따라 다양한 해상도를 선택해서 실시간으로 볼 수 있으며, 네트워크 상황에 따라 다른 해상도를 서버에서 분배함으로써 그룹 통화에서 스케일러블 기능을 충분히 활용하고 있습니다.

아래 그래프는 하이브리드 코덱의 품질 성능을 보여줍니다. 성능 비교를 위해 사용한 VP9 SVC 코덱은 다양한 해상도의 스케일러블 코딩을 지원하는 소프트웨어 코덱으로 실험을 위해 실시간 코딩 옵션으로 설정한 뒤 하이브리드 코덱과 비교했습니다. 품질 성능에서 하이브리드 코덱이 더 좋은 성능을 보여주는 것을 확인할 수 있습니다. VP8 코덱은 다양한 해상도로 스케일러블 코딩을 지원하는 코덱은 아니지만, 하나의 해상도로만 압축하며 성능을 측정한 뒤, 하이브리드 코덱이 하나의 계층만 압축하는 것과 비교하면 어느 정도의 성능인지 보기 위해서 그래프에 추가했습니다. 그래프를 보면 하이브리드 코덱의 성능이 VP9 SVC와 VP8 사이 정도라는 것을 확인할 수 있습니다.

VP9 SVC 코덱의 실시간 옵션을 해제하고 비교하면 VP9 SVC의 품질 성능이 더 좋을 수 있으나, 해당 코덱은 압축에 시간이 너무 많이 소모되기 때문에 스마트폰에서 사용하기는 어렵습니다. 이번 실험은 하이브리드 코덱이 기존의 스케일러블 코덱과 비교해서 어느 정도의 품질 성능을 달성하는지 비교하기 위한 실험이었습니다.

하이브리드 코덱의 가장 큰 장점은 하드웨어 코덱을 활용하여 압축에 걸리는 시간을 획기적으로 줄일 수 있다는 것입니다. 이를 통해 스마트폰에서도 HD와 VGA, QVGA의 해상도를 다양하게 선택할 수 있는 스케일러블 데이터 스트림 압축을 실시간으로 해낼 수 있습니다.

아래 그래프는 10초 길이의 HD 영상을 30FPS로 압축할 때, 스마트폰(iPhone 8)에서 하이브리드 코덱이 소모하는 시간을 정리한 것입니다. L1과 L2, L3는 각 해상도 레이어의 압축 시간을 계산한 것이고, ETC는 각각의 코덱에서 소모된 시간 외에 차이값을 계산하거나 이미지의 해상도를 변경하는 데 소모된 시간입니다.

그래프를 통해 하이브리드 코덱이 데드라인(10초)의 56% 수준에서 압축을 완료하는 것을 알 수 있습니다. 여기서 특기할 만한 사항은, 가장 시간이 오래 걸리는 HD 계층의 압축을 하드웨어 코덱으로 진행하는 덕분에 그동안 CPU가 병렬적으로 다른 작업을 진행할 수 있다는 점입니다.

또한 중복 데이터를 제거하기 위해 각 계층의 압축 작업 외에도 기타 알고리즘이 소모하는 시간이 꽤 많은 것을 볼 수 있는데요. SIMD와 같은 기술을 이용하면 좀 더 최적화할 수 있어 추후 업그레이드할 계획입니다.

현재 연구 개발을 통해 영상 통화에 더욱 적합한 성능과 기능을 하이브리드 코덱에 추가하고 있습니다. 이러한 기술 개발과 함께 앞으로 그룹 영상 통화 플랫폼으로 더 많은 LINE 서비스가 출시되고, 더 많은 사용자들이 각각의 환경에 적합한 최적의 영상 품질을 즐길 수 있게 되길 기대합니다!