Ticket #2984: FindMPEG2Keyframes.diff
File FindMPEG2Keyframes.diff, 4.1 KB (added by , 19 years ago) |
---|
-
libs/libmythtv/dtvrecorder.h
66 71 QString _recording_type; 67 72 68 73 // used for scanning pes headers for keyframes 69 uint 74 uint32_t _header_pos; 70 75 int _first_keyframe; 71 76 unsigned long long _last_gop_seen; 72 77 unsigned long long _last_seq_seen; -
libs/libmythtv/dtvrecorder.cpp
13 13 #include "dtvrecorder.h" 14 14 #include "tv_rec.h" 15 15 16 #include <arpa/inet.h> 17 16 18 #define LOC QString("DTVRec(%1): ").arg(tvrec->GetCaptureCardNum()) 17 19 #define LOC_ERR QString("DTVRec(%1) Error: ").arg(tvrec->GetCaptureCardNum()) 18 20 … … 214 217 if (!tspacket->HasPayload()) // no payload to scan 215 218 return !haveBufferedData; 216 219 217 // if packet contains start of PES packet, start218 // looking for first byte of MPEG start code (3 bytes 0 0 1)219 // otherwise, pick up search where we left off.220 const bool payloadStart = tspacket->PayloadStart();221 _header_pos = (payloadStart) ? 0 : _header_pos;222 223 220 // Just make these local for efficiency reasons (gcc not so smart..) 224 221 const uint maxKFD = kMaxKeyFrameDistance; 225 222 bool hasFrame = false; … … 231 228 // 00 00 01 B8: group_start_code 232 229 // 00 00 01 B3: seq_start_code 233 230 // (there are others that we don't care about) 234 uint i = tspacket->AFCOffset(); 235 for (; i < TSPacket::SIZE; i++) 231 232 const unsigned char* pos = tspacket->data(); 233 const unsigned char* const end = pos + TSPacket::SIZE - 1; 234 pos += tspacket->AFCOffset(); 235 236 // If packet contains start of PES packet, start 237 // looking for first byte of MPEG start code (3 bytes 0 0 1) 238 // otherwise, check last 3 bytes of previous packet. 239 const bool payloadStart = tspacket->PayloadStart(); 240 241 if (!payloadStart) 236 242 { 237 const unsigned char k = tspacket->data()[i]; 238 if (0 == _header_pos) 239 _header_pos = (k == 0x00) ? 1 : 0; 240 else if (1 == _header_pos) 241 _header_pos = (k == 0x00) ? 2 : 0; 242 else if (2 == _header_pos) 243 _header_pos = (k == 0x00) ? 2 : ((k == 0x01) ? 3 : 0); 244 else if (3 == _header_pos) 243 int match = 0; 244 if (_header_pos << 8 == 0x00000100) // X 0 0 1 | K X X X 245 match = 3; 246 else if (!(_header_pos << 16) && pos[0] == 0x01) // X X 0 0 | 1 K X X 247 match = 2; 248 else if (!(_header_pos << 24) && !pos[0] && pos[1] == 0x01) // X X X 0 | 0 1 K X 249 match = 1; 250 251 if (match) 245 252 { 246 _header_pos = 0; 253 //VERBOSE(VB_RECORD, LOC + QString("Matched! %1 %2 %3%4%5%6").arg(match) 254 // .arg(_header_pos,0,16).arg(pos[0],2,16).arg(pos[1],2,16).arg(pos[2],2,16).arg(pos[3],2,16)); 255 pos += 3 - match; 256 goto startcode; 257 } 258 } 259 pos += 2; // two zeros 260 261 while (pos < end) 262 { 263 if (*pos > 0x01) 264 pos += 3; 265 else if (!(*pos)) 266 pos++; 267 else if (pos[-2] || pos[-1]) 268 pos += 3; 269 else 270 { 247 271 // At this point we have seen the start code 0 0 1 248 272 // the next byte will be the PES packet stream id. 249 const int stream_id = k; 273 ++pos; 274 startcode: 275 const int stream_id = *pos; 276 pos += 3; 277 // if it matched then skip it, else it's not 0x00 so skip it 250 278 if (PESStreamID::PictureStartCode == stream_id) 251 279 hasFrame = true; 252 280 else if (PESStreamID::GOPStartCode == stream_id) … … 261 289 } 262 290 } 263 291 } 292 // Save last 4 bytes for next time 293 unsigned long *last_word = (unsigned long *)(end - 3); 294 _header_pos = ntohl(*last_word); 264 295 265 296 if (hasFrame && !hasKeyFrame) 266 297 {