mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
More changes from Reinhard Nissl
This commit is contained in:
parent
94c74762ab
commit
62aa0902b0
196
remux.c
196
remux.c
@ -11,7 +11,7 @@
|
|||||||
* The cDolbyRepacker code was originally written by Reinhard Nissl <rnissl@gmx.de>,
|
* The cDolbyRepacker code was originally written by Reinhard Nissl <rnissl@gmx.de>,
|
||||||
* and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de.
|
* and adapted to the VDR coding style by Klaus.Schmidinger@cadsoft.de.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 1.40 2005/08/27 09:03:56 kls Exp $
|
* $Id: remux.c 1.41 2005/08/28 11:23:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -90,14 +90,15 @@ ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset,
|
|||||||
|
|
||||||
class cRepacker {
|
class cRepacker {
|
||||||
protected:
|
protected:
|
||||||
|
bool initiallySyncing;
|
||||||
int maxPacketSize;
|
int maxPacketSize;
|
||||||
uint8_t subStreamId;
|
uint8_t subStreamId;
|
||||||
static void DroppedData(const char *Reason, int Count) { esyslog("%s (dropped %d bytes)", Reason, Count); }
|
static void DroppedData(const char *Reason, int Count) { esyslog("%s (dropped %d bytes)", Reason, Count); }
|
||||||
public:
|
public:
|
||||||
static int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded);
|
static int Put(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count, int CapacityNeeded);
|
||||||
cRepacker(void) { maxPacketSize = 6 + 65535; subStreamId = 0; }
|
cRepacker(void) { initiallySyncing = true; maxPacketSize = 6 + 65535; subStreamId = 0; }
|
||||||
virtual ~cRepacker() {}
|
virtual ~cRepacker() {}
|
||||||
virtual void Reset(void) {}
|
virtual void Reset(void) { /* initiallySyncing = true; */ }
|
||||||
virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count) = 0;
|
virtual void Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count) = 0;
|
||||||
virtual int BreakAt(const uchar *Data, int Count) = 0;
|
virtual int BreakAt(const uchar *Data, int Count) = 0;
|
||||||
virtual int QuerySnoopSize(void) { return 0; }
|
virtual int QuerySnoopSize(void) { return 0; }
|
||||||
@ -139,6 +140,7 @@ protected:
|
|||||||
|
|
||||||
void cCommonRepacker::Reset(void)
|
void cCommonRepacker::Reset(void)
|
||||||
{
|
{
|
||||||
|
cRepacker::Reset();
|
||||||
skippedBytes = 0;
|
skippedBytes = 0;
|
||||||
packetTodo = maxPacketSize - 6 - 3;
|
packetTodo = maxPacketSize - 6 - 3;
|
||||||
fragmentLen = 0;
|
fragmentLen = 0;
|
||||||
@ -293,16 +295,14 @@ void cVideoRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
// the byte count get's negative then the current buffer ends in a
|
// the byte count get's negative then the current buffer ends in a
|
||||||
// partitial start code that must be stripped off, as it shall be put
|
// partitial start code that must be stripped off, as it shall be put
|
||||||
// in the next packet.
|
// in the next packet.
|
||||||
if (!PushOutPacket(ResultBuffer, payload, data - 3 - payload)) {
|
PushOutPacket(ResultBuffer, payload, data - 3 - payload);
|
||||||
DroppedData("cVideoRepacker: result buffer overflow", Count - (done - 3));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// go on with syncing to the next picture
|
// go on with syncing to the next picture
|
||||||
state = syncing;
|
state = syncing;
|
||||||
}
|
}
|
||||||
if (state == syncing) {
|
if (state == syncing) {
|
||||||
// report that syncing dropped some bytes
|
if (initiallySyncing) // omit report for the typical initial case
|
||||||
if (skippedBytes > SkippedBytesLimit)
|
initiallySyncing = false;
|
||||||
|
else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes
|
||||||
esyslog("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - SkippedBytesLimit);
|
esyslog("cVideoRepacker: skipped %d bytes to sync on next picture", skippedBytes - SkippedBytesLimit);
|
||||||
skippedBytes = 0;
|
skippedBytes = 0;
|
||||||
// if there is a PES header available, then use it ...
|
// if there is a PES header available, then use it ...
|
||||||
@ -408,10 +408,7 @@ void cVideoRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
const uchar *excessData = fragmentData + fragmentLen + bite;
|
const uchar *excessData = fragmentData + fragmentLen + bite;
|
||||||
// a negative byte count means to drop some bytes from the current
|
// a negative byte count means to drop some bytes from the current
|
||||||
// fragment's tail, to not exceed the maximum packet size.
|
// fragment's tail, to not exceed the maximum packet size.
|
||||||
if (!PushOutPacket(ResultBuffer, payload, bite)) {
|
PushOutPacket(ResultBuffer, payload, bite);
|
||||||
DroppedData("cVideoRepacker: result buffer overflow", Count - done);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// create a continuation PES header
|
// create a continuation PES header
|
||||||
pesHeaderLen = 0;
|
pesHeaderLen = 0;
|
||||||
pesHeader[pesHeaderLen++] = 0x00;
|
pesHeader[pesHeaderLen++] = 0x00;
|
||||||
@ -463,7 +460,8 @@ void cVideoRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
}
|
}
|
||||||
// report that syncing dropped some bytes
|
// report that syncing dropped some bytes
|
||||||
if (skippedBytes > SkippedBytesLimit) {
|
if (skippedBytes > SkippedBytesLimit) {
|
||||||
esyslog("cVideoRepacker: skipped %d bytes while syncing on next picture", skippedBytes - SkippedBytesLimit);
|
if (!initiallySyncing) // omit report for the typical initial case
|
||||||
|
esyslog("cVideoRepacker: skipped %d bytes while syncing on next picture", skippedBytes - SkippedBytesLimit);
|
||||||
skippedBytes = SkippedBytesLimit;
|
skippedBytes = SkippedBytesLimit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,14 +506,14 @@ int cVideoRepacker::BreakAt(const uchar *Data, int Count)
|
|||||||
|
|
||||||
class cAudioRepacker : public cCommonRepacker {
|
class cAudioRepacker : public cCommonRepacker {
|
||||||
private:
|
private:
|
||||||
static int bitRates[];
|
static int bitRates[2][3][16];
|
||||||
enum eState {
|
enum eState {
|
||||||
syncing,
|
syncing,
|
||||||
scanFrame
|
scanFrame
|
||||||
} state;
|
} state;
|
||||||
int frameTodo;
|
int frameTodo;
|
||||||
int frameSize;
|
int frameSize;
|
||||||
bool IsValidAudioHeader(uint32_t Header, int *FrameSize = NULL);
|
static bool IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize = NULL);
|
||||||
public:
|
public:
|
||||||
cAudioRepacker(void);
|
cAudioRepacker(void);
|
||||||
virtual void Reset(void);
|
virtual void Reset(void);
|
||||||
@ -523,13 +521,19 @@ public:
|
|||||||
virtual int BreakAt(const uchar *Data, int Count);
|
virtual int BreakAt(const uchar *Data, int Count);
|
||||||
};
|
};
|
||||||
|
|
||||||
int cAudioRepacker::bitRates[] = { // all values are specified as kbits/s
|
int cAudioRepacker::bitRates[2][3][16] = { // all values are specified as kbits/s
|
||||||
// Layer I
|
// MPEG 1, Layer I
|
||||||
0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1,
|
0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1,
|
||||||
// Layer II
|
// MPEG 1, Layer II
|
||||||
0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1,
|
0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1,
|
||||||
// Layer III
|
// MPEG 1, Layer III
|
||||||
0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1
|
0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1,
|
||||||
|
// MPEG 2, Layer I
|
||||||
|
0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1,
|
||||||
|
// MPEG 2, Layer II/III
|
||||||
|
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1,
|
||||||
|
// MPEG 2, Layer II/III
|
||||||
|
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
cAudioRepacker::cAudioRepacker(void)
|
cAudioRepacker::cAudioRepacker(void)
|
||||||
@ -546,7 +550,7 @@ void cAudioRepacker::Reset(void)
|
|||||||
frameSize = 0;
|
frameSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, int *FrameSize)
|
bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, bool Mpeg2, int *FrameSize)
|
||||||
{
|
{
|
||||||
int syncword = (Header & 0xFFF00000) >> 20;
|
int syncword = (Header & 0xFFF00000) >> 20;
|
||||||
int id = (Header & 0x00080000) >> 19;
|
int id = (Header & 0x00080000) >> 19;
|
||||||
@ -565,7 +569,7 @@ bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, int *FrameSize)
|
|||||||
if (syncword != 0xFFF)
|
if (syncword != 0xFFF)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (id == 0) // reserved
|
if (id == 0 && !Mpeg2) // reserved in MPEG 1
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (layer == 0) // reserved
|
if (layer == 0) // reserved
|
||||||
@ -584,16 +588,32 @@ bool cAudioRepacker::IsValidAudioHeader(uint32_t Header, int *FrameSize)
|
|||||||
if (bitrate_index == 0)
|
if (bitrate_index == 0)
|
||||||
*FrameSize = 0;
|
*FrameSize = 0;
|
||||||
else {
|
else {
|
||||||
static int samplingFrequencies[] = { 44100, 48000, 32000 }; // Hz
|
static int samplingFrequencies[2][4] = { // all values are specified in Hz
|
||||||
|
// MPEG 1
|
||||||
|
44100, 48000, 32000, -1,
|
||||||
|
// MPEG 2
|
||||||
|
22050, 24000, 16000, -1
|
||||||
|
};
|
||||||
|
|
||||||
int br = 1000 * bitRates[ (3 - layer) * 0x10 + bitrate_index ]; // bits/s
|
static int slots_per_frame[2][3] = {
|
||||||
int sf = samplingFrequencies[sampling_frequency];
|
// MPEG 1, Layer I, II, III
|
||||||
|
12, 144, 144,
|
||||||
|
// MPEG 2, Layer I, II, III
|
||||||
|
12, 144, 72
|
||||||
|
};
|
||||||
|
|
||||||
bool layerI = (layer == 3);
|
int mpegIndex = 1 - id;
|
||||||
|
int layerIndex = 3 - layer;
|
||||||
|
|
||||||
int N = (layerI ? 12 : 144) * br / sf; // slots
|
// Layer I (i. e., layerIndex == 0) has a larger slot size
|
||||||
|
int slotSize = (layerIndex == 0) ? 4 : 1; // bytes
|
||||||
|
|
||||||
*FrameSize = (N + padding_bit) * (layerI ? 4 : 1); // bytes
|
int br = 1000 * bitRates[mpegIndex][layerIndex][bitrate_index]; // bits/s
|
||||||
|
int sf = samplingFrequencies[mpegIndex][sampling_frequency];
|
||||||
|
|
||||||
|
int N = slots_per_frame[mpegIndex][layerIndex] * br / sf; // slots
|
||||||
|
|
||||||
|
*FrameSize = (N + padding_bit) * slotSize; // bytes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -632,29 +652,35 @@ void cAudioRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
// collect number of skipped bytes while syncing
|
// collect number of skipped bytes while syncing
|
||||||
if (state <= syncing)
|
if (state <= syncing)
|
||||||
skippedBytes++;
|
skippedBytes++;
|
||||||
else if (frameTodo > 0)
|
else if (frameTodo > 0) {
|
||||||
frameTodo--;
|
frameTodo--;
|
||||||
|
if (frameTodo == 0 && state == scanFrame) {
|
||||||
|
// the current audio frame is is done now. So push out the packet to
|
||||||
|
// start a new packet for the next audio frame.
|
||||||
|
PushOutPacket(ResultBuffer, payload, data - payload);
|
||||||
|
// go on with syncing to the next audio frame
|
||||||
|
state = syncing;
|
||||||
|
}
|
||||||
|
}
|
||||||
// did we reach an audio frame header?
|
// did we reach an audio frame header?
|
||||||
scanner <<= 8;
|
scanner <<= 8;
|
||||||
scanner |= *data;
|
scanner |= *data;
|
||||||
if ((scanner & 0xFFF00000) == 0xFFF00000) {
|
if ((scanner & 0xFFF00000) == 0xFFF00000) {
|
||||||
if (frameTodo <= 0 && IsValidAudioHeader(scanner, &frameSize)) {
|
if (frameTodo <= 0 && IsValidAudioHeader(scanner, mpegLevel == phMPEG2, &frameSize)) {
|
||||||
if (state == scanFrame) {
|
if (state == scanFrame) {
|
||||||
// As a new audio frame starts here, the previous one is done. So push
|
// As a new audio frame starts here, the previous one is done. So push
|
||||||
// out the packet to start a new packet for the next audio frame. If
|
// out the packet to start a new packet for the next audio frame. If
|
||||||
// the byte count gets negative then the current buffer ends in a
|
// the byte count gets negative then the current buffer ends in a
|
||||||
// partitial audio frame header that must be stripped off, as it shall
|
// partitial audio frame header that must be stripped off, as it shall
|
||||||
// be put in the next packet.
|
// be put in the next packet.
|
||||||
if (!PushOutPacket(ResultBuffer, payload, data - 3 - payload)) {
|
PushOutPacket(ResultBuffer, payload, data - 3 - payload);
|
||||||
DroppedData("cAudioRepacker: result buffer overflow", Count - (done - 3));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// go on with syncing to the next audio frame
|
// go on with syncing to the next audio frame
|
||||||
state = syncing;
|
state = syncing;
|
||||||
}
|
}
|
||||||
if (state == syncing) {
|
if (state == syncing) {
|
||||||
// report that syncing dropped some bytes
|
if (initiallySyncing) // omit report for the typical initial case
|
||||||
if (skippedBytes > SkippedBytesLimit)
|
initiallySyncing = false;
|
||||||
|
else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes
|
||||||
esyslog("cAudioRepacker: skipped %d bytes to sync on next audio frame", skippedBytes - SkippedBytesLimit);
|
esyslog("cAudioRepacker: skipped %d bytes to sync on next audio frame", skippedBytes - SkippedBytesLimit);
|
||||||
skippedBytes = 0;
|
skippedBytes = 0;
|
||||||
// if there is a PES header available, then use it ...
|
// if there is a PES header available, then use it ...
|
||||||
@ -693,11 +719,10 @@ void cAudioRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
// the next packet's payload will begin with the fourth byte of
|
// the next packet's payload will begin with the fourth byte of
|
||||||
// the audio frame header (= the actual byte)
|
// the audio frame header (= the actual byte)
|
||||||
payload = data;
|
payload = data;
|
||||||
// as there is no length information available, assume the
|
|
||||||
// maximum we can hold in one PES packet
|
// maximum we can hold in one PES packet
|
||||||
packetTodo = maxPacketSize - pesHeaderLen;
|
packetTodo = maxPacketSize - pesHeaderLen;
|
||||||
// setup expected audio frame size to omit false audio header detection
|
// expected remainder of audio frame: so far we have read 3 bytes from the frame header
|
||||||
frameTodo = frameSize;
|
frameTodo = frameSize - 3;
|
||||||
// go on with collecting the frame's data
|
// go on with collecting the frame's data
|
||||||
((int &)state)++;
|
((int &)state)++;
|
||||||
}
|
}
|
||||||
@ -751,10 +776,7 @@ void cAudioRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
const uchar *excessData = fragmentData + fragmentLen + bite;
|
const uchar *excessData = fragmentData + fragmentLen + bite;
|
||||||
// A negative byte count means to drop some bytes from the current
|
// A negative byte count means to drop some bytes from the current
|
||||||
// fragment's tail, to not exceed the maximum packet size.
|
// fragment's tail, to not exceed the maximum packet size.
|
||||||
if (!PushOutPacket(ResultBuffer, payload, bite)) {
|
PushOutPacket(ResultBuffer, payload, bite);
|
||||||
DroppedData("cAudioRepacker: result buffer overflow", Count - done);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// create a continuation PES header
|
// create a continuation PES header
|
||||||
pesHeaderLen = 0;
|
pesHeaderLen = 0;
|
||||||
pesHeader[pesHeaderLen++] = 0x00;
|
pesHeader[pesHeaderLen++] = 0x00;
|
||||||
@ -806,7 +828,8 @@ void cAudioRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
}
|
}
|
||||||
// report that syncing dropped some bytes
|
// report that syncing dropped some bytes
|
||||||
if (skippedBytes > SkippedBytesLimit) {
|
if (skippedBytes > SkippedBytesLimit) {
|
||||||
esyslog("cAudioRepacker: skipped %d bytes while syncing on next audio frame", skippedBytes - SkippedBytesLimit);
|
if (!initiallySyncing) // omit report for the typical initial case
|
||||||
|
esyslog("cAudioRepacker: skipped %d bytes while syncing on next audio frame", skippedBytes - SkippedBytesLimit);
|
||||||
skippedBytes = SkippedBytesLimit;
|
skippedBytes = SkippedBytesLimit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -815,7 +838,8 @@ int cAudioRepacker::BreakAt(const uchar *Data, int Count)
|
|||||||
{
|
{
|
||||||
int PesPayloadOffset = 0;
|
int PesPayloadOffset = 0;
|
||||||
|
|
||||||
if (AnalyzePesHeader(Data, Count, PesPayloadOffset) <= phInvalid)
|
ePesHeader MpegLevel = AnalyzePesHeader(Data, Count, PesPayloadOffset);
|
||||||
|
if (MpegLevel <= phInvalid)
|
||||||
return -1; // not enough data for test
|
return -1; // not enough data for test
|
||||||
|
|
||||||
// determine amount of data to fill up packet and to append next audio frame header
|
// determine amount of data to fill up packet and to append next audio frame header
|
||||||
@ -845,7 +869,7 @@ int cAudioRepacker::BreakAt(const uchar *Data, int Count)
|
|||||||
localScanner <<= 8;
|
localScanner <<= 8;
|
||||||
localScanner |= *data++;
|
localScanner |= *data++;
|
||||||
// check whether the next audio frame follows
|
// check whether the next audio frame follows
|
||||||
if ((localScanner & 0xFFF00000) == 0xFFF00000 && IsValidAudioHeader(localScanner))
|
if (((localScanner & 0xFFF00000) == 0xFFF00000) && IsValidAudioHeader(localScanner, MpegLevel == phMPEG2))
|
||||||
return data - Data;
|
return data - Data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -879,8 +903,8 @@ private:
|
|||||||
int skippedBytes;
|
int skippedBytes;
|
||||||
void ResetPesHeader(bool ContinuationFrame = false);
|
void ResetPesHeader(bool ContinuationFrame = false);
|
||||||
void AppendSubStreamID(bool ContinuationFrame = false);
|
void AppendSubStreamID(bool ContinuationFrame = false);
|
||||||
bool FinishRemainder(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Done, int &Bite);
|
bool FinishRemainder(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Bite);
|
||||||
bool StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Done, int &Bite);
|
bool StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Bite);
|
||||||
public:
|
public:
|
||||||
cDolbyRepacker(void);
|
cDolbyRepacker(void);
|
||||||
virtual void Reset(void);
|
virtual void Reset(void);
|
||||||
@ -947,6 +971,7 @@ void cDolbyRepacker::ResetPesHeader(bool ContinuationFrame)
|
|||||||
|
|
||||||
void cDolbyRepacker::Reset(void)
|
void cDolbyRepacker::Reset(void)
|
||||||
{
|
{
|
||||||
|
cRepacker::Reset();
|
||||||
ResetPesHeader();
|
ResetPesHeader();
|
||||||
state = find_0b;
|
state = find_0b;
|
||||||
ac3todo = 0;
|
ac3todo = 0;
|
||||||
@ -958,26 +983,24 @@ void cDolbyRepacker::Reset(void)
|
|||||||
skippedBytes = 0;
|
skippedBytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDolbyRepacker::FinishRemainder(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Done, int &Bite)
|
bool cDolbyRepacker::FinishRemainder(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Bite)
|
||||||
{
|
{
|
||||||
|
bool success = true;
|
||||||
// enough data available to put PES packet into buffer?
|
// enough data available to put PES packet into buffer?
|
||||||
if (fragmentTodo <= Todo) {
|
if (fragmentTodo <= Todo) {
|
||||||
// output a previous fragment first
|
// output a previous fragment first
|
||||||
if (fragmentLen > 0) {
|
if (fragmentLen > 0) {
|
||||||
Bite = fragmentLen;
|
Bite = fragmentLen;
|
||||||
int n = Put(ResultBuffer, fragmentData, Bite, fragmentLen + fragmentTodo);
|
int n = Put(ResultBuffer, fragmentData, Bite, fragmentLen + fragmentTodo);
|
||||||
if (Bite != n) {
|
if (Bite != n)
|
||||||
Reset();
|
success = false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fragmentLen = 0;
|
fragmentLen = 0;
|
||||||
}
|
}
|
||||||
Bite = fragmentTodo;
|
Bite = fragmentTodo;
|
||||||
int n = Put(ResultBuffer, Data, Bite, Bite);
|
if (success) {
|
||||||
if (Bite != n) {
|
int n = Put(ResultBuffer, Data, Bite, Bite);
|
||||||
Reset();
|
if (Bite != n)
|
||||||
Done += n;
|
success = false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
fragmentTodo = 0;
|
fragmentTodo = 0;
|
||||||
// ac3 frame completely processed?
|
// ac3 frame completely processed?
|
||||||
@ -987,19 +1010,16 @@ bool cDolbyRepacker::FinishRemainder(cRingBufferLinear *ResultBuffer, const ucha
|
|||||||
else {
|
else {
|
||||||
// copy the fragment into separate buffer for later processing
|
// copy the fragment into separate buffer for later processing
|
||||||
Bite = Todo;
|
Bite = Todo;
|
||||||
if (fragmentLen + Bite > (int)sizeof(fragmentData)) {
|
|
||||||
Reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(fragmentData + fragmentLen, Data, Bite);
|
memcpy(fragmentData + fragmentLen, Data, Bite);
|
||||||
fragmentLen += Bite;
|
fragmentLen += Bite;
|
||||||
fragmentTodo -= Bite;
|
fragmentTodo -= Bite;
|
||||||
}
|
}
|
||||||
return true;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cDolbyRepacker::StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Done, int &Bite)
|
bool cDolbyRepacker::StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar *const Data, const int Todo, int &Bite)
|
||||||
{
|
{
|
||||||
|
bool success = true;
|
||||||
int packetLen = pesHeaderLen + ac3todo;
|
int packetLen = pesHeaderLen + ac3todo;
|
||||||
// limit packet to maximum size
|
// limit packet to maximum size
|
||||||
if (packetLen > maxPacketSize)
|
if (packetLen > maxPacketSize)
|
||||||
@ -1010,16 +1030,13 @@ bool cDolbyRepacker::StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar
|
|||||||
// enough data available to put PES packet into buffer?
|
// enough data available to put PES packet into buffer?
|
||||||
if (packetLen - pesHeaderLen <= Todo) {
|
if (packetLen - pesHeaderLen <= Todo) {
|
||||||
int n = Put(ResultBuffer, pesHeader, Bite, packetLen);
|
int n = Put(ResultBuffer, pesHeader, Bite, packetLen);
|
||||||
if (Bite != n) {
|
if (Bite != n)
|
||||||
Reset();
|
success = false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Bite = packetLen - pesHeaderLen;
|
Bite = packetLen - pesHeaderLen;
|
||||||
n = Put(ResultBuffer, Data, Bite, Bite);
|
if (success) {
|
||||||
if (Bite != n) {
|
n = Put(ResultBuffer, Data, Bite, Bite);
|
||||||
Reset();
|
if (Bite != n)
|
||||||
Done += n;
|
success = false;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// ac3 frame completely processed?
|
// ac3 frame completely processed?
|
||||||
if (Bite >= ac3todo)
|
if (Bite >= ac3todo)
|
||||||
@ -1028,24 +1045,16 @@ bool cDolbyRepacker::StartNewPacket(cRingBufferLinear *ResultBuffer, const uchar
|
|||||||
else {
|
else {
|
||||||
fragmentTodo = packetLen;
|
fragmentTodo = packetLen;
|
||||||
// copy the pesheader into separate buffer for later processing
|
// copy the pesheader into separate buffer for later processing
|
||||||
if (fragmentLen + Bite > (int)sizeof(fragmentData)) {
|
|
||||||
Reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(fragmentData + fragmentLen, pesHeader, Bite);
|
memcpy(fragmentData + fragmentLen, pesHeader, Bite);
|
||||||
fragmentLen += Bite;
|
fragmentLen += Bite;
|
||||||
fragmentTodo -= Bite;
|
fragmentTodo -= Bite;
|
||||||
// copy the fragment into separate buffer for later processing
|
// copy the fragment into separate buffer for later processing
|
||||||
Bite = Todo;
|
Bite = Todo;
|
||||||
if (fragmentLen + Bite > (int)sizeof(fragmentData)) {
|
|
||||||
Reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(fragmentData + fragmentLen, Data, Bite);
|
memcpy(fragmentData + fragmentLen, Data, Bite);
|
||||||
fragmentLen += Bite;
|
fragmentLen += Bite;
|
||||||
fragmentTodo -= Bite;
|
fragmentTodo -= Bite;
|
||||||
}
|
}
|
||||||
return true;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDolbyRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count)
|
void cDolbyRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data, int Count)
|
||||||
@ -1139,8 +1148,9 @@ void cDolbyRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
state = find_0b;
|
state = find_0b;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// report that syncing dropped some bytes
|
if (initiallySyncing) // omit report for the typical initial case
|
||||||
if (skippedBytes > SkippedBytesLimit)
|
initiallySyncing = false;
|
||||||
|
else if (skippedBytes > SkippedBytesLimit) // report that syncing dropped some bytes
|
||||||
esyslog("cDolbyRepacker: skipped %d bytes to sync on next AC3 frame", skippedBytes - SkippedBytesLimit);
|
esyslog("cDolbyRepacker: skipped %d bytes to sync on next AC3 frame", skippedBytes - SkippedBytesLimit);
|
||||||
skippedBytes = 0;
|
skippedBytes = 0;
|
||||||
// append read data to header for common output processing
|
// append read data to header for common output processing
|
||||||
@ -1154,18 +1164,11 @@ void cDolbyRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
case output_packet: {
|
case output_packet: {
|
||||||
int bite = 0;
|
int bite = 0;
|
||||||
// finish remainder of ac3 frame?
|
// finish remainder of ac3 frame?
|
||||||
if (fragmentTodo > 0) {
|
if (fragmentTodo > 0)
|
||||||
if (!FinishRemainder(ResultBuffer, data, todo, done, bite)) {
|
FinishRemainder(ResultBuffer, data, todo, bite);
|
||||||
DroppedData("cDolbyRepacker: result buffer overflow", Count - done);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
// start a new packet
|
// start a new packet
|
||||||
if (!StartNewPacket(ResultBuffer, data, todo, done, bite)) {
|
StartNewPacket(ResultBuffer, data, todo, bite);
|
||||||
DroppedData("cDolbyRepacker: result buffer overflow", Count - done);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// prepare for next (continuation) packet
|
// prepare for next (continuation) packet
|
||||||
ResetPesHeader(state == output_packet);
|
ResetPesHeader(state == output_packet);
|
||||||
}
|
}
|
||||||
@ -1178,7 +1181,8 @@ void cDolbyRepacker::Repack(cRingBufferLinear *ResultBuffer, const uchar *Data,
|
|||||||
}
|
}
|
||||||
// report that syncing dropped some bytes
|
// report that syncing dropped some bytes
|
||||||
if (skippedBytes > SkippedBytesLimit) {
|
if (skippedBytes > SkippedBytesLimit) {
|
||||||
esyslog("cDolbyRepacker: skipped %d bytes while syncing on next AC3 frame", skippedBytes - 4);
|
if (!initiallySyncing) // omit report for the typical initial case
|
||||||
|
esyslog("cDolbyRepacker: skipped %d bytes while syncing on next AC3 frame", skippedBytes - 4);
|
||||||
skippedBytes = SkippedBytesLimit;
|
skippedBytes = SkippedBytesLimit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user