비디오js의핵심 트랜스믹서인 Mux.js를빌드하는 동안 우리는Mux.js의 출력이 올바른지 어떻게 확인할 수 있을까 하는 문제에 직면했습니다.
초기에 저희는 FFmpeg를 코엑싱하여 MPEG2-TS 세그먼트에서 MP4를 만들어 브라우저에서 재생하는 방법을 알아냈는데, 당시에는 Chrome만 가능했습니다. 하지만 트랜스룩서의 출력과 FFmpeg에서 생성된 출력을 간단하게 비교할 수 있는 방법이 필요했습니다. 두 출력의 바이트가 동일할 가능성은 거의 없기 때문에 MP4 형식을 염두에 두고 비교해야 했습니다.
MP4 인스펙터 구축
이 문제에 대한 해답은 MP4를 파싱하고 관련 상자와 그 내용에 대한 일종의 JSON과 같은 덤프를 표시하는 도구인 mp4 인스펙터를 구축하는 것이었습니다. Mux.js에서 출력 덤프를 생성하고 FFmpeg로 생성된 알려진 좋은 조각과 비교하여 트랜스럭서의 출력이 어디에서 다른지 확인할 수 있었습니다.
MP4 인스펙터는 두 세그먼트의 차이를 그래픽으로 색상으로 구분할 수 있도록 웹 페이지로 제작되었습니다. 시간이 지나면서 페이지에 비디오 요소가 추가되었고, 세그먼트 트랜스믹싱 결과를 비디오 요소의 미디어소스에 직접 추가하여 Mux.js의 변경 사항에 대한 즉각적인 피드백과 검증을 지원하기 시작했습니다.
개발이 계속되면서 가끔 새롭고 흥미로운 방식으로 실패하는 스트림이 발생하기도 했습니다. 이러한 실패 중 일부는 Mux.js의 버그로 인한 것이었습니다. Mux.js 자체가 더욱 견고해지면서 스트림의 문제나 MSE 사양의 특정 구현 문제로 인한 실패가 점점 더 많이 발생했습니다.
결국 동영상 내부에서 어떤 일이 일어나고 있는지 더 자세히 알아볼 필요가 있다는 사실을 깨달았습니다. 미디어 컨테이너 수준에서 일어나는 일뿐만 아니라 더 깊이 들어가서 동영상 데이터 자체를 들여다볼 필요가 있었습니다. 이를 위해 썸코일을 만들었습니다.
Thumbcoil은 MP4 또는 MPEG2-TS 컨테이너 파일에 포함된 H.264 동영상 비트스트림의 내부를 들여다볼 수 있도록 설계된 도구 모음입니다. Thumbcoil의 도구를 사용하면 지원되는 두 가지 미디어 컨테이너 형식의 내부 구조를 자세히 살펴볼 수 있습니다.
또한 이 도구는 H.264 비트스트림을 구성하는 가장 중요한 NAL 유닛에 포함된 정보를 보여주는 기능도 제공합니다. 동영상 인코더가 디코더가 사용할 수 있도록 어떤 종류의 비밀 정보를 숨겨 놓았는지 궁금한 적이 있나요? 썸코일을 사용하면 직접 확인할 수 있습니다.
MP4 인스펙터를 구축한 이유
2016년에는 미디어 컨테이너의 구조와 컨테이너에 포함된 데이터를 어느 정도 그래픽으로 표시할 수 있는 좋은 도구가 거의 없었습니다. 동영상 재생 문제를 디버깅하는 작업은 일반적으로 여러 가지 난해한 FFmpeg 및 FFprobe 주문을 사용하는 지루한 작업입니다. 안타깝게도 FFprobe는 관심 있는 데이터의 일부만 출력할 수 있는 것이 최선입니다.
예를 들어 다양한 매개변수 세트 내부의 정확한 데이터는 명령줄을 통해 확인할 수 없습니다. FFprobe 내부에서 해당 데이터는 파싱되어 저장되지만 사람이 읽을 수 있는 형태로 정보를 덤프할 수 있는 쉬운 방법은 없습니다.
H.264에는 두 가지 특별한 유형의 NAL 단위가 있습니다. seq\_parameter\_set
(SPS) 및 pic\_parameter\_set
(PPS). 이 두 개의 NAL 유닛에는 많은 정보가 포함되어 있습니다. 디코더는 비디오를 재구성하기 위해 이 정보를 필요로 합니다.
썸코일은 매개변수 세트 정보를 매우 상세하게 제공할 뿐만 아니라 정보가 포함된 박스나 지정한 프레임 등 주변 컨텍스트와 함께 정보를 유지합니다. 이러한 컨텍스트는 스트림의 문제나 특성을 이해하는 데 매우 중요한 역할을 합니다.
MP4 인스펙터를 구축한 방법
Thumbcoil이 매개변수 집합을 구문 분석하는 방식에서 흥미로운 점 중 하나는 각 NAL 단위 유형에 대해 내부적으로 "코덱"이라고 불리는 것을 구축한다는 점입니다. 이러한 코덱은 본질적으로 멋진 파서 결합기 유형의 설정을 사용하여 지정됩니다.
두 매개변수 세트의 데이터 대부분은 지수-골롬 인코딩이라는 방법을 사용하여 저장됩니다. 이 방법은 가변 비트 수를 사용하여 숫자를 저장하며 특히 크기가 작은 값에 적합합니다.
코덱을 빌드하는 데 사용되는 각 함수는 디코딩과 인코딩의 두 가지 함수가 있는 객체를 반환합니다. 즉, 예를 들어 예를 들어 seq\_parameter\_set
NAL 단위를 한 번만 입력하면 해당 특정 NAL 단위의 비트 스트림에서 구문 분석하고 해당 비트 스트림에 쓸 수 있습니다.
NAL 단위 코덱을 지정하는 데 사용되는 문법은 H.264 사양(ISO/IEC 14496-10)에서 사용하는 문법과 매우 유사합니다. Thumbcoil의 코덱이 이해하는 데이터 유형은 일부 확장을 제외하고는 부호 및 부호 없는 지수 골롬 인코딩 정수 등 사양에 정의된 것과 동일한 유형일 뿐입니다.
파라미터 세트 외에도 Thumbcoil은 슬라이스 레이어 자체의 구조에 대한 인사이트를 제공합니다. slice\_header
데이터를 파싱합니다. 하지만 실제 데이터를 파싱하는 데 그치지 않고 slice\_data
세부 사항으로 내려갈수록 일이 더 어려워지고 유용성이 떨어지기 때문입니다.
모든 Video.js 프로젝트와 마찬가지로 Thumbcoil은 오픈 소스 소프트웨어이며 Github에서 제안, 문제 및 기여를 환영합니다.
기술 용어집
- 트랜스럭서. 트랜스럭서는 특정 파일 형식에 포함된 미디어를 가져와 내부에서 압축된 원본 비디오와 오디오를 추출하고(디멀싱이라고 하는 프로세스) 재압축을 수행하지 않고 압축된 데이터를 다른 형식으로 다시 패키징(리멀싱이라고 하는 프로세스)합니다.
- MP4. MP4 파일은 박스 계층형 논리 단위로 구성되며, 편리하게도 모두 32비트 길이와 32비트 박스 유형으로 시작됩니다. 박스는 종종 다른 하위 박스를 포함합니다.
- 미디어 컨테이너. MP4와 같은 미디어 컨테이너 내부에는 비디오와 오디오가 비트스트림이라는 데이터에 포함되어 있습니다. 비트스트림은 인코더가 오디오 신호 또는 비디오 프레임을 표현하기 위해 생성하는 데이터입니다. 일반적인 비트스트림으로는 오디오의 경우 AAC, 비디오의 경우 H.264(AVC)가 있습니다.
- NAL 단위. H.264로 인코딩된 비트스트림은 네트워크 추상화 계층(NAL) 단위로 구성됩니다. NAL은 비트를 최대한 효율적으로 사용하도록 설계된 간단한 패킷 형식입니다.