diff options
author | cehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-04-01 03:03:05 +0000 |
---|---|---|
committer | cehoyos <cehoyos@b3059339-0415-0410-9bf9-f77b7e298cf2> | 2007-04-01 03:03:05 +0000 |
commit | 407c037cfb165956fad9abf21ea9201047f58ab5 (patch) | |
tree | 2d68756c0cb2f646f7acd65c5dbbd803af65110d /libmpdemux/demux_rtp.cpp | |
parent | 46fbb1bd66b8aff9aea086eeb3c6e309420ce704 (diff) | |
download | mpv-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/demux_rtp.cpp')
-rw-r--r-- | libmpdemux/demux_rtp.cpp | 51 |
1 files changed, 51 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()), |