학창시절부터 DTV에 관심이 많았다. 학창시절만 해도 DTV만 제대로 되면 못할것이 없다고 믿었지만, 조금씩 현실을 인정해 가며 현재 스펙부터 하나하나 이해하며 조금씩 앞으로 나아가고 있다.
지털 방송이 이뤄지면서 고화질의 TV가 탄생되었다. 잡음이 없는, 화면 떨림이 없는, 잔상이 없는 TV. 디지털 방송은 수신이 제대로 되면 나오고, 수신이 미약하면 나오지 않는다. 아날로그 TV처럼 지지직거리면서라도 나오는 것이 아니다. 그것은 디지털이기 때문에 그렇다. 디지털 방송의 또 다른 특징 중의 하나가 EPG (Electronic Program Guide)를 제공한다는 것이다. EPG란 간단하게 말하면 ‘TV 편성표’를 의미한다.
예를 들면, 내가 TV를 보던 중 문득 토요명화에서 어떤 프로가 방영할 예정인지, 몇 시에 시작하는지 궁금하게 되었다고 하자. 이런 상황에서 내가 디지털 TV를 수신 중이었다면, 리모콘을 이용하여 ‘가이드’를 선택한다. 그러면 현재 채널에 대한, 혹은 전체 채널에 대한 TV 편성표의 정보를 볼 수 있다. 방송사에서 많은 양의 정보를 보내줄 경우, 프로그램에 대한 상세한 정보(줄거리, 등장 인물 등)까지 알 수 있다.
디지털 방송은 단순히 TV 편성표 열람으로 끝나지 않는다. 디지털 방송으로 전송되는 최소의 부가 정보인 PSIP(Program and System Information Protocol)는 현재 시간에 대한 정보를 알 수 있고, 15세 관람 불가와 같은 시청 제약 등을 사용할 수 있으며, EPG 정보를 사용할 수 있다.
이중 특히 유용한 정보라 할 수 있는 EPG 정보를 이용한다면, 지금까지 어렵게 사용됐던 예약녹화도 아주 간단히 사용될 수 있다. 몇 가지 예를 들면, 첫 번째가 TV 시청 예약이다. 드라마 시청 전의 광고가 나오고 있는 상황이라고 가정하자. 드라마가 시작되기 전의 광고는 평균 5분 정도 방영될 것이다.
하지만 나는 이 광고가 보기 싫고, 5분이란 시간 동안 다른 채널의 프로그램을 시청하고 싶은 경우가 있을 것이다. 이럴 경우, 디지털 TV의 시청 예약 기능을 이용할 수 있다. 즉, 이 상황에서 리모콘의 버튼을 이용해 다음 방송 프로그램의 예약을 수행한 후, 채널을 아무 곳으로나 돌린다. 돌리던 중 잠깐 휴식을 취할 방송 프로그램에서 채널을 멈춰 이 채널을 시청하고 있는 동안 예약된 방송 프로그램이 시작하는 시점에서 채널은 자동으로 드라마 프로그램 채널로 전환된다.
다음으로 EPG를 이용한 예약 녹화이다. 지금까지 우리는 방송을 녹화하려 할 때 현재 시간을 정확히 입력하고, 녹화하려는 프로그램의 시간 또한 정확히 입력해야만 제대로 된 녹화가 가능했다. 혹은 시간의 오차로 인해 처음부터 녹화되지 않거나, 녹화 프로그램이 끝까지 녹화되지 않은 불상사가 발생하는 경우도 있었다.
하지만 EPG를 이용해 녹화를 예약한다면 시간을 설정할 필요 없이 단지 디지털 TV의 TV 편성표 화면에서 커서를 움직여 선택함으로써 간단하게 예약 녹화를 수행할 수 있을 것이다. 또한 녹화 프로그램이 처음부터 녹화되지 않거나, 끝까지 녹화가 되지 않는 불상사를 방지할 수 있으며, 정확한 시간동안 예약한 프로그램의 녹화가 가능케 된다.
디지털 TV에서 이러한 모든 것들이 가능한 이유는 ATSC에서 제시한 PSIP의 부가 정보를 이용하기 때문이다. 물론 이러한 기능이 모든 디지털 TV나 셋톱박스에서 가능한 것은 아니다. 제조업체에서 ATSC의 PSIP 정보를 어떻게 이용하느냐에 따라 제품적인 차이점이 있을 수 있다. 녹화 또한 DVR이나 PVR이라는 제품을 통해 일반 녹화 테이프가 아닌 하드디스크를 이용해 녹화한다(JVC의 경우 디지털 녹화 테이프를 이용한다).
여기서는 크게 두 가지를 설명할 것이다. 첫 번째가 우리 머리 위로 돌아다니는 방송파(Transport Stream, 이하 TS)가 만들어지는 과정과 분석하는 과정이고, 두 번째가 TS에서 EPG 데이터(ATSC A/65a spec)를 추출하는 방법, 즉 ATSC의 PSIP 분석에 관한 내용이다.
이번 호에서는 TS가 만들어지는 과정과 TS 헤더의 구조, PES 패킷 헤더(packet header)의 구조에 대해 알아볼 것이고, 다음 호에서는 EPG를 구성하는 실제 데이터인 PSIP의 구조(STT, MGT, VCT, RRT, EIT, ETT 섹션)와 각각의 섹션마다 주어진 역할을 살펴본 후 분석해 볼 것이다. 마지막으로 비주얼 C++를 이용한 PSIP 분석기(analyzer)를 제작하는 방법에 대해 고려해 보도록 할 것이다. 생소한 약자들이 많이 사용돼 어리둥절하겠지만, 차근차근 모든 것을 알아볼 것이니 너무 어려워하지 말고 잘 따라오기 바란다.
디지털 방송이 만들어지는 과정
디지털 방송의 실제 데이터인 TS가 만들어지는 과정에 대해 알아보자. 영상 데이터가 디지털 방송의 실제 데이터인 TS로 변화하기 위해 거치는 인코더와 생성(generator), 그리고 MUX에 대해 알아볼 것이다. 이 때 데이터가 어떤 식으로 변형되는지 변화 과정 또한 알아볼 것이고, 마지막으로 각각의 인코더와 MUX를 거치기 전과 거친 후의 변화되는 모양새를 살펴볼 것이다.
디지털 방송 TS의 생성 원리
우선 PES(Packetized Elementary Stream) 패킷이 무엇이고, TS가 무엇인가에 대해 알아보자. TS는 ‘Transport Stream’의 약자이다. 즉, 디지털 방송을 전송하는 실제 데이터들의 연속적인 모임을 말하는 것이다. 방송사에서는 TS를 전송하고, 수신측(DTV, 셋톱박스)에서는 이 TS를 받아서 디코딩해 화면에 영상을 표시하고, 음성을 들려주고, 여러가지 부가 서비스를 위한 정보를 골라내 사용한다. 이때 사용되는 영상은 MPEG-2(ISO/IEC 13818-1)이고, 음성은 AC3(돌비 디지털 사운드)를 사용한다.
이 TS는 몇 가지 특징이 가지고 있다. 첫 번째가 TS는 일련의 TS 패킷이란 것으로 구성되는데, TS 패킷들은 각각의 길이가 188바이트로 일정하다는 것이고, 두 번째가 TS의 데이터 구조는 복수 프로그램을 운반하기 위한 목적으로 ITU-T(구 CITT)에 의한 표준인 ATM 방식과 유사하다는 것이다.
이러한 TS가 생성되는 과정을 간략하게 알아보도록 하자. <그림 1>은 실제 영상과 음성이 방송파(TS)로 변하는 과정을 나타낸다. 실제 영상을 받아서 MPEG-2로 변환(encoding)하고, 음성은 AC3로 변환한다. 이것을 각각의 비디오 ES, 오디오 ES라고 한다.

그림1
이 ES를 가변적 크기로 잘라낸 후 헤더를 붙여 PES 패킷으로 변환한다. 이 PES 패킷의 크기는 고정되지 않고 가변적이다. 이 PES 패킷을 고정된 크기 188바이트로 잘라내고 헤더를 붙여(헤더 포함 188바이트) TS 패킷으로 변환한다. 만들어진 TS를 주파수에 실어 전송한다고 간단하면서도 어렵게 설명할 수 있다. 그럼 좀더 세부적으로 살펴보도록 하자.
싱글-프로그램 인코더가 PES 패킷이 생성되는 부분
디지털 방송은 MPEG-2를 사용한다. MPEG-2는 비디오와 오디오가 따로 구성된다. 그렇기 때문에 <그림 1>의 싱글 프로그램 인코더(single-program encoder) 부분을 보면 비디오와 오디오가 각각 인코딩된다. 그럼 우선 비디오 하나만 가지고 살펴보도록 하자.
<그림 1>을 보면 ‘Video → [MPEG-2 Encoder] → MPEG-2 Bitstream → [Transport Mux] → SP transport Stream’으로 표현된다. 여기서 비디오 데이터가 MPEG-2 인코더를 거쳐서 생성되는 MPEG-2 비트스트림이 ES를 의미하고, 이 ES가 Transport Mux를 거쳐서 생성되는 것이 PES 패킷을 의미한다.
SP(Single Program) 트랜스포트 스트림과 MP(Multi Program) 트랜스포트 스트림으로 나눠지는 이유는 디지털 방송이 멀티채널의 구현이 가능하기 때문이다. 멀티채널이란 하나의 방송 프로그램 영역에 여러 개의 프로그램을 같이 포함시켜 서로 다른 프로그램을 송출하는 것을 의미한다. 간단한 예를 들자면 8번 채널에서 8-1, 8-2, 8-3, 8-4와 같이 8번 채널이 4개로 분할되어 4개의 서로 다른 프로그램의 방영이 가능한 것을 말한다. 우리나라에서의 디지털 지상파 방송 규격은 HD(고화질 디지털 방송)이기 때문에 다채널이 제공되지 않는다. 다채널을 사용하기 위해서는 SD(일반화질 디지털 방송)급의 방송을 사용한다. 외국이나 위성 방송에서는 SD를 사용한다.

싱글-프로그램 인코더 부분을 좀더 상세하게 표현한 <그림 2>를 살펴보자. Video Data가 Video Encoder를 거쳐서 Video ES가 만들어지고, 생성된 Video ES가 Packetizer를 거쳐서 Video PES 패킷으로 변환된다. 그럼 PES 패킷이란 무엇인가? 그것은 ‘The data structure used to carry elementary stream data. It consists of a PES packet header followed by PES packet payload and is described’라고 13818-1에 표현되어 있다. 정확한 이해를 위해 원문을 적었다.
정리하자면 비디오 인코더를 이용해 ES가 생성된다. 이 ES는 비디오의 처음부터 끝까지의 일련의 데이터이다. 이것을 그대로 전송할 경우, 잡음에 의한 데이터 손실이 있을 수 있고, 혹은 데이터의 분실이 생길 수도 있다. 그렇기 때문에 원활한 전송을 위해 ES를 나누고, 나눈 각각에 헤더를 포함시켜서 연결 정보 및 데이터의 손상 여부에 대한 정보 등을 추가시켜 수신측에서 데이터를 원활히 수신하도록 만드는 것이다. 이것이 바로 PES 패킷인 것이다. 만약에 중간에 PES 패킷 한 개를 유실했더라도 유실된 정보를 알 수 있기에 디코딩에 실패하지 않고 복구할 수 있다.

그림2

그림3
그래서 패킷타이저(packetizer)를 거침으로써 ES에 헤더가 포함되고 일정하지 않은 크기로 잘라낸 패킷을 만드는 것이다. PES 패킷의 헤더에는 이것들의 순서의 정보도 가지고 있고, 다른 정보들이 왔을 때 무시하는 아이덴티파이어(identifier) 정보도 포함하는 것이다. 변화의 과정이 <그림 3>처럼 표현되는 것이다.
- ◆ <그림 1>의 PSI과 PSIP 제너레이터 부분이 PSI, PSIP가 생성되는 부분이다
싱글-프로그램 인코더 부분은 MPEG-2를 위한 부분이고, PSI와 PSIP 제너레이터 부분은 MPEG-2의 디코딩 정보와 부가 정보가 만들어지는 부분이다. PSIP에 관한 세부 내용은 다음 호에서 설명하도록 한다.
◆ <그림 1>의 트랜스포트 MUX 부분이 TS가 생성되는 부분이다

싱글-프로그램 인코더 부분의 수행으로 우리는 PES 스트림(PES 패킷들의 연속된 모임을 PES 스트림이라고 한다)을 얻었다. 이 PES 스트림을 이용해 TS 혹은 PS가 생성된다. PES 스트림이 TS Mux를 거치면 TS가 생성되고, PS Mux를 거치면 PS가 생성되게 되는 것이다.
그림4
PES 패킷의 TS 생성 과정을 살펴보면 PES 패킷만을 이용해 TS를 생성하는 것이 아니라, PSI와 PSIP 제너레이터를 이용해 생성된 PSI, PSIP 섹션도 함께 TS Mux에 삽입해야 한다. 그러면 완전한 TS가 생성되는 것이다. 싱글-프로그램 인코더에서 생성된 PES 스트림과 PSI와 PSIP 제너레이터에서 생성된 PSIP, PSI 섹션을 가지고 TS Mux(MP Transport Mux)가 TS(188바이트)를 만드는 것이다. 이것이 주파수를 타고 날아오는 실제 데이터이고, 실제 수신측은 이것을 받아 디코딩해 화면과 영상을 보여주는 것이다.
여기까지 실제 비디오 데이터가 TS로 변화되는 과정에 대한 원리를 살펴보았다. 다음으로 데이터 구조에 대해 살펴보도록 하자.
단위 모양새가 궁금하다
ES가 TS로 변하는 과정에서의 데이터 구조의 변화에 대해 자세히 살펴보도록 하자. <그림 5>를 참조한다.

그림5
<그림 5>의 ①번은 ES를 나타낸다. 이것이 오디오인지 비디오인지는 중요하지 않다. 그 이유는 같은 방식이기 때문이다. 우선 ES(오디오 또는 비디오)가 있다고 가정한다. ②번이 패키타이저를 통해 ES를 일정하지 않은 크기(일정한 형식에 맞추어)로 잘라낸 후 헤더를 추가해 PES 패킷이 생성된 모습을 표현한 것이다. PES 패킷 옆에 있는 것이 PSIP 제너레이터로 생성된 PSIP 섹션이다.
③번이 TS Mux를 통해 PES 스트림과 PSIP 섹션을 TS로 변환한 모습을 표현한 것이다. 이것 역시 헤더가 추가되며, PES 스트림을 이용해 TS를 만드는 사이사이에 PSIP, PSI 섹션도 같이 추가되어 하나의 TS가 완성되는 것이다. 실제 TS가 만들어지기 위해서는 한 개의 원본에(ES) 두 개의 헤더가 각기 추가됨을 알 수 있다. 그렇기 때문에 역으로 TS에서 원본을 추출하기 위해서는 두 개의 껍데기를 벗겨내야 하는 것이다.
TS를 자세히 살펴보니 데이터 영역에 스터핑(stuffing)이란 것이 새롭게 추가된 것을 알 수 있다. <그림 5>와 <그림 6>에 포함된 스터핑이란 것은 무엇인가? 실제적인 데이터 크기를 고려해 스터핑이 무엇이고, 왜 생겼는지에 대해 알아보자.

그림6
스터핑이란 TS가 188바이트라는 고정된 크기를 갖는 특성 때문에 생긴 것으로 빈 공간에 채워지는 의미 없는 데이터를 의미한다. 예를 들면 PES 패킷의 크기가 300바이트라고 가정하자. 이것을 TS로 변환하려면 최소 2개의 TS를 사용해야 한다. 참고로 TS 헤더의 크기는 4바이트이다. 즉 데이터로 사용할 수 있는 크기는 ‘188 - 4 = 184바이트’이다(어댑션_필드(adaptation_field)가 아닌 데이터_바이트(data_byte)가 올 때만 적용된다).
그렇기 때문에 ‘300/184 = 1과 116’의 나머지의 값이 2개의 TS에 나누어 저장되고 ‘184 - 116 = 68바이트’ 값을 스터핑이라 하는 것이다. 이 스터핑의 값은 모든 비트는 아무런 의미 없는 ‘1’로 채워지게 된다. 그렇기 때문에 수신측에서 디코딩할 때에 이 값은 모두 버리게 되는 것이다. <그림 6>을 참고하도록 한다.
여기까지 실제 비디오 데이터가 TS로 변화되는 과정에 대한 원리와 구조까지 살펴봤다.
다음으로 TS에서 PSIP 정보를 추출해 내는 방법과 PSIP의 스펙에 대해 자세히 알아보도록 하자.


TS, PES 패킷의 헤더 신텍스
헤더 신텍스
지금까지 TS의 원리와 구조에 대해 알아봤다. 이제는 신텍스(syntax)에 대해 알아볼 차례다. 지금까지 공부한 내용을 이해했기를 바란다. 만약 TS의 원리와 구조를 이해하지 못했다면 신텍스 부분으로 넘어가서는 안 된다. 구조를 이해하지 못한 채 신텍스를 이해하려 하는 것은 잘못된 방법이다. 만약 신텍스를 완벽히 이해했다고 하더라도 구조를 이해하지 못했다면 그건 그림조각 맞추기 퍼즐에서 하나하나의 그림조각 모두를 이해했지만, 그림조각을 하나로 맞추어 완벽한 하나의 그림을 만들 수 없는 것과 같다고 할 수 있다. 그렇기 때문에 지금까지 공부한 원리와 구조가 이해되지 않았다면 다시 한 번 차근차근히 읽어 본 후 다음 부분으로 넘어가야 할 것이다.
샘플 TS 비트
이제 실제 TS 하나를 살펴보고, 분석하는 것이 TS를 이해하는 가장 좋은 방법이다. 필자 역시 처음 ISO/IEC 13818-1과 A/65A 스펙을 봤을 때는 정말 막연하고 답답했지만, 실제 비트 열을 A4지에 출력해 싱크_바이트(sync_byte)를 찾고, 다음으로 오는 트랜스포트_에러_인디케이터(transport_error_indicator)를 찾고, 다음으로 오는 것들을 스펙을 보면서 하나하나 신텍스에 맞게 구별해 보았다. 이렇게 TS를 구별하고 구별된 TS를 손으로 그려가며 분석을 해보니 신텍스에 대한 이해가 아주 쉽게 되었다.

표1
<표 1>은 실제 1개의 TS(188바이트)를 나타낸 것이다. 이와 같이 TS 수만 개가 모여서 하나의 프로그램(방송)을 이루는 것이고, PSIP 정보를 분리해 EPG를 표현하는 것이다. 이어서 설명이 될 PSIP 신텍스를 이용해 연필과 색연필을 들고 TS 헤더, PSIP 헤더를 분석해 보면 <표 1>이 어떤 테이블을 의미하는지 쉽게 찾을 수 있을 것이다. 앞의 TS는 PSIP의 MGT 섹션이 전송되는 TS이다(MGT 섹션에 관한 신텍스는 다음 호에서 다룰 것이다).
이제 본격적으로 TS 헤더의 신텍스에 대해 알아보도록 하자. 신텍스를 모두 표현하기에는 지면이 허락하지 않는 관계로 중요한 것들만을 살펴보도록 하자.
TS 헤더 신텍스
188바이트로 이뤄진 TS 중 최초부터 4바이트까지의 부분으로써 기본적인 정보를 표현한다. <그림 7>은 TS를 다이어그램으로 보기 쉽게 나타낸 것으로 ISO/IEC 13818-1 스펙에서 인용한 그림이다. 이 문서는 TS 및 PSIP 분석을 위한 문서이므로 어댑션_필드에 관한 내용은 설명하지 않는 것을 양해하기 바란다. 필드에서 어댑션_필드_컨트롤(adaptation_field_control)의 값을 판단해 패이로드(payload) 값이 데이터인지, 어댑션_필드인지를 판별하게 된다.

그림7
이 문서는 어댑션_필드_컨트롤의 값이 01인 경우만을 사용한다. 그렇기에 <그림 7>에서 참고할 부분은 빨간 테두리 안의 내용만 참고하면 될 것이다. <그림 7>에 나타난 부분 외에 아래 부분을 TS 헤더라고도 한다. TS의 헤더 크기는 4바이트이고 패이로드(데이터)의 크기는 184바이트이다. 패이로드 부분에 스터핑 데이터가 포함되기도 한다. 184바이트보다 큰 하나의 섹션을 구성하기 위해서는 컨티뉴티_카운터(continuity_counter)를 이용해 여러 개의 패이로드(데이터)를 합쳐서 1개의 섹션을 구성할 수 있다. TS 헤더의 시작은 항상 0×47로 시작하기 때문에 1바이트씩 읽어서 0×47을 찾아 싱크를 맞추면 된다.


TS 헤더의 필드 값은 다음과 같이 정의된다.
- ◆ 싱크_바이트(sync_byte) : 항상 ‘0100 0111‘(0×47)의 값을 갖는다.
◆ 트랜스포트_에러_인디케이터 : 1비트의 플래그(flag) 값이다. 항상 0의 값을 가져야 한다. 트랜스포트 레이어 부분에 문제가 발생되었을 때 이 값은 1로 셋팅이 된다.
◆ 패이로드_유니트_스타트_인디케이터(Payload_unit_start_indicator, pusi) : pusi가 ‘1’이면 PES 패킷의 첫 번째 부분임을 나타낸다. 여러 개의 TS가 모여서 하나의 PES 패킷을 구성할 때 pusi가 ‘1’인 것을 먼저 찾은 후 컨티뉴티_카운터 값의 연속성을 이용해 다음 TS를 찾아내어 합치면 하나의 PES 패킷을 구성할 수 있게 된 것이다. Pusi가 ‘0’이라면 PES 패킷의 시작 부분이 아니라 중간, 혹은 마지막 부분임을 의미한다. Pusi가 ‘1’일 경우 8비트의 포인터_필드가 추가된다(PSI의 경우).
◆ 트랜스포트_프라이어티(Transport_priority) : 같은 PID가 들어 왔을 때, 이 값이 ‘1’로 셋팅된 TS의 우선 순위가 높다.
◆ PID : 13비트의 패킷 ID 이다. PID 테이블의 정의는 <표 3>과 같다.
◆ 트랜스포트_스크램블링_컨트롤(transport_scrambling_control) : ‘00’의 값은 ‘not scrambled’를 의미하고 그 외의 나머지 값들은 정의되지 않았다(not defined).
◆ 어댑션_필드_컨트롤(adaptation_field_control) : 2비트의 값으로 헤더 다음에 나오는 데이터가 어댑션 필드인지 혹은 패이로드인지 구별하는 값이다. 그 구별 값의 정의는 <표 4>와 같다.
◆ 컨티뉴티_카운터 : 같은 PID를 갖는 TS 패킷에 사용되며, 0부터 4비트의 최대 표현 값까지 사용된다. 어댑션_필드_컨트롤 값이 ‘00’, ‘01’ 일 경우에는 이 값이 증가되어서는 안 된다.



PES 패킷 헤더 신텍스
<그림 8>의 신텍스는 PES 패킷을 나타낸 것이다. TS 중에 PSI 섹션과 구별된다고 생각할 수 있다. TS에서 PES 패킷을 찾는 방법은 TS 헤더의 PID 값 중 0x0010~0x1FFF의 값을 갖는 것들이 PES 패킷이 될 수 있다. 물론 이중에 PSI 섹션의 NIT와 PMT도 포함될 수 있음을 상기하고 구별해야 한다. 우선은 PES 패킷의 최소 헤더 부분만을 이해하기 위해 <그림 8>에서 참고할 부분은 빨간 테두리 안의 내용만 참고하면 될 것이고, 우선은 최소 헤더 부분만 설명하도록 하겠다.

그림8
PES 패킷 헤더의 필드 값은 다음과 같다.
- ◆ packet_start_code_prefix : 패킷의 시작을 알리는 고정된 값으로 ‘0000 0000 0000 0000 0000 0001’(0x000001)의 값을 갖는다.
◆ Stream_id : 스트림 타입에 관한 값이 정의되어 있다. 정의된 값은 <표 5>를 참고한다.
◆ PES_packet_length : 16비트의 PES 패킷의 바이트 값을 나타낸다. TS의 비디오 엘리먼터리 스트림의 패이로드 값을 나타내거나, 포함할 경우 ‘0’의 값으로 셋팅이 이뤄진다.

다음에는 PSIP에서 사용되는 실제 바디 부분의 신텍스와 C++ 구조를 이용한 PSIP 분석기를 구현하는 방법에 대해 고려해 보도록 하자.@