Ticket #1356: dtvrecorder_patch

File dtvrecorder_patch, 5.4 KB (added by mark.goodman+mythtv@…, 20 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)