mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Improved clearing the MTD buffer and syncing on TS packets
This commit is contained in:
parent
9e808255f8
commit
b313d88db1
9
device.c
9
device.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c 4.9 2017/03/23 14:19:59 kls Exp $
|
* $Id: device.c 4.10 2017/03/26 11:35:38 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
@ -1570,13 +1570,8 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (Length >= TS_SIZE) {
|
while (Length >= TS_SIZE) {
|
||||||
if (Data[0] != TS_SYNC_BYTE) {
|
if (int Skipped = TS_SYNC(Data, Length))
|
||||||
int Skipped = 1;
|
|
||||||
while (Skipped < Length && (Data[Skipped] != TS_SYNC_BYTE || Length - Skipped > TS_SIZE && Data[Skipped + TS_SIZE] != TS_SYNC_BYTE))
|
|
||||||
Skipped++;
|
|
||||||
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
|
|
||||||
return Played + Skipped;
|
return Played + Skipped;
|
||||||
}
|
|
||||||
int Pid = TsPid(Data);
|
int Pid = TsPid(Data);
|
||||||
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
|
if (TsHasPayload(Data)) { // silently ignore TS packets w/o payload
|
||||||
int PayloadOffset = TsPayloadOffset(Data);
|
int PayloadOffset = TsPayloadOffset(Data);
|
||||||
|
23
mtd.c
23
mtd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: mtd.c 1.5 2017/03/25 14:09:31 kls Exp $
|
* $Id: mtd.c 1.6 2017/03/26 13:01:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mtd.h"
|
#include "mtd.h"
|
||||||
@ -229,7 +229,6 @@ cMtdCamSlot::cMtdCamSlot(cCamSlot *MasterSlot, int Index)
|
|||||||
mtdBuffer = new cRingBufferLinear(MTD_BUFFER_SIZE, TS_SIZE, true, "MTD buffer");
|
mtdBuffer = new cRingBufferLinear(MTD_BUFFER_SIZE, TS_SIZE, true, "MTD buffer");
|
||||||
mtdMapper = new cMtdMapper(Index + 1, MasterSlot->SlotNumber());
|
mtdMapper = new cMtdMapper(Index + 1, MasterSlot->SlotNumber());
|
||||||
delivered = false;
|
delivered = false;
|
||||||
clearBuffer = false;
|
|
||||||
ciAdapter = MasterSlot->ciAdapter; // we don't pass the CI adapter in the constructor, to prevent this one from being inserted into CamSlots
|
ciAdapter = MasterSlot->ciAdapter; // we don't pass the CI adapter in the constructor, to prevent this one from being inserted into CamSlots
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,8 +278,10 @@ void cMtdCamSlot::StopDecrypting(void)
|
|||||||
cCamSlot::StopDecrypting();
|
cCamSlot::StopDecrypting();
|
||||||
if (!MasterSlot()->IsDecrypting())
|
if (!MasterSlot()->IsDecrypting())
|
||||||
MasterSlot()->StopDecrypting();
|
MasterSlot()->StopDecrypting();
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
mtdMapper->Clear();
|
mtdMapper->Clear();
|
||||||
clearBuffer = true;
|
mtdBuffer->Clear();
|
||||||
|
delivered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count)
|
uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count)
|
||||||
@ -297,18 +298,19 @@ uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count)
|
|||||||
else
|
else
|
||||||
Count = 0;
|
Count = 0;
|
||||||
// Drop delivered data from previous call:
|
// Drop delivered data from previous call:
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
if (delivered) {
|
if (delivered) {
|
||||||
mtdBuffer->Del(TS_SIZE);
|
mtdBuffer->Del(TS_SIZE);
|
||||||
delivered = false;
|
delivered = false;
|
||||||
}
|
}
|
||||||
if (clearBuffer) {
|
|
||||||
mtdBuffer->Clear();
|
|
||||||
clearBuffer = false;
|
|
||||||
}
|
|
||||||
// Receive data from buffer:
|
// Receive data from buffer:
|
||||||
int c = 0;
|
int c = 0;
|
||||||
uchar *d = mtdBuffer->Get(c);
|
uchar *d = mtdBuffer->Get(c);
|
||||||
if (d) {
|
if (d) {
|
||||||
|
if (int Skipped = TS_SYNC(d, c)) {
|
||||||
|
mtdBuffer->Del(Skipped);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (c >= TS_SIZE) {
|
if (c >= TS_SIZE) {
|
||||||
TsSetPid(d, mtdMapper->UniqToRealPid(TsPid(d)));
|
TsSetPid(d, mtdMapper->UniqToRealPid(TsPid(d)));
|
||||||
delivered = true;
|
delivered = true;
|
||||||
@ -321,6 +323,13 @@ uchar *cMtdCamSlot::Decrypt(uchar *Data, int &Count)
|
|||||||
|
|
||||||
int cMtdCamSlot::PutData(const uchar *Data, int Count)
|
int cMtdCamSlot::PutData(const uchar *Data, int Count)
|
||||||
{
|
{
|
||||||
|
cMutexLock MutexLock(&mutex);
|
||||||
|
int Free = mtdBuffer->Free();
|
||||||
|
Free -= Free % TS_SIZE;
|
||||||
|
if (Free < TS_SIZE)
|
||||||
|
return 0;
|
||||||
|
if (Free < Count)
|
||||||
|
Count = Free;
|
||||||
return mtdBuffer->Put(Data, Count);
|
return mtdBuffer->Put(Data, Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
mtd.h
4
mtd.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: mtd.h 1.4 2017/03/23 12:48:22 kls Exp $
|
* $Id: mtd.h 1.5 2017/03/25 14:47:03 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MTD_H
|
#ifndef __MTD_H
|
||||||
@ -151,10 +151,10 @@ void MtdMapPid(uchar *p, cMtdMapper *MtdMapper);
|
|||||||
|
|
||||||
class cMtdCamSlot : public cCamSlot {
|
class cMtdCamSlot : public cCamSlot {
|
||||||
private:
|
private:
|
||||||
|
cMutex mutex;
|
||||||
cMtdMapper *mtdMapper;
|
cMtdMapper *mtdMapper;
|
||||||
cRingBufferLinear *mtdBuffer;
|
cRingBufferLinear *mtdBuffer;
|
||||||
bool delivered;
|
bool delivered;
|
||||||
bool clearBuffer;
|
|
||||||
protected:
|
protected:
|
||||||
virtual const int *GetCaSystemIds(void);
|
virtual const int *GetCaSystemIds(void);
|
||||||
virtual void SendCaPmt(uint8_t CmdId);
|
virtual void SendCaPmt(uint8_t CmdId);
|
||||||
|
22
remux.c
22
remux.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.c 4.4 2017/01/09 15:05:05 kls Exp $
|
* $Id: remux.c 4.5 2017/03/26 13:07:01 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remux.h"
|
#include "remux.h"
|
||||||
@ -144,6 +144,19 @@ void TsSetPcr(uchar *p, int64_t Pcr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TsSync(const uchar *Data, int Length, const char *File, const char *Function, int Line)
|
||||||
|
{
|
||||||
|
int Skipped = 0;
|
||||||
|
while (Length > 0 && (*Data != TS_SYNC_BYTE || Length > TS_SIZE && Data[TS_SIZE] != TS_SYNC_BYTE)) {
|
||||||
|
Data++;
|
||||||
|
Length--;
|
||||||
|
Skipped++;
|
||||||
|
}
|
||||||
|
if (Skipped && File && Function && Line)
|
||||||
|
esyslog("ERROR: skipped %d bytes to sync on start of TS packet at %s/%s(%d)", Skipped, File, Function, Line);
|
||||||
|
return Skipped;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t TsGetPts(const uchar *p, int l)
|
int64_t TsGetPts(const uchar *p, int l)
|
||||||
{
|
{
|
||||||
// Find the first packet with a PTS and use it:
|
// Find the first packet with a PTS and use it:
|
||||||
@ -1557,13 +1570,8 @@ int cFrameDetector::Analyze(const uchar *Data, int Length)
|
|||||||
newFrame = independentFrame = false;
|
newFrame = independentFrame = false;
|
||||||
while (Length >= MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) { // makes sure we are looking at enough data, in case the frame type is not stored in the first TS packet
|
while (Length >= MIN_TS_PACKETS_FOR_FRAME_DETECTOR * TS_SIZE) { // makes sure we are looking at enough data, in case the frame type is not stored in the first TS packet
|
||||||
// Sync on TS packet borders:
|
// Sync on TS packet borders:
|
||||||
if (Data[0] != TS_SYNC_BYTE) {
|
if (int Skipped = TS_SYNC(Data, Length))
|
||||||
int Skipped = 1;
|
|
||||||
while (Skipped < Length && (Data[Skipped] != TS_SYNC_BYTE || Length - Skipped > TS_SIZE && Data[Skipped + TS_SIZE] != TS_SYNC_BYTE))
|
|
||||||
Skipped++;
|
|
||||||
esyslog("ERROR: skipped %d bytes to sync on start of TS packet", Skipped);
|
|
||||||
return Processed + Skipped;
|
return Processed + Skipped;
|
||||||
}
|
|
||||||
// Handle one TS packet:
|
// Handle one TS packet:
|
||||||
int Handled = TS_SIZE;
|
int Handled = TS_SIZE;
|
||||||
if (TsHasPayload(Data) && !TsIsScrambled(Data)) {
|
if (TsHasPayload(Data) && !TsIsScrambled(Data)) {
|
||||||
|
11
remux.h
11
remux.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remux.h 4.2 2017/02/27 16:11:57 kls Exp $
|
* $Id: remux.h 4.3 2017/03/26 13:06:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMUX_H
|
#ifndef __REMUX_H
|
||||||
@ -144,6 +144,15 @@ inline int64_t TsGetPcr(const uchar *p)
|
|||||||
void TsHidePayload(uchar *p);
|
void TsHidePayload(uchar *p);
|
||||||
void TsSetPcr(uchar *p, int64_t Pcr);
|
void TsSetPcr(uchar *p, int64_t Pcr);
|
||||||
|
|
||||||
|
// Helper macro and function to quickly check whether Data points to the beginning
|
||||||
|
// of a TS packet. The return value is the number of bytes that need to be skipped
|
||||||
|
// to synchronize on the next TS packet (zero if already sync'd). TsSync() can be
|
||||||
|
// called directly, the macro just performs the initial check inline and adds some
|
||||||
|
// debug information for logging.
|
||||||
|
|
||||||
|
#define TS_SYNC(Data, Length) (*Data == TS_SYNC_BYTE ? 0 : TsSync(Data, Length, __FILE__, __FUNCTION__, __LINE__))
|
||||||
|
int TsSync(const uchar *Data, int Length, const char *File = NULL, const char *Function = NULL, int Line = 0);
|
||||||
|
|
||||||
// The following functions all take a pointer to a sequence of complete TS packets.
|
// The following functions all take a pointer to a sequence of complete TS packets.
|
||||||
|
|
||||||
int64_t TsGetPts(const uchar *p, int l);
|
int64_t TsGetPts(const uchar *p, int l);
|
||||||
|
Loading…
Reference in New Issue
Block a user