diff -Nru vdr-2.2.0/debian/changelog vdr-2.2.0/debian/changelog --- vdr-2.2.0/debian/changelog 2016-02-01 18:28:00.000000000 +0000 +++ vdr-2.2.0/debian/changelog 2016-06-05 13:21:55.000000000 +0000 @@ -1,3 +1,10 @@ +vdr (2.2.0-13yavdr0~trusty) trusty; urgency=medium + + * add patch for h.265 parser + * add patch against mutex deadlock + + -- Lars Hanisch Sun, 05 Jun 2016 15:21:24 +0200 + vdr (2.2.0-12yavdr0~trusty) trusty; urgency=medium * new patch for graphtftng diff -Nru vdr-2.2.0/debian/patches/series vdr-2.2.0/debian/patches/series --- vdr-2.2.0/debian/patches/series 2016-01-13 18:15:27.000000000 +0000 +++ vdr-2.2.0/debian/patches/series 2016-06-05 13:19:14.000000000 +0000 @@ -20,3 +20,6 @@ vdr-2.2.0-toomanypids.patch vdr-2.2.0-caid_buffer-v3.patch +vdr-2.2.0-h265-frame-parser.patch +vdr-2.2.0-mutex-deadlock.patch + diff -Nru vdr-2.2.0/debian/patches/vdr-2.2.0-h265-frame-parser.patch vdr-2.2.0/debian/patches/vdr-2.2.0-h265-frame-parser.patch --- vdr-2.2.0/debian/patches/vdr-2.2.0-h265-frame-parser.patch 1970-01-01 00:00:00.000000000 +0000 +++ vdr-2.2.0/debian/patches/vdr-2.2.0-h265-frame-parser.patch 2016-06-05 13:19:43.000000000 +0000 @@ -0,0 +1,141 @@ +From ce4d2a08e6448b7bfab68b89a12a156ed3294a63 Mon Sep 17 00:00:00 2001 +From: Thomas Reufer +Date: Mon, 28 Mar 2016 19:47:14 +0200 +Subject: [PATCH] Implement H.265 frame parser + +--- + pat.c | 1 + + remux.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 82 insertions(+), 3 deletions(-) + +--- a/pat.c ++++ b/pat.c +@@ -440,6 +440,7 @@ + case 1: // STREAMTYPE_11172_VIDEO + case 2: // STREAMTYPE_13818_VIDEO + case 0x1B: // H.264 ++ case 0x24: // H.265 + Vpid = esPid; + Ppid = pmt.getPCRPid(); + Vtype = stream.getStreamType(); +--- a/remux.c ++++ b/remux.c +@@ -708,6 +708,7 @@ + case 0x01: // STREAMTYPE_11172_VIDEO + case 0x02: // STREAMTYPE_13818_VIDEO + case 0x1B: // H.264 ++ case 0x24: // H.265 + vpid = stream.getPid(); + vtype = stream.getStreamType(); + ppid = Pmt.getPCRPid(); +@@ -1204,16 +1205,16 @@ + nutSequenceParameterSet = 7, + nutAccessUnitDelimiter = 9, + }; +- cTsPayload tsPayload; + uchar byte; // holds the current byte value in case of bitwise access + int bit; // the bit index into the current byte (-1 if we're not in bit reading mode) + int zeroBytes; // the number of consecutive zero bytes (to detect 0x000003) +- uint32_t scanner; + // Identifiers written in '_' notation as in "ITU-T H.264": + bool separate_colour_plane_flag; + int log2_max_frame_num; + bool frame_mbs_only_flag; +- // ++protected: ++ cTsPayload tsPayload; ++ uint32_t scanner; + bool gotAccessUnitDelimiter; + bool gotSequenceParameterSet; + uchar GetByte(bool Raw = false); +@@ -1430,6 +1431,81 @@ + } + } + ++// --- cH265Parser ----------------------------------------------------------- ++ ++class cH265Parser : public cH264Parser { ++private: ++ enum eNalUnitType { ++ nutSliceSegmentTrailingN = 0, ++ nutSliceSegmentTrailingR = 1, ++ nutSliceSegmentTSAN = 2, ++ nutSliceSegmentTSAR = 3, ++ nutSliceSegmentSTSAN = 4, ++ nutSliceSegmentSTSAR = 5, ++ nutSliceSegmentRADLN = 6, ++ nutSliceSegmentRADLR = 7, ++ nutSliceSegmentRASLN = 8, ++ nutSliceSegmentRASLR = 9, ++ nutSliceSegmentBLAWLP = 16, ++ nutSliceSegmentBLAWRADL = 17, ++ nutSliceSegmentBLANLP = 18, ++ nutSliceSegmentIDRWRADL = 19, ++ nutSliceSegmentIDRNLP = 20, ++ nutSliceSegmentCRANUT = 21, ++ nutVideoParameterSet = 32, ++ nutSequenceParameterSet = 33, ++ nutPictureParameterSet = 34, ++ nutAccessUnitDelimiter = 35, ++ nutEndOfSequence = 36, ++ nutEndOfBitstream = 37, ++ nutFillerData = 38, ++ nutPrefixSEI = 39, ++ nutSuffixSEI = 40, ++ nutNonVCLRes0 = 41, ++ nutNonVCLRes3 = 44, ++ nutUnspecified0 = 48, ++ nutUnspecified7 = 55, ++ }; ++public: ++ cH265Parser(void); ++ virtual int Parse(const uchar *Data, int Length, int Pid); ++ }; ++ ++cH265Parser::cH265Parser(void) : ++ cH264Parser() ++{ ++} ++ ++int cH265Parser::Parse(const uchar *Data, int Length, int Pid) ++{ ++ newFrame = independentFrame = false; ++ tsPayload.Setup(const_cast(Data), Length, Pid); ++ if (TsPayloadStart(Data)) { ++ tsPayload.SkipPesHeader(); ++ scanner = EMPTY_SCANNER; ++ } ++ for (;;) { ++ scanner = (scanner << 8) | GetByte(true); ++ if ((scanner & 0xFFFFFF00) == 0x00000100) { // NAL unit start ++ uchar NalUnitType = (scanner >> 1) & 0x3F; ++ GetByte(); // nuh_layer_id + nuh_temporal_id_plus1 ++ if (NalUnitType <= nutSliceSegmentRASLR || (NalUnitType >= nutSliceSegmentBLAWLP && NalUnitType <= nutSliceSegmentCRANUT)) { ++ if (NalUnitType == nutSliceSegmentIDRWRADL || NalUnitType == nutSliceSegmentIDRNLP || NalUnitType == nutSliceSegmentCRANUT) ++ independentFrame = true; ++ if (GetBit()) { // first_slice_segment_in_pic_flag ++ newFrame = true; ++ tsPayload.Statistics(); ++ } ++ break; ++ } ++ } ++ if (tsPayload.AtPayloadStart() // stop at any new payload start to have the buffer refilled if necessary ++ || tsPayload.Eof()) // or if we're out of data ++ break; ++ } ++ return tsPayload.Used(); ++} ++ + // --- cFrameDetector -------------------------------------------------------- + + cFrameDetector::cFrameDetector(int Pid, int Type) +@@ -1463,6 +1539,8 @@ + parser = new cMpeg2Parser; + else if (type == 0x1B) + parser = new cH264Parser; ++ else if (type == 0x24) ++ parser = new cH265Parser; + else if (type == 0x04 || type == 0x06) // MPEG audio or AC3 audio + parser = new cAudioParser; + else if (type != 0) diff -Nru vdr-2.2.0/debian/patches/vdr-2.2.0-mutex-deadlock.patch vdr-2.2.0/debian/patches/vdr-2.2.0-mutex-deadlock.patch --- vdr-2.2.0/debian/patches/vdr-2.2.0-mutex-deadlock.patch 1970-01-01 00:00:00.000000000 +0000 +++ vdr-2.2.0/debian/patches/vdr-2.2.0-mutex-deadlock.patch 2016-06-05 13:20:51.000000000 +0000 @@ -0,0 +1,87 @@ +--- a/device.c ++++ b/device.c +@@ -1683,7 +1683,8 @@ + } + } + // Distribute the packet to all attached receivers: +- Lock(); ++ { ++ cMutexLock MutexLock(&mutexReceiver); + for (int i = 0; i < MAXRECEIVERS; i++) { + if (receiver[i] && receiver[i]->WantsPid(Pid)) { + if (DetachReceivers && cs && (!cs->IsActivating() || receiver[i]->Priority() >= LIVEPRIORITY)) { +@@ -1697,7 +1698,7 @@ + ChannelCamRelations.SetDecrypt(receiver[i]->ChannelID(), CamSlotNumber); + } + } +- Unlock(); ++ } + } + } + else +@@ -1739,6 +1740,8 @@ + return false; + } + #endif ++ bool breakout = false; ++ { + cMutexLock MutexLock(&mutexReceiver); + for (int i = 0; i < MAXRECEIVERS; i++) { + if (!receiver[i]) { +@@ -1754,16 +1757,23 @@ + Receiver->device = this; + receiver[i] = Receiver; + Unlock(); +- if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver +- camSlot->StartDecrypting(); +- startScrambleDetection = time(NULL); +- } +- Start(); +- return true; ++ breakout = true; ++ break; // leave mutexReceiver-block asap + } + } +- esyslog("ERROR: no free receiver slot!"); +- return false; ++ } ++ if (breakout) { ++ if (camSlot && Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver ++ camSlot->StartDecrypting(); ++ startScrambleDetection = time(NULL); ++ } ++ Start(); // has to be outside of mutexReceiver-block ++ return true; ++ } ++ else { ++ esyslog("ERROR: no free receiver slot!"); ++ return false; ++ } + } + + void cDevice::Detach(cReceiver *Receiver) +@@ -1773,6 +1783,7 @@ + if (!Receiver || Receiver->device != this) + return; + bool receiversLeft = false; ++ { + cMutexLock MutexLock(&mutexReceiver); + for (int i = 0; i < MAXRECEIVERS; i++) { + if (receiver[i] == Receiver) { +@@ -1787,6 +1798,7 @@ + else if (receiver[i]) + receiversLeft = true; + } ++ } // leave mutexReceiver-block asap + if (camSlot) { + if (Receiver->priority > MINPRIORITY) { // priority check to avoid an infinite loop with the CAM slot's caPidReceiver + camSlot->StartDecrypting(); +@@ -1795,7 +1807,7 @@ + } + } + if (!receiversLeft) +- Cancel(-1); ++ Cancel(-1); // has to be outside of mutexReceiver-block + } + + void cDevice::DetachAll(int Pid)