summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorcehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2>2007-04-01 03:03:05 +0000
committercehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2>2007-04-01 03:03:05 +0000
commit407c037cfb165956fad9abf21ea9201047f58ab5 (patch)
tree2d68756c0cb2f646f7acd65c5dbbd803af65110d /libmpdemux
parent46fbb1bd66b8aff9aea086eeb3c6e309420ce704 (diff)
downloadmpv-407c037cfb165956fad9abf21ea9201047f58ab5.tar.bz2
mpv-407c037cfb165956fad9abf21ea9201047f58ab5.tar.xz
Support h264 over rtsp
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@22870 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/demux_rtp.cpp51
-rw-r--r--libmpdemux/demux_rtp_codec.cpp57
-rw-r--r--libmpdemux/demux_rtp_internal.h5
3 files changed, 113 insertions, 0 deletions
diff --git a/libmpdemux/demux_rtp.cpp b/libmpdemux/demux_rtp.cpp
index 3df37cfd7a..0637c41f42 100644
--- a/libmpdemux/demux_rtp.cpp
+++ b/libmpdemux/demux_rtp.cpp
@@ -44,6 +44,9 @@ public:
void savePendingBuffer(demux_packet_t* dp);
demux_packet_t* getPendingBuffer();
+ // For H264 over rtsp using AVParser, the next packet has to be saved
+ demux_packet_t* nextpacket;
+
private:
demux_packet_t* pendingDPHead;
demux_packet_t* pendingDPTail;
@@ -377,6 +380,13 @@ static void afterReading(void* clientData, unsigned frameSize,
if (bufferQueue->readSource()->isAMRAudioSource())
headersize = 1;
+ else if (bufferQueue == rtpState->videoBufferQueue &&
+ ((sh_video_t*)demuxer->video->sh)->format == mmioFOURCC('H','2','6','4')) {
+ dp->buffer[0]=0x00;
+ dp->buffer[1]=0x00;
+ dp->buffer[2]=0x01;
+ headersize = 3;
+ }
resize_demux_packet(dp, frameSize + headersize);
@@ -440,6 +450,8 @@ static demux_packet_t* getBuffer(demuxer_t* demuxer, demux_stream_t* ds,
int headersize = 0;
if (ds == demuxer->video) {
bufferQueue = rtpState->videoBufferQueue;
+ if (((sh_video_t*)ds->sh)->format == mmioFOURCC('H','2','6','4'))
+ headersize = 3;
} else if (ds == demuxer->audio) {
bufferQueue = rtpState->audioBufferQueue;
if (bufferQueue->readSource()->isAMRAudioSource())
@@ -465,10 +477,21 @@ static demux_packet_t* getBuffer(demuxer_t* demuxer, demux_stream_t* ds,
}
// Allocate a new packet buffer, and arrange to read into it:
+ if (!bufferQueue->nextpacket) {
dp = new_demux_packet(MAX_RTP_FRAME_SIZE);
bufferQueue->dp = dp;
if (dp == NULL) return NULL;
+ }
+#ifdef USE_LIBAVCODEC
+ extern AVCodecParserContext * h264parserctx;
+ int consumed, poutbuf_size = 1;
+ uint8_t *poutbuf = NULL;
+ float lastpts;
+
+ do {
+ if (!bufferQueue->nextpacket) {
+#endif
// Schedule the read operation:
bufferQueue->blockingFlag = 0;
bufferQueue->readSource()->getNextFrame(&dp->buffer[headersize], MAX_RTP_FRAME_SIZE - headersize,
@@ -482,6 +505,33 @@ static demux_packet_t* getBuffer(demuxer_t* demuxer, demux_stream_t* ds,
if (headersize == 1) // amr
dp->buffer[0] =
((AMRAudioSource*)bufferQueue->readSource())->lastFrameHeader();
+#ifdef USE_LIBAVCODEC
+ } else {
+ bufferQueue->dp = dp = bufferQueue->nextpacket;
+ bufferQueue->nextpacket = NULL;
+ }
+ if (headersize == 3 && h264parserctx) { // h264
+ consumed = h264parserctx->parser->parser_parse(h264parserctx,
+ NULL,
+ &poutbuf, &poutbuf_size,
+ dp->buffer, dp->len);
+
+ if (!consumed && !poutbuf_size)
+ return NULL;
+
+ if (!poutbuf_size) {
+ lastpts=dp->pts;
+ free_demux_packet(dp);
+ bufferQueue->dp = dp = new_demux_packet(MAX_RTP_FRAME_SIZE);
+ } else {
+ bufferQueue->nextpacket = dp;
+ bufferQueue->dp = dp = new_demux_packet(poutbuf_size);
+ memcpy(dp->buffer, poutbuf, poutbuf_size);
+ dp->pts=lastpts;
+ }
+ }
+ } while (!poutbuf_size);
+#endif
// Set the "ptsBehind" result parameter:
if (bufferQueue->prevPacketPTS != 0.0
@@ -523,6 +573,7 @@ static void teardownRTSPorSIPSession(RTPState* rtpState) {
ReadBufferQueue::ReadBufferQueue(MediaSubsession* subsession,
demuxer_t* demuxer, char const* tag)
: prevPacketWasSynchronized(False), prevPacketPTS(0.0), otherQueue(NULL),
+ nextpacket(NULL),
dp(NULL), pendingDPHead(NULL), pendingDPTail(NULL),
fReadSource(subsession == NULL ? NULL : subsession->readSource()),
fRTPSource(subsession == NULL ? NULL : subsession->rtpSource()),
diff --git a/libmpdemux/demux_rtp_codec.cpp b/libmpdemux/demux_rtp_codec.cpp
index 578d4e6cc0..b2258e42ce 100644
--- a/libmpdemux/demux_rtp_codec.cpp
+++ b/libmpdemux/demux_rtp_codec.cpp
@@ -6,6 +6,54 @@ extern "C" {
#include <limits.h>
#include <math.h>
#include "stheader.h"
+#include "base64.h"
+}
+
+#ifdef USE_LIBAVCODEC
+AVCodecParserContext * h264parserctx;
+#endif
+
+// Copied from vlc
+static unsigned char* parseH264ConfigStr( char const* configStr,
+ unsigned int& configSize )
+{
+
+ char *dup, *psz;
+ int i, i_records = 1;
+
+ if( configSize )
+ configSize = 0;
+ if( configStr == NULL || *configStr == '\0' )
+ return NULL;
+ psz = dup = strdup( configStr );
+
+ /* Count the number of comma's */
+ for( psz = dup; *psz != '\0'; ++psz )
+ {
+ if( *psz == ',')
+ {
+ ++i_records;
+ *psz = '\0';
+ }
+ }
+
+ unsigned char *cfg = new unsigned char[5 * strlen(dup)];
+ psz = dup;
+ for( i = 0; i < i_records; i++ )
+ {
+
+ cfg[configSize++] = 0x00;
+ cfg[configSize++] = 0x00;
+ cfg[configSize++] = 0x01;
+ configSize += av_base64_decode( (uint8_t*)&cfg[configSize],
+ psz,
+ 5 * strlen(dup) - 3 );
+
+ psz += strlen(psz)+1;
+ }
+ if( dup ) free( dup );
+
+ return cfg;
}
static void
@@ -63,6 +111,15 @@ void rtpCodecInitialize_video(demuxer_t* demuxer,
} else if (strcmp(subsession->codecName(), "H264") == 0) {
bih->biCompression = sh_video->format
= mmioFOURCC('H','2','6','4');
+ unsigned int configLen = 0;
+ unsigned char* configData
+ = parseH264ConfigStr(subsession->fmtp_spropparametersets(), configLen);
+ sh_video->bih = bih = insertVideoExtradata(bih, configData, configLen);
+ delete[] configData;
+#ifdef USE_LIBAVCODEC
+ av_register_codec_parser(&h264_parser);
+ h264parserctx = av_parser_init(CODEC_ID_H264);
+#endif
needVideoFrameRate(demuxer, subsession);
} else if (strcmp(subsession->codecName(), "H261") == 0) {
bih->biCompression = sh_video->format
diff --git a/libmpdemux/demux_rtp_internal.h b/libmpdemux/demux_rtp_internal.h
index abcfd819fe..4602da3a86 100644
--- a/libmpdemux/demux_rtp_internal.h
+++ b/libmpdemux/demux_rtp_internal.h
@@ -10,6 +10,11 @@ extern "C" {
#ifndef __DEMUXER_H
#include "demuxer.h"
#endif
+#ifdef USE_LIBAVCODEC_SO
+#include <ffmpeg/avcodec.h>
+#elif defined(USE_LIBAVCODEC)
+#include "libavcodec/avcodec.h"
+#endif
}
#ifndef _LIVEMEDIA_HH