mirror of
https://github.com/mpv-player/mpv
synced 2025-03-25 04:38:01 +00:00
Support h264 over rtsp
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@22870 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
46fbb1bd66
commit
407c037cfb
@ -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()),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user