#define SEARCH_SPSPPS 0
#define WRITE_SPS 1
#define WRITE_PPS 2
const
BYTE
hex_avcC[4] = {0x61, 0x76, 0x63, 0x43};
const
BYTE
hex_mdat[4] = {0x6D, 0x64, 0x61, 0x74};
const
BYTE
hex_SCP[4] = {0x00, 0x00, 0x00, 0x01};
WvH264DataExtract::WvH264DataExtract(
void
)
{
this
->stop =
false
;
this
->mp4Buffer = NULL;
this
->h264Buffer = NULL;
this
->keyMP4 = NULL;
this
->keyH264 = NULL;
this
->
thread
= NULL;
}
WvH264DataExtract::~WvH264DataExtract(
void
)
{
this
->mp4Buffer = NULL;
this
->h264Buffer = NULL;
this
->keyMP4 = NULL;
this
->keyH264 = NULL;
this
->
thread
= NULL;
}
static
size_t
hex2dec(
char
* hex)
{
size_t
num = 0;
int
buf;
int
i;
for
(i = 0; ; i++)
{
if
(hex[i] >=
'0'
&& hex[i] <=
'9'
)
{
buf = hex[i] -
'0'
;
}
else
if
(hex[i] >=
'a'
&& hex[i] <=
'f'
)
{
buf = hex[i] -
'a'
+ 10;
}
else
if
(hex[i] >=
'A'
&& hex[i] <=
'F'
)
{
buf = hex[i] -
'A'
+ 10;
}
else
if
(hex[i] ==
'\0'
)
{
break
;
}
else
{
num = 0xFFFFFFFF;
break
;
}
num *= 16;
num += buf;
if
(i >= 8)
{
num = 0xFFFFFFFF;
break
;
}
}
return
(num);
}
static
int
GetSize(
BYTE
* buf,
int
size)
{
int
i;
int
data_size = 0;
BYTE
size_hex_buf[4];
char
size_hex[10];
char
format[20] =
""
;
if
(size > 4)
{
return
0;
}
for
(i = 0; i < size; i++)
{
size_hex_buf[i] = buf[i];
strcat
(format,
"%02x"
);
}
sprintf
(size_hex, format, size_hex_buf[0], size_hex_buf[1],
size_hex_buf[2], size_hex_buf[3]);
data_size = hex2dec(size_hex);
return
data_size;
}
void
WvH264DataExtract::WriteBuffer(
BYTE
buf)
{
this
->keyH264->Lock();
this
->h264Buffer->push_back(buf);
this
->keyH264->Unlock();
}
void
WvH264DataExtract::WriteBuffers(
BYTE
* buf,
int
size)
{
if
(size < 0)
{
return
;
}
this
->keyH264->Lock();
this
->h264Buffer->insert(h264Buffer->end(), buf, buf + size);
this
->keyH264->Unlock();
}
int
WvH264DataExtract::GetBuffers(
BYTE
* buf,
int
size)
{
int
i;
if
(size < 0)
{
return
0;
}
while
(stop ==
false
)
{
if
(mp4Buffer->empty() ==
false
&& (
int
)mp4Buffer->size() > size)
{
keyMP4->Lock();
for
(i = 0; i < size; i++)
{
buf[i] = (
BYTE
)mp4Buffer->front();
mp4Buffer->pop_front();
}
keyMP4->Unlock();
return
size;
}
else
{
::Sleep(1);
continue
;
}
}
return
0;
}
int
WvH264DataExtract::SPSPPS_extract(
BYTE
* buf,
int
index)
{
bool
SPSflg =
false
;
bool
PPSflg =
false
;
BYTE
dat;
int
i;
int
cnt = 0;
int
condition = SEARCH_SPSPPS;
int
avcC_size = 0;
int
SPSPPS_size = 0;
avcC_size = GetSize(buf + index, 4);
for
(i = 4; i < avcC_size; i++)
{
dat = buf[index + i];
switch
(condition)
{
case
SEARCH_SPSPPS:
if
(dat == 0x67)
{
WriteBuffers((
BYTE
*)hex_SCP, 4);
SPSPPS_size = GetSize(buf + (index + i - 2), 2);
condition = WRITE_SPS;
cnt = 0;
i--;
}
else
if
(dat == 0x68)
{
WriteBuffers((
BYTE
*)hex_SCP, 4);
SPSPPS_size = GetSize(buf + (index + i - 2), 2);
condition = WRITE_PPS;
cnt = 0;
i--;
}
break
;
case
WRITE_SPS:
WriteBuffer(dat);
cnt++;
if
(cnt >= SPSPPS_size)
{
SPSflg =
true
;
condition = SEARCH_SPSPPS;
cnt = 0;
}
break
;
case
WRITE_PPS:
WriteBuffer(dat);
cnt++;
if
(cnt >= SPSPPS_size)
{
PPSflg =
true
;
condition = SEARCH_SPSPPS;
cnt = 0;
}
break
;
default
:
printf
(
"error : writing SPS or PPS\n"
);
return
-1;
}
}
if
(!SPSflg | !PPSflg)
{
printf
(
"error : not found SPS or PPS\n"
);
return
-1;
}
return
index + i;
}