-
Notifications
You must be signed in to change notification settings - Fork 50
/
H264_V4l2DeviceSource.cpp
executable file
·113 lines (97 loc) · 3.1 KB
/
H264_V4l2DeviceSource.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** H264_V4l2DeviceSource.cpp
**
** H264 V4L2 Live555 source
**
** -------------------------------------------------------------------------*/
#include <sstream>
// live555
#include <Base64.hh>
// project
#include "H264_V4l2DeviceSource.h"
// ---------------------------------
// H264 V4L2 FramedSource
// ---------------------------------
H264_V4L2DeviceSource* H264_V4L2DeviceSource::createNew(UsageEnvironment& env, V4L2DeviceParameters params, int outputFd, bool useThread)
{
H264_V4L2DeviceSource* source = NULL;
source = new H264_V4L2DeviceSource(env, params, outputFd, useThread);
return source;
}
// Constructor
H264_V4L2DeviceSource::H264_V4L2DeviceSource(UsageEnvironment& env, V4L2DeviceParameters params, int outputFd, bool useThread)
: V4L2DeviceSource(env, params, outputFd,useThread)
{
}
// Destructor
H264_V4L2DeviceSource::~H264_V4L2DeviceSource()
{
}
// split packet in frames
std::list< std::pair<unsigned char*,size_t> > H264_V4L2DeviceSource::splitFrames(unsigned char* frame, unsigned frameSize)
{
std::list< std::pair<unsigned char*,size_t> > frameList;
size_t bufSize = frameSize;
size_t size = 0;
unsigned char* buffer = this->extractFrame(frame, bufSize, size);
while (buffer != NULL)
{
frameList.push_back(std::make_pair<unsigned char*,size_t>(buffer, size));
switch (buffer[0]&0x1F)
{
case 7:
//LOG(INFO) << "SPS";
//fprintf(stderr, "SPS\n" );
m_sps.assign((char*)buffer,size);
break;
case 8:
//fprintf(stderr, "PPS\n" );
m_pps.assign((char*)buffer,size);
break;
default: break;
}
if (m_auxLine.empty() && !m_sps.empty() && !m_pps.empty())
{
u_int32_t profile_level_id = 0;
if (m_sps.size() >= 4) profile_level_id = (m_sps[1]<<16)|(m_sps[2]<<8)|m_sps[3];
char* sps_base64 = base64Encode(m_sps.c_str(), m_sps.size());
char* pps_base64 = base64Encode(m_pps.c_str(), m_pps.size());
std::ostringstream os;
os << "profile-level-id=" << std::hex << std::setw(6) << profile_level_id;
os << ";sprop-parameter-sets=" << sps_base64 <<"," << pps_base64;
m_auxLine.assign(os.str());
free(sps_base64);
free(pps_base64);
//LOG(NOTICE) << m_auxLine;
fprintf(stderr, "m_a %s\n", m_auxLine.c_str() );
}
buffer = this->extractFrame(&buffer[size], bufSize, size);
}
return frameList;
}
// extract a frame
unsigned char* H264_V4L2DeviceSource::extractFrame(unsigned char* frame, size_t& size, size_t& outsize)
{
unsigned char * outFrame = NULL;
outsize = 0;
if ( (size>= sizeof(H264marker)) && (memcmp(frame,H264marker,sizeof(H264marker)) == 0) )
{
size -= sizeof(H264marker);
outFrame = &frame[sizeof(H264marker)];
outsize = size;
for (int i=0; i+sizeof(H264marker) < size; ++i)
{
if (memcmp(&outFrame[i],H264marker,sizeof(H264marker)) == 0)
{
outsize = i;
break;
}
}
size -= outsize;
}
return outFrame;
}