Ticket #2984: FindMPEG2Keyframes.diff

File FindMPEG2Keyframes.diff, 4.1 KB (added by gnome42@…, 19 years ago)

dtvrecorder patch

  • libs/libmythtv/dtvrecorder.h

     
    6671    QString _recording_type;
    6772
    6873    // used for scanning pes headers for keyframes
    69     uint      _header_pos;
     74    uint32_t  _header_pos;
    7075    int       _first_keyframe;
    7176    unsigned long long _last_gop_seen;
    7277    unsigned long long _last_seq_seen;
  • libs/libmythtv/dtvrecorder.cpp

     
    1313#include "dtvrecorder.h"
    1414#include "tv_rec.h"
    1515
     16#include <arpa/inet.h>
     17
    1618#define LOC QString("DTVRec(%1): ").arg(tvrec->GetCaptureCardNum())
    1719#define LOC_ERR QString("DTVRec(%1) Error: ").arg(tvrec->GetCaptureCardNum())
    1820
     
    214217    if (!tspacket->HasPayload()) // no payload to scan
    215218        return !haveBufferedData;
    216219
    217     // if packet contains start of PES packet, start
    218     // 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 
    223220    // Just make these local for efficiency reasons (gcc not so smart..)
    224221    const uint maxKFD = kMaxKeyFrameDistance;
    225222    bool hasFrame     = false;
     
    231228    //   00 00 01 B8: group_start_code
    232229    //   00 00 01 B3: seq_start_code
    233230    //   (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)
    236242    {
    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)
    245252        {
    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        {
    247271            // At this point we have seen the start code 0 0 1
    248272            // the next byte will be the PES packet stream id.
    249             const int stream_id = k;
     273            ++pos;
     274startcode:
     275            const int stream_id = *pos;
     276            pos += 3;
     277            // if it matched then skip it, else it's not 0x00 so skip it
    250278            if (PESStreamID::PictureStartCode == stream_id)
    251279                hasFrame = true;
    252280            else if (PESStreamID::GOPStartCode == stream_id)
     
    261289            }
    262290        }
    263291    }
     292    // Save last 4 bytes for next time
     293    unsigned long *last_word = (unsigned long *)(end - 3);
     294    _header_pos = ntohl(*last_word);
    264295
    265296    if (hasFrame && !hasKeyFrame)
    266297    {