📄 mediastrm.cxx
字号:
return FALSE;
defaultDataSize = dataSize;
return TRUE;
}
BOOL OpalMediaStream::RequiresPatchThread() const
{
return TRUE;
}
void OpalMediaStream::EnableJitterBuffer() const
{
}
void OpalMediaStream::SetPatch(OpalMediaPatch * patch)
{
patchMutex.Wait();
patchThread = patch;
patchMutex.Signal();
}
///////////////////////////////////////////////////////////////////////////////
OpalNullMediaStream::OpalNullMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource)
: OpalMediaStream(mediaFormat, sessionID, isSource)
{
}
BOOL OpalNullMediaStream::ReadData(BYTE * /*buffer*/, PINDEX /*size*/, PINDEX & /*length*/)
{
return FALSE;
}
BOOL OpalNullMediaStream::WriteData(const BYTE * /*buffer*/, PINDEX /*length*/, PINDEX & /*written*/)
{
return FALSE;
}
BOOL OpalNullMediaStream::RequiresPatchThread() const
{
return FALSE;
}
BOOL OpalNullMediaStream::IsSynchronous() const
{
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
OpalRTPMediaStream::OpalRTPMediaStream(const OpalMediaFormat & mediaFormat,
BOOL isSource,
RTP_Session & rtp,
unsigned minJitter,
unsigned maxJitter)
: OpalMediaStream(mediaFormat, rtp.GetSessionID(), isSource),
rtpSession(rtp),
minAudioJitterDelay(minJitter),
maxAudioJitterDelay(maxJitter)
{
/* If we are a source then we should set our buffer size to the max
practical UDP packet size. This means we have a buffer that can accept
whatever the RTP sender throws at us. For sink, we just clamp it to that
maximum size. */
if (isSource || defaultDataSize > RTP_DataFrame::MaxEthernetPayloadSize)
defaultDataSize = RTP_DataFrame::MaxEthernetPayloadSize;
}
BOOL OpalRTPMediaStream::Open()
{
if (isOpen)
return TRUE;
rtpSession.Reopen(IsSource());
return OpalMediaStream::Open();
}
BOOL OpalRTPMediaStream::Close()
{
PTRACE(3, "Media\tClosing RTP for " << *this);
// Break any I/O blocks and wait for the thread that uses this object to
// terminate before we allow it to be deleted.
rtpSession.Close(IsSource());
return OpalMediaStream::Close();
}
BOOL OpalRTPMediaStream::ReadPacket(RTP_DataFrame & packet)
{
if (IsSink()) {
PTRACE(1, "Media\tTried to read from sink media stream");
return FALSE;
}
if (!rtpSession.ReadBufferedData(timestamp, packet))
return FALSE;
timestamp = packet.GetTimestamp();
return TRUE;
}
BOOL OpalRTPMediaStream::WritePacket(RTP_DataFrame & packet)
{
if (paused)
packet.SetPayloadSize(0);
if (IsSource()) {
PTRACE(1, "Media\tTried to write to source media stream");
return FALSE;
}
timestamp = packet.GetTimestamp();
if (packet.GetPayloadSize() == 0)
return TRUE;
return rtpSession.WriteData(packet);
}
BOOL OpalRTPMediaStream::IsSynchronous() const
{
return FALSE;
}
void OpalRTPMediaStream::EnableJitterBuffer() const
{
if (mediaFormat.NeedsJitterBuffer())
rtpSession.SetJitterBufferSize(minAudioJitterDelay*mediaFormat.GetTimeUnits(),
maxAudioJitterDelay*mediaFormat.GetTimeUnits(),
mediaFormat.GetTimeUnits());
}
///////////////////////////////////////////////////////////////////////////////
OpalRawMediaStream::OpalRawMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource,
PChannel * chan, BOOL autoDel)
: OpalMediaStream(mediaFormat, sessionID, isSource)
{
channel = chan;
autoDelete = autoDel;
}
OpalRawMediaStream::~OpalRawMediaStream()
{
if (autoDelete)
delete channel;
}
BOOL OpalRawMediaStream::ReadData(BYTE * buffer, PINDEX size, PINDEX & length)
{
length = 0;
if (IsSink()) {
PTRACE(1, "Media\tTried to read from sink media stream");
return FALSE;
}
if (channel == NULL)
return FALSE;
if (!channel->Read(buffer, size))
return FALSE;
length = channel->GetLastReadCount();
return TRUE;
}
BOOL OpalRawMediaStream::WriteData(const BYTE * buffer, PINDEX length, PINDEX & written)
{
written = 0;
if (IsSource()) {
PTRACE(1, "Media\tTried to write to source media stream");
return FALSE;
}
if (channel == NULL)
return FALSE;
if (buffer != NULL && length != 0) {
if (!channel->Write(buffer, length))
return FALSE;
}
else {
PBYTEArray silence(defaultDataSize);
if (!channel->Write(silence, defaultDataSize))
return FALSE;
}
written = channel->GetLastWriteCount();
return TRUE;
}
BOOL OpalRawMediaStream::Close()
{
PTRACE(1, "Media\tClosing raw media stream " << *this);
if (!OpalMediaStream::Close())
return FALSE;
if (channel == NULL)
return FALSE;
return channel->Close();
}
///////////////////////////////////////////////////////////////////////////////
OpalFileMediaStream::OpalFileMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource,
PFile * file,
BOOL autoDel)
: OpalRawMediaStream(mediaFormat, sessionID, isSource, file, autoDel)
{
}
OpalFileMediaStream::OpalFileMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource,
const PFilePath & path)
: OpalRawMediaStream(mediaFormat, sessionID, isSource,
new PFile(path, isSource ? PFile::ReadOnly : PFile::WriteOnly),
TRUE)
{
}
BOOL OpalFileMediaStream::IsSynchronous() const
{
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
OpalAudioMediaStream::OpalAudioMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource,
PINDEX buffers,
PSoundChannel * channel,
BOOL autoDel)
: OpalRawMediaStream(mediaFormat, sessionID, isSource, channel, autoDel)
{
soundChannelBuffers = buffers;
}
OpalAudioMediaStream::OpalAudioMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
BOOL isSource,
PINDEX buffers,
const PString & deviceName)
: OpalRawMediaStream(mediaFormat, sessionID, isSource,
new PSoundChannel(deviceName,
isSource ? PSoundChannel::Recorder
: PSoundChannel::Player,
1, mediaFormat.GetClockRate(), 16),
TRUE)
{
soundChannelBuffers = buffers;
}
BOOL OpalAudioMediaStream::SetDataSize(PINDEX dataSize)
{
PTRACE(3, "Media\tAudio " << (IsSource() ? "source" : "sink") << " data size set to "
<< dataSize << " bytes and " << soundChannelBuffers << " buffers.");
return OpalMediaStream::SetDataSize(dataSize) &&
((PSoundChannel *)channel)->SetBuffers(dataSize, soundChannelBuffers);
}
BOOL OpalAudioMediaStream::IsSynchronous() const
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
OpalVideoMediaStream::OpalVideoMediaStream(const OpalMediaFormat & mediaFormat,
unsigned sessionID,
PVideoInputDevice * in,
PVideoOutputDevice * out,
BOOL del)
: OpalMediaStream(mediaFormat, sessionID, in != NULL),
inputDevice(in),
outputDevice(out),
autoDelete(del)
{
PAssert(in != NULL || out != NULL, PInvalidParameter);
}
OpalVideoMediaStream::~OpalVideoMediaStream()
{
if (autoDelete) {
delete inputDevice;
delete outputDevice;
}
}
BOOL OpalVideoMediaStream::SetDataSize(PINDEX dataSize)
{
if (inputDevice != NULL) {
PINDEX minDataSize = inputDevice->GetMaxFrameBytes();
if (dataSize < minDataSize)
dataSize = minDataSize;
}
if (outputDevice != NULL) {
PINDEX minDataSize = outputDevice->GetMaxFrameBytes();
if (dataSize < minDataSize)
dataSize = minDataSize;
}
return OpalMediaStream::SetDataSize(sizeof(OpalVideoTranscoder::FrameHeader)+dataSize);
}
BOOL OpalVideoMediaStream::Open()
{
if (isOpen)
return TRUE;
unsigned width = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameWidthOption, 176);
unsigned height = mediaFormat.GetOptionInteger(OpalVideoFormat::FrameHeightOption, 144);
if (inputDevice != NULL) {
if (!inputDevice->SetColourFormatConverter(mediaFormat)) {
PTRACE(1, "Media\tCould not set colour format in grabber to " << mediaFormat);
return FALSE;
}
if (!inputDevice->SetFrameSizeConverter(width, height, FALSE)) {
PTRACE(1, "Media\tCould not set frame size in grabber to " << width << 'x' << height << " in " << mediaFormat);
return FALSE;
}
if (!inputDevice->Start()) {
PTRACE(1, "Media\tCould not start video grabber");
return FALSE;
}
lastGrabTime = PTimer::Tick();
}
if (outputDevice != NULL) {
if (!outputDevice->SetColourFormatConverter(mediaFormat)) {
PTRACE(1, "Media\tCould not set colour format in video display to " << mediaFormat);
return FALSE;
}
if (!outputDevice->SetFrameSizeConverter(width, height, FALSE)) {
PTRACE(1, "Media\tCould not set frame size in video display to " << width << 'x' << height << " in " << mediaFormat);
return FALSE;
}
if (!outputDevice->Start()) {
PTRACE(1, "Media\tCould not start video display device");
return FALSE;
}
}
SetDataSize(0); // Gets set to minimum of device buffer requirements
return OpalMediaStream::Open();
}
BOOL OpalVideoMediaStream::ReadData(BYTE * data, PINDEX size, PINDEX & length)
{
if (IsSink()) {
PTRACE(1, "Media\tTried to read from sink media stream");
return FALSE;
}
if (inputDevice == NULL) {
PTRACE(1, "Media\tTried to read from video display device");
return FALSE;
}
if (size < inputDevice->GetMaxFrameBytes()) {
PTRACE(1, "Media\tTried to read with insufficient buffer size");
return FALSE;
}
unsigned width, height;
inputDevice->GetFrameSize(width, height);
OpalVideoTranscoder::FrameHeader * frame = (OpalVideoTranscoder::FrameHeader *)PAssertNULL(data);
frame->x = frame->y = 0;
frame->width = width;
frame->height = height;
PINDEX bytesReturned;
if (!inputDevice->GetFrameData(frame->data, &bytesReturned))
return FALSE;
PTimeInterval currentGrabTime = PTimer::Tick();
timestamp += ((lastGrabTime - currentGrabTime)*1000/OpalMediaFormat::VideoClockRate).GetInterval();
lastGrabTime = currentGrabTime;
marker = TRUE;
length = bytesReturned + sizeof(OpalVideoTranscoder::FrameHeader);
if (outputDevice == NULL)
return TRUE;
return outputDevice->SetFrameData(0, 0, width, height, frame->data, TRUE);
}
BOOL OpalVideoMediaStream::WriteData(const BYTE * data, PINDEX length, PINDEX & written)
{
if (IsSource()) {
PTRACE(1, "Media\tTried to write to source media stream");
return FALSE;
}
if (outputDevice == NULL) {
PTRACE(1, "Media\tTried to write to video capture device");
return FALSE;
}
// Assume we are writing the exact amount (check?)
written = length;
// Check for missing packets, we do nothing at this level, just ignore it
if (data == NULL)
return TRUE;
const OpalVideoTranscoder::FrameHeader * frame = (const OpalVideoTranscoder::FrameHeader *)data;
outputDevice->SetFrameSize(frame->width, frame->height);
return outputDevice->SetFrameData(frame->x, frame->y,
frame->width, frame->height,
frame->data, marker);
}
BOOL OpalVideoMediaStream::IsSynchronous() const
{
return IsSource();
}
// End of file ////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -