<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Hello<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Our goal was to generated an H264 + AAC live streaming starting from an USB camera and a microphone.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>To reach the goal we have used the following chain: USB camera -> ffmpeg -> RSTP live555. <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Finally, the live stream works and when we connect with a client like VLC or ffplay, we can see the camera shooting.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>The only problem that we have is due to fact that we can only have a limited number of connections (client vlc) and this <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>number is related to the source's resolution.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>If you exceed this number all the VLC clients begin to display artifacts.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Source's resolution 320 x 240 allows just 6 VLC connections.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Source's resolution 640 x 480 allows just 3 VLC connections.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Source's resolution 1920 x 1080 allows just 1 VLC connection.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>We already checks the cpu usage and the bandwidth, the cpu usage is around 40% and the average bandwich is 1 Mbit.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>The OS is windows.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Below, what we did:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>1) We used ffmpeg to capture the images from the camera and convert them to H264 + AAC frames (avcoded)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>2) These frames were pushed in a circular queue<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>3) In a thread we created a RTP Server, the media session and two subsession, one for the video and the other one audio (see the code below)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>4) Starting from the DeviceSource.cpp we created a source that reads the frames from the circular queue.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>5) When a client connects to the RTPserver, we create a NewStreamSource and a NewRTPSink. As you can see in the code below, <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>for the video StreamSource we create a H264VideoStreamDiscreteFramer for the audio we leave as it is.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Regarding the RTPSink, for the video, we create an H264VideoRTPSink and for the audio we create MPEG4GenericRTPSink.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>I will appreciate any help.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Thanks<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>Bye<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>**********************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>unsigned long WINAPI Live555Thread (void *param)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>{<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> OutPacketBuffer::maxSize = MAX_FRAME_SIZE;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> TaskScheduler *serverTsk = BasicTaskScheduler::createNew();<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> UsageEnvironment *serverEnv = BasicUsageEnvironment::createNew(*serverTsk);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> RTSPServer *rtspServer = RTSPServer::createNew(*serverEnv, g_nRTSPServerPort, NULL);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> ServerMediaSession *sms;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> if (rtspServer == NULL) {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> *serverEnv << "LIVE555: Failed to create RTSP server: %s\n", serverEnv->getResultMsg();<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> return 0;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> else {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> char const* descriptionString = "Session streamed by \"QMServer\"";<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> char RTSP_Address[1024];<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> RTSP_Address[0]=0x00;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> sms = ServerMediaSession::createNew(*serverEnv, RTSP_Address, RTSP_Address, descriptionString);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> sms->addSubsession(Live555ServerMediaSubsession::createNew(VIDEO_TYPE, *serverEnv, ESTIMATED_VIDEO_BITRATE));<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> sms->addSubsession(Live555ServerMediaSubsession::createNew(AUDIO_TYPE, *serverEnv, ESTIMATED_AUDIO_BITRATE));<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> rtspServer->addServerMediaSession(sms);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> char* url = rtspServer->rtspURL(sms);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> *serverEnv << "Play this stream using the URL \"" << url << "\"\n";<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> for (;;) {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> serverEnv->taskScheduler().doEventLoop(&g_cExitThread); // does not return<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> if (g_cExitThread)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> break;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> Medium::close(rtspServer);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> return 0;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>}<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>**********************************************************************************<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>FramedSource* Live555ServerMediaSubsession::createNewStreamSource (unsigned /*clientSessionId*/, unsigned& estBitrate)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>{<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> estBitrate = fEstimatedKbps;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> m_source = Live555Source::createNew(envir(), m_type, false);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> if (m_type == VIDEO_TYPE) {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> return (H264VideoStreamDiscreteFramer::createNew(envir(), m_source));<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> else<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> return m_source;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>}<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>RTPSink* Live555ServerMediaSubsession::createNewRTPSink (Groupsock* rtpGroupsock, unsigned char /*rtpPayloadTypeIfDynamic*/, FramedSource* inputSource)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'>{<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> OutPacketBuffer::maxSize = MAX_FRAME_SIZE;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> if (m_type == VIDEO_TYPE) {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> return (H264VideoRTPSink::createNew(envir(), rtpGroupsock, 96));<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> else {<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> unsigned char audioSpecificConfig[2];<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> char fConfigStr[10];<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";color:black'> </span><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'>audioSpecificConfig[0] = (AUDIO_AAC_TYPE << 3) | (AUDIO_SRATE_INDEX >> 1);<o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'> audioSpecificConfig[1] = (AUDIO_SRATE_INDEX << 7) | (AUDIO_CHANNELS << 3);<o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'> sprintf(fConfigStr, "%02X%02x", audioSpecificConfig[0], audioSpecificConfig[1]);<o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'><o:p> </o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'> return (MPEG4GenericRTPSink::createNew(envir(), rtpGroupsock, 96, AUDIO_SRATE, "audio", "AAC-hbr", fConfigStr, AUDIO_CHANNELS));<o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'> }<o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:10.0pt;font-family:"Courier New";color:black'>}</span><span lang=IT><o:p></o:p></span></p><p class=MsoNormal><span lang=IT><o:p> </o:p></span></p><p class=MsoNormal><span lang=IT><o:p> </o:p></span></p><p class=MsoNormal><b><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'>________________________________________________________________</span></b><span lang=IT style='color:navy'><o:p></o:p></span></p><p class=MsoNormal><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>Ing. Giovanni Iamonte<o:p></o:p></span></b></p><p class=MsoNormal><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>Area Tecnologie e sviluppi<o:p></o:p></span></b></p><p class=MsoNormal><b><span style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>Quintetto Srl – Pont Saint Martin (AO)<o:p></o:p></span></b></p><p class=MsoNormal><span lang=IT style='font-size:8.0pt;font-family:Wingdings;color:#339966'>(</span><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'> </span><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>mobile: +39 393 9196310<o:p></o:p></span></b></p><p class=MsoNormal><span lang=IT style='font-size:8.0pt;font-family:Wingdings;color:#339966'>(</span><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'> </span><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>tel: +39 0165 1845290</span></b><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'><o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:8.0pt;font-family:Wingdings;color:#339966'>+</span><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'> </span><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>e-mail: <a href="mailto:iamonte@quintetto.it"><span style='color:blue'>iamonte@quintetto.it</span></a></span></b><span lang=IT style='font-size:12.0pt;font-family:"Times New Roman","serif";color:navy'><o:p></o:p></span></p><p class=MsoNormal><span lang=IT style='font-size:8.0pt;font-family:Wingdings;color:#339966'>[</span><span lang=IT style='font-size:8.0pt;font-family:"Arial","sans-serif";color:#339966'> </span><b><span lang=IT style='font-size:8.0pt;font-family:"Tahoma","sans-serif";color:#339966'>web: <a href="http://www.quintetto.it/" title="http://www.quintetto.it/"><span style='color:blue'>www.quintetto.it</span></a></span></b><span style='color:navy'><o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>