Ticket #1356: dtvrecorder_patch

File dtvrecorder_patch, 5.4 KB (added by mark.goodman+mythtv@…, 18 years ago)

Patch to restore DTVRecorder::FindKeyframes? from 0.18.1

Line 
1--- /home/mythtv/work2/mythtv-0.19/libs/libmythtv/dtvrecorder.h 2005-12-14 07:54:48.000000000 -0800
2+++ libs/libmythtv/dtvrecorder.h        2006-02-20 18:22:59.000000000 -0800
3@@ -59,6 +59,7 @@
4     // used for scanning pes headers for keyframes
5     uint      _header_pos;
6     int       _first_keyframe;
7+    int       _position_within_gop_header;
8     unsigned long long _last_gop_seen;
9     unsigned long long _last_seq_seen;
10     unsigned long long _last_keyframe_seen;
11--- /home/mythtv/work2/mythtv-0.19/libs/libmythtv/dtvrecorder.cpp       2006-02-07 13:56:06.000000000 -0800
12+++ libs/libmythtv/dtvrecorder.cpp      2006-02-20 18:49:09.000000000 -0800
13@@ -37,6 +37,7 @@
14     _stream_fd(-1),
15     // used for scanning pes headers for keyframes
16     _header_pos(0),                 _first_keyframe(-1),
17+    _position_within_gop_header(0),
18     _last_gop_seen(0),              _last_seq_seen(0),
19     _last_keyframe_seen(0),
20     // settings
21@@ -126,6 +127,7 @@
22 
23     _header_pos                 = 0;
24     _first_keyframe             =-1;
25+    _position_within_gop_header = 0;
26     _last_keyframe_seen         = 0;
27     _last_gop_seen              = 0;
28     _last_seq_seen              = 0;
29@@ -195,6 +197,101 @@
30  */
31 bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
32 {
33+#define AVG_KEYFRAME_DIFF 16
34+#define MAX_KEYFRAME_DIFF 32
35+#define DEBUG_FIND_KEY_FRAMES 0 /* set to 1 to debug */
36+    bool haveBufferedData = !_payload_buffer.empty();
37+    bool hasKeyFrame = false;
38+    bool noPayload = !tspacket->HasPayload();
39+    bool payloadStart = tspacket->PayloadStart();
40+
41+    if (noPayload)
42+        return !haveBufferedData; // no payload to scan
43+
44+    if (payloadStart)
45+    { // packet contains start of PES packet
46+        _position_within_gop_header = 0; // start looking for first byte of pattern
47+    }
48+
49+    // Scan for PES header codes; specifically picture_start
50+    // and group_start (of_pictures).  These should be within
51+    // this first TS packet of the PES packet.
52+    //   00 00 01 00: picture_start_code
53+    //   00 00 01 B8: group_start_code
54+    //   00 00 01 B3: seq_start_code
55+    //   (there are others that we don't care about)
56+    long long frameSeenNum = _frames_seen_count;
57+    const unsigned char *buffer = tspacket->data();
58+    for (unsigned int i = tspacket->AFCOffset(); i+1<TSPacket::SIZE; i++)
59+    {
60+        const unsigned char k = buffer[i];
61+        if (0 == _position_within_gop_header)
62+            _position_within_gop_header = (k == 0x00) ? 1 : 0;
63+        else if (1 == _position_within_gop_header)
64+            _position_within_gop_header = (k == 0x00) ? 2 : 0;
65+        else
66+        {
67+            if (0x01 != k)
68+            {
69+                _position_within_gop_header = (k == 0x00) ? 2 : 0;
70+                continue;
71+            }
72+            const unsigned char k1 = buffer[i+1];
73+            if (0x00 == k1)
74+            {   //   00 00 01 00: picture_start_code
75+                _frames_written_count += (_first_keyframe > 0) ? 1 : 0;
76+                _frames_seen_count++;
77+                // We've seen 30 frames and no GOP or seq header? let's pretend we have them
78+                if ((0==(_frames_seen_count & 0xf)) &&
79+                    (_last_gop_seen+(MAX_KEYFRAME_DIFF+AVG_KEYFRAME_DIFF))<frameSeenNum &&
80+                    (_last_seq_seen+(MAX_KEYFRAME_DIFF+AVG_KEYFRAME_DIFF))<frameSeenNum) {
81+#if DEBUG_FIND_KEY_FRAMES
82+                    VERBOSE(VB_RECORD, QString("f16 sc(%1) wc(%2) lgop(%3) lseq(%4)").
83+                            arg(_frames_seen_count).arg(_frames_written_count).
84+                            arg(_last_gop_seen).arg(_last_seq_seen));
85+#endif
86+                    HandleKeyframe();
87+                   hasKeyFrame = true;
88+                    _last_keyframe_seen = frameSeenNum;
89+                }
90+            } else if (0xB8 == k1)
91+            {   //   00 00 01 B8: group_start_code
92+#if DEBUG_FIND_KEY_FRAMES
93+                VERBOSE(VB_RECORD, QString("GOP sc(%1) wc(%2) lgop(%3) lseq(%4)").
94+                        arg(_frames_seen_count).arg(_frames_written_count).
95+                        arg(_last_gop_seen).arg(_last_seq_seen));
96+#endif
97+                HandleKeyframe();
98+               hasKeyFrame = true;
99+                _last_keyframe_seen = _last_gop_seen = frameSeenNum;
100+            } else if (0xB3 == k1)
101+            {   //   00 00 01 B3: seq_start_code
102+                if ((_last_gop_seen+MAX_KEYFRAME_DIFF)<frameSeenNum)
103+                {
104+#if DEBUG_FIND_KEY_FRAMES
105+                    VERBOSE(VB_RECORD, QString("seq sc(%1) wc(%2) lgop(%3) lseq(%4)").
106+                        arg(_frames_seen_count).arg(_frames_written_count).
107+                        arg(_last_gop_seen).arg(_last_seq_seen));
108+#endif
109+                    HandleKeyframe();
110+                   hasKeyFrame = true;
111+                    _last_keyframe_seen = frameSeenNum;
112+                }
113+                _last_seq_seen = frameSeenNum;
114+            }
115+            _position_within_gop_header = 0;
116+        }
117+    }
118+#undef AVG_KEYFRAME_DIFF
119+#undef MAX_KEYFRAME_DIFF
120+#undef DEBUG_FIND_KEY_FRAMES
121+
122+    return hasKeyFrame || (_payload_buffer.size() >= (188*50));
123+}
124+
125+/*
126+bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
127+{
128     bool haveBufferedData = !_payload_buffer.empty();
129     if (!tspacket->HasPayload()) // no payload to scan
130         return !haveBufferedData;
131@@ -273,6 +370,7 @@
132 
133     return hasKeyFrame || (_payload_buffer.size() >= (188*50));
134 }
135+*/
136 
137 // documented in recorderbase.h
138 void DTVRecorder::SetNextRecording(const ProgramInfo *progInf, RingBuffer *rb)