2
#include "xineCommon.h"
5
#include <vdr/transfer.h>
7
#include "xineDevice.h"
9
#include "xineSettings.h"
18
void cXineSpuDecoder::ptsAdjust(uint32_t &pts)
21
|| -1 == (int32_t)pts)
26
const int64_t ptsXine = m_xineDevice->GetSTC();
31
// ::fprintf(stderr, "ptsAdjust: %ld, %lld, %lld\n", pts, ptsXine, pts - ptsXine);
33
pts = (uint32_t)ptsXine;
36
int cXineSpuDecoder::setTime(uint32_t pts)
40
return cDvbSpuDecoder::setTime(pts);
43
static cXineDevice *theXineDevice = 0;
45
bool cXineDevice::HasDecoder(void) const
50
cSpuDecoder *cXineDevice::GetSpuDecoder(void)
55
m_spuDecoder = new cXineSpuDecoder(this);
61
bool cXineDevice::CanReplay(void) const
66
static bool findVideo = false;
67
static bool foundVideo = false;
69
static bool f = false;
70
static bool np = false;
71
static bool muted = false;
72
static int jumboPESsize = 0;
73
static int jumboPEStail = 0;
74
static ePlayMode pm = pmNone;
75
static bool audioSeen = false;
77
static int64_t ptsV = -1, ptsA = -1, ptsP = -1, ptsD = -1;
79
static enum { sstNone = 0, sstNormal, sstNoMetronom } softStartTrigger = sstNone;
87
softStartState = sIdle;
92
::gettimeofday(&tv, 0);
93
return tv.tv_sec + tv.tv_usec / 1.0e+6;
96
static double ttt0 = tNow(), ttt1 = tNow(), ttt2 = 0, ttt3 = 0, ttt4 = 0, ttt5 = 0, ttt6 = 0;
98
// static int streams[ 256 ];
99
static bool doClear = false;
101
bool cXineDevice::SetPlayMode(ePlayMode PlayMode)
103
if (pmNone == PlayMode)
112
::gettimeofday(&tv0, 0);
117
static time_t t0 = t1;
119
if (0 == PlayMode && (t1 - t0) > (30 * 60))
125
bool playModeSupported = false;
131
case pmAudioOnlyBlack:
132
case pmExtern_THIS_SHOULD_BE_AVOIDED:
133
playModeSupported = true;
136
#if APIVERSNUM >= 10308
142
ptsV = ptsA = ptsP = ptsD = -1;
148
xfprintf(stderr, "SetPlayMode: %d\n", PlayMode);
150
m_xineLib.pause(false);
151
m_xineLib.execFuncTrickSpeedMode(false);
152
m_xineLib.execFuncSetSpeed(100.0);
157
m_xineLib.execFuncMute(false);
160
if (pmNone == PlayMode)
162
if (pmExtern_THIS_SHOULD_BE_AVOIDED == pm)
163
m_xineLib.enableExternal(false);
170
for (unsigned int i = 0; i < sizeof (streams) / sizeof (*streams); i++)
173
fprintf(stderr, "stream: 0x%02x\n", i);
178
// m_xineLib.execFuncMute();
179
// m_xineLib.execFuncSetPrebuffer(0);
180
m_xineLib.execFuncClear(-2);
181
// m_xineLib.execFuncStart();
182
// m_xineLib.execFuncMetronom(0);
183
m_xineLib.execFuncStillFrame();
184
m_xineLib.execFuncWait();
186
// for (int i = 0; i < 2; i++)
187
m_xineLib.showNoSignal();
190
m_xineLib.execFuncFlush();
192
softStartTrigger = sstNone;
193
softStartState = sIdle;
201
softStartTrigger = sstNone;
202
softStartState = sIdle;
204
// ::memset(&streams, 0, sizeof (streams));
207
m_xineLib.ignore(false);
209
m_xineLib.freeze(false);
212
m_xineLib.execFuncFlush();
213
m_xineLib.execFuncWait();
215
// m_xineLib.execFuncSetPrebuffer(m_settings.GetModeParams()->m_prebufferFrames);
216
// m_xineLib.execFuncSetPrebuffer(0);
217
m_xineLib.execFuncClear(-4);
218
// m_xineLib.execFuncStart();
219
m_xineLib.execFuncWait();
221
#if APIVERSNUM < 10342
222
m_settings.SelectReplayPrebufferMode(0 == cTransferControl::ReceiverDevice());
224
m_settings.SelectReplayPrebufferMode(!Transferring());
227
if (m_settings.LiveTV())
229
// ::fprintf(stderr, "LiveTV\n");
230
softStartTrigger = sstNormal;
238
cMutexLock pmMutexLock(&m_pmMutex);
240
m_pmCondVar.Broadcast();
243
if (pmExtern_THIS_SHOULD_BE_AVOIDED == PlayMode)
244
m_xineLib.enableExternal();
247
::gettimeofday(&tv1, 0);
249
fprintf(stderr, "spm: %.3lf ms\n", 1000 * ((tv1.tv_sec + tv1.tv_usec / 1.0e+6) - (tv0.tv_sec + tv0.tv_usec / 1.0e+6)));
251
if (pmNone == PlayMode) {
252
ttt1 = tNow(); ttt4 = 0; ttt5 = 0; }
255
return playModeSupported;
258
static bool lastCmdWasClear = false;
260
void cXineDevice::TrickSpeed(int Speed)
265
xfprintf(stderr, "TrickSpeed: %d\n", Speed);
266
m_xineLib.execFuncTrickSpeedMode(lastCmdWasClear);
267
m_xineLib.execFuncSetSpeed(100.0 / Speed);
268
m_xineLib.execFuncWait();
269
m_xineLib.freeze(false);
270
m_xineLib.pause(false);
273
void cXineDevice::Clear(void)
275
lastCmdWasClear = true;
278
ptsV = ptsA = ptsP = ptsD = -1;
280
static int cntClear = 0;
282
xfprintf(stderr, "Clear(%d)", cntClear);
290
m_xineLib.execFuncSetSpeed(100.0);
292
m_xineLib.execFuncClear(cntClear++);
293
// m_xineLib.execFuncStart();
297
m_xineLib.execFuncSetSpeed(0.0);
299
m_xineLib.execFuncWait();
300
m_xineLib.pause(false);
301
xfprintf(stderr, "!\n");
302
if (m_settings.LiveTV())
303
softStartTrigger = sstNoMetronom;
308
void cXineDevice::Play(void)
310
lastCmdWasClear = false;
315
xfprintf(stderr, "Play\n");
316
m_xineLib.execFuncTrickSpeedMode(false);
317
m_xineLib.execFuncSetSpeed(100.0);
322
m_xineLib.execFuncMute(false);
325
m_xineLib.execFuncWait();
326
m_xineLib.freeze(false);
327
m_xineLib.pause(false);
328
LOG_ME(::fprintf(stderr, "----\n");)
331
void cXineDevice::Freeze(void)
333
lastCmdWasClear = false;
337
xfprintf(stderr, "Freeze\n");
340
m_xineLib.execFuncSetSpeed(0.0);
341
m_xineLib.execFuncWait();
342
LOG_ME(::fprintf(stderr, "------\n");)
345
void cXineDevice::Mute(void)
347
xfprintf(stderr, "Mute\n");
348
m_xineLib.execFuncMute(true);
353
static void store_frame(const unsigned char *buf, int len, int line)
360
::sprintf(name, "/tmp/frame_%05d_%05d", line, cnt++);
362
FILE *f = fopen(name, "wb");
363
size_t r = fwrite(buf, 1, len, f);
369
#define VERBOSE_NOP() do{ xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); } while (0)
370
#define VERBOSE_NOP1() do{ store_frame(Data, Length, __LINE__); xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); } while (0)
371
#define VERBOSE_RETURN0(x) do{ xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); return x; } while (0)
372
#define VERBOSE_RETURN1(x) do{ store_frame(buf0, len0, __LINE__); xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); return x; } while (0)
373
#define VERBOSE_RETURN2(x) do{ store_frame(buf, len, __LINE__); xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); return x; } while (0)
374
#define VERBOSE_RETURN3(x) do{ store_frame(Data, Length, __LINE__); xfprintf(stderr, "FIXME: %s:%d\n", __FILE__, __LINE__); return x; } while (0)
376
#if APIVERSNUM < 10331
385
static ePesHeader AnalyzePesHeader(const uchar *Data, int Count, int &PesPayloadOffset, bool *ContinuationHeader = NULL)
388
return phNeedMoreData; // too short
390
if ((Data[6] & 0xC0) == 0x80) { // MPEG 2
392
return phNeedMoreData; // too short
394
PesPayloadOffset = 6 + 3 + Data[8];
395
if (Count < PesPayloadOffset)
396
return phNeedMoreData; // too short
398
if (ContinuationHeader)
399
*ContinuationHeader = ((Data[6] == 0x80) && !Data[7] && !Data[8]);
401
return phMPEG2; // MPEG 2
404
// check for MPEG 1 ...
405
PesPayloadOffset = 6;
407
// skip up to 16 stuffing bytes
408
for (int i = 0; i < 16; i++) {
409
if (Data[PesPayloadOffset] != 0xFF)
412
if (Count <= ++PesPayloadOffset)
413
return phNeedMoreData; // too short
416
// skip STD_buffer_scale/size
417
if ((Data[PesPayloadOffset] & 0xC0) == 0x40) {
418
PesPayloadOffset += 2;
420
if (Count <= PesPayloadOffset)
421
return phNeedMoreData; // too short
424
if (ContinuationHeader)
425
*ContinuationHeader = false;
427
if ((Data[PesPayloadOffset] & 0xF0) == 0x20) {
429
PesPayloadOffset += 5;
431
else if ((Data[PesPayloadOffset] & 0xF0) == 0x30) {
433
PesPayloadOffset += 10;
435
else if (Data[PesPayloadOffset] == 0x0F) {
436
// continuation header
439
if (ContinuationHeader)
440
*ContinuationHeader = true;
443
return phInvalid; // unknown
445
if (Count < PesPayloadOffset)
446
return phNeedMoreData; // too short
448
return phMPEG1; // MPEG 1
453
//#if APIVERSNUM < 10345
458
#define SC_SEQUENCE 0xB3 // "sequence header code"
459
#define SC_GROUP 0xB8 // "group start code"
460
#define SC_PICTURE 0x00 // "picture start code"
462
int GetPacketLength(const uchar *Data, int Count, int Offset)
464
// Returns the length of the packet starting at Offset, or -1 if Count is
465
// too small to contain the entire packet.
466
int Length = (Offset + 5 < Count) ? (Data[Offset + 4] << 8) + Data[Offset + 5] + 6 : -1;
467
if (Length > 0 && Offset + Length <= Count)
472
bool IsFrameH264(const uchar *Data, int Length)
474
int PesPayloadOffset;
475
const uchar *limit = Data + Length;
476
if (AnalyzePesHeader(Data, Length, PesPayloadOffset) <= phInvalid)
477
return false; // neither MPEG1 nor MPEG2
479
Data += PesPayloadOffset + 3; // move to video payload and skip 00 00 01
481
// cVideoRepacker ensures that in case of H264 we will see an access unit delimiter here
482
if (0x01 == Data[-1] && 9 == Data[0] && 0x00 == Data[-2] && 0x00 == Data[-3])
489
int ScanVideoPacket(const uchar *Data, int Count, int Offset, uchar &PictureType)
491
// Scans the video packet starting at Offset and returns its length.
492
// If the return value is -1 the packet was not completely in the buffer.
493
int Length = GetPacketLength(Data, Count, Offset);
495
const bool h264 = IsFrameH264(Data + Offset, Length);
496
int PesPayloadOffset = 0;
497
if (AnalyzePesHeader(Data + Offset, Length, PesPayloadOffset) >= phMPEG1) {
498
const uchar *p = Data + Offset + PesPayloadOffset + 2;
499
const uchar *pLimit = Data + Offset + Length - 3;
500
#if APIVERSNUM >= 10326
501
// cVideoRepacker ensures that a new PES packet is started for a new sequence,
502
// group or picture which allows us to easily skip scanning through a huge
503
// amount of video data.
505
if (p[-2] || p[-1] || p[0] != 0x01)
506
pLimit = 0; // skip scanning: packet doesn't start with 0x000001
509
int nal_unit_type = p[1] & 0x1F;
510
switch (nal_unit_type) {
511
case 9: // access unit delimiter
512
// when the MSB in p[1] is set (which violates H.264) then this is a hint
513
// from cVideoRepacker::HandleNalUnit() that this bottom field shall not
514
// be reported as picture.
516
((uchar *)p)[1] &= ~0x80; // revert the hint and fall through
519
default: // skip scanning: packet doesn't start a new picture
529
default: // skip scanning: packet doesn't start a new sequence, group or picture
536
while (p < pLimit && (p = (const uchar *)memchr(p, 0x01, pLimit - p))) {
537
if (!p[-2] && !p[-1]) { // found 0x000001
539
int nal_unit_type = p[1] & 0x1F;
540
switch (nal_unit_type) {
541
case 9: { // access unit delimiter
542
int primary_pic_type = p[2] >> 5;
543
switch (primary_pic_type) {
547
PictureType = I_FRAME;
551
case 6: // I, SI, P, SP
552
PictureType = P_FRAME;
555
case 7: // I, SI, P, SP, B
556
PictureType = B_FRAME;
565
case SC_PICTURE: PictureType = (p[3] >> 3) & 0x07;
569
p += 4; // continue scanning after 0x01ssxxyy
572
p += 3; // continue scanning after 0x01xxyy
575
PictureType = NO_PICTURE;
585
static bool IsNotVideoIorPframe(const uchar *buf, int len)
587
if (0xe0 != (0xf0 & buf[ 3 ])) // not video
590
uchar pt = NO_PICTURE;
591
cRemux::ScanVideoPacket(buf, len, 0, pt);
593
return (I_FRAME == pt || P_FRAME == pt);
597
static char *getFrameType(const uchar *buf, int len)
599
if (0xe0 != (0xf0 & buf[ 3 ])) // not video
602
static char *frameTypes[ 8 ] =
614
uchar pt = NO_PICTURE;
615
cRemux::ScanVideoPacket(buf, len, 0, pt);
617
return frameTypes[ pt ];
620
static bool getPTS(const unsigned char *buf0, int len0, int64_t &pts)
627
&& 0x00 == buf0[ 2 ])
636
&& 0x00 == buf0[ 2 ])
642
VERBOSE_RETURN1(false);
644
if (0x00 != buf0[ 0 ]
646
|| 0x01 != buf0[ 2 ])
648
VERBOSE_RETURN1(false);
651
if (0xe0 != (0xf0 & buf0[ 3 ]) // video
652
&& 0xc0 != (0xe0 & buf0[ 3 ]) // audio
653
&& 0xbd != (0xff & buf0[ 3 ]) // dolby
654
&& 0xbe != (0xff & buf0[ 3 ])) // padding (DVD)
656
VERBOSE_RETURN1(false);
659
int len = (6 + buf0[ 4 ] * 0x100 + buf0[ 5 ]);
661
VERBOSE_RETURN1(false);
663
const unsigned char *buf = buf0;
670
if (0xbe == (0xff & buf[ 3 ])) // padding (DVD)
674
VERBOSE_RETURN2(false);
676
if (0x80 != (0xc0 & buf[ 6 ])) // MPEG1
678
do // ... while (false);
682
for (int i = 0; i < 16; i++)
684
if (buf[ 6 + o ] != 0xff)
688
VERBOSE_RETURN2(false);
691
if (0x40 == (0xc0 & buf[ 6 + o ]))
695
VERBOSE_RETURN2(false);
697
if (0x31 == (0xf1 & buf[ 6 + o + 0 ]))
699
if (len < (6 + o + 5 + 5))
700
VERBOSE_RETURN2(false);
702
if (0x01 != (0x01 & buf[ 6 + o + 2 ]))
703
VERBOSE_RETURN2(false);
705
if (0x01 != (0x01 & buf[ 6 + o + 4 ]))
706
VERBOSE_RETURN2(false);
708
if (0x11 != (0xf1 & buf[ 6 + o + 5 + 0 ]))
709
VERBOSE_RETURN2(false);
711
if (0x01 != (0x01 & buf[ 6 + o + 5 + 2 ]))
712
VERBOSE_RETURN2(false);
714
if (0x01 != (0x01 & buf[ 6 + o + 5 + 4 ]))
715
VERBOSE_RETURN2(false);
717
int64_t _pts = ((int64_t)(0x0e & buf[ 6 + o + 0 ])) << 29
718
| (0xff & buf[ 6 + o + 1 ]) << 22
719
| (0xfe & buf[ 6 + o + 2 ]) << 14
720
| (0xff & buf[ 6 + o + 3 ]) << 7
721
| (0xfe & buf[ 6 + o + 4 ]) >> 1;
723
// ::fprintf(stderr, "pts: %lld\n", _pts);
728
// if (!IsNotVideoIorPframe(buf, len)) // only PTS of I and P frames are progressive in time
735
else if (0x21 == (0xf1 & buf[ 6 + o + 0 ]))
737
if (len < (6 + o + 5))
738
VERBOSE_RETURN2(false);
740
if (0x01 != (0x01 & buf[ 6 + o + 2 ]))
741
VERBOSE_RETURN2(false);
743
if (0x01 != (0x01 & buf[ 6 + o + 4 ]))
744
VERBOSE_RETURN2(false);
746
int64_t _pts = ((int64_t)(0x0e & buf[ 6 + o + 0 ])) << 29
747
| (0xff & buf[ 6 + o + 1 ]) << 22
748
| (0xfe & buf[ 6 + o + 2 ]) << 14
749
| (0xff & buf[ 6 + o + 3 ]) << 7
750
| (0xfe & buf[ 6 + o + 4 ]) >> 1;
752
// ::fprintf(stderr, "pts: %lld\n", _pts);
757
// if (!IsNotVideoIorPframe(buf, len)) // only PTS of I and P frames are progressive in time
764
else if (0x0f == (0xff & buf[ 6 + o + 0 ]))
769
for (int i = 0; i < 30; i++)
770
xfprintf(stderr, "%02x ", buf[ i ]);
771
xfprintf(stderr, "\n");
773
VERBOSE_RETURN2(false);
780
if (0x40 == (0xc0 & buf[ 7 ]))
781
VERBOSE_RETURN2(false);
783
if (0x00 == (0xc0 & buf[ 7 ]))
787
// if (0x00 != (0x3f & buf[ 7 ]))
788
// VERBOSE_RETURN2(false);
790
bool hasPTS = (0 != (0x80 & buf[ 7 ]));
791
bool hasDTS = (0 != (0x40 & buf[ 7 ]));
793
unsigned char hdl = buf[ 8 ];
795
if (hdl < ((hasPTS + hasDTS) * 5))
796
VERBOSE_RETURN2(false);
798
if (len < (6 + 3 + hdl))
799
VERBOSE_RETURN2(false);
801
if ((0x20 * hasPTS + 0x10 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
803
if ((0x20 * hasPTS + 0x00 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
805
// accept streams, that start with '00X0' instead of '00X1'.
807
else if ((0x00 * hasPTS + 0x10 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
809
// accept streams, that start with '000X' instead of '001X'.
813
VERBOSE_RETURN2(false);
817
if (0x01 != (0x01 & buf[ 11 ]))
818
VERBOSE_RETURN2(false);
820
if (0x01 != (0x01 & buf[ 13 ]))
821
VERBOSE_RETURN2(false);
825
if (0x11 != (0xf1 & buf[ 14 ]))
826
VERBOSE_RETURN2(false);
828
if (0x01 != (0x01 & buf[ 16 ]))
829
VERBOSE_RETURN2(false);
831
if (0x01 != (0x01 & buf[ 18 ]))
832
VERBOSE_RETURN2(false);
835
fprintf(stderr, " %02x %02x %02x %02x %02x\n"
842
int64_t _pts = ((int64_t)(0x0e & buf[ 9 ])) << 29
843
| (0xff & buf[ 10 ]) << 22
844
| (0xfe & buf[ 11 ]) << 14
845
| (0xff & buf[ 12 ]) << 7
846
| (0xfe & buf[ 13 ]) >> 1;
851
// if (!IsNotVideoIorPframe(buf, len)) // only PTS of I and P frames are progressive in time
859
// VERBOSE_RETURN2(false);
863
static bool stripPTSandDTS(unsigned char *buf0, int len0)
870
&& 0x00 == buf0[ 2 ])
879
&& 0x00 == buf0[ 2 ])
885
VERBOSE_RETURN1(false);
887
if (0x00 != buf0[ 0 ]
889
|| 0x01 != buf0[ 2 ])
891
VERBOSE_RETURN1(false);
894
if (0xe0 != (0xf0 & buf0[ 3 ]) // video
895
&& 0xc0 != (0xe0 & buf0[ 3 ]) // audio
896
&& 0xbd != (0xff & buf0[ 3 ]) // dolby
897
&& 0xbe != (0xff & buf0[ 3 ]) // padding (DVD)
898
&& 0xba != (0xff & buf0[ 3 ]) // system layer: pack header
899
&& 0xbb != (0xff & buf0[ 3 ]) // system layer: system header
900
&& 0xb9 != (0xff & buf0[ 3 ])) // system layer: stream end
902
//fprintf(stderr, "buf0[ 3 ]: %02x\n", buf0[ 3 ]);
903
VERBOSE_RETURN1(false);
906
int len = (6 + buf0[ 4 ] * 0x100 + buf0[ 5 ]);
907
if (0xba == buf0[ 3 ]) // pack header has fixed length
909
if (0x00 == (0xc0 & buf0[ 4 ])) // MPEG 1
912
len = 14 + (buf0[ 13 ] & 0x07);
914
else if (0xb9 == buf0[ 3 ]) // stream end has fixed length
920
VERBOSE_RETURN1(false);
922
unsigned char *buf = buf0;
929
if (0xbe == (0xff & buf[ 3 ]) // padding (DVD)
930
|| 0xba == (0xff & buf[ 3 ]) // system layer: pack header
931
|| 0xbb == (0xff & buf[ 3 ]) // system layer: system header
932
|| 0xb9 == (0xff & buf[ 3 ])) // system layer: stream end
938
VERBOSE_RETURN2(false);
940
if (0x80 != (0xc0 & buf[ 6 ])) // MPEG1
944
do // ... while (false);
948
for (int i = 0; i < 16; i++)
950
if (buf[ 6 + o ] != 0xff)
954
VERBOSE_RETURN2(false);
957
if (0x40 == (0xc0 & buf[ 6 + o ]))
961
VERBOSE_RETURN2(false);
963
if (0x31 == (0xf1 & buf[ 6 + o + 0 ]))
965
if (0x01 != (0x01 & buf[ 6 + o + 2 ]))
966
VERBOSE_RETURN2(false);
968
if (0x01 != (0x01 & buf[ 6 + o + 4 ]))
969
VERBOSE_RETURN2(false);
971
if (0x11 != (0xf1 & buf[ 6 + o + 5 + 0 ]))
972
VERBOSE_RETURN2(false);
974
if (0x01 != (0x01 & buf[ 6 + o + 5 + 2 ]))
975
VERBOSE_RETURN2(false);
977
if (0x01 != (0x01 & buf[ 6 + o + 5 + 4 ]))
978
VERBOSE_RETURN2(false);
980
buf[ 6 + o + 0 ] = 0xff;
981
buf[ 6 + o + 1 ] = 0xff;
982
buf[ 6 + o + 2 ] = 0xff;
983
buf[ 6 + o + 3 ] = 0xff;
984
buf[ 6 + o + 4 ] = 0xff;
986
buf[ 6 + o + 5 + 0 ] = 0xff;
987
buf[ 6 + o + 5 + 1 ] = 0xff;
988
buf[ 6 + o + 5 + 2 ] = 0xff;
989
buf[ 6 + o + 5 + 3 ] = 0xff;
990
buf[ 6 + o + 5 + 4 ] = 0x0f;
994
else if (0x21 == (0xf1 & buf[ 6 + o + 0 ]))
996
if (0x01 != (0x01 & buf[ 6 + o + 2 ]))
997
VERBOSE_RETURN2(false);
999
if (0x01 != (0x01 & buf[ 6 + o + 4 ]))
1000
VERBOSE_RETURN2(false);
1002
buf[ 6 + o + 0 ] = 0xff;
1003
buf[ 6 + o + 1 ] = 0xff;
1004
buf[ 6 + o + 2 ] = 0xff;
1005
buf[ 6 + o + 3 ] = 0xff;
1006
buf[ 6 + o + 4 ] = 0x0f;
1010
else if (0x0f == (0xff & buf[ 6 + o + 0 ]))
1018
for (int i = 0; i < 30; i++)
1019
xfprintf(stderr, "%02x ", buf[ i ]);
1020
xfprintf(stderr, "\n");
1022
VERBOSE_RETURN2(false);
1030
if (0x40 == (0xc0 & buf[ 7 ]))
1031
VERBOSE_RETURN2(false);
1033
if (0x00 == (0xc0 & buf[ 7 ]))
1037
// if (0x00 != (0x3f & buf[ 7 ]))
1038
// VERBOSE_RETURN2(false);
1040
bool hasPTS = (0 != (0x80 & buf[ 7 ]));
1041
bool hasDTS = (0 != (0x40 & buf[ 7 ]));
1043
unsigned char hdl = buf[ 8 ];
1045
if (hdl < ((hasPTS + hasDTS) * 5))
1046
VERBOSE_RETURN2(false);
1048
if (len < (6 + 3 + hdl))
1049
VERBOSE_RETURN2(false);
1051
if ((0x20 * hasPTS + 0x10 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
1053
if ((0x20 * hasPTS + 0x00 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
1055
// accept streams, that start with '00X0' instead of '00X1'.
1057
else if ((0x00 * hasPTS + 0x10 * hasDTS + 0x01) != (0xf1 & buf[ 9 ]))
1059
// accept streams, that start with '000X' instead of '001X'.
1063
VERBOSE_RETURN2(false);
1067
if (0x01 != (0x01 & buf[ 11 ]))
1068
VERBOSE_RETURN2(false);
1070
if (0x01 != (0x01 & buf[ 13 ]))
1071
VERBOSE_RETURN2(false);
1075
if (0x11 != (0xf1 & buf[ 14 ]))
1076
VERBOSE_RETURN2(false);
1078
if (0x01 != (0x01 & buf[ 16 ]))
1079
VERBOSE_RETURN2(false);
1081
if (0x01 != (0x01 & buf[ 18 ]))
1082
VERBOSE_RETURN2(false);
1087
for (int i = 9; i < (9 + ((hasPTS + hasDTS) * 5)); i++)
1094
static uchar padding[ 6 + 0xffff ] =
1104
int cXineDevice::PushOut()
1106
uchar *Data = padding;
1107
int Length = sizeof (padding);
1109
return PlayCommon3(Data, Length, -1);
1112
//static bool blahblah = false;
1114
void cXineDevice::StillPicture(const uchar *Data, int Length)
1116
xfprintf(stderr, "StillPicture: %p, %d\n", Data, Length);
1120
for (int i = 0; i < Length - 3; i++)
1123
&& Data[ i + 0 ] == 0x00
1124
&& Data[ i + 1 ] == 0x00
1125
&& Data[ i + 2 ] == 0x01)
1127
xfprintf(stderr, "\n");
1130
xfprintf(stderr, "%02x ", Data[ i ]);
1133
for (int i = Length - 3; i < Length; i++)
1135
xfprintf(stderr, "%02x ", Data[ i ]);
1138
xfprintf(stderr, "\n");
1141
const int maxPackets = 3;
1142
uchar pes[ maxPackets * (6 + 0xffff) ];
1143
static const uchar header[ 6 + 3 ] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 };
1145
do // ... while (false);
1153
if (0x00 != Data[ 0 ]
1154
|| 0x00 != Data[ 1 ]
1155
|| 0x01 != Data[ 2 ])
1161
if (0xe0 != (0xf0 & Data[ 3 ]) // video
1162
&& 0xc0 != (0xe0 & Data[ 3 ]) // audio
1163
&& 0xbd != (0xff & Data[ 3 ]) // dolby
1164
&& 0xbe != (0xff & Data[ 3 ])) // padding (DVD)
1166
if (Length > maxPackets * (0xffff - 3))
1173
const uchar *src = Data;
1178
::memcpy(dst, header, sizeof (header));
1182
if (bite > 0xffff - 3)
1187
dst[ 4 ] = 0xff & ((bite + 3) >> 8);
1188
dst[ 5 ] = 0xff & (bite + 3);
1190
::memcpy(dst + sizeof (header), src, bite);
1192
Length += sizeof (header);
1193
dst += sizeof (header) + bite;
1202
stripPTSandDTS((uchar *)Data, Length);
1206
m_xineLib.execFuncTrickSpeedMode(false);
1207
m_xineLib.execFuncSetSpeed(100.0);
1208
m_xineLib.execFuncStillFrame();
1209
m_xineLib.execFuncWait();
1213
m_xineLib.pause(false);
1219
for (int i = 0; i < 1 /* 4 */; i++)
1221
//fprintf(stderr, " (%d) ", i);
1222
int r = PlayVideo1(Data, Length, true);
1228
// m_xineLib.execFuncFlush(0);
1229
m_xineLib.execFuncFlush();
1231
// ::fprintf(stderr, "------------\n");
1232
LOG_ME(::fprintf(stderr, "------------\n");)
1235
static bool softStartPoll(cXineLib &xineLib, cPoller &poller, const int timeout, const bool result);
1237
bool cXineDevice::Poll(cPoller &Poller, int TimeoutMs /* = 0 */)
1239
if (softStartState != sIdle)
1242
if (m_xineLib.Poll(Poller, TimeoutMs))
1243
return softStartPoll(m_xineLib, Poller, TimeoutMs, true);
1245
return softStartPoll(m_xineLib, Poller, TimeoutMs, false);
1248
static bool jw = false;
1250
bool cXineDevice::Flush(int TimeoutMs /* = 0 */)
1252
const bool jw0 = jw;
1254
m_xineLib.pause(false);
1263
bool retVal = m_xineLib.execFuncFlush(TimeoutMs, jw0);
1266
xfprintf(stderr, jw0 ? "f" : "F");
1273
static bool dumpAudio(const char *proc, const uchar *Data, int Length)
1286
VERBOSE_RETURN0(false);
1288
if (0x00 != Data[ 0 ]
1289
|| 0x00 != Data[ 1 ]
1290
|| 0x01 != Data[ 2 ])
1292
VERBOSE_RETURN3(false);
1295
int l = Data[ 4 ] * 0x0100 + Data[ 5 ];
1296
if (Length < (6 + l))
1297
VERBOSE_RETURN0(false);
1299
if (0xe0 == (Data[ 3 ] & 0xf0) //video
1300
|| 0xc0 == (Data[ 3 ] & 0xe0) //audio
1301
|| 0xbe == Data[ 3 ]) //padding
1308
// if (0xbd != Data[ 3 ]) //private (dolby, pcm)
1309
// VERBOSE_RETURN0(false);
1311
// fprintf(stderr, "private ");
1313
if (l < (3 + 0 + 2))
1314
VERBOSE_RETURN0(false);
1317
if (l < (3 + h + 2))
1318
VERBOSE_RETURN0(false);
1326
, Data[ 6 + 3 + h + 0 ]
1327
, Data[ 6 + 3 + h + 1 ]);
1334
static bool IsVideo(const uchar *Data, int Length)
1337
&& 0x00 == Data[ 0 ]
1338
&& 0x00 == Data[ 1 ]
1339
&& 0x01 == Data[ 2 ]
1340
&& 0xe0 == (0xf0 & Data[ 3 ]));
1343
int cXineDevice::PlayVideo(const uchar *Data, int Length)
1345
if (ttt4 == 0) ttt4 = tNow();
1346
// static FILE *f = fopen("/tmp/egon1", "wb");
1347
// fwrite(Data, Length, 1, f);
1349
return PlayVideo1(Data, Length, false);
1352
int cXineDevice::PlayVideo1(const uchar *Data, int Length, const bool stillImageData)
1354
LOG_ME(::fprintf(stderr, "V");)
1358
LOG_ME(::fprintf(stderr, "<");)
1364
cMutexLock pmMutexLock(&m_pmMutex);
1367
m_pmCondVar.Wait(m_pmMutex);
1370
int retVal = PlayVideo2(Data, Length, stillImageData);
1372
LOG_ME(::fprintf(stderr, "v");)
1377
int cXineDevice::PlayCommon2(const uchar *Data, int Length, int64_t ptsForce)
1382
fprintf(stderr, "blahblah C2");
1383
for (int i = 0; i < 50 && i < Length; i++)
1384
fprintf(stderr, " %02x", Data[ i ]);
1385
fprintf(stderr, "\n");
1388
do // ... while (false);
1396
if (0x00 != Data[ 0 ]
1397
|| 0x00 != Data[ 1 ]
1398
|| 0x01 != Data[ 2 ])
1404
int l = 6 + Data[ 4 ] * 0x0100 + Data[ 5 ];
1411
if (0xe0 != (Data[ 3 ] & 0xf0) //video
1412
&& 0xc0 != (Data[ 3 ] & 0xe0) //audio
1413
&& 0xbd != Data[ 3 ]) //private (dolby, pcm)
1419
int payloadOffset = 0;
1420
if (AnalyzePesHeader(Data, Length, payloadOffset) <= phInvalid)
1426
if (l <= payloadOffset)
1428
// drop short frames
1429
// ::fprintf(stderr, "i");
1433
// if (0xc0 == (Data[ 3 ] & 0xe0)) //audio
1438
return PlayCommon3(Data, Length, ptsForce);
1441
typedef long long int lld_t;
1443
static int xzabc = 0;
1445
int cXineDevice::PlayCommon3(const uchar *Data, int Length, int64_t ptsForce)
1447
// if (!m_settings.LiveTV())
1456
if (0xe0 == (Data[ 3 ] & 0xf0)) //video
1458
uchar pt = NO_PICTURE;
1459
cRemux::ScanVideoPacket(Data, Length, 0, pt);
1461
if (pt != NO_PICTURE)
1463
static int64_t last = -1;
1465
getPTS(Data, Length, pts);
1466
fprintf(stderr, "** %c ** %lld ** %lld ** %lld **\n", "0IPB4567"[pt], (lld_t)ptsForce, (lld_t)(ptsForce - last), (lld_t)pts);
1470
if (0xc0 == (Data[ 3 ] & 0xe0)) //audio
1473
static int64_t last = -1;
1475
getPTS(Data, Length, pts);
1476
fprintf(stderr, "\t\t\t\t\t\t\t** %c ** %lld ** %lld ** %lld **\n", 'A', (lld_t)ptsForce, (lld_t)(ptsForce - last), (lld_t)pts);
1483
int64_t pts = ptsForce;
1485
|| getPTS(Data, Length, pts))
1490
if (0xe0 == (Data[ 3 ] & 0xf0)) //video
1494
else if (0xc0 == (Data[ 3 ] & 0xe0)) //audio
1498
else if (0xbd == Data[ 3 ]) //private (dolby, pcm)
1500
int h = Data[ 6 + 2 ];
1502
if (0xa0 == (0xf0 & Data[ 6 + 3 + h + 0 ])) // pcm?
1509
xfprintf(stderr, "0x%02x\t", Data[ 3 ]);
1519
m_xineLib.execFuncGetPTS(ptsX);
1521
int64_t dV = (ptsV != -1 && ptsX != -1) ? ptsV - ptsX : 0;
1522
int64_t dA = (ptsA != -1 && ptsX != -1) ? ptsA - ptsX : 0;
1523
int64_t dP = (ptsP != -1 && ptsX != -1) ? ptsP - ptsX : 0;
1524
int64_t dD = (ptsD != -1 && ptsX != -1) ? ptsD - ptsX : 0;
1526
int64_t dVA = (ptsV != -1 && ptsA != -1) ? ptsA - ptsV : 0;
1527
int64_t dVD = (ptsV != -1 && ptsD != -1) ? ptsD - ptsV : 0;
1529
fprintf(stderr, "ptsVideo: %lld, ptsAudio: %lld, ptsPCM: %lld, ptsDolby: %lld, ptsXine: %lld, dVA: %lld, dVD: %lld, dV: %lld, dA: %lld, dP: %lld, dD: %lld\n", (lld_t)ptsV, (lld_t)ptsA, (lld_t)ptsP, (lld_t)ptsD, (lld_t)ptsX, (lld_t)dVA, (lld_t)dVD, (lld_t)dV, (lld_t)dA, (lld_t)dP, (lld_t)dD);
1538
fprintf(stderr, "blahblah C3");
1539
for (int i = 0; i < 50 && i < Length; i++)
1540
fprintf(stderr, " %02x", Data[ i ]);
1541
fprintf(stderr, "\n");
1547
while (done < Length)
1549
int r = m_xineLib.execFuncStream1(Data + done, Length - done);
1559
int cXineDevice::PlayVideo2(const uchar *Data, int Length, const bool stillImageData)
1561
// fprintf(stderr, "D");
1565
while (done < Length)
1569
int todo = Length - done;
1573
if (0x00 == Data[ done + 0 ]
1574
&& 0x00 == Data[ done + 1 ]
1575
&& 0x01 == Data[ done + 2 ])
1577
int id = Data[ done + 3 ];
1578
int len = 6 + Data[ done + 4 ] * 0x0100 + Data[ done + 5 ];
1580
if (0xba == id) // pack header has fixed length
1582
if (0x00 == (0xc0 & Data[ done + 4 ])) // MPEG 1
1585
len = 14 + (Data[ done + 13 ] & 0x07);
1587
else if (0xb9 == id) // stream end has fixed length
1596
if (0xbe == id // padding
1597
|| 0xba == id // system layer: pack header
1598
|| 0xbb == id // system layer: system header
1599
|| 0xb9 == id) // system layer: stream end
1603
// fprintf(stderr, "x");
1611
// ::fprintf(stderr, "todo: %d, len: %d\t", todo, len);
1630
// fprintf(stderr, "%c", ch);
1632
int r = PlayVideo3(Data + done, todo, stillImageData);
1642
static void resetScramblingControl(const uchar *Data, int Length)
1650
if (0x00 != Data[ 0 ]
1651
|| 0x00 != Data[ 1 ]
1652
|| 0x01 != Data[ 2 ])
1658
if (0xe0 != (0xf0 & Data[ 3 ]) // video
1659
&& 0xc0 != (0xe0 & Data[ 3 ]) // audio
1660
&& 0xbd != (0xff & Data[ 3 ]) // dolby
1661
&& 0xbe != (0xff & Data[ 3 ]) // padding (DVD)
1662
&& 0xba != (0xff & Data[ 3 ]) // system layer: pack header
1663
&& 0xbb != (0xff & Data[ 3 ]) // system layer: system header
1664
&& 0xb9 != (0xff & Data[ 3 ])) // system layer: stream end
1670
if (0xbe == (0xff & Data[ 3 ]) // padding (DVD)
1671
|| 0xba == (0xff & Data[ 3 ]) // system layer: pack header
1672
|| 0xbb == (0xff & Data[ 3 ]) // system layer: system header
1673
|| 0xb9 == (0xff & Data[ 3 ])) // system layer: stream end
1678
int len = (6 + Data[ 4 ] * 0x100 + Data[ 5 ]);
1686
if (0x00 != (0x30 & Data[ 6 ]))
1688
if (0x80 == (0xc0 & Data[ 6 ])) // only touch MPEG2
1690
xfprintf(stderr, "reseting PES_scrambling_control: 0x%02x\n", Data[ 6 ]);
1692
((uchar *)Data)[ 6 ] &= ~0x30;
1697
int cXineDevice::PlayVideo3(const uchar *Data, int Length, const bool stillImageData)
1702
fprintf(stderr, "blahblah V3");
1703
for (int i = 0; i < 50 && i < Length; i++)
1704
fprintf(stderr, " %02x", Data[ i ]);
1705
fprintf(stderr, "\n");
1708
resetScramblingControl(Data, Length);
1710
dumpAudio("Video", Data, Length);
1712
return PlayCommon(Data, Length, stillImageData);
1715
static double videoFrameDuration(const uchar *Data, int Length)
1717
int PesPayloadOffset = 0;
1718
ePesHeader ph = AnalyzePesHeader(Data, Length, PesPayloadOffset);
1722
if ((Data[ 3 ] & 0xf0) != 0xe0)
1725
if (Length < PesPayloadOffset + 8)
1728
const uchar *p = Data + PesPayloadOffset;
1744
static const double frameRates[ 16 ] =
1764
int frameRateIndex = *p & 0x0f;
1766
if (frameRates[ frameRateIndex ] < 0)
1773
const uchar *const limit = Data + Length - 10 + 3;
1776
if (p[ 0 ] != 0x01 || p[ -1 ] != 0x00 || p[ -2 ] != 0x00)
1782
if (p[ 1 ] != 0xb5) // extension start code
1785
if ((p[ 2 ] & 0xf0) != 0x10) // sequence extension
1790
n = (*p & 0x60) >> 5;
1796
return 90000 / (frameRates[ frameRateIndex ] * (n + 1) / (d + 1));
1799
static int frameSizes[ 256 ];
1801
static double audioFrameDuration(const uchar *Data, int Length)
1803
int PesPayloadOffset = 0;
1804
ePesHeader ph = AnalyzePesHeader(Data, Length, PesPayloadOffset);
1808
if ((Data[ 3 ] & 0xff) == 0xbd)
1810
static int samplingFrequencies[ 4 ] = // all values are specified in Hz
1812
48000, 44100, 32000, -1
1815
if (PesPayloadOffset + 5 <= Length
1816
&& Data[ PesPayloadOffset + 0 ] == 0x0b
1817
&& Data[ PesPayloadOffset + 1 ] == 0x77
1818
&& frameSizes[ Data[ PesPayloadOffset + 4 ] ] > 0)
1820
if (samplingFrequencies[ Data[ PesPayloadOffset + 4 ] >> 6 ] < 0)
1823
return 90000.0 * 1536 / samplingFrequencies[ Data[ PesPayloadOffset + 4 ] >> 6 ];
1825
else if (PesPayloadOffset + 4 + 5 <= Length
1826
&& Data[ PesPayloadOffset + 4 + 0 ] == 0x0b
1827
&& Data[ PesPayloadOffset + 4 + 1 ] == 0x77
1828
&& frameSizes[ Data[ PesPayloadOffset + 4 + 4 ] ] > 0)
1830
if (samplingFrequencies[ Data[ PesPayloadOffset + 4 + 4 ] >> 6 ] < 0)
1833
return 90000.0 * 1536 / samplingFrequencies[ Data[ PesPayloadOffset + 4 + 4 ] >> 6 ];
1839
if ((Data[ 3 ] & 0xe0) != 0xc0)
1842
if (Length < PesPayloadOffset + 4)
1846
Header |= Data[ PesPayloadOffset + 0 ];
1848
Header |= Data[ PesPayloadOffset + 1 ];
1850
Header |= Data[ PesPayloadOffset + 2 ];
1852
Header |= Data[ PesPayloadOffset + 3 ];
1854
bool Mpeg2 = (ph == phMPEG2);
1856
int syncword = (Header & 0xFFF00000) >> 20;
1857
int id = (Header & 0x00080000) >> 19;
1858
int layer = (Header & 0x00060000) >> 17;
1859
// int protection_bit = (Header & 0x00010000) >> 16;
1860
int bitrate_index = (Header & 0x0000F000) >> 12;
1861
int sampling_frequency = (Header & 0x00000C00) >> 10;
1862
// int padding_bit = (Header & 0x00000200) >> 9;
1863
// int private_bit = (Header & 0x00000100) >> 8;
1864
// int mode = (Header & 0x000000C0) >> 6;
1865
// int mode_extension = (Header & 0x00000030) >> 4;
1866
// int copyright = (Header & 0x00000008) >> 3;
1867
// int orignal_copy = (Header & 0x00000004) >> 2;
1868
int emphasis = (Header & 0x00000003);
1870
if (syncword != 0xFFF)
1873
if (id == 0 && !Mpeg2) // reserved in MPEG 1
1876
if (layer == 0) // reserved
1879
if (bitrate_index == 0xF) // forbidden
1882
if (sampling_frequency == 3) // reserved
1885
if (emphasis == 2) // reserved
1888
static int samplingFrequencies[ 2 ][ 4 ] = // all values are specified in Hz
1890
{ 44100, 48000, 32000, -1 }, // MPEG 1
1891
{ 22050, 24000, 16000, -1 } // MPEG 2
1894
static int slots_per_frame[ 2 ][ 3 ] =
1896
{ 12, 144, 144 }, // MPEG 1, Layer I, II, III
1897
{ 12, 144, 72 } // MPEG 2, Layer I, II, III
1900
int mpegIndex = 1 - id;
1901
int layerIndex = 3 - layer;
1903
// Layer I (i. e., layerIndex == 0) has a larger slot size
1904
int slotSize = (layerIndex == 0) ? 4 : 1; // bytes
1906
int sf = samplingFrequencies[ mpegIndex ][ sampling_frequency ];
1908
//fprintf(stderr, "afd: %.3f ms, PES-Length: %d\n", 1000.0 * 8 * slotSize * slots_per_frame[ mpegIndex ][ layerIndex ] / sf, Length);
1910
return 90000.0 * 8 * slotSize * slots_per_frame[ mpegIndex ][ layerIndex ] / sf;
1913
static double softStartTime = 0;
1914
static const double softStartSpeedStart = 0.75;
1915
static const double softStartSpeedMin = 0.15;
1916
static double softStartDuration = 31 / 25.0;
1917
static const int softStartMaxSpeedChanges = 20;
1918
static double softStartLastSpeed = -1;
1919
static double softStartSpeedChangeTime = -1;
1920
static int64_t softStartPtsVdr = -1;
1921
static const int64_t softStartLogPtsDelta = 4 * 90000;
1922
static int softStartHitPoll = 0;
1923
static bool softStartNoMetronom = false;
1924
static const double pi = 4 * ::atan(1);
1927
static double softStartCalcSpeed0(const double /* t */)
1932
static double softStartCalcSpeed1(const double t)
1934
const double p = (1 + ::cos(2 * pi * t)) / 2;
1936
return softStartSpeedMin + p * ((softStartSpeedStart * (1 - t) + 1.0 * t) - softStartSpeedMin);
1939
static double softStartCalcSpeed2(const double t)
1941
double p = 2 * t - 1;
1948
return softStartSpeedMin + p * ((softStartSpeedStart * (1 - t) + 1.0 * t) - softStartSpeedMin);
1951
static double softStartCalcSpeed3(const double t)
1954
return softStartSpeedStart;
1957
return softStartSpeedMin + (1 - softStartSpeedMin) * 0 / 3;
1960
return softStartSpeedMin + (1 - softStartSpeedMin) * 1 / 3;
1962
return softStartSpeedMin + (1 - softStartSpeedMin) * 2 / 3;
1965
static double softStartCalcSpeed4(const double t)
1967
const double p = (1 + ::cos(pi * (1 + t))) / 2;
1969
return softStartSpeedMin + (1 - softStartSpeedMin) * p;
1972
static double softStartCalcSpeed(const double t)
1977
return softStartCalcSpeed0(t); // choose a method
1979
(void)softStartCalcSpeed0;
1980
(void)softStartCalcSpeed1;
1981
(void)softStartCalcSpeed2;
1982
(void)softStartCalcSpeed3;
1983
(void)softStartCalcSpeed4;
1986
bool softStartPoll(cXineLib &xineLib, cPoller &poller, const int timeout, bool result)
1988
if (softStartState > sIdle)
1992
softStartHitPoll = 0;
1994
else if (++softStartHitPoll >= 2)
1998
softStartState = sIdle;
2000
xineLib.execFuncFirstFrame();
2001
xineLib.execFuncSetSpeed(100.0);
2002
xineLib.execFuncWait();
2004
while (!xineLib.Poll(poller, timeout, true));
2006
softStartHitPoll = 0;
2010
// ::fprintf(stderr, "softStartHitPoll: %d, %d\n", result, softStartHitPoll);
2016
static int64_t vpts, apts, extra0, extra;
2017
static bool useApts;
2018
static bool seenAudio = false;
2019
static bool seenVideo = false;
2020
static bool seenApts = false;
2021
static bool seenVpts = false;
2023
static const int64_t extra_max = 50 * 90000 / 25;
2025
static bool oldMode = false;
2027
static inline double softStartCalcQ0(int64_t vdr, int64_t xine, int64_t hyst)
2029
if (vdr < 0 || xine < 0)
2032
double delta = (vdr - xine) / 90000.0;
2036
if (delta >= softStartLogPtsDelta / 90000.0)
2039
if (delta >= (softStartDuration + hyst / 90000.0))
2042
return delta / (softStartDuration + hyst / 90000.0);
2045
static bool gotQ1 = false;
2046
static int64_t hystQ = 0;
2047
static int64_t hystQ1 = 0;
2048
static bool vdrTime100reload = false;
2050
static inline double softStartCalcQ(int64_t vdr, int64_t xine)
2052
double q = softStartCalcQ0(vdr, xine, hystQ);
2054
bool gQ1 = (q >= 1);
2065
vdrTime100reload = true;
2066
hystQ = (hystQ1 += 90000 / 25);
2070
//fprintf(stderr, "q: %.3lf, gq1: %d, hystQ: %lld, hystQ1: %lld, vdr: %lld, xine: %lld, d: %lld\n", q, gotQ1, hystQ, hystQ1, vdr, xine, vdr - xine);
2074
static int64_t vdrPTSLast = -2;
2075
static int64_t vdrAptsLast = -1;
2076
static int64_t vdrVptsLast = -1;
2078
static double vdrVptsCalced = -1;
2079
static double vdrAptsCalced = -1;
2080
static double vdrVduration = -1;
2081
static double vdrAduration = -1;
2083
static double vdrVptsBuffered[ 2 ] = { -1, -1 };
2085
static bool getPTS(const uchar *Data, int Length, int64_t &pts, bool isVideo, bool isAudio, double &vptsCalced, double &aptsCalced, double &vDuration, double &aDuration, double vptsBuffered[2])
2087
uchar pt = NO_PICTURE;
2091
cRemux::ScanVideoPacket(Data, Length, 0, pt);
2093
if (pt != NO_PICTURE && vDuration > 0 && vptsBuffered[ 1 ] > 0)
2094
vptsBuffered[ 1 ] += vDuration;
2097
bool retVal = false;
2099
if (getPTS(Data, Length, pts))
2105
double duration = audioFrameDuration(Data, Length);
2107
aDuration = duration;
2114
else if (pt != NO_PICTURE)
2115
vptsBuffered[ 1 ] = pts;
2117
double duration = videoFrameDuration(Data, Length);
2119
vDuration = duration;
2131
double duration = audioFrameDuration(Data, Length);
2133
bool frameStart = (duration > -1);
2135
if (aptsCalced > -1 && aDuration > -1 && frameStart)
2137
aptsCalced += aDuration;
2138
while (aptsCalced >= 0x200000000ull)
2139
aptsCalced -= 0x200000000ull;
2141
pts = (int64_t)aptsCalced;
2147
aDuration = duration;
2153
double dur = vDuration;
2155
if (pt != B_FRAME && pt != NO_PICTURE)
2157
vptsCalced = vptsBuffered[ 0 ];
2158
vptsBuffered[ 0 ] = vptsBuffered[ 1 ];
2162
bool frameStart = (pt != NO_PICTURE);
2164
if (vptsCalced > -1 && dur > -1 && frameStart)
2167
while (vptsCalced >= 0x200000000ull)
2168
vptsCalced -= 0x200000000ull;
2170
pts = (int64_t)vptsCalced;
2175
double duration = videoFrameDuration(Data, Length);
2177
vDuration = duration;
2184
static double vdrTime100 = -1;
2186
int cXineDevice::PlayCommon(const uchar *Data, int Length, const bool stillImageData)
2188
const bool isAudio = !IsVideo(Data, Length);
2189
const bool isVideo = !isAudio && !stillImageData;
2194
// ::fprintf(stderr, "x");
2199
fprintf(stderr, "writing: %d\n", Length - 6);
2201
if (findVideo && (isVideo || isAudio))
2204
foundVideo = isVideo;
2205
//xfprintf(stderr, "foundVideo: %d\n", foundVideo);
2209
static int64_t opts = -1;
2210
static int64_t xpts = -1;
2211
getPTS(Data, Length, xpts, isVideo, isAudio, vdrVptsCalced, vdrAptsCalced, vdrVduration, vdrAduration, vdrVptsBuffered);
2212
//fprintf(stderr, "audio: %.3lf, %d, %lld, %lld\n", audioFrameDuration(Data, Length), Length, xpts, xpts - opts);
2216
static int64_t opts = -1;
2217
static int64_t xpts = -1;
2218
getPTS(Data, Length, xpts, isVideo, isAudio, vdrVptsCalced, vdrAptsCalced, vdrVduration, vdrAduration, vdrVptsBuffered);
2219
//fprintf(stderr, "video: %.3lf, %d, %lld, %lld\n", videoFrameDuration(Data, Length), Length, xpts, xpts - opts);
2223
int64_t ptsForce = -1;
2225
if (softStartTrigger
2228
softStartNoMetronom = (sstNoMetronom == softStartTrigger);
2229
softStartTrigger = sstNone;
2231
softStartState = sInitiateSequence;
2232
//fprintf(stderr, "/////////////////////////////\n");
2233
// ::fprintf(stderr, "#(%d,%d)", ::getpid(), pthread_self());
2238
softStartLastSpeed = -1;
2240
else if (softStartState > sIdle)
2243
::gettimeofday(&tv, 0);
2245
const double now = (tv.tv_sec + tv.tv_usec / 1.0e+6);
2247
if (softStartState == sInitiateSequence)
2249
xfprintf(stderr, "[");
2251
softStartDuration = m_settings.GetModeParams()->m_prebufferFrames / 25.0;
2253
softStartTime = now;
2255
softStartSpeedChangeTime = -1;
2256
softStartLastSpeed = -1;
2257
softStartPtsVdr = -1;
2258
softStartHitPoll = 0;
2260
softStartState = sStartSequence;
2283
vdrVptsBuffered[ 0 ] = -1;
2284
vdrVptsBuffered[ 1 ] = -1;
2287
vdrTime100reload = false;
2290
hystQ = hystQ1 = 90000 * m_settings.GetModeParams()->m_prebufferHysteresis / 25;
2294
char packetType = 0;
2295
char packetTypeOnce = 0;
2302
// ::fprintf(stderr, "seen video\n");
2303
// xfprintf(stderr, "v");
2304
packetTypeOnce = 'v';
2315
// ::fprintf(stderr, "seen audio\n");
2316
// xfprintf(stderr, "a");
2317
packetTypeOnce = 'a';
2324
if (getPTS(Data, Length, pts, isVideo, isAudio, vdrVptsCalced, vdrAptsCalced, vdrVduration, vdrAduration, vdrVptsBuffered))
2333
// ::fprintf(stderr, "seen video pts\n");
2334
// xfprintf(stderr, "V");
2335
packetTypeOnce = 'V';
2344
int64_t delta = vpts - apts;
2352
// ::fprintf(stderr, "max. A/V delta: %lld pts => total extra buffering: %d frames", extra0, (int)(extra0 * 25 / 90000));
2356
if (extra > extra_max)
2360
// ::fprintf(stderr, ", limited to %d frames", (int)(extra * 25 / 90000));
2363
// ::fprintf(stderr, "\n");
2365
xfprintf(stderr, "+%d", (int)(extra * 25 / 90000));
2369
// ::fprintf(stderr, "video: v: %lld, a: %lld, d: %lld, e: %lld\n", vpts, apts, vpts - apts, extra);
2376
// ::fprintf(stderr, "seen audio pts\n");
2377
// xfprintf(stderr, "A");
2378
packetTypeOnce = 'A';
2387
int64_t delta = vpts - apts;
2395
// ::fprintf(stderr, "max. A/V delta: %lld pts => total extra buffering: %d frames", extra0, (int)(extra0 * 25 / 90000));
2399
if (extra > extra_max)
2403
// ::fprintf(stderr, ", limited to %d frames", (int)(extra * 25 / 90000));
2406
// ::fprintf(stderr, "\n");
2408
xfprintf(stderr, "+%d", (int)(extra * 25 / 90000));
2412
// ::fprintf(stderr, "audio: v: %lld, a: %lld, d: %lld, e: %lld\n", vpts, apts, vpts - apts, extra);
2416
//xfprintf(stderr, "%s%c", getFrameType(Data, Length), packetType); packetTypeOnce = 0; //ZZZ
2419
xfprintf(stderr, "%c", packetTypeOnce);
2422
if (seenVideo && !seenVpts
2423
|| seenAudio && !seenApts)
2425
softStartTime = now;
2428
if (softStartState >= sStartSequence)
2436
softStartPtsVdr = ptsForce;
2437
// getPTS(Data, Length, softStartPtsVdr);
2439
if (softStartPtsVdr != -1)
2441
int64_t ptsXine = -1;
2442
m_xineLib.execFuncGetPTS(ptsXine);
2444
const int64_t delta = (ptsXine != -1) ? (softStartPtsVdr - ptsXine) : 0;
2445
if (softStartState == sStartSequence
2446
|| delta < -softStartLogPtsDelta
2447
|| delta > +softStartLogPtsDelta)
2449
// if (softStartState != sStartSequence)
2450
// ::fprintf(stderr, "SoftStart: ptsVdr: %lld, ptsXine: %lld, delta: %lld\n", softStartPtsVdr, ptsXine, delta);
2452
//AAA m_xineLib.execFuncStart();
2453
//AAA m_xineLib.execFuncWait();
2455
if (!softStartNoMetronom)
2457
xfprintf(stderr, "M");
2459
//ZZZ m_xineLib.execFuncMetronom(softStartPtsVdr);
2460
//ZZZ m_xineLib.execFuncWait();
2463
softStartTime = now;
2465
softStartState = sContinueSequence;
2471
// if (softStartState <= sStartSequence)
2472
// stripPTSandDTS((uchar *)Data, Length);
2474
m_xineLib.execFuncFirstFrame();
2476
int64_t vdrPTS = -1;
2478
if (seenVideo && vpts <= -1
2479
|| seenAudio && apts <= -1)
2484
if (apts > -1 && vpts > apts)
2492
int64_t xinePTS = -1;
2494
m_xineLib.execFuncGetPTS(xinePTS);
2496
const double totalDuration = (softStartDuration + extra / 90000.0);
2497
const double q = oldMode ? ((now - softStartTime) / totalDuration) : softStartCalcQ(vdrPTS, xinePTS);
2498
double p = softStartCalcSpeed(q);
2502
if (vdrPTSLast == vdrPTS || vdrVptsLast > vpts || vdrAptsLast > apts)
2503
p = softStartLastSpeed / 100;
2505
vdrPTSLast = vdrPTS;
2507
if (apts != vdrAptsLast || vpts != vdrVptsLast)
2509
// xfprintf(stderr, "p: %.3lf, DA: %lld, DV: %lld, DC: %lld\n", p, (apts > -1) ? (apts - xinePTS) : -1, (vpts > -1) ? (vpts - xinePTS) : -1, (vdrPTS > - 1) ? (vdrPTS - xinePTS) : -1);
2510
// xfprintf(stderr, "(%.1lf|%.1lf)", 25 * ((apts > -1) ? ((apts - xinePTS) / 90000.0) : 0.0), 25 * ((vpts > -1) ? ((vpts - xinePTS) / 90000.0) : 0.0));
2517
double speed = (p > 0) ? (100.0 * p) : 12.5;
2519
if (speed >= 100.0 || xinePTS == -1)
2521
bool newlineRequired = false;
2527
fprintf(stderr, "+++++ %.3lf ms, %.3lf ms, %.3lf ms, (%.3lf ms, %.3lf ms, %.3lf ms) +++++\n"
2528
, (ttt1 - ttt0) * 1000.0
2529
, (ttt2 - ttt1) * 1000.0
2530
, (ttt3 - ttt2) * 1000.0
2531
, (ttt4 - ttt3) * 1000.0
2532
, (ttt5 - ttt3) * 1000.0
2533
, (ttt6 - ttt3) * 1000.0
2538
xfprintf(stderr, "]");
2539
newlineRequired = true;
2544
if (vdrTime100reload)
2546
vdrTime100reload = false;
2552
softStartState = sIdle;
2553
else if ((now - vdrTime100) >= m_settings.GetModeParams()->m_monitoringDuration)
2555
if (m_settings.GetModeParams()->MonitoringContinuous())
2556
hystQ1 = 90000 * (m_settings.GetModeParams()->m_prebufferHysteresis - 1) / 25;
2558
softStartState = sIdle;
2561
if ((softStartState == sIdle || speed != softStartLastSpeed) && vdrPTS > -1 && xinePTS > -1)
2563
xfprintf(stderr, "buffered %.1lf frames (v:%.1lf, a:%.1lf)", (vdrPTS - xinePTS) / 90000.0 * 25, (vpts > -1) ? ((vpts - xinePTS) / 90000.0 * 25) : 0.0, (apts > -1) ? ((apts - xinePTS) / 90000.0 * 25) : 0.0);
2564
if (softStartState == sIdle)
2565
xfprintf(stderr, " <<<<<");
2566
newlineRequired = true;
2569
if (newlineRequired)
2570
xfprintf(stderr, "\n");
2574
|| (speed != softStartLastSpeed
2575
&& (!oldMode || (now - softStartSpeedChangeTime) > (totalDuration / softStartMaxSpeedChanges))))
2577
softStartSpeedChangeTime = now;
2579
// fprintf(stderr, "slowstart: %lg, %lg\n", speed, p);
2581
m_xineLib.execFuncSetSpeed(speed);
2582
m_xineLib.execFuncWait();
2584
// if (100.0 == speed)
2585
// m_xineLib.execFuncSetPrebuffer(m_settings.GetModeParams()->m_prebufferFrames);
2587
softStartLastSpeed = speed;
2593
// fprintf(stderr, "v");
2597
stripPTSandDTS((uchar *)Data, Length);
2603
if (np && getPTS(Data, Length, pts))
2607
// fprintf(stderr, "M %lld %llx\n", pts);
2608
m_xineLib.execFuncMetronom(pts);
2609
m_xineLib.execFuncWait();
2613
int r = PlayCommon1(Data, Length, ptsForce);
2615
// fprintf(stderr, "V");
2620
int cXineDevice::PlayCommon1(const uchar *Data, int Length, int64_t ptsForce)
2625
fprintf(stderr, "blahblah C1");
2626
for (int i = 0; i < 50 && i < Length; i++)
2627
fprintf(stderr, " %02x", Data[ i ]);
2628
fprintf(stderr, "\n");
2632
return PlayCommon2(Data, Length, ptsForce);
2642
static sBuffer *pHead = 0;
2643
static sBuffer *pTail = 0;
2644
static int bufCount = 0;
2646
while (!doClear && pHead)
2648
if (sIdle != softStartState)
2651
if (!m_xineLib.Poll(p, -1))
2655
int r = PlayCommon2(pHead->data, pHead->length, pHead->ptsForce);
2659
pHead = pHead->next;
2661
//fprintf(stderr, "bufCount: %d\n", --bufCount);
2668
pHead = pHead->next;
2674
//fprintf(stderr, "--- bufCount: %d\n", bufCount);
2686
pHead = pHead->next;
2693
//fprintf(stderr, "=== bufCount: %d\n", bufCount);
2702
do // ... while (false);
2704
if (sIdle != softStartState)
2707
if (!m_xineLib.Poll(p, -1))
2709
//fprintf(stderr, "### bufCount: %d\n", bufCount);
2712
return PlayCommon2(Data, Length, ptsForce);
2717
sBuffer *p = (sBuffer *)::malloc(sizeof (sBuffer) - sizeof (p->data) + Length);
2723
p->ptsForce = ptsForce;
2724
memcpy(&p->data, Data, Length);
2734
//fprintf(stderr, "*** bufCount: %d\n", ++bufCount);
2738
static uchar jumboPESdata[ 6 + 0xffff ];
2739
static uchar *jumboPEStailData = 0;
2741
static bool mkJumboPES(const uchar *Data, int Length)
2743
int origJumboPESsize = jumboPESsize;
2747
VERBOSE_RETURN0(false);
2749
if (0x00 != Data[ 0 ])
2750
VERBOSE_RETURN0(false);
2752
if (0x00 != Data[ 1 ])
2753
VERBOSE_RETURN0(false);
2755
if (0x01 != Data[ 2 ])
2756
VERBOSE_RETURN0(false);
2758
if (0xbd != Data[ 3 ])
2759
VERBOSE_RETURN0(false);
2761
int l = Data[ 4 ] * 256 + Data[ 5 ];
2762
if ((6 + l) != Length)
2764
const uchar *data = Data + (6 + l);
2765
int length = Length - (6 + l);
2768
VERBOSE_RETURN3(false);
2770
if (0x00 != data[ 0 ])
2771
VERBOSE_RETURN3(false);
2773
if (0x00 != data[ 1 ])
2774
VERBOSE_RETURN3(false);
2776
if (0x01 != data[ 2 ])
2777
VERBOSE_RETURN3(false);
2779
if (0xbe != data[ 3 ])
2780
VERBOSE_RETURN3(false);
2782
int L = data[ 4 ] * 256 + data[ 5 ];
2783
if ((6 + L) != length)
2784
VERBOSE_RETURN3(false);
2790
for (int i = 0; i < 20; i++)
2791
fprintf(stderr, "%02x ", Data[ i ]);
2792
fprintf(stderr, "\n");
2794
bool cont = (0x80 == Data[ 6 ]
2795
&& 0x00 == Data[ 7 ]
2796
&& 0x00 == Data[ 8 ]);
2799
&& Length >= 6 + 3 + 5
2800
&& Data[ 9 ] == 0x0b
2801
&& Data[ 10 ] == 0x77
2802
&& frameSizes[ Data[ 13 ] ] > 0)
2808
|| 0 == origJumboPESsize)
2810
if (0 != origJumboPESsize)
2811
VERBOSE_RETURN0(false);
2813
if ((origJumboPESsize + Length - 0) > (6 + 0xffff))
2814
VERBOSE_RETURN0(false);
2816
if (jumboPEStail > 0)
2818
int headerSize = 6 + 3 + Data[ 8 ];
2819
::memcpy(&jumboPESdata[ origJumboPESsize ], &Data[ 0 ], headerSize);
2821
::memmove(&jumboPESdata[ origJumboPESsize + headerSize ], jumboPEStailData, jumboPEStail);
2823
::memcpy(&jumboPESdata[ origJumboPESsize + headerSize + jumboPEStail ], &Data[ headerSize ], Length - headerSize);
2825
origJumboPESsize += headerSize + jumboPEStail + Length - headerSize;
2828
jumboPEStailData = 0;
2830
//FIXME: PTS should be adjusted to take care of jumboPEStail's duration.
2831
// Otherwise there is a certain jitter on audio duration <=> PTS.
2835
::memcpy(&jumboPESdata[ origJumboPESsize ], &Data[ 0 ], Length - 0);
2836
origJumboPESsize += Length - 0;
2841
if (0 == origJumboPESsize)
2842
VERBOSE_RETURN0(false);
2844
if ((origJumboPESsize + Length - 9) > (6 + 0xffff))
2845
VERBOSE_RETURN0(false);
2847
::memcpy(&jumboPESdata[ origJumboPESsize ], &Data[ 9 ], Length - 9);
2848
origJumboPESsize += Length - 9;
2851
if (0 == origJumboPESsize)
2852
VERBOSE_RETURN0(false);
2854
jumboPESsize = origJumboPESsize;
2858
// fprintf(stderr, " b %d", jumboPESsize);
2862
jumboPESdata[ 4 ] = (jumboPESsize - 6) >> 8;
2863
jumboPESdata[ 5 ] = (jumboPESsize - 6) & 0xff;
2865
// fprintf(stderr, " B %d", jumboPESsize);
2869
static int initFrameSizes()
2871
::memset(frameSizes, 0, sizeof (frameSizes));
2874
frameSizes[ 0x00 ] = 64;
2875
frameSizes[ 0x01 ] = 64;
2876
frameSizes[ 0x02 ] = 80;
2877
frameSizes[ 0x03 ] = 80;
2878
frameSizes[ 0x04 ] = 96;
2879
frameSizes[ 0x05 ] = 96;
2880
frameSizes[ 0x06 ] = 112;
2881
frameSizes[ 0x07 ] = 112;
2882
frameSizes[ 0x08 ] = 128;
2883
frameSizes[ 0x09 ] = 128;
2884
frameSizes[ 0x0a ] = 160;
2885
frameSizes[ 0x0b ] = 160;
2886
frameSizes[ 0x0c ] = 192;
2887
frameSizes[ 0x0d ] = 192;
2888
frameSizes[ 0x0e ] = 224;
2889
frameSizes[ 0x0f ] = 224;
2890
frameSizes[ 0x10 ] = 256;
2891
frameSizes[ 0x11 ] = 256;
2892
frameSizes[ 0x12 ] = 320;
2893
frameSizes[ 0x13 ] = 320;
2894
frameSizes[ 0x14 ] = 384;
2895
frameSizes[ 0x15 ] = 384;
2896
frameSizes[ 0x16 ] = 448;
2897
frameSizes[ 0x17 ] = 448;
2898
frameSizes[ 0x18 ] = 512;
2899
frameSizes[ 0x19 ] = 512;
2900
frameSizes[ 0x1a ] = 640;
2901
frameSizes[ 0x1b ] = 640;
2902
frameSizes[ 0x1c ] = 768;
2903
frameSizes[ 0x1d ] = 768;
2904
frameSizes[ 0x1e ] = 896;
2905
frameSizes[ 0x1f ] = 896;
2906
frameSizes[ 0x20 ] = 1024;
2907
frameSizes[ 0x21 ] = 1024;
2908
frameSizes[ 0x22 ] = 1152;
2909
frameSizes[ 0x23 ] = 1152;
2910
frameSizes[ 0x24 ] = 1280;
2911
frameSizes[ 0x25 ] = 1280;
2914
frameSizes[ 0x40 ] = 69;
2915
frameSizes[ 0x41 ] = 70;
2916
frameSizes[ 0x42 ] = 87;
2917
frameSizes[ 0x43 ] = 88;
2918
frameSizes[ 0x44 ] = 104;
2919
frameSizes[ 0x45 ] = 105;
2920
frameSizes[ 0x46 ] = 121;
2921
frameSizes[ 0x47 ] = 122;
2922
frameSizes[ 0x48 ] = 139;
2923
frameSizes[ 0x49 ] = 140;
2924
frameSizes[ 0x4a ] = 174;
2925
frameSizes[ 0x4b ] = 175;
2926
frameSizes[ 0x4c ] = 208;
2927
frameSizes[ 0x4d ] = 209;
2928
frameSizes[ 0x4e ] = 243;
2929
frameSizes[ 0x4f ] = 244;
2930
frameSizes[ 0x50 ] = 278;
2931
frameSizes[ 0x51 ] = 279;
2932
frameSizes[ 0x52 ] = 348;
2933
frameSizes[ 0x53 ] = 349;
2934
frameSizes[ 0x54 ] = 417;
2935
frameSizes[ 0x55 ] = 418;
2936
frameSizes[ 0x56 ] = 487;
2937
frameSizes[ 0x57 ] = 488;
2938
frameSizes[ 0x58 ] = 557;
2939
frameSizes[ 0x59 ] = 558;
2940
frameSizes[ 0x5a ] = 696;
2941
frameSizes[ 0x5b ] = 697;
2942
frameSizes[ 0x5c ] = 835;
2943
frameSizes[ 0x5d ] = 836;
2944
frameSizes[ 0x5e ] = 975;
2945
frameSizes[ 0x5f ] = 976;
2946
frameSizes[ 0x60 ] = 1114;
2947
frameSizes[ 0x61 ] = 1115;
2948
frameSizes[ 0x62 ] = 1253;
2949
frameSizes[ 0x63 ] = 1254;
2950
frameSizes[ 0x64 ] = 1393;
2951
frameSizes[ 0x65 ] = 1394;
2954
frameSizes[ 0x80 ] = 96;
2955
frameSizes[ 0x81 ] = 96;
2956
frameSizes[ 0x82 ] = 120;
2957
frameSizes[ 0x83 ] = 120;
2958
frameSizes[ 0x84 ] = 144;
2959
frameSizes[ 0x85 ] = 144;
2960
frameSizes[ 0x86 ] = 168;
2961
frameSizes[ 0x87 ] = 168;
2962
frameSizes[ 0x88 ] = 192;
2963
frameSizes[ 0x89 ] = 192;
2964
frameSizes[ 0x8a ] = 240;
2965
frameSizes[ 0x8b ] = 240;
2966
frameSizes[ 0x8c ] = 288;
2967
frameSizes[ 0x8d ] = 288;
2968
frameSizes[ 0x8e ] = 336;
2969
frameSizes[ 0x8f ] = 336;
2970
frameSizes[ 0x90 ] = 384;
2971
frameSizes[ 0x91 ] = 384;
2972
frameSizes[ 0x92 ] = 480;
2973
frameSizes[ 0x93 ] = 480;
2974
frameSizes[ 0x94 ] = 576;
2975
frameSizes[ 0x95 ] = 576;
2976
frameSizes[ 0x96 ] = 672;
2977
frameSizes[ 0x97 ] = 672;
2978
frameSizes[ 0x98 ] = 768;
2979
frameSizes[ 0x99 ] = 768;
2980
frameSizes[ 0x9a ] = 960;
2981
frameSizes[ 0x9b ] = 960;
2982
frameSizes[ 0x9c ] = 1152;
2983
frameSizes[ 0x9d ] = 1152;
2984
frameSizes[ 0x9e ] = 1344;
2985
frameSizes[ 0x9f ] = 1344;
2986
frameSizes[ 0xa0 ] = 1536;
2987
frameSizes[ 0xa1 ] = 1536;
2988
frameSizes[ 0xa2 ] = 1728;
2989
frameSizes[ 0xa3 ] = 1728;
2990
frameSizes[ 0xa4 ] = 1920;
2991
frameSizes[ 0xa5 ] = 1920;
2996
#if APIVERSNUM < 10318
2998
void cXineDevice::PlayAudio(const uchar *Data, int Length)
3000
cDevice::PlayAudio(Data, Length);
3002
PlayAudioCommon(Data, Length);
3007
int cXineDevice::GetAudioChannelDevice(void)
3009
return m_audioChannel;
3012
void cXineDevice::SetAudioChannelDevice(int AudioChannel)
3014
xfprintf(stderr, "SetAudioChannelDevice: %d\n", AudioChannel);
3016
m_audioChannel = AudioChannel;
3018
m_xineLib.execFuncSelectAudio(m_audioChannel);
3021
void cXineDevice::SetDigitalAudioDevice(bool On)
3023
xfprintf(stderr, "SetDigitalAudioDevice: %d\n", On);
3025
m_xineLib.execFuncSelectAudio(On ? -1 : m_audioChannel);
3030
if (m_settings.LiveTV()
3033
if (softStartState == sIdle)
3034
softStartTrigger = sstNoMetronom;
3045
m_xineLib.execFuncSetSpeed(100.0);
3046
//double t0 = tNow();
3047
if (m_settings.LiveTV()
3048
|| !foundVideo) // radio recording: audio channels are not related
3050
ptsV = ptsA = ptsP = ptsD = -1;
3052
m_xineLib.execFuncClear(-3);
3055
// m_xineLib.execFuncStart();
3059
m_xineLib.execFuncResetAudio();
3062
m_xineLib.execFuncSetSpeed(0.0);
3064
m_xineLib.execFuncWait();
3066
m_xineLib.pause(false);
3067
//double t1 = tNow(); fprintf(stderr, "!!!!!!! %.3lf ms\n", (t1 - t0) * 1000);
3068
if (m_settings.LiveTV())
3069
softStartTrigger = sstNoMetronom;
3071
//fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
3074
#if APIVERSNUM < 10342
3076
int cXineDevice::PlayAudio(const uchar *Data, int Length)
3078
// fprintf(stderr, " 0x%02x ", Data[ 3 ]);
3079
return PlayAudioCommon(Data, Length);
3084
int cXineDevice::PlayAudio(const uchar *Data, int Length, uchar /* Id */)
3086
// fprintf(stderr, " 0x%02x ", Data[ 3 ]);
3087
return PlayAudioCommon(Data, Length);
3093
int cXineDevice::PlayAudioCommon(const uchar *Data, int Length)
3095
if (ttt5 == 0) ttt5 = tNow();
3096
// fprintf(stderr, " 0x%02x: %d ", Data[ 3 ], Data[4] * 256 + Data[5]);
3098
if (Data[ 3 ] == 0xd0) {
3099
FILE *f = fopen("/tmp/d0", "ab");
3100
fwrite(Data, Length, 1, f);
3105
static int i = initFrameSizes();
3109
store_frame(Data, Length, __LINE__);
3111
LOG_ME(::fprintf(stderr, "A");)
3115
LOG_ME(::fprintf(stderr, "<");)
3121
cMutexLock pmMutexLock(&m_pmMutex);
3124
m_pmCondVar.Wait(m_pmMutex);
3127
int retVal = PlayAudio2(Data, Length);
3129
LOG_ME(::fprintf(stderr, "a"));
3134
int cXineDevice::PlayAudio2(const uchar *Data, int Length)
3136
// fprintf(stderr, "D");
3140
while (done < Length)
3146
int todo = Length - done;
3149
if (0x00 == Data[ done + 0 ]
3150
&& 0x00 == Data[ done + 1 ]
3151
&& 0x01 == Data[ done + 2 ])
3153
id = Data[ done + 3 ];
3154
int len = Data[ done + 4 ] * 0x0100 + Data[ done + 5 ];
3156
if (todo >= (6 + len))
3164
// ::fprintf(stderr, "x");
3188
// ::fprintf(stderr, "%c", ch);
3193
r = PlayAudio3(Data + done, todo);
3195
r = PlayVideo3(Data + done, todo, false);
3209
int cXineDevice::PlayAudio3(const uchar *Data, int Length)
3211
resetScramblingControl(Data, Length);
3213
store_frame(Data, Length, __LINE__);
3215
::fprintf(stderr, "l: %d\t", Length);
3216
for (int i = 0; i < 20; i++)
3217
::fprintf(stderr, "%02x ", Data[ i ]);
3218
::fprintf(stderr, "\n");
3220
// fprintf(stderr, "A");
3222
if (mkJumboPES(Data, Length))
3224
int todo = jumboPESsize;
3227
dumpAudio("Audio", jumboPESdata, todo);
3234
if (todo < (6 + 3 + 0 + 2))
3237
if (0x00 != jumboPESdata[ 0 ]
3238
|| 0x00 != jumboPESdata[ 1 ]
3239
|| 0x01 != jumboPESdata[ 2 ]
3240
|| 0xbd != jumboPESdata[ 3 ])
3245
int l = jumboPESdata[ 4 ] * 0x0100 + jumboPESdata[ 5 ];
3246
if (l < (3 + 0 + 2))
3252
int h = jumboPESdata[ 8 ];
3253
if (l < (3 + h + 2))
3256
if (0x0b == jumboPESdata[ 6 + 3 + h + 0 ]
3257
&& 0x77 == jumboPESdata[ 6 + 3 + h + 1 ])
3259
if (l < (3 + h + 2 + 2 + 1))
3265
int frameStart = 6 + 3 + h;
3266
bool failed = false;
3270
int frameSize = 2 * frameSizes[ jumboPESdata[ frameStart + 4 ] ];
3275
xfprintf(stderr, "frame_size_code: 0x%02x\n", jumboPESdata[ frameStart + 4 ]);
3280
if (frameStart + frameSize > todo)
3283
frameStart += frameSize;
3285
if (frameStart + 2 + 2 + 1 > todo)
3288
if (0x0b != jumboPESdata[ frameStart + 0 ]
3289
|| 0x77 != jumboPESdata[ frameStart + 1 ])
3301
jumboPEStail = todo - frameStart;
3302
jumboPEStailData = jumboPESdata + frameStart;
3306
jumboPESdata[ 4 + 0 ] = (todo - 6) >> 8;
3307
jumboPESdata[ 4 + 1 ] = (todo - 6) & 0xff;
3310
store_frame(jumboPESdata, todo, __LINE__);
3314
if (0x80 == (0xf0 & jumboPESdata[ 6 + 3 + h + 0 ]))
3320
if (0xa0 == (0xf0 & jumboPESdata[ 6 + 3 + h + 0 ]))
3326
for (int i = 6 + 3 + h; i < todo - 2 - 2 - 1; i++)
3328
if (0x0b == jumboPESdata[ i + 0 ]
3329
&& 0x77 == jumboPESdata[ i + 1 ]
3330
&& 0 != frameSizes[ jumboPESdata[ i + 4 ] ])
3332
jumboPEStail = todo - i;
3333
jumboPEStailData = jumboPESdata + i;
3340
|| (dolby && m_settings.AudioDolbyOn()))
3346
int r = PlayCommon(jumboPESdata + done, todo - done, false);
3350
// fprintf(stderr, ".");
3355
// Don't return done here as the remaining bytes were buffered elsewhere!
3359
else if (jumboPESsize == Length)
3361
int todo = jumboPESsize;
3368
if (todo < (6 + 3 + 0 + 2))
3371
if (0x00 != jumboPESdata[ 0 ]
3372
|| 0x00 != jumboPESdata[ 1 ]
3373
|| 0x01 != jumboPESdata[ 2 ]
3374
|| 0xbd != jumboPESdata[ 3 ])
3379
int l = jumboPESdata[ 4 ] * 0x0100 + jumboPESdata[ 5 ];
3380
if (l < (3 + 0 + 2))
3386
int h = jumboPESdata[ 8 ];
3387
if (l < (3 + h + 2))
3390
if (0x80 == (0xf0 & jumboPESdata[ 6 + 3 + h + 0 ]))
3396
if (0xa0 == (0xf0 & jumboPESdata[ 6 + 3 + h + 0 ]))
3406
dumpAudio("Audio", jumboPESdata, todo);
3412
|| (dolby && m_settings.AudioDolbyOn()))
3418
int r = PlayCommon(jumboPESdata + done, todo - done, false);
3422
// fprintf(stderr, ".");
3427
// Don't return done here as the remaining bytes were buffered elsewhere!
3432
// fprintf(stderr, "\n");
3437
#if APIVERSNUM >= 10338
3438
uchar *cXineDevice::GrabImage(int &Size, bool Jpeg /* = true */, int Quality /* = -1 */, int SizeX /* = -1 */, int SizeY /* = -1 */)
3440
const char *const FileName = 0;
3442
bool cXineDevice::GrabImage(const char *FileName, bool Jpeg /* = true */, int Quality /* = -1 */, int SizeX /* = -1 */, int SizeY /* = -1 */)
3446
xfprintf(stderr, "GrabImage ...\n\n");
3452
SizeX = m_settings.DefaultGrabSizeX();
3455
SizeY = m_settings.DefaultGrabSizeY();
3457
uchar *result = m_xineLib.execFuncGrabImage(FileName, Size, Jpeg, Quality, SizeX, SizeY);
3459
xfprintf(stderr, result ? "\nGrabImage succeeded.\n" : "\nGrabImage failed.\n");
3463
int64_t cXineDevice::GetSTC(void)
3465
// ::fprintf(stderr, "GetSTC: ");
3469
if (!m_xineLib.execFuncGetPTS(pts) || pts < 0)
3470
pts = cDevice::GetSTC();
3472
// ::fprintf(stderr, "%lld\n", pts);
3477
void cXineDevice::SetVideoFormat(bool VideoFormat16_9)
3479
xfprintf(stderr, "SetVideoFormat: %d\n", VideoFormat16_9);
3480
cDevice::SetVideoFormat(VideoFormat16_9);
3483
static bool firstCallToSetVolume = true;
3484
static void switchSkin(const bool restore);
3486
void cXineDevice::SetVolumeDevice(int Volume)
3488
if (firstCallToSetVolume)
3490
firstCallToSetVolume = false;
3492
if (m_settings.ShallSwitchSkin())
3496
xfprintf(stderr, "SetVolumeDevice: %d\n", Volume);
3497
m_xineLib.execFuncSetVolume(Volume);
3500
#if APIVERSNUM < 10307
3501
cOsdBase *cXineDevice::NewOsd(int x, int y)
3502
#elif APIVERSNUM < 10509
3503
cOsd *cXineDevice::NewOsd(int x, int y)
3505
cOsd *cXineDevice::NewOsd(int x, int y, uint Level)
3508
// ::fprintf(stderr, "NewOsd ---: %s\n", ::ctime(&(const time_t &)::time(0)));
3509
cMutexLock osdLock(&m_osdMutex);
3510
// ::fprintf(stderr, "NesOsd +++: %s\n", ::ctime(&(const time_t &)::time(0)));
3511
#if APIVERSNUM < 10509
3514
esyslog("vdr-xine: new OSD(%d, %d) requested while another OSD is active", x, y);
3515
xfprintf(stderr, "vdr-xine: new OSD(%d, %d) requested while another OSD is active", x, y);
3521
esyslog("vdr-xine: new OSD(%d, %d) requested with coordinates out of range", x, y);
3522
xfprintf(stderr, "vdr-xine: new OSD(%d, %d) requested with coordinates out of range", x, y);
3525
#if APIVERSNUM < 10509
3526
m_currentOsd = new cXineOsd(*this, x, y);
3528
return new cXineOsd(*this, x, y, Level);
3531
return m_currentOsd;
3534
#if APIVERSNUM < 10307
3535
void cXineDevice::OnFreeOsd(cOsdBase *const osd)
3537
void cXineDevice::OnFreeOsd(cOsd *const osd)
3540
#if APIVERSNUM < 10509
3541
cMutexLock osdLock(&m_osdMutex);
3543
assert(osd == m_currentOsd);
3549
bool cXineDevice::ChangeCurrentOsd(cXineOsd *const osd, bool on)
3551
cMutexLock osdLock(&m_osdMutex);
3557
esyslog("vdr-xine: OSD activation requested while another OSD is active -- ignoring request");
3558
xfprintf(stderr, "vdr-xine: OSD activation requested while another OSD is active -- ignoring request");
3561
else if (m_currentOsd != osd)
3563
esyslog("vdr-xine: OSD deactivation requested for an OSD which is not active -- ignoring request");
3564
xfprintf(stderr, "vdr-xine: OSD deactivation requested for an OSD which is not active -- ignoring request");
3576
esyslog("vdr-xine: OSD deactivation requested while no OSD is active -- ignoring request");
3577
xfprintf(stderr, "vdr-xine: OSD deactivation requested while no OSD is active -- ignoring request");
3591
static cDevice *originalPrimaryDevice = 0;
3593
#if APIVERSNUM >= 10307
3595
void cXineDevice::MakePrimaryDevice(bool On)
3597
xfprintf(stderr, "-------------------------\n");
3598
xfprintf(stderr, "MakePrimaryDevice: %d\n", On);
3599
xfprintf(stderr, "=========================\n");
3602
new cXineOsdProvider(*this);
3604
cOsdProvider::Shutdown();
3606
originalPrimaryDevice = 0;
3613
#if APIVERSNUM >= 10320
3614
static cSkin *origSkin = 0;
3617
static void switchSkin(const bool restore)
3619
#if APIVERSNUM >= 10320
3622
Skins.SetCurrent(origSkin->Name());
3623
cThemes::Load(Skins.Current()->Name(), Setup.OSDTheme, Skins.Current()->Theme());
3627
origSkin = Skins.Current();
3628
Skins.SetCurrent("curses");
3629
cThemes::Load(Skins.Current()->Name(), Setup.OSDTheme, Skins.Current()->Theme());
3632
#warning vdr-xine: switching skins is only available for VDR versions >= 1.3.20
3633
isyslog("vdr-xine: switching skins is only available for VDR versions >= 1.3.20");
3637
void cXineDevice::reshowCurrentOsd(const bool dontOptimize /* = true */, const int frameLeft /* = -1 */, const int frameTop /* = -1 */, const int frameWidth /* = -1 */, const int frameHeight /* = -1 */, const int frameZoomX /* = -1 */, const int frameZoomY /* = -1 */)
3639
cMutexLock osdLock(&m_osdMutex);
3642
m_currentOsd->ReshowCurrentOsd(dontOptimize, frameLeft, frameTop, frameWidth, frameHeight, frameZoomX, frameZoomY);
3645
void cXineDevice::mainMenuTrampoline()
3647
#if APIVERSNUM >= 10332
3648
cMutexLock switchPrimaryDeviceLock(&m_switchPrimaryDeviceMutex);
3649
if (m_switchPrimaryDeviceDeviceNo < 0)
3652
cControl::Shutdown();
3654
if (m_switchPrimaryDeviceDeviceNo == (1 + DeviceNumber()))
3657
::asprintf(&msg, tr("Switching primary DVB to %s..."), m_plugin->Name());
3659
Skins.Message(mtInfo, msg);
3663
SetPrimaryDevice(m_switchPrimaryDeviceDeviceNo);
3665
if (m_switchPrimaryDeviceDeviceNo != (1 + DeviceNumber()))
3668
::asprintf(&msg, tr("Switched primary DVB back from %s"), m_plugin->Name());
3670
Skins.Message(mtInfo, msg);
3674
m_switchPrimaryDeviceDeviceNo = -1;
3676
m_switchPrimaryDeviceCond.Broadcast();
3680
void cXineDevice::switchPrimaryDevice(const int deviceNo, const bool waitForExecution)
3682
#if APIVERSNUM >= 10332
3683
#if APIVERSNUM < 10347
3684
while (cRemote::HasKeys())
3685
cCondWait::SleepMs(10);
3688
cMutexLock switchPrimaryDeviceLock(&m_switchPrimaryDeviceMutex);
3689
m_switchPrimaryDeviceDeviceNo = deviceNo;
3691
#if APIVERSNUM < 10347
3692
cRemote::CallPlugin(m_plugin->Name());
3695
if (waitForExecution)
3696
m_switchPrimaryDeviceCond.Wait(m_switchPrimaryDeviceMutex);
3698
#warning vdr-xine: switching primary device is no longer supported for VDR versions < 1.3.32
3699
isyslog("vdr-xine: switching primary device is no longer supported for VDR versions < 1.3.32");
3703
void cXineDevice::OnClientConnect()
3707
if (m_settings.LiveTV())
3708
softStartTrigger = sstNormal;
3710
if (m_settings.AutoPrimaryDevice())
3712
cDevice *primaryDevice = cDevice::PrimaryDevice();
3713
if (this != primaryDevice)
3714
switchPrimaryDevice(1 + DeviceNumber(), true);
3716
originalPrimaryDevice = primaryDevice;
3719
if (m_settings.ShallSwitchSkin())
3723
void cXineDevice::OnClientDisconnect()
3725
if (m_settings.ShallSwitchSkin())
3728
if (m_settings.AutoPrimaryDevice()
3729
&& originalPrimaryDevice)
3731
if (this != originalPrimaryDevice)
3732
switchPrimaryDevice(1 + originalPrimaryDevice->DeviceNumber(), false);
3736
void cXineDevice::ReshowCurrentOSD(const int frameLeft, const int frameTop, const int frameWidth, const int frameHeight, const int frameZoomX, const int frameZoomY)
3738
// ::fprintf(stderr, ">>> cXineDevice::ReshowCurrentOSD()\n");
3739
reshowCurrentOsd(false, frameLeft, frameTop, frameWidth, frameHeight, frameZoomX, frameZoomY);
3740
// ::fprintf(stderr, "<<< cXineDevice::ReshowCurrentOSD()\n");
3743
bool cXineDevice::DeviceReplayingOrTransferring()
3745
return Replaying() || Transferring();
3748
bool cXineDevice::open()
3750
if (!m_xineLib.Open())
3753
if (m_settings.ShallSwitchSkin())
3755
#if APIVERSNUM >= 10320
3756
Skins.SetCurrent(Setup.OSDSkin);
3757
cThemes::Load(Skins.Current()->Name(), Setup.OSDTheme, Skins.Current()->Theme());
3765
void cXineDevice::close()
3769
if (m_settings.ShallSwitchSkin())
3773
void cXineDevice::Stop()
3778
theXineDevice->close();
3781
cXineDevice::cXineDevice(cPlugin *const plugin, cXineSettings &settings, cXineRemote *remote)
3783
, m_settings(settings)
3788
, m_switchPrimaryDeviceDeviceNo(-1)
3789
, m_xineLib(plugin, settings, m_osdMutex, remote)
3791
m_xineLib.SetEventSink(this);
3794
cXineDevice::~cXineDevice()
3796
#if APIVERSNUM < 10320
3800
delete m_spuDecoder;
3803
bool cXineDevice::Create(cPlugin *const plugin, cXineSettings &settings, cXineRemote *remote)
3808
theXineDevice = new cXineDevice(plugin, settings, remote);
3810
return 0 != theXineDevice
3811
&& theXineDevice->hasNoSignalStream();
3814
bool cXineDevice::Open()
3819
return theXineDevice->open();
3822
cXineDevice *cXineDevice::GetDevice()
3824
return theXineDevice;