Y = krR + kgG + kbB Cr = R - Y Cg = G - Y Cb = B - Y
1 = kb + kr + kg kr = 0.299 kg = 0.587 kb = 0.114 Y = krR + (1 - kb - kr)G + kbB Cb = 0.5(B - Y)/(1 - kb) Cr = 0.5(R - Y)/(1 - kr) R = Y + (1 - kr)Cr/0.5 G = Y - 2kb(1 - kb)Cb/(1 - kb - kr) - 2kr(1 - kr)Cr/(1 - kb - kr) B = Y + (1 - kb)Cb/0.5
Y = 0.299R + 0.587G + 0.114B Cb = 0.564(B - Y) Cr = 0.713(R - Y) R = Y + 1.402Cr G = Y - 0.344Cb - 0.714Cr B = Y + 1.772Cb
Y = 0.299R + 0.587G + 0.114B = 77R/256 + 150G/256 + 29B/256 Cb = -0.16874R - 0.33126Green + 0.5B = -(44R/256) - 87G/256 + 131B/256 +128 Cr = 0.5R - 0.41869G - 0.08131B = 131R/256 - 110G/256 + 21B/256 +128 R = Y + 1.402Cr = s_Y + (359Cr - 128)/256 G = Y - 0.34414Cb - 0.71414Cr = Y - (88Cb - 128)/256 - (183Cr - 128)/256 B = Y + 1.772Cb = s_Y + (454Cb - 128)/256
void RGB_YCbCr(int s_Red, int s_Green, int s_Blue, int *s_Y, int *s_Cb, int *s_Cr)
{ /* 변환과정에서 색감 손실이 약 5% 까지 발생 */
s_Red &= 0xff, s_Green &= 0xff, s_Blue &= 0xff;
*s_Y = (int)( ((19595 * s_Red) >> 16) + ((38470 * s_Green) >> 16) + ((7471 * s_Blue) >> 16) );
*s_Cb = (int)( -((11059 * s_Red) >> 16) - ((21709 * s_Green) >> 16) + ((32768 * s_Blue) >> 16) + 128 );
*s_Cr = (int)( ((32768 * s_Red) >> 16) - ((27439 * s_Green) >> 16) - ((5329 * s_Blue) >> 16) + 128 );
*s_Y = (int)( (*s_Y > 0) ? *s_Y : 0); *s_Y = (int)((*s_Y < 255) ? *s_Y : 255 );
*s_Cb = (int)( (*s_Cb > 0) ? *s_Cb : 0); *s_Cb = (int)((*s_Cb < 255) ? *s_Cb : 255 );
*s_Cr = (int)( (*s_Cr > 0) ? *s_Cr : 0); *s_Cr = (int)((*s_Cr < 255) ? *s_Cr : 255 );
}
void YCbCr_RGB(int s_Y, int s_Cb, int s_Cr, int *s_Red, int *s_Green, int *s_Blue)
{ /* 변환과정에서 색감 손실이 약 5% 까지 발생 */
s_Y &= 0xff, s_Cb &= 0xff, s_Cr &= 0xff;
s_Cb -= 128;
s_Cr -= 128;
*(s_Red) = (int)( s_Y + ((91881 *s_Cr)/65536) );
*(s_Green) = (int)( s_Y - ((22554 *s_Cb)/65536) - ((46802*s_Cr)/65536) );
*(s_Blue) = (int)( s_Y + ((116130*s_Cb)/65536) );
}
상호변환library(http://blog.naver.com/minzkn/60020904427)
| 기능 | 값의 순환이 고려될 때 | 부호가 고려될 때 | 부호가 고려되지 않을 때 |
| 산술덧셈 | PADDB, PADDW, PADDD | PADDSB, PADDSW | PADDUB, PADDUW |
| 산술뺄셈 | PSUBB, PSUBW, PSUBD | PSUBSB, PSUBSW | PSUBUB, PSUBUW |
| 산술곱셈 | PMULL, PMULH | ||
| 산술곱셈자리올림 | PMADD | ||
| 비교 | PCMPEQB, PCMPEQW, PCMPEQD | ||
| PCMPGTPB, PCMPGTPW, PCMPGTPD | |||
| 변환 | PUNPCKHBW | PACKSSWB | PACKUSWB |
| PUNPCKHWD | PACKSSDW | ||
| PUNPCKHDQ | |||
| PUNPCKLBW | |||
| PUNPCKLWD | |||
| PUNPCKLDQ | |||
| 논리연산 | 묶음의 단위 | Quad단위 | |
| PAND | |||
| PANDN | |||
| POR | |||
| PXOR | |||
| PSLLQ | |||
| PSRLQ | |||
| 전송 | Double word 전송 | Quad word 전송 | |
| MOVD | MOVQ | ||
| MMX 상태를 비움 | EMMS | ||
| 시간의 흐름 -> | ||||||||||
| 1 | 2 | 4 | 7 | 7 | 10 | 9 | 7 | 4 | 3 | 1 |
| 시간의 흐름 -> | ||||||||||
| 1 | 1 | 2 | 3 | 0 | 3 | -1 | -2 | -3 | -1 | -2 |
#include <stdio.h>
typedef int t_gcm_value;
static t_gcm_value _gcm_to_abs(t_gcm_value s_value)
{
static t_gcm_value sg_msb = (((t_gcm_value)1) << ((sizeof(t_gcm_value) << 3) - 1));
t_gcm_value s_temp;
s_temp = sg_msb >> ((sizeof(t_gcm_value) << 3) - 1);
if(s_temp != ((t_gcm_value)1))
{ /* t_gcm_value is signed type */
if((s_value & sg_msb) == sg_msb)
{ /* s_value < 0 */
s_value = -s_value;
}
}
return(s_value);
}
static t_gcm_value _gcm(t_gcm_value s_value1, t_gcm_value s_value2)
{
t_gcm_value s_temp;
if(s_value1 < s_value2)
{ /* swap */
s_temp = s_value1;
s_value1 = s_value2;
s_value2 = s_temp;
}
do
{
s_temp = s_value1 % s_value2;
if(s_temp == ((t_gcm_value)0))break;
s_value1 = s_value2;
s_value2 = s_temp;
}while(1);
return(_gcm_to_abs(s_value2));
}
void gcm(t_gcm_value s_value1, t_gcm_value s_value2)
{
t_gcm_value s_value;
s_value = _gcm(s_value1, s_value2);
(void)fprintf(stdout, "gcm(%4ld, %4ld) = %4ld (ASPECT RATIO=%ld:%ld)\n",
(long)s_value1,
(long)s_value2,
(long)s_value,
(long)(s_value1 / s_value),
(long)(s_value2 / s_value));
}
int main(void)
{
/* test suite */
gcm(640, 480);
gcm(720, 480);
gcm(960, 720);
gcm(1280, 720);
gcm(1440, 1080);
gcm(1920, 1080);
return(0);
}
/* End of source */
#include <stdio.h>
static int _gcm(int s_value1, int s_value2)
{
int s_temp;
if(s_value1 < s_value2)
{ /* swap */
s_temp = s_value1;
s_value1 = s_value2;
s_value2 = s_temp;
}
do
{
s_temp = s_value1 % s_value2;
if(s_temp == 0)break;
s_value1 = s_value2;
s_value2 = s_temp;
}while(1);
return(((s_value2 >> ((sizeof(s_value2) << 3) - 1)) ^ s_value2) - (s_value2 >> ((sizeof(s_value2) << 3) - 1)));
}
void pixel_aspect_ratio(int s_resx, int s_resy, int s_ax, int s_ay, int *s_sax, int *s_say)
{
int s_value, s_x = s_resy * s_ax, s_y = s_resx * s_ay;
if((s_x != 0) && (s_y != 0))
{
s_value = _gcm(s_x, s_y);
*(s_sax) = s_x / s_value, *(s_say) = s_y / s_value;
}
else *(s_sax) = *(s_say) = 1;
}
void test(int s_resx, int s_resy)
{
int s_sax, s_say;
(void)fprintf(stdout, "%4d x %4d | ", s_resx, s_resy);
pixel_aspect_ratio(s_resx, s_resy, 4, 3, &s_sax, &s_say);
(void)fprintf(stdout, "%3d:%3d ", s_sax, s_say);
pixel_aspect_ratio(s_resx, s_resy, 16, 9, &s_sax, &s_say);
(void)fprintf(stdout, "%3d:%3d\n", s_sax, s_say);
(void)fflush(stdout);
}
int (main)(void)
{
(void)fprintf(stdout,
"===============================\n"
"resolution | 4:3disp 16:9disp\n"
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
test( 0, 0);
test(-720,-576);
test( 720, 576);
test( 768, 576);
test(1024, 576);
test( 720, 576);
test( 768, 576);
test(1024, 576);
(void)fprintf(stdout,
"===============================\n");
return(0);
}
/* End of source */
| moov | Meta data 최상위 | |
| mvhd | Movie header | |
| iods | Object 기술자 | |
| trak | Trak 또는 Stream 관여 |
#define Frame header preview
32bit big endian - AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
#define Frame header bit index
A[31..21] : Frame sync
B[20..19] : MPEG audio version indentification
C[18..17] : Layer description
D[16] : Protection bit
E[15..12] : Bitrate index
F[11..10] : Sampling rate frequency index
G[9] : Padding bit
H[8] : Private bit
I[7..6] : Channel mode
J[5..4] : Mode extension
K[3] : Copyright
L[2] : Original
M[1..0] : Emphasis
#define Frame header description
A: 11bit - Frame sync (All bit '1')
'11111111 111'
B: 2bit - MPEG audio version identification
'00': MPEG version 2.5
'01': Reserved
'10': MPEG version 2.0 (ISO/IEC 13818-3)
'11': MPEG version 1.0 (ISO/IEC 11172-3)
C: 2bit - Layer description
'00': Reserved
'01': Layer III
'10': Layer II
'11': Layer I
D: 1bit - Protection bit
'0': Protected by CRC (16bit crc follow header)
'1': Not protected
E: 4bit - Bitrate index
아래참조
F: 2bit - Sampling rate frequency index
MPEG version 1.0
'00': 44100
'01': 48000
'10': 32000
'11': Reserved
MPEG version 2.0
'00': 22050
'01': 24000
'10': 16000
'11': Reserved
MPEG version 2.5
'00': 11025
'01': 12000
'10': 8000
'11': Reserved
G: 1bit - Padding bit
'0': Frame is not padded
'1': Frame is padded with one extra slot
Layer I frame size
((12000 * Bitrate / Samplerate) + Padding) * 4
Layer II/III frame size
(144000 * Bitrate / Samplerate) + Padding
H: 1bit - Private bit
I: 2bit - Channel mode
'00': Stereo
'01': Joint stereo (Stereo)
'10': Dual channel (Stereo)
'11': Single channel (Mono)
J: 2bit - Mode extension (Only if joint stereo)
Layer I/II
'00': Bands 4 to 31
'01': Bands 8 to 31
'10': Bands 12 to 31
'11': Bands 16 to 31
Layer III
'00': Intensity stereo off, MS stereo off
'01': Intensity stereo on , MS stereo off
'10': Intensity stereo off, MS stereo on
'11': Intensity stereo on , MS stereo on
K: 1bit - Copyright
'0': Audio is not copyrighted
'1': Audio is copyrighted
L: 1bit - Original
'0': Copy of original media
'1': Original media
M: 2bit - Emphasis
'00': None
'01': 50/15ms
'10': Reserved
'11': CCIT J.17
#define hint
A: MPEG version 1.0, Layer I
B: V1,Layer II
C: V1,Layer III
D: V2,Layer I
E: V2, L2 & L3
-: Free format
x: Not use (Invalid bitrate !)
#define table
[A] [B] [C] [D] [E]
0000 - - - - -
0001 32 32 32 32 8
0010 64 48 40 48 16
0011 96 56 48 56 24
0100 128 64 56 64 32
0101 160 80 64 80 40
0110 192 96 80 96 48
0111 224 112 96 112 56
1000 256 128 112 128 64
1001 288 160 128 144 80
1010 320 192 160 160 96
1011 352 224 192 176 112
1100 384 256 224 192 128
1101 416 320 256 224 144
1110 448 384 320 256 160
1111 x x x x x
static const unsigned int _ac3_FrameSizeTbl[38][3] =
{
{64, 69, 96}, {64, 70, 96}, {80, 87, 120}, {80, 88, 120}, {96, 104, 144},
{96, 105, 144}, {112, 121, 168}, {112, 122, 168}, {128, 139, 192}, {128, 140, 192},
{160, 174, 240}, {160, 175, 240}, {192, 208, 288}, {192, 209, 288}, {224, 243, 336},
{224, 244, 336}, {256, 278, 384}, {256, 279, 384}, {320, 348, 480}, {320, 349, 480},
{384, 417, 576}, {384, 418, 576}, {448, 487, 672}, {448, 488, 672}, {512, 557, 768},
{512, 558, 768}, {640, 696, 960}, {640, 697, 960}, {768, 835, 1152}, {768, 836, 1152},
{896, 975, 1344}, {896, 976, 1344}, {1024, 1114, 1536}, {1024, 1115, 1536}, {1152, 1253, 1728},
{1152, 1254, 1728}, {1280, 1393, 1920}, {1280, 1394, 1920}
};
static unsigned int _AC3GetFrameLen(char *pFrameBuf)
{
unsigned int nFsCod, nFrmSizeCod;
if (pFrameBuf == NULL) {
return 0;
}
// Sync word check
if (pFrameBuf[0] != 0x0b || pFrameBuf[1] != 0x77) {
return 0;
}
nFsCod = (pFrameBuf[4] & 0xc0) >> 6;
if (nFsCod > 3) {
// nFsCod 가 4 이면 Reserved....
return 0;
}
nFrmSizeCod = pFrameBuf[4] & 0x3f;
if (nFrmSizeCod > 37) {
// nFrmSizeCod 가 37 보다 크면 Error
return 0;
}
return _ac3_FrameSizeTbl[nFrmSizeCod][nFsCod] << 1;
}
Demux 샘플 프로그램 다운로드
(http://minzkn.wowdns.com:2744/phpBB2/viewtopic.php?t=262) : 안타깝게도 소스는 공개하지 못하게 되어 있습니다. 언젠가 공개할수 있도록 노력중입니다.
http://www.minzkn.com:2744/blog/232에서 구현해 보았습니다.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
static __inline int __mzmatch_filter(const unsigned char *s_data, const unsigned char *s_mask, const unsigned char *s_mode, const unsigned char *s_comp, size_t s_size);
int mzmatch_filter(const void *s_data, const void *s_mask, const void *s_mode, const void *s_comp, size_t s_size);
static __inline int __mzmatch_filter(const unsigned char *s_data, const unsigned char *s_mask, const unsigned char *s_mode, const unsigned char *s_comp, size_t s_size)
{
size_t s_offset = (size_t)0;
unsigned char s_positive_mask, s_negative_mask;
while(s_offset < s_size) {
s_positive_mask = s_mask[s_offset] & s_mode[s_offset];
s_negative_mask = s_mask[s_offset] & (~s_mode[s_offset]);
if(((s_positive_mask & s_data[s_offset]) != (s_positive_mask & s_comp[s_offset])) ||
((s_negative_mask != ((unsigned char)0)) && ((s_negative_mask & (s_data[s_offset] ^ s_comp[s_offset])) == ((unsigned char)0)))) {
return(0);
}
s_offset++;
}
return(1);
}
int mzmatch_filter(const void *s_data, const void *s_mask, const void *s_mode, const void *s_comp, size_t s_size)
{
return(__mzmatch_filter((const unsigned char *)s_data, (const unsigned char *)s_mask, (const unsigned char *)s_mode, (const unsigned char *)s_comp, s_size));
}
void test(unsigned char s_mask, unsigned char s_mode, unsigned char s_comp)
{
int s_match_condition;
unsigned int s_data_min = 0x00u, s_data_max = 0xffu;
(void)fprintf(stdout, "TEST => data=%02X~%02X mask=%02X mode=%02X comp=%02X",
(unsigned int)s_data_min,
(unsigned int)s_data_max,
(unsigned int)s_mask,
(unsigned int)s_mode,
(unsigned int)s_comp
);
do {
if((s_data_min % 0x10u) == 0x00u)(void)fputs("\n", stdout);
s_match_condition = mzmatch_filter(&s_data_min, &s_mask, &s_mode, &s_comp, (size_t)1);
#if defined(__linux__) /* can use ansi code(escape sequence code) */
(void)fprintf(stdout,
" %s%02X\x1b[0m",
(s_match_condition == 0) ? "\x1b[1;31m" : "\x1b[1;33m",
(unsigned int)s_data_min);
#else
if(s_match_condition != 0) {
(void)fprintf(stdout,
" %02X",
(unsigned int)s_data_min);
}
#endif
}while((s_data_min++) < s_data_max);
(void)fputs("\n", stdout);
}
int main(void)
{
test(0xffu, 0xffu, 0x80u);
test(0xffu, 0x00u, 0x80u);
test(0xffu, 0xf9u, 0xceu);
test(0xffu, 0xf0u, 0x24u);
test(0x3fu, ~((unsigned char)0x3fu), 0x04u);
/* TS filter */
test(0xffu, 0xffu, 0x00u); /* PAT */
test(0xffu, 0xffu, 0x01u); /* CAT */
test(0xffu, 0xffu, 0x02u); /* PMT */
test(0xffu, 0xffu, 0x3eu); /* DSM CC */
test(0xfcu, 0xffu, 0x80u); /* ECM 0x80, 0x81, 0x82 */
return(EXIT_SUCCESS);
}