summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dxr3audiodecoder.c291
-rw-r--r--dxr3syncbuffer.c216
2 files changed, 228 insertions, 279 deletions
diff --git a/dxr3audiodecoder.c b/dxr3audiodecoder.c
index d670d19..a9dda79 100644
--- a/dxr3audiodecoder.c
+++ b/dxr3audiodecoder.c
@@ -2,7 +2,7 @@
* dxr3audiodecoder.c
*
* Copyright (C) 2002-2004 Kai Möller
- * Copyright (C) 2004 Christian Gmeiner
+ * Copyright (C) 2004-2009 Christian Gmeiner
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -70,14 +70,14 @@ cDxr3AudioDecoder::cDxr3AudioDecoder() : rbuf(50000), ac3dtsDecoder(&rbuf)
cDxr3AudioDecoder::~cDxr3AudioDecoder()
{
// close codec, if it is open
- avcodec_close(contextAudio);
+ avcodec_close(contextAudio);
}
// ==================================
//! (re)init ffmpeg codec
void cDxr3AudioDecoder::Init()
{
- avcodec_close(contextAudio);
+ avcodec_close(contextAudio);
// create a new codec context
contextAudio = avcodec_alloc_context();
@@ -89,7 +89,7 @@ void cDxr3AudioDecoder::Init()
}
foundHeader = false;
- decodeAudio = true;
+ decodeAudio = true;
//lastHeader[0] = 0xFF;
//lastHeader[1] = lastHeader[2] = lastHeader[3] = 0;
@@ -104,92 +104,79 @@ void cDxr3AudioDecoder::Decode(cDxr3PesFrame *frame, uint32_t pts, cDxr3SyncBuff
enum audioException
{
- WRONG_LENGTH,
+ WRONG_LENGTH,
};
const uint8_t *buf = frame->GetPayload();
int length = frame->GetPayloadLength();
int i = 0;
- for (i = 0; i < length-4 && !foundHeader; i++)
- {
- unsigned int tempHead = *((unsigned int*)(buf+i));
- if (HeadCheck(tempHead))
- {
- if ((buf[i+2] & 0xFC) != (lastHeader[2] & 0xFC))
- {
- dsyslog("dxr3: audiodecoder: found different audio header"
- " (new: %#x, old: %#x), (re)initializing",
- *((uint32_t*) lastHeader), *((uint32_t*) (buf+i)));
-
- Init();
- lastHeader[0] = buf[i];
- lastHeader[1] = buf[i+1];
- lastHeader[2] = buf[i+2];
- lastHeader[3] = buf[i+3];
- }
- foundHeader = true;
- }
+ for (i = 0; i < length-4 && !foundHeader; i++) {
+ unsigned int tempHead = *((unsigned int*)(buf+i));
+ if (HeadCheck(tempHead)) {
+ if ((buf[i+2] & 0xFC) != (lastHeader[2] & 0xFC)) {
+ dsyslog("dxr3: audiodecoder: found different audio header"
+ " (new: %#x, old: %#x), (re)initializing",
+ *((uint32_t*) lastHeader), *((uint32_t*) (buf+i)));
+
+ Init();
+ lastHeader[0] = buf[i];
+ lastHeader[1] = buf[i+1];
+ lastHeader[2] = buf[i+2];
+ lastHeader[3] = buf[i+3];
+ }
+ foundHeader = true;
+ }
}
- if (audioSynched)
- {
- // no header found
- decodeAudio = true;
- }
- else
- {
- if (foundHeader && pts)
- {
- decodeAudio = true;
- audioSynched = true;
- }
+ if (audioSynched) {
+ // no header found
+ decodeAudio = true;
+ } else {
+ if (foundHeader && pts)
+ {
+ decodeAudio = true;
+ audioSynched = true;
+ }
}
- try
- {
- while (length > 0 && decodeAudio)
- {
+ try {
+ while (length > 0 && decodeAudio) {
#if LIBAVCODEC_VERSION_INT < ((51<<16)+(29<<8)+0)
- len = avcodec_decode_audio(
+ len = avcodec_decode_audio(
#else
- len = avcodec_decode_audio2(
+ len = avcodec_decode_audio2(
#endif
- contextAudio, (short *)(&pcmbuf), &out_size,
- const_cast<uint8_t *>(buf), length);
- if (len < 0 || out_size < 0)
- throw WRONG_LENGTH;
-
- if (out_size)
- {
- cFixedLengthFrame* pTempFrame = aBuf.Push(pcmbuf,
- out_size, pts);
- if (pTempFrame)
- {
- // TODO: should we break out of the loop on push timeout?
- pTempFrame->SetChannelCount(contextAudio->channels);
- pTempFrame->SetSampleRate(contextAudio->sample_rate);
- }
- }
- length -= len;
- buf += len;
- }
- }
- catch (audioException ex)
- {
- switch (ex)
- {
- case WRONG_LENGTH:
- esyslog("dxr3: audiodecoder: wrong length");
- break;
-
- default:
- esyslog("dxr3: audiodecoder: unexpected exception");
- break;
- }
- esyslog("dxr3: audiodecoder: skipping %d broken data bytes", length);
-
- Init();
+ contextAudio, (short *)(&pcmbuf), &out_size,
+ const_cast<uint8_t *>(buf), length);
+ if (len < 0 || out_size < 0)
+ throw WRONG_LENGTH;
+
+ if (out_size) {
+ cFixedLengthFrame* pTempFrame = aBuf.Push(pcmbuf,
+ out_size, pts);
+ if (pTempFrame) {
+ // TODO: should we break out of the loop on push timeout?
+ pTempFrame->SetChannelCount(contextAudio->channels);
+ pTempFrame->SetSampleRate(contextAudio->sample_rate);
+ }
+ }
+ length -= len;
+ buf += len;
+ }
+ } catch (audioException ex) {
+ switch (ex) {
+ case WRONG_LENGTH:
+ esyslog("dxr3: audiodecoder: wrong length");
+ break;
+
+ default:
+ esyslog("dxr3: audiodecoder: unexpected exception");
+ break;
+ }
+
+ esyslog("dxr3: audiodecoder: skipping %d broken data bytes", length);
+ Init();
}
}
@@ -200,53 +187,48 @@ void cDxr3AudioDecoder::DecodeLpcm(cDxr3PesFrame *frame, uint32_t pts, cDxr3Sync
const uint8_t *buf = frame->GetPayload();
int length = frame->GetPayloadLength();
- if (length > (LPCM_HEADER_LENGTH + 2))
- {
- // only even number of bytes are allowed
- if ((length - LPCM_HEADER_LENGTH) % 2 != 0)
- {
- esyslog("dxr3: audiodecoder: skipping %d lpcm bytes", length);
- return;
- }
-
- uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH];
- for (int i = LPCM_HEADER_LENGTH; i < length; i += 2)
- {
- pFrame[i - LPCM_HEADER_LENGTH] = buf[i + 1];
- pFrame[i - LPCM_HEADER_LENGTH + 1] = buf[i];
- }
-
- int codedSpeed = (buf[5] >> 4) & 0x03;
- int speed = 0;
-
- switch (codedSpeed)
- {
- case 1:
- speed = 96000;
- break;
-
- case 2:
- speed = 44100;
- break;
-
- case 3:
- speed = 32000;
- break;
-
- default:
- speed = 48000;
- break;
- }
-
- cFixedLengthFrame* pTempFrame = aBuf.Push(pFrame,
- length - LPCM_HEADER_LENGTH,
- pts);
- if (pTempFrame)
- {
- pTempFrame->SetChannelCount(1);
- pTempFrame->SetSampleRate(speed);
- }
- delete[] pFrame;
+ if (length > (LPCM_HEADER_LENGTH + 2)) {
+ // only even number of bytes are allowed
+ if ((length - LPCM_HEADER_LENGTH) % 2 != 0) {
+ esyslog("dxr3: audiodecoder: skipping %d lpcm bytes", length);
+ return;
+ }
+
+ uint8_t* pFrame = new uint8_t[length - LPCM_HEADER_LENGTH];
+ for (int i = LPCM_HEADER_LENGTH; i < length; i += 2) {
+ pFrame[i - LPCM_HEADER_LENGTH] = buf[i + 1];
+ pFrame[i - LPCM_HEADER_LENGTH + 1] = buf[i];
+ }
+
+ int codedSpeed = (buf[5] >> 4) & 0x03;
+ int speed = 0;
+
+ switch (codedSpeed) {
+ case 1:
+ speed = 96000;
+ break;
+
+ case 2:
+ speed = 44100;
+ break;
+
+ case 3:
+ speed = 32000;
+ break;
+
+ default:
+ speed = 48000;
+ break;
+ }
+
+ cFixedLengthFrame* pTempFrame = aBuf.Push(pFrame,
+ length - LPCM_HEADER_LENGTH,
+ pts);
+ if (pTempFrame) {
+ pTempFrame->SetChannelCount(1);
+ pTempFrame->SetSampleRate(speed);
+ }
+ delete[] pFrame;
}
}
@@ -263,23 +245,21 @@ void cDxr3AudioDecoder::DecodeAc3Dts(const uint8_t* pPes, const uint8_t* buf,
ac3dtsDecoder.Encapsulate(pBuf + headerLength, length);
cFrame* pFrame = 0;
- while ((pFrame = rbuf.Get()))
- {
- if (pFrame && pFrame->Count())
- {
- cDxr3PesFrame tempPes;
- tempPes.parse(pFrame->Data(), pFrame->Count());
- int pesHeaderLength = (int) (tempPes.GetPayload() - tempPes.GetPesStart());
- uint8_t* pData = pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH;
-
- for (int i = 0; i < pFrame->Count() - pesHeaderLength - LPCM_HEADER_LENGTH; i += 2)
- {
- std::swap(pData[i], pData[i + 1]);
- }
-
- aBuf.Push(pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH, pFrame->Count() - pesHeaderLength - 7, tempPes.GetPts());
- if (pFrame) rbuf.Drop(pFrame);
- }
+ while ((pFrame = rbuf.Get())) {
+ if (pFrame && pFrame->Count()) {
+ cDxr3PesFrame tempPes;
+ tempPes.parse(pFrame->Data(), pFrame->Count());
+ int pesHeaderLength = (int) (tempPes.GetPayload() - tempPes.GetPesStart());
+ uint8_t* pData = pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH;
+
+ for (int i = 0; i < pFrame->Count() - pesHeaderLength - LPCM_HEADER_LENGTH; i += 2) {
+ std::swap(pData[i], pData[i + 1]);
+ }
+
+ aBuf.Push(pFrame->Data() + pesHeaderLength + LPCM_HEADER_LENGTH, pFrame->Count() - pesHeaderLength - 7, tempPes.GetPts());
+ if (pFrame)
+ rbuf.Drop(pFrame);
+ }
}
}
@@ -290,25 +270,16 @@ bool cDxr3AudioDecoder::HeadCheck(unsigned long head)
bool retval = false;
uint8_t* phead = (uint8_t*) (&head);
- if (phead[0] != 0xFF)
- {
- retval = false;
- }
- else if (phead[1] != 0xFC && phead[1] != 0xFE)
- {
- retval = false;
- }
- else if ((phead[2] & 0xF0) == 0xF0)
- {
- retval = false;
- }
- else if ((phead[2] & 0xC) == 0xC)
- {
- retval = false;
- }
- else
- {
- retval = true;
+ if (phead[0] != 0xFF) {
+ retval = false;
+ } else if (phead[1] != 0xFC && phead[1] != 0xFE) {
+ retval = false;
+ } else if ((phead[2] & 0xF0) == 0xF0) {
+ retval = false;
+ } else if ((phead[2] & 0xC) == 0xC) {
+ retval = false;
+ } else {
+ retval = true;
}
return retval;
diff --git a/dxr3syncbuffer.c b/dxr3syncbuffer.c
index d51e530..7712e6c 100644
--- a/dxr3syncbuffer.c
+++ b/dxr3syncbuffer.c
@@ -45,9 +45,8 @@ cFixedLengthFrame::cFixedLengthFrame() :
// ==================================
cFixedLengthFrame::~cFixedLengthFrame()
{
- if (m_pData)
- {
- delete[] m_pData;
+ if (m_pData) {
+ delete[] m_pData;
}
}
@@ -59,10 +58,9 @@ void cFixedLengthFrame::Init(uint32_t lenght)
m_pData = new uint8_t[lenght];
// allocation ok?
- if (!m_pData)
- {
- esyslog("dxr3: fatal: unable to allocate memory for new frame");
- exit(1);
+ if (!m_pData) {
+ esyslog("dxr3: fatal: unable to allocate memory for new frame");
+ exit(1);
}
}
@@ -70,11 +68,10 @@ void cFixedLengthFrame::Init(uint32_t lenght)
void cFixedLengthFrame::CopyFrame(const uint8_t* pStart, int length,
uint32_t pts, eFrameType type)
{
- if (length > m_length)
- {
- delete[] m_pData;
- m_pData = new uint8_t[length];
- m_length = length;
+ if (length > m_length) {
+ delete[] m_pData;
+ m_pData = new uint8_t[length];
+ m_length = length;
}
m_type = type;
m_count = length;
@@ -115,16 +112,14 @@ cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength,
m_pBuffer = new cFixedLengthFrame[frameCount];
// got we a valid m_pBuffer?
- if (!m_pBuffer)
- {
- esyslog("dxr3: fatal: unable to allocate memory for new frame");
- exit(1);
+ if (!m_pBuffer) {
+ esyslog("dxr3: fatal: unable to allocate memory for new frame");
+ exit(1);
}
// init our new m_pBuffer;
- for (int i = 0; i < frameCount; i++)
- {
- m_pBuffer[i].Init(frameLength);
+ for (int i = 0; i < frameCount; i++) {
+ m_pBuffer[i].Init(frameLength);
}
// set some default values
@@ -143,9 +138,8 @@ cDxr3SyncBuffer::cDxr3SyncBuffer(int frameCount, int frameLength,
// ==================================
cDxr3SyncBuffer::~cDxr3SyncBuffer()
{
- if (m_pBuffer)
- {
- delete[] m_pBuffer;
+ if (m_pBuffer) {
+ delete[] m_pBuffer;
}
}
@@ -167,33 +161,30 @@ bool cDxr3SyncBuffer::Poll(int TimeoutMs)
struct timeval tv_start, tv;
m_bPollSync = true;
gettimeofday(&tv_start, NULL);
- if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE)
- {
- if (Available() >= Size() - (Size()*BUFFER_LIMIT/100))
- {
- m_bPollSync = true;
- while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) &&
- ((m_dxr3Device.GetSysClock() - currTime) <
- ((uint32_t)TimeoutMs * (uint32_t)45)))
- {
- int d_s, d_us, ms;
- m_bPutBlock = true;
- EnableGet();
- WaitForPut();
- gettimeofday(&tv, NULL);
- d_s = tv.tv_sec - tv_start.tv_sec;
- d_us = tv.tv_usec - tv_start.tv_usec;
- ms = d_s * 1000 + d_us / 1000;
- if (ms > TimeoutMs * 2) {
- esyslog("dxr3: sync: secondary timeout");
- break;
- }
- }
- if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100)
- {
- retVal = false;
- }
- }
+ if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE) {
+ if (Available() >= Size() - (Size()*BUFFER_LIMIT/100)) {
+ m_bPollSync = true;
+ while ((Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) &&
+ ((m_dxr3Device.GetSysClock() - currTime) <
+ ((uint32_t)TimeoutMs * (uint32_t)45)))
+ {
+ int d_s, d_us, ms;
+ m_bPutBlock = true;
+ EnableGet();
+ WaitForPut();
+ gettimeofday(&tv, NULL);
+ d_s = tv.tv_sec - tv_start.tv_sec;
+ d_us = tv.tv_usec - tv_start.tv_usec;
+ ms = d_s * 1000 + d_us / 1000;
+ if (ms > TimeoutMs * 2) {
+ esyslog("dxr3: sync: secondary timeout");
+ break;
+ }
+ }
+ if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100) {
+ retVal = false;
+ }
+ }
}
return retVal;
@@ -206,51 +197,47 @@ cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint
struct timeval tv_start, tv;
gettimeofday(&tv_start, NULL);
- switch (m_demuxMode)
- {
+ switch (m_demuxMode) {
case DXR3_DEMUX_TRICK_MODE:
- break;
+ break;
case DXR3_DEMUX_TV_MODE:
case DXR3_DEMUX_REPLAY_MODE:
default:
- while ((Available() >= Size() - (Size()*10)/100))
- {
- int d_s, d_us, ms;
- m_bPutBlock = true;
- EnableGet();
- WaitForPut();
- gettimeofday(&tv, NULL);
- d_s = tv.tv_sec - tv_start.tv_sec;
- d_us = tv.tv_usec - tv_start.tv_usec;
- ms = d_s * 1000 + d_us / 1000;
- if (ms > 2000) {
- esyslog("dxr3: sync: push timeout");
- return NULL;
- }
- }
-
- lastIndex = m_nextFree;
- m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type);
- m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT);
- m_pBuffer[m_nextFree].SetSampleRate(UNKNOWN_DATA_RATE);
- m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO);
- m_nextFree++;
- m_count++;
- m_nextFree %= Size();
-
- if (m_nextFree == m_next)
- {
- esyslog("dxr3: sync: push buffer overrun");
- Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented
- throw(SYNC_BUFFER_OVERRUN);
- }
- if (m_bStartReceiver)
- {
- EnableGet();
- }
- break;
+ while ((Available() >= Size() - (Size()*10)/100)) {
+ int d_s, d_us, ms;
+ m_bPutBlock = true;
+ EnableGet();
+ WaitForPut();
+ gettimeofday(&tv, NULL);
+ d_s = tv.tv_sec - tv_start.tv_sec;
+ d_us = tv.tv_usec - tv_start.tv_usec;
+ ms = d_s * 1000 + d_us / 1000;
+ if (ms > 2000) {
+ esyslog("dxr3: sync: push timeout");
+ return NULL;
+ }
+ }
+
+ lastIndex = m_nextFree;
+ m_pBuffer[m_nextFree].CopyFrame(pStart, length, pts, type);
+ m_pBuffer[m_nextFree].SetChannelCount(UNKNOWN_CHANNEL_COUNT);
+ m_pBuffer[m_nextFree].SetSampleRate(UNKNOWN_DATA_RATE);
+ m_pBuffer[m_nextFree].SetAspectRatio(UNKNOWN_ASPECT_RATIO);
+ m_nextFree++;
+ m_count++;
+ m_nextFree %= Size();
+
+ if (m_nextFree == m_next) {
+ esyslog("dxr3: sync: push buffer overrun");
+ Clear(); // XXX This is only a workaround until a sufficient control algorithm is implemented
+ throw(SYNC_BUFFER_OVERRUN);
+ }
+ if (m_bStartReceiver) {
+ EnableGet();
+ }
+ break;
}
return &m_pBuffer[lastIndex];
@@ -275,23 +262,18 @@ cFixedLengthFrame* cDxr3SyncBuffer::Get(void)
{
cFixedLengthFrame* pRet = 0;
- if (!m_bStopped)
- {
- while ((!Available() || !m_bStartReceiver) && !m_bStopped)
- {
- m_bGetBlock = true;
- ReceiverStopped();
- WaitForGet();
- }
-
- if (m_nextFree != m_next)
- {
- pRet = &m_pBuffer[m_next];
- }
- }
- else
- {
- WaitForGet();
+ if (!m_bStopped) {
+ while ((!Available() || !m_bStartReceiver) && !m_bStopped) {
+ m_bGetBlock = true;
+ ReceiverStopped();
+ WaitForGet();
+ }
+
+ if (m_nextFree != m_next) {
+ pRet = &m_pBuffer[m_next];
+ }
+ } else {
+ WaitForGet();
}
return pRet;
@@ -305,10 +287,9 @@ void cDxr3SyncBuffer::Clear(void)
m_count = 0;
m_bStartReceiver = false;
m_bPollSync = false;
- if (m_bPutBlock)
- {
- EnablePut();
- m_bPutBlock = false;
+ if (m_bPutBlock) {
+ EnablePut();
+ m_bPutBlock = false;
}
}
@@ -317,17 +298,15 @@ void cDxr3SyncBuffer::Start(void)
{
m_bStartReceiver = true;
m_bStopped = false;
- if (Available())
- {
- EnableGet();
+ if (Available()) {
+ EnableGet();
}
}
// ==================================
void cDxr3SyncBuffer::WakeUp(void)
{
- if (m_bStartReceiver == true)
- {
+ if (m_bStartReceiver == true) {
EnableGet();
}
}
@@ -335,11 +314,10 @@ void cDxr3SyncBuffer::WakeUp(void)
// ==================================
void cDxr3SyncBuffer::WaitForReceiverStopped(void)
{
- if (!m_bGetBlock)
- {
- receiverStoppedMutex.Lock();
- receiverStopped.Wait(receiverStoppedMutex);
- receiverStoppedMutex.Unlock();
+ if (!m_bGetBlock) {
+ receiverStoppedMutex.Lock();
+ receiverStopped.Wait(receiverStoppedMutex);
+ receiverStoppedMutex.Unlock();
}
}