Mercurial > mplayer.hg
changeset 22852:d7f4da5e9ee4
Support h264 over rtsp
author | cehoyos |
---|---|
date | Sun, 01 Apr 2007 03:03:05 +0000 |
parents | e878a71cb27f |
children | aaaedf34d589 |
files | libmpdemux/demux_rtp.cpp libmpdemux/demux_rtp_codec.cpp libmpdemux/demux_rtp_internal.h |
diffstat | 3 files changed, 113 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/demux_rtp.cpp Sun Apr 01 03:00:47 2007 +0000 +++ b/libmpdemux/demux_rtp.cpp Sun Apr 01 03:03:05 2007 +0000 @@ -44,6 +44,9 @@ 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 @@ 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 @@ 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 @@ } // 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 @@ 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 @@ 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()),
--- a/libmpdemux/demux_rtp_codec.cpp Sun Apr 01 03:00:47 2007 +0000 +++ b/libmpdemux/demux_rtp_codec.cpp Sun Apr 01 03:03:05 2007 +0000 @@ -6,6 +6,54 @@ #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 @@ } 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
--- a/libmpdemux/demux_rtp_internal.h Sun Apr 01 03:00:47 2007 +0000 +++ b/libmpdemux/demux_rtp_internal.h Sun Apr 01 03:03:05 2007 +0000 @@ -10,6 +10,11 @@ #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