changeset 22463:979b2aa16e80

support for AMR; it works inserting in the first byte of the demux_packet a 1-byte header that live555 seems to be stripping for some reason, although according to the specs it should be there. Patch by Carl Eugen Hoyos.
author nicodvb
date Tue, 06 Mar 2007 22:53:52 +0000
parents adc2bfb6dcaf
children ba459e2e1187
files libmpdemux/demux_rtp.cpp libmpdemux/demux_rtp_codec.cpp
diffstat 2 files changed, 17 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libmpdemux/demux_rtp.cpp	Tue Mar 06 19:10:36 2007 +0000
+++ b/libmpdemux/demux_rtp.cpp	Tue Mar 06 22:53:52 2007 +0000
@@ -362,6 +362,7 @@
 			 unsigned /*numTruncatedBytes*/,
 			 struct timeval presentationTime,
 			 unsigned /*durationInMicroseconds*/) {
+  int headersize = 0;
   if (frameSize >= MAX_RTP_FRAME_SIZE) {
     fprintf(stderr, "Saw an input frame too large (>=%d).  Increase MAX_RTP_FRAME_SIZE in \"demux_rtp.cpp\".\n",
 	    MAX_RTP_FRAME_SIZE);
@@ -372,8 +373,11 @@
 
   if (frameSize > 0) demuxer->stream->eof = 0;
 
+  if (bufferQueue->readSource()->isAMRAudioSource())
+    headersize = 1;
+
   demux_packet_t* dp = bufferQueue->dp;
-  resize_demux_packet(dp, frameSize);
+  resize_demux_packet(dp, frameSize + headersize);
 
   // Set the packet's presentation time stamp, depending on whether or
   // not our RTP source's timestamps have been synchronized yet: 
@@ -432,10 +436,13 @@
   //  the demuxer's 'priv' field)
   RTPState* rtpState = (RTPState*)(demuxer->priv);
   ReadBufferQueue* bufferQueue = NULL;
+  int amr = 0;
   if (ds == demuxer->video) {
     bufferQueue = rtpState->videoBufferQueue;
   } else if (ds == demuxer->audio) {
     bufferQueue = rtpState->audioBufferQueue;
+    if (bufferQueue->readSource()->isAMRAudioSource())
+      amr = 1;
   } else {
     fprintf(stderr, "(demux_rtp)getBuffer: internal error: unknown stream\n");
     return NULL;
@@ -463,7 +470,7 @@
 
   // Schedule the read operation:
   bufferQueue->blockingFlag = 0;
-  bufferQueue->readSource()->getNextFrame(dp->buffer, MAX_RTP_FRAME_SIZE,
+  bufferQueue->readSource()->getNextFrame(&dp->buffer[amr], MAX_RTP_FRAME_SIZE - amr,
 					  afterReading, bufferQueue,
 					  onSourceClosure, bufferQueue);
   // Block ourselves until data becomes available:
@@ -471,6 +478,10 @@
     = bufferQueue->readSource()->envir().taskScheduler();
   scheduler.doEventLoop(&bufferQueue->blockingFlag);
 
+  if (amr)
+    dp->buffer[0] =
+        ((AMRAudioSource*)bufferQueue->readSource())->lastFrameHeader();
+
   // Set the "ptsBehind" result parameter:
   if (bufferQueue->prevPacketPTS != 0.0
       && bufferQueue->prevPacketWasSynchronized
--- a/libmpdemux/demux_rtp_codec.cpp	Tue Mar 06 19:10:36 2007 +0000
+++ b/libmpdemux/demux_rtp_codec.cpp	Tue Mar 06 22:53:52 2007 +0000
@@ -184,6 +184,10 @@
     wf->nBlockAlign = 1;
     wf->wBitsPerSample = 8;
     wf->cbSize = 0;
+  } else if (strcmp(subsession->codecName(), "AMR") == 0) {
+    wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','m','r');
+  } else if (strcmp(subsession->codecName(), "AMR-WB") == 0) {
+    wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','w','b');
   } else if (strcmp(subsession->codecName(), "GSM") == 0) {
     wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m');
     wf->nAvgBytesPerSec = 1650;