1. PCR (Program Clock Reference)
    TS stream에서 프로그램에 대한 상대적인 시간 기준값을 나타내고 식 (1)과 같이 계산 할 수 있다.
         PCR_base(i) = ( ( system_clock_frequency x t(i) ) DIV300 ) % 2^33
         PCR_ext(i) = ( ( system_clock_frequency x t(i) ) DIV1 ) % 300                                                                        식 (1)
         PCR(i) = PCR_base(i) x 300 + PCR_ext(i)

         여기서 i는 i번째 byte를 의미하고 t(i)는 i번째 byte가 T-STD에 입력되는 시간을 나타낸다.
         system_clock_frequency는 27Mhz이고

                       27Mhz - 810hz ≤ system_clock_frequency ≤ 27Mhz + 810hz
                       system_clock_frequency의 시간변화율 ≤ 75 x 10^-3hz/sec

         이라는 제한을 갖는다.

식 (1)에서 알 수 있듯이 PCR_base는 90Khz 단위로 33bit로 표현되고 PCR_ext는 27Mhz단위로 9bit로 표현된다. 이런 이유로 TS header의 adaptation field나
PES header에 시간 정보는 42 (33 + 9)bit를 이용하여 표현하도록 되어 있다.
    PCR값은 인코더의 system clock으로부터 만들어지게 된다. i번째 byte가 인코더로부터 생성되어 TS stream으로 만들어지는 과정에서 i번째 byte가 만들어진
시점의 PCR 값이 생성되는 것이다. 디코더에서는 이 PCR 값을 수신하여 현재 디코딩 하려는 프로그램의 기준 시간값으로 설정하고 뒤에서 설명할 DTS, PTS 시간을
이 PCR값과 비교하여 디코딩을 하고 재생을 하게 된다.

2. DTS (Decoding time Stamp)
    DTS는 STD에서 ES가 디코딩 되어야 하는 시점을 나타내는 값으로 system_clock_frequency의 1/300 (90Khz)단위로 표현이 된다. 식 (2)는 DTS를 계산하는 방법을
보여준다.

         DTS(j) = ( ( system_clock_frequency x tdn(j) ) DIV300 ) % 2^33                                                                    식 (2)

         여기서 tdn(j)는 n번째 ES의 j번째 access unit이 디코딩 되어야 할 시간을 나타낸다.
        
예를 들어 앞서 설명한 PCR값이 10000이고 DTS(j)값이 20000이라면 디코더는 PCR이 20000이 될때까지 10000만큼 디코딩을 delay 시켜야 한다. 즉 디코더는 j번째 byte를
수신한 뒤 10000 x 300 / system_clock_frequency (약 111 μsec)만큼의 절대 시간을 기다리고 나서야 디코딩을 할 수 있다는 것이다. 여기서 또 생각해야 하는 부분은 delay가
발생함으로서 생기는 stream buffering 문제이다. 만약 1Mbps의 전송속도를 갖는 환경에서 앞의 예를 이어서 설명을 한다면 111 μsec동안 약

         111000 (1Mbit x 111 μsec) bit를 더 수신하게 된다.

이정도의 스트림을 디코더에서 저장, 관리 할 수 있어야 한다는 얘기가 된다. Delay가 길어지면 길어질 수록 관리해야 하는 buffer의 크기는 커질 수밖에 없다. 그리고 DTS를
계산하는 식은 정확히 떨어지는 연산이 아니기 때문에 어느 정도의 오차 (300 / system_clock_frequency)도 고려를 해야한다. 이 부분이 잘못 구현되면 buffer의 overflow나
underflow가 발생하여 시스템을 불안정하게 만들 수도 있다.


3. PTS (Presentation Time Stamp)
    PTS는 디코딩 된 access unit이 재생되어져야 하는 시점을 나타내는 값으로 식 (3)과 같이 계산된다.

          PTS(j) = ( ( system_clock_frequency x tpn(j) ) DIV300 ) %2^33                                                                     식 (3)

    PTS도 DTS와 마찬가지로 PCR을 reference로 사용하여 PTS(j) 시간에 재생을 하게 된다. B_picture가 포함되어 있는 비디오의 경우 I_picture와 P_picture는 디코딩 되야 하는
시각과 재생되어져야 하는 시각이 다르기 때문에 PTS와 DTS 정보 모두를 전송하게 되고 B_picture의 경우는 디코딩과 동시에 재생이 되어야 하기 때문에 PTS와 DTS값이 동일하다.
이 경우에는 DTS정보는 생략하고 PTS값을 전송하고 이 값을 DTS값으로 같이 사용하여 디코딩 시점을 결정하게 된다.

    PTS와 DTS는 모두 최대 0.7sec 이내 (PCR은 0.1sec) 에 적어도 한번씩은 정보를 보내도록 되어 있기 때문에 모든 picture에 들어가지는 않을 수도 있다. 시간 정보가 없는
경우는 디코더에서 자체적으로 시간을 interpolation하여 사용하게 된다.


이올린에 북마크하기
Writer profile
DDURI
Posted by dduri.
TAGS , , ,

Leave your greetings here.

[로그인][오픈아이디란?]

0과 1이나 true/false같은 switch개념의 변수를 사용하려면 C언어에서 최소사양에 해당하는 char형을 생각해 볼 수 있습니다. 물론 int형이나 그 밖에 다른 형을 써도 상관은 없지만 1Bit만 있으면 되므로 굳이 많은 Data형을 할당하여 Memory를 낭비할 필요는 없습니다.

그런데 char형도 그리 효츌적이지는 않습니다. 왜냐하면 char는 1Byte단위(8bit)이므로 0과 1을 표시하는데 1Bit를 할당하고 나면 나머지 7Bit는 결국 낭비되기 때문입니다.

따라서 C에서는 Bit단위의 Data를 다룰때 해당 Bit영역을 최대한 활용하기 위해 Bit Field라는 것을 사용합니다.

Bit Field는 선언하고자 하는 Data형의 크기 만큼 Bit Field를 구조체 형식으로 선언하면 됩니다.

struct bitfield{
    unsigned char a : 1;
    unsigned char b : 1;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
    unsigned char f : 1;
    unsigned char g : 1;
    unsigned char h : 1;
};

bitfield라는 이름으로 unsigned char형(8bit)의 a부터 h까지 Bit Field를 선언하였습니다.

unsigned char라고 한 이유는 char형의 전체 8Bit중 최상위 Bit(부호를 정하는 bit)까지 모두 사용하기 위해서 입니다.(만약 unsigned int라고 한다면 16Bit만큼을 의미하게 됩니다.)

unsigned char는 전체 8bit이므로 a부터 h까지 1비트씩 차지하여 결국 합이 1Byte의 Memory를 할당하게 됩니다. 이때 a부터 h까지 1Bit씩 차지한다는 것은 a : 1 등에 의해 정해지게 됩니다.

따라서 1Bit가 아닌 그 이상의 Bit를 할당하고자 할 경우에는 오른쪽의 숫자만 바꾸어 주면 될것입니다.

struct bitfield{
    unsigned char a : 2;
    unsigned char b : 3;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
};

a는 2Bit, b는 3Bit.. 나머지는 모두 1Bit를 할당하였습니다. 따라서 a는 2Bit이므로 0~3까지 그리고 b는 3Bit이므로 최소 0~7까지의 Data를 담을 수 있습니다.

이때 만약 Data형의 범위를 벗어나도록 bit field를 지정하면 어떻게 될까요?

struct bitfield{
    unsigned char a : 2;
    unsigned char b : 3;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
    unsigned char f : 1;
};

f 1Bit까지 전체 9Bit를 할당하였습니다.

unsigned char는 8bit이므로 f를 수용할 수 없습니다. 하지만 Compiler는 오류를 표시하지 않고 위에서 순서대로 각 Bit를 모두 담은 뒤 그 이상의 Bit가 존재하면 다음 영역을 또 다시 확보하고 해당 Bit를 담게 됩니다.

즉, 처음 a부터 e까지 8Bit(1Byte)에 담고 그 다음 f를 위해 다시 8Bit(char = 1Byte)영역을 확보한 후 처음 Bit부분에 f를 담게 되는 것입니다.(나머지 7bit는 낭비됩니다.)

#include <stdio.h>

main()
{
  struct bitfield{
    unsigned char a : 2;
    unsigned char b : 3;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
  };
 
  struct bitfield bit;
 
  bit.a = 2;
  bit.b = 5;
  bit.c = 1;
  bit.d = 0;
  bit.e = 1;
 
  printf("%d\n", bit.a);
  printf("%d\n", bit.b);
  printf("%d\n", bit.c);
  printf("%d\n", bit.d);
  printf("%d\n", bit.e);
}


각 Bit에 값을 설정하고 해당 값을 확인합니다.


bit field라고 해서 특별히 정해진 구문이 있는것은 아닙니다. 단지 bit field를 선언하는데 구조체의 선언방법을 빌려 선언되는것 뿐이며 구문상의 차이도 몇 Bit의 영역을 차지하는가를 나타내는 : x 형식의 구현부분만 다를 뿐입니다.

때문에 실제 bit filed와 구조체사이에는 그리 큰 차이가 없습니다.

#include <stdio.h>
#include <string.h>

main()
{
  struct bitfield{
    unsigned char a : 2;
    unsigned char b : 3;
    unsigned char c : 1;
    unsigned char d : 1;
    unsigned char e : 1;
   
    char name[10];
    int age;
  };
 
  struct bitfield bit;
 
  bit.a = 2;
  bit.b = 5;
  bit.c = 1;
  bit.d = 0;
  bit.e = 1;
 
  strcpy(bit.name, "youngsoo");
  bit.age = 30;
 
  printf("%d\n", bit.a);
  printf("%d\n", bit.b);
  printf("%d\n", bit.c);
  printf("%d\n", bit.d);
  printf("%d\n", bit.e);
 
  printf("%s\n", bit.name);
  printf("%d\n", bit.age);
}


구조체와 bit field를 동시에 구현합니다.


bit field를 선언할때 몇 Bit를 할당할지에 대한 내용은 생략하고 Data형만 쓰는 경우가 있습니다. 이는 실제 Bit영역을 사용하지 않으면서 Program구조상에 구분영역을 만들어 주는 역활을 수행하기 위함입니다.

또한 Bit를 처음부터 채우지 않고 일정부분 비워둬야 하는 경우에도 자주 쓰이는 방법입니다.

#include <stdio.h>

main()
{
  struct bitfield{
    unsigned char a : 2;
    unsigned char   : 3;
    unsigned char c : 1;
    unsigned char   : 1;
    unsigned char e : 1;
  };
 
  struct bitfield bit;
 
  bit.a = 2;
  bit.c = 0;
  bit.e = 1;
 
  printf("%d\n", bit.a);
  printf("%d\n", bit.c);
  printf("%d\n", bit.e);
}


bit field의 3번째 부터 5번째(이전의 b영역)과 7번째(이전의 d영역)은 사용하지 않습니다. 또한 a와 c, e를 영역별로 구분하도록 합니다.


참고 :
각 Field의 구분은 Program이 아닌 개발자 입장에서 입니다.


이올린에 북마크하기
Writer profile
DDURI
Posted by dduri.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]
« Previous : 1 : 2 : 3 : 4 : 5 : ... 367 : Next »