[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-server-cvs
Subject:    [Server-cvs] engine/core source_container.cpp, 1.8,
From:       ckarusala () helixcommunity ! org
Date:       2011-11-24 4:53:23
[Download RAW message or body]

Update of /cvsroot/server/engine/core
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv23276

Modified Files:
	source_container.cpp static_source_container.cpp 
Log Message:

Synopsis
========
This CR contains changes for the iOS Closed Caption support and numerous updates & \
fixes for multi-track.

Branch : SERVER_14_2_RN, HEAD
Suggested Reviewer : Sujeet, Dean

Description:
==========
This CR adds the support for multi-language closed captions to HLS packetization and \
streaming in server. The closed caption tracks "clcp" tracks are read from the mp4 \
fileformat, packetized as H264 SEI NAL units, merged with H264 elementary stream, \
packetized into TS and written to the segments. Closed captions are only supported \
for VOD and for HLS only. Users will be able to choose the required CC stream using \
the query paramter "cc" (configurable) in the HLS URLs. Below are the details about \
this feature and the additional updates & fixes made in general to multi-track \
feature as per the new specs.

mp4fileformat: Updated the mp4fileformat to read "clcp" tracks from ISO files, these \
are only read if the packetization is "pes" (for HLS) and are ignored for RTSP and \
RTMP packetizations. Updated the private class factory to create a "pes" packetizer \
that will handle the "clcp" track data.

mpeg pes payload updates : Added a new packetizer (CH264CCPayload), which will take \
the closed caption track data and construct H264 SEI NAL units out of it as per the \
packet format specified in 14496-10, ATSC-53/Part 4, ATSC-72 Part 1 specs. Also \
updated the h264 pes packetizer to add SPS-PPS only if it is not already present. And \
AUD NAL should be added before adding the SPS-PPS NAL. Corrected that.

mpeg2 file writer: Updated the filewriter to handle the live archiving for \
multi-track live and create correct segment library names for each of the audio-video \
combinations. Added a new line at the end of the VOD playlist which was missing \
before. Updated the writer to handle multiple videos (as opposed to single video as \
was done before). Now when there are more than one streams of same type and name, \
they will be made as part of a multi-rate presentations. Bitrate query parameters are \
not necessary for HLS. Updated the multitrack wrapper class to handle multiple videos \
with the same name (similar to how audio were handled) and construct multirate \
presentations. This wrapper class will only handle live streams now. It pairs up each \
unique audio with each unique video and comes up with all the possible SR/MR \
presentations, creates the mappings, writers and pass the TS packets to writers.

tsmuxer changes: Updated TS muxer to ignore the stream headers for CC tracks as the \
packets from the CC tracks do not reach the muxer. They are merged with video data \
earlier. So muxer should not be listing the CC stream as a independent stream in the \
program specific information (PSI) tables.

m3ugen changes: Updated m3ugen to ignore video bitrate query parameter. It will now \
look for CC QP for VOD requests. Also, while sending packetization requests to \
mpeg2ts plugin, it will now send the complete URL with QPs for VOD cases so that the \
mpeg2ts plugin knows which streams to segment. And m3ugen takes the final M3U8 \
filename from the mpeg2ts plugin since what is created can be different due to \
(un)availability of different streams selected in URL QPs. Also updated the m3ugen to \
look for MDAT file to determine if VOD content is completely segmented instead of the \
earlier logic of opening playlists and looking for END tags.

mpeg2ts plugin: Major changes are made to CStreamHandler class. It will now segment \
only the requested combinations for VOD content as opposed to all. It will determine \
if the content is a mulit-track request or not by looking at the mountpoint name for \
live and the presence of MP QPs for VOD. We don't need the special "Helix MT Content" \
string anymore in the "Title" of the VOD content. Cleanup of the live playlists at \
the end of the segmentation was failing for MT live since the playlist/segment \
library names will have extensions based on the video/audio stream names. Added a \
list to keep track of all the extensions and used it to cleanup at the end. Stream \
handler now uses the CMultiplexerURLParser class to determine if the multiplexing is \
enabled and what the streams are selected in the URL QPs. It has been updated to \
handle the CC streams for VOD content. A new helper class CCMerger is created to \
merge the closed catpion packets into H264 PES packets. Only one CC stream will be \
active at a time. A CCMerger class is created for each of the active video streams. \
And both the video packets and the CC packets are passed to the CCMerger class which \
will merge and output new packets.

ccmerger: Helper class to merge cc packets (containing H264 SEI NAL
units) and the H264 Video packets.

rtmpserver: Multi-track URL parsing is happening at a wrong place resulting in always \
streaming a video and audio even though wrong streamnames are speicifed in the MT \
QPs. Corrected that.

source_container : Current call flow of initializing the source causing issues in \
BroadcastStreamer causing it think the sinks are MDP sinks when they are not. \
Adjusted the flow to correct that.

static_source_container : This class maintain an array for GetPacketCallbacks for \
each of the streams on which StartPackets() is called, but the total number of \
streams it counts is the total number of StartPackets() calls made on it. This is \
causing problems when StartPackets() is called on, for example, stream 3 & 4. In this \
case it is trying to reference indexes 0 & 1 for these streams. Converted the array \
into a map.

mpurlparser: Updated to

1. Handle and match Language in addition to just the StreamName.
2. Handle CC query parameter.
3. Return multi-trate streams for HLS cases.
4. Handle "default" for vid, aud & cc QPs.

livemultiplexer : Updated it to not write/append the special string "Helix MT \
Content" to the "Title" of the presentation.

Files New
=========
datatype_rn/mpeg2/payload/h264ccpespyld.cpp
datatype_rn/mpeg2/payload/pub/h264ccpespyld.h
server_rn/datatype/mpeg2ts/ccmerge.cpp
server_rn/datatype/mpeg2ts/pub/ccmerge.h

Files Modified
==========
datatype/mp4/fileformat/qtatmmgs.cpp
datatype/mp4/fileformat/qttrack.cpp
datatype/mp4/fileformat/pub/qtatmmgs.h
datatype/mp4/fileformat/pub/qtatoms.h
datatype_rn/mp4/fileformat/qtpluspacketizerfct.cpp
datatype_rn/mpeg2/payload/Umakefil
datatype_rn/mpeg2/payload/h264pespyld.cpp
datatype_rn/mpeg2/ts/filewriter/ctsarchiver.cpp
datatype_rn/mpeg2/ts/filewriter/mpeg2tsfwrtr.cpp
datatype_rn/mpeg2/ts/filewriter/multitrackwrapper.cpp
datatype_rn/mpeg2/ts/filewriter/pub/mpeg2tsfwrtr.h
datatype_rn/mpeg2/ts/filewriter/pub/multitrackwrapper.h
datatype_rn/mpeg2/ts/filewriter/pub/playlistgen.h
datatype_rn/mpeg2/ts/muxer/tsmux.cpp
datatype_rn/mpeg2/ts/muxer/pub/tsmux.h
server_rn/appext/m3ugen/m3ugenfsys.cpp
server_rn/datatype/mpeg2ts/Umakefil
server_rn/datatype/mpeg2ts/mpeg2tsplin.cpp
server_rn/datatype/mpeg2ts/streamhandler.cpp
server_rn/datatype/mpeg2ts/pub/streamhandler.h
server_rn/protocol/flash/rtmpserv/rtmpserv.cpp
server/engine/core/source_container.cpp
server/engine/core/static_source_container.cpp
server/engine/core/pub/static_source_container.h
server/protocol/common/mp_url_parser.cpp
server/protocol/common/pub/mp_url_parser.h
server-restricted/broadcast/app/multiplexer/livemultiplexer.cpp

Testing Performed
=================
Unit Tests:
- Tested various content SR/MR with mutliple variations of number and type of \
streams. Verified cc streams in both SR and MR. Playback to IPad is verified for \
various combinations selected in the URLs. Verified live archiving is working for \
HLS.

Integration Tests:
- None.

Leak Tests:
- Verified that no major leaks are added.

Performance Tests:
- None

Platforms Tested: linux-rhel5-x86_64
Build Verified: linux-rhel5-x86_64

Thanks,
Chytanya



Index: static_source_container.cpp
===================================================================
RCS file: /cvsroot/server/engine/core/static_source_container.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- static_source_container.cpp	12 Nov 2009 00:47:45 -0000	1.6
+++ static_source_container.cpp	24 Nov 2011 04:53:20 -0000	1.7
@@ -40,6 +40,7 @@
 #include "hxtypes.h"
 #include "hxcom.h"
 #include "hxengin.h"
+#include "chxmaplongtoobj.h"
 #include "static_source_container.h"
 #include "hxassert.h"
 #include "timeval.h"
@@ -47,22 +48,17 @@
 
 StaticSourceContainer::StaticSourceContainer(IUnknown*           pContext,
 					     IHXPSourceControl* pSourceControl)
-    : m_bReady(FALSE)
-    , m_bPacketsStarted(FALSE)
+    : m_bPacketsStarted(FALSE)
     , m_bAdvanceSchedulerTime(FALSE)
     , m_bOneStreamStarted(FALSE)
-    , m_bGetPacketOutstanding(FALSE)
     , m_bDone(FALSE)
 
     , m_lRefCount(0)
-    , m_ulStopPacketsSeen(0)
-    , m_nStreamCount(0)
-
     , m_pSourcePackets(NULL)
     , m_pScheduler(NULL)
     , m_pThreadSafeScheduler(NULL)
     , m_pSink(NULL)
-    , m_ppPacketStreams(NULL)
+    , m_pPacketStreams(NULL)
 
     , m_pContext(pContext)
     , m_pSourceControl(pSourceControl)
@@ -86,6 +82,8 @@
 	HX_VERIFY(HXR_OK == pSourceControl->QueryInterface(IID_IHXPSourcePackets,
 							   (void **)&m_pSourcePackets));
     }
+
+    m_pPacketStreams = new CHXMapLongToObj();
 }
 
 StaticSourceContainer::~StaticSourceContainer()
@@ -105,18 +103,24 @@
 	HX_RELEASE(m_pSink);
     }
 
-    if (m_ppPacketStreams)
+    if (m_pPacketStreams)
     {
-	for (UINT32 i = 0; i < m_nStreamCount; i++)
-	{
-	    if (m_ppPacketStreams [i]->m_Handle)
-	    {
-		m_pThreadSafeScheduler->Remove(m_ppPacketStreams[i]->m_Handle);
-	    }
+        CHXMapLongToObj::Iterator it;
+        for (it = m_pPacketStreams->Begin(); it != m_pPacketStreams->End(); it++)
+        {
+            GetPacketCallback* pGetPacketCallback = (GetPacketCallback*)(*it);
 
-	    HX_RELEASE(m_ppPacketStreams [i]);
-	}
-	HX_VECTOR_DELETE(m_ppPacketStreams);
+            if (pGetPacketCallback && pGetPacketCallback->m_Handle && \
m_pThreadSafeScheduler) +            {
+                m_pThreadSafeScheduler->Remove(pGetPacketCallback->m_Handle);
+                pGetPacketCallback->m_Handle = 0;
+            }
+
+            HX_RELEASE(pGetPacketCallback);
+        }
+            
+        m_pPacketStreams->RemoveAll();
+        HX_DELETE(m_pPacketStreams);
     }
 
     HX_RELEASE(m_pScheduler);
@@ -245,17 +249,25 @@
 
     m_bDone = TRUE;
 
-    for (UINT32 i = 0; i < m_nStreamCount; i++)
+    if (m_pPacketStreams)
     {
-	if ( (m_ppPacketStreams) && (m_ppPacketStreams [i]) &&
-	     (m_ppPacketStreams [i]->m_Handle) )
-	{
-            m_pThreadSafeScheduler->Remove(m_ppPacketStreams[i]->m_Handle);
-	}
+        CHXMapLongToObj::Iterator it;
+        for (it = m_pPacketStreams->Begin(); it != m_pPacketStreams->End(); it++)
+        {
+            GetPacketCallback* pGetPacketCallback = (GetPacketCallback*)(*it);
 
-        HX_RELEASE(m_ppPacketStreams [i]);
+            if (pGetPacketCallback && pGetPacketCallback->m_Handle && \
m_pThreadSafeScheduler) +            {
+                m_pThreadSafeScheduler->Remove(pGetPacketCallback->m_Handle);
+                pGetPacketCallback->m_Handle = 0;
+            }
+
+            HX_RELEASE(pGetPacketCallback);
+        }
+            
+        m_pPacketStreams->RemoveAll();
+        HX_DELETE(m_pPacketStreams);
     }
-    HX_VECTOR_DELETE(m_ppPacketStreams);
 
     if (m_pSourceControl)
     {
@@ -306,10 +318,15 @@
 
         m_pSink->PacketReady(HXR_OK, pPacket);
         
+        GetPacketCallback* pGetPacketCallback = NULL;
+        m_pPacketStreams->Lookup(uStreamNo, (REF(void*))pGetPacketCallback);
+
+        HX_ASSERT(pGetPacketCallback);
+    
         if (0 == m_ulBandWidthFactor)
         {
-            m_ppPacketStreams[uStreamNo]->m_pTimeToSchedule = \
                m_pScheduler->GetCurrentSchedulerTime();
-            m_ppPacketStreams[uStreamNo]->ScheduleNextPacket();
+            pGetPacketCallback->m_pTimeToSchedule = \
m_pScheduler->GetCurrentSchedulerTime(); +            \
pGetPacketCallback->ScheduleNextPacket();  }
         else
         {
@@ -349,9 +366,9 @@
                     tPacket -= m_SchedulerTimeOffset;
                 }
 
-                m_ppPacketStreams[uStreamNo]->m_pTimeToSchedule.tv_sec =  \
                tPacket.tv_sec;
-                m_ppPacketStreams[uStreamNo]->m_pTimeToSchedule.tv_usec = \
                tPacket.tv_usec;
-                m_ppPacketStreams[uStreamNo]->ScheduleNextPacket();
+                pGetPacketCallback->m_pTimeToSchedule.tv_sec =  tPacket.tv_sec;
+                pGetPacketCallback->m_pTimeToSchedule.tv_usec = tPacket.tv_usec;
+                pGetPacketCallback->ScheduleNextPacket();
             }
             else
             {
@@ -366,26 +383,10 @@
 STDMETHODIMP
 StaticSourceContainer::StartPackets(UINT16 unStreamNumber)
 {
-    /* this class never sees the stream headers
-     * so we need to grow the vector of
-     * GetPackeCallbacks as needed.
-     */
-    m_nStreamCount++;
-
-    GetPacketCallback** pOld = m_ppPacketStreams;
-
-    m_ppPacketStreams = new GetPacketCallback* [m_nStreamCount];
-    memset(m_ppPacketStreams, 0, sizeof(GetPacketCallback*) * m_nStreamCount);
-
-    if (pOld != NULL)
-    {
-	memcpy(m_ppPacketStreams, pOld, sizeof(GetPacketCallback*) * (m_nStreamCount-1));
-    }
-
-    HX_VECTOR_DELETE(pOld);
+    GetPacketCallback* pGetPacketCallback = new GetPacketCallback (this, \
unStreamNumber); +    pGetPacketCallback->AddRef();
 
-    m_ppPacketStreams [unStreamNumber] = new GetPacketCallback (this, \
                unStreamNumber);
-    m_ppPacketStreams [unStreamNumber]->AddRef();
+    m_pPacketStreams->SetAt(unStreamNumber, (void*)pGetPacketCallback);
 
     /* Setup timing adjustments for GetPacket scheduling */
     if(!m_bOneStreamStarted)
@@ -414,7 +415,7 @@
     }
 
     /* start the flow of packets */
-    m_ppPacketStreams[unStreamNumber]->m_bPacketsStarted = m_bPacketsStarted = TRUE;
+    pGetPacketCallback->m_bPacketsStarted = m_bPacketsStarted = TRUE;
 
     m_pSourcePackets->GetPacket(unStreamNumber);
 
@@ -425,15 +426,25 @@
 StaticSourceContainer::StopPackets(UINT16 unStreamNumber)
 {
     m_bPacketsStarted = FALSE;
+    m_bOneStreamStarted = FALSE;
 
-    if ( (m_ppPacketStreams) && (m_ppPacketStreams [unStreamNumber]) )
+    if (m_pPacketStreams)
     {
-	if  (m_ppPacketStreams [unStreamNumber]->m_Handle)
-	{
-            m_pThreadSafeScheduler->Remove(m_ppPacketStreams \
                [unStreamNumber]->m_Handle);
-	}
+        GetPacketCallback* pGetPacketCallback = NULL;
+        m_pPacketStreams->Lookup(unStreamNumber, (REF(void*))pGetPacketCallback);
 
-	m_ppPacketStreams [unStreamNumber]->m_bPacketsStarted = FALSE;
+        if (pGetPacketCallback)
+        {
+            if (pGetPacketCallback->m_Handle && m_pThreadSafeScheduler)
+            {
+                m_pThreadSafeScheduler->Remove(pGetPacketCallback->m_Handle);
+                pGetPacketCallback->m_Handle = 0;
+            }
+
+            pGetPacketCallback->m_bPacketsStarted = FALSE;
+            m_pPacketStreams->RemoveKey(unStreamNumber);
+            HX_RELEASE(pGetPacketCallback);        
+        }
     }
 
     return HXR_OK;

Index: source_container.cpp
===================================================================
RCS file: /cvsroot/server/engine/core/source_container.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- source_container.cpp	26 Sep 2011 19:54:23 -0000	1.8
+++ source_container.cpp	24 Nov 2011 04:53:20 -0000	1.9
@@ -160,26 +160,27 @@
 	 * we could be released... so AddRef ourselves
 	 */
 	AddRef();
-	h_result = m_pSourceControl->Init((IHXPSinkControl*)m_pSink);
+	
+    if (m_pSourceLivePackets)
+    {
+	    h_result = m_pSourceLivePackets->Init(this);
 
-	if (HXR_OK == h_result)
-	{
-	    if (m_pSourceLivePackets)
+        if (h_result == HXR_OK)
+        {
+            h_result = m_pSourceControl->Init((IHXPSinkControl*)m_pSink);
+        }
+	    if (HXR_OK == h_result)
 	    {
-		h_result = m_pSourceLivePackets->Init(this);
-
-		if (HXR_OK == h_result)
-		{
 		    goto InitOK;
-		}
-	    }
-	    else
-	    {
-		// if there are no source packets, we must be done
-		// so, proceed without error.
-		goto InitOK;
 	    }
-	}
+    }
+    else
+    {
+	    // if there are no source packets, we must be done
+	    // so, proceed without error.
+	    goto InitOK;
+    }
+
 
 	m_pSink->Release();
 	m_pSink = 0;


_______________________________________________
Server-cvs mailing list
Server-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/server-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic