Ticket #4622: zero_copy_mpeg_streams.diff

File zero_copy_mpeg_streams.diff, 19.9 KB (added by bradley.kite@…, 16 years ago)

Reduces copying of tspackets on the stack.

  • libs/libmythtv/dvbrecorder.cpp

     
    181181    {
    182182        uint next_cc = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    183183        pat->tsheader()->SetContinuityCounter(next_cc);
    184         BufferedWrite(*(reinterpret_cast<TSPacket*>(pat->tsheader())));
     184        BufferedWrite(reinterpret_cast<TSPacket*>(pat->tsheader()));
    185185    }
    186186
    187187    uint posB[2] = { ringBuffer->GetWritePosition(), _payload_buffer.size() };
     
    221221    uint posA[2] = { ringBuffer->GetWritePosition(), _payload_buffer.size() };
    222222
    223223    for (uint i = 0; i < size ; i += TSPacket::SIZE)
    224         BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i])));
     224        BufferedWrite(reinterpret_cast<TSPacket*>(&buf[i]));
    225225
    226226    uint posB[2] = { ringBuffer->GetWritePosition(), _payload_buffer.size() };
    227227
     
    475475    return paused;
    476476}
    477477
    478 bool DVBRecorder::ProcessVideoTSPacket(const TSPacket &tspacket)
     478bool DVBRecorder::ProcessVideoTSPacket(const TSPacket *tspacket)
    479479{
    480     uint streamType = _stream_id[tspacket.PID()];
     480    uint streamType = _stream_id[tspacket->PID()];
    481481
    482482    // Check for keyframes and count frames
    483483    if (streamType == StreamID::H264Video)
    484484    {
    485         _buffer_packets = !FindH264Keyframes(&tspacket);
     485        _buffer_packets = !FindH264Keyframes(tspacket);
    486486        if (!_seen_sps)
    487487            return true;
    488488    }
    489489    else
    490490    {
    491         _buffer_packets = !FindMPEG2Keyframes(&tspacket);
     491        _buffer_packets = !FindMPEG2Keyframes(tspacket);
    492492    }
    493493
    494494    return ProcessTSPacket(tspacket);
    495495}
    496496
    497 bool DVBRecorder::ProcessAudioTSPacket(const TSPacket &tspacket)
     497bool DVBRecorder::ProcessAudioTSPacket(const TSPacket *tspacket)
    498498{
    499     _buffer_packets = !FindAudioKeyframes(&tspacket);
     499    _buffer_packets = !FindAudioKeyframes(tspacket);
    500500    return ProcessTSPacket(tspacket);
    501501}
    502502
    503 bool DVBRecorder::ProcessTSPacket(const TSPacket &tspacket)
     503bool DVBRecorder::ProcessTSPacket(const TSPacket *tspacket)
    504504{
    505     const uint pid = tspacket.PID();
     505    const uint pid = tspacket->PID();
    506506
    507507    // Check continuity counter
    508     if ((pid != 0x1fff) && !CheckCC(pid, tspacket.ContinuityCounter()))
     508    if ((pid != 0x1fff) && !CheckCC(pid, tspacket->ContinuityCounter()))
    509509    {
    510510        VERBOSE(VB_RECORD, LOC +
    511511                QString("PID 0x%1 discontinuity detected").arg(pid,0,16));
     
    518518
    519519    // Sync streams to the first Payload Unit Start Indicator
    520520    // _after_ first keyframe iff _wait_for_keyframe_option is true
    521     if (!(_pid_status[pid] & kPayloadStartSeen) && tspacket.HasPayload())
     521    if (!(_pid_status[pid] & kPayloadStartSeen) && tspacket->HasPayload())
    522522    {
    523         if (!tspacket.PayloadStart())
     523        if (!tspacket->PayloadStart())
    524524            return true; // not payload start - drop packet
    525525
    526526        VERBOSE(VB_RECORD,
  • libs/libmythtv/dvbrecorder.h

     
    8484    void HandleSDT(uint /*tsid*/, const ServiceDescriptionTable*) {}
    8585
    8686    // TSPacketListener
    87     bool ProcessTSPacket(const TSPacket& tspacket);
     87    bool ProcessTSPacket(const TSPacket* tspacket);
    8888
    8989    // TSPacketListenerAV
    90     bool ProcessVideoTSPacket(const TSPacket& tspacket);
    91     bool ProcessAudioTSPacket(const TSPacket& tspacket);
     90    bool ProcessVideoTSPacket(const TSPacket* tspacket);
     91    bool ProcessAudioTSPacket(const TSPacket* tspacket);
    9292
    9393    void SetStreamData(MPEGStreamData*);
    9494    MPEGStreamData* GetStreamData(void) { return _stream_data; }
  • libs/libmythtv/hdhrrecorder.h

     
    6464    bool AdjustEITPIDs(void);
    6565
    6666    void ProcessTSData(const unsigned char *buffer, int len);
    67     bool ProcessTSPacket(const TSPacket& tspacket);
     67    bool ProcessTSPacket(const TSPacket* tspacket);
    6868    void TeardownAll(void);
    6969   
    7070  private:
  • libs/libmythtv/hdhrrecorder.cpp

     
    153153            return;
    154154        }
    155155
    156         const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(data);
    157         ProcessTSPacket(*tspacket);
     156        ProcessTSPacket(reinterpret_cast<const TSPacket*>(data));
    158157
    159158        data += 188;
    160159    }
     
    242241
    243242    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    244243    pat->tsheader()->SetContinuityCounter(next);
    245     BufferedWrite(*(reinterpret_cast<TSPacket*>(pat->tsheader())));
     244    BufferedWrite(reinterpret_cast<TSPacket*>(pat->tsheader()));
    246245}
    247246
    248247void HDHRRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
     
    252251
    253252    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
    254253    pmt->tsheader()->SetContinuityCounter(next);
    255     BufferedWrite(*(reinterpret_cast<TSPacket*>(pmt->tsheader())));
     254    BufferedWrite(reinterpret_cast<TSPacket*>(pmt->tsheader()));
    256255}
    257256
    258257/** \fn HDHRRecorder::HandleMGT(const MasterGuideTable*)
     
    272271}
    273272*/
    274273
    275 bool HDHRRecorder::ProcessTSPacket(const TSPacket& tspacket)
     274bool HDHRRecorder::ProcessTSPacket(const TSPacket* tspacket)
    276275{
    277     bool ok = !tspacket.TransportError();
    278     if (ok && !tspacket.ScramplingControl())
     276    bool ok = !tspacket->TransportError();
     277    if (ok && !tspacket->ScramplingControl())
    279278    {
    280         if (tspacket.HasAdaptationField())
    281             GetStreamData()->HandleAdaptationFieldControl(&tspacket);
    282         if (tspacket.HasPayload())
     279        if (tspacket->HasAdaptationField())
     280            GetStreamData()->HandleAdaptationFieldControl(tspacket);
     281        if (tspacket->HasPayload())
    283282        {
    284             const unsigned int lpid = tspacket.PID();
     283            const unsigned int lpid = tspacket->PID();
    285284
    286285            if ((GetStreamData()->VideoPIDSingleProgram() > 0x1fff) &&
    287286                _wait_for_keyframe_option)
     
    293292            if (lpid == GetStreamData()->VideoPIDSingleProgram())
    294293            {
    295294                //cerr<<"v";
    296                 _buffer_packets = !FindMPEG2Keyframes(&tspacket);
     295                _buffer_packets = !FindMPEG2Keyframes(tspacket);
    297296                BufferedWrite(tspacket);
    298297            }
    299298            else if (GetStreamData()->IsAudioPID(lpid))
    300299            {
    301300                //cerr<<"a";
    302                 _buffer_packets = !FindAudioKeyframes(&tspacket);
     301                _buffer_packets = !FindAudioKeyframes(tspacket);
    303302                BufferedWrite(tspacket);
    304303            }
    305304            else if (GetStreamData()->IsListeningPID(lpid))
    306305            {
    307306                //cerr<<"t";
    308                 GetStreamData()->HandleTSTables(&tspacket);
     307                GetStreamData()->HandleTSTables(tspacket);
    309308            }
    310309            else if (GetStreamData()->IsWritingPID(lpid))
    311310                BufferedWrite(tspacket);
  • libs/libmythtv/dtvrecorder.h

     
    5353
    5454    void HandleKeyframe();
    5555
    56     void BufferedWrite(const TSPacket &tspacket);
     56    void BufferedWrite(const TSPacket *tspacket);
    5757
    5858    // MPEG "audio only" support
    5959    bool FindAudioKeyframes(const TSPacket *tspacket);
  • libs/libmythtv/firewirerecorder.cpp

     
    9090        if (bufsz)
    9191            buffer.clear();
    9292
    93         ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(data)));
     93        ProcessTSPacket(reinterpret_cast<const TSPacket*>(data));
    9494        return;
    9595    }
    9696
     
    112112
    113113    while (sync_at + TSPacket::SIZE < bufsz)
    114114    {
    115         ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(
    116                               &buffer[0] + sync_at)));
     115        ProcessTSPacket(reinterpret_cast<const TSPacket*>(
     116                              &buffer[0] + sync_at));
    117117
    118118        sync_at += TSPacket::SIZE;
    119119    }
     
    123123    return;
    124124}
    125125
    126 void FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket)
     126void FirewireRecorder::ProcessTSPacket(const TSPacket *tspacket)
    127127{
    128     if (tspacket.TransportError())
     128    if (tspacket->TransportError())
    129129        return;
    130130
    131     if (tspacket.ScramplingControl())
     131    if (tspacket->ScramplingControl())
    132132        return;
    133133
    134     if (tspacket.HasAdaptationField())
    135         GetStreamData()->HandleAdaptationFieldControl(&tspacket);
     134    if (tspacket->HasAdaptationField())
     135        GetStreamData()->HandleAdaptationFieldControl(tspacket);
    136136
    137     if (tspacket.HasPayload())
     137    if (tspacket->HasPayload())
    138138    {
    139         const unsigned int lpid = tspacket.PID();
     139        const unsigned int lpid = tspacket->PID();
    140140
    141141        // Pass or reject packets based on PID, and parse info from them
    142142        if (lpid == GetStreamData()->VideoPIDSingleProgram())
    143143        {
    144             _buffer_packets = !FindMPEG2Keyframes(&tspacket);
     144            _buffer_packets = !FindMPEG2Keyframes(tspacket);
    145145            BufferedWrite(tspacket);
    146146        }
    147147        else if (GetStreamData()->IsAudioPID(lpid))
    148148        {
    149             _buffer_packets = !FindAudioKeyframes(&tspacket);
     149            _buffer_packets = !FindAudioKeyframes(tspacket);
    150150            BufferedWrite(tspacket);
    151151        }
    152152        else if (GetStreamData()->IsListeningPID(lpid))
    153             GetStreamData()->HandleTSTables(&tspacket);
     153            GetStreamData()->HandleTSTables(tspacket);
    154154        else if (GetStreamData()->IsWritingPID(lpid))
    155155            BufferedWrite(tspacket);
    156156    }
     
    218218
    219219    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    220220    pat->tsheader()->SetContinuityCounter(next);
    221     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader())));
     221    BufferedWrite(reinterpret_cast<const TSPacket*>(pat->tsheader()));
    222222}
    223223
    224224void FirewireRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
     
    228228
    229229    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
    230230    pmt->tsheader()->SetContinuityCounter(next);
    231     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader())));
     231    BufferedWrite(reinterpret_cast<const TSPacket*>(pmt->tsheader()));
    232232}
  • libs/libmythtv/dtvrecorder.cpp

     
    175175        curRecording->ClearPositionMap(MARK_GOP_BYFRAME);
    176176}
    177177
    178 void DTVRecorder::BufferedWrite(const TSPacket &tspacket)
     178void DTVRecorder::BufferedWrite(const TSPacket *tspacket)
    179179{
    180180    // delay until first GOP to avoid decoder crash on res change
    181181    if (_wait_for_keyframe_option && _first_keyframe<0)
     
    186186    {
    187187        int idx = _payload_buffer.size();
    188188        _payload_buffer.resize(idx + TSPacket::SIZE);
    189         memcpy(&_payload_buffer[idx], tspacket.data(), TSPacket::SIZE);
     189        memcpy(&_payload_buffer[idx], tspacket->data(), TSPacket::SIZE);
    190190        return;
    191191    }
    192192
     
    200200    }
    201201
    202202    if (ringBuffer)
    203         ringBuffer->Write(tspacket.data(), TSPacket::SIZE);
     203        ringBuffer->Write(tspacket->data(), TSPacket::SIZE);
    204204}
    205205
    206206/** \fn DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket)
  • libs/libmythtv/firewirerecorder.h

     
    4343    bool PauseAndWait(int timeout = 100);
    4444
    4545    void AddData(const unsigned char *data, uint dataSize);
    46     void ProcessTSPacket(const TSPacket &tspacket);
     46    void ProcessTSPacket(const TSPacket *tspacket);
    4747
    4848    // Sets
    4949    void SetOptionsFromProfile(RecordingProfile *profile,
  • libs/libmythtv/mpeg/mpegstreamdata.cpp

     
    935935        }
    936936
    937937        const TSPacket *pkt = reinterpret_cast<const TSPacket*>(&buffer[pos]);
    938         if (ProcessTSPacket(*pkt))
     938        if (ProcessTSPacket(pkt))
    939939            pos += TSPacket::SIZE; // Advance to next TS packet
    940940        else // Let it resync in case of dropped bytes
    941941            buffer[pos] = SYNC_BYTE + 1;
     
    944944    return len - pos;
    945945}
    946946
    947 bool MPEGStreamData::ProcessTSPacket(const TSPacket& tspacket)
     947bool MPEGStreamData::ProcessTSPacket(const TSPacket* tspacket)
    948948{
    949     bool ok = !tspacket.TransportError();
     949    bool ok = !tspacket->TransportError();
    950950
    951     if (IsEncryptionTestPID(tspacket.PID()))
     951    if (IsEncryptionTestPID(tspacket->PID()))
    952952    {
    953953        ProcessEncryptedPacket(tspacket);
    954954    }
     
    956956    if (!ok)
    957957        return false;
    958958
    959     if (!tspacket.ScramplingControl() && tspacket.HasPayload())
     959    if (!tspacket->ScramplingControl() && tspacket->HasPayload())
    960960    {
    961         if (IsVideoPID(tspacket.PID()))
     961        if (IsVideoPID(tspacket->PID()))
    962962        {
    963963            for (uint j = 0; j < _ts_av_listeners.size(); j++)
    964964                _ts_av_listeners[j]->ProcessVideoTSPacket(tspacket);
     
    966966            return true;
    967967        }
    968968
    969         if (IsAudioPID(tspacket.PID()))
     969        if (IsAudioPID(tspacket->PID()))
    970970        {
    971971            for (uint j = 0; j < _ts_av_listeners.size(); j++)
    972972                _ts_av_listeners[j]->ProcessAudioTSPacket(tspacket);
     
    974974            return true;
    975975        }
    976976
    977         if (IsWritingPID(tspacket.PID()) && _ts_writing_listeners.size())
     977        if (IsWritingPID(tspacket->PID()) && _ts_writing_listeners.size())
    978978        {
    979979            for (uint j = 0; j < _ts_writing_listeners.size(); j++)
    980980                _ts_writing_listeners[j]->ProcessTSPacket(tspacket);
    981981        }
    982982
    983         if (IsListeningPID(tspacket.PID()))
     983        if (IsListeningPID(tspacket->PID()))
    984984        {
    985             HandleTSTables(&tspacket);
     985            HandleTSTables(tspacket);
    986986        }
    987987    }
    988988
     
    16661666/** \fn MPEGStreamData::ProcessEncryptedPacket(const TSPacket& tspacket)
    16671667 *  \brief counts en/decrypted packets to decide if a stream is en/decrypted
    16681668 */
    1669 void MPEGStreamData::ProcessEncryptedPacket(const TSPacket& tspacket)
     1669void MPEGStreamData::ProcessEncryptedPacket(const TSPacket* tspacket)
    16701670{
    16711671    QMutexLocker locker(&_encryption_lock);
    16721672
    1673     const uint pid = tspacket.PID();
     1673    const uint pid = tspacket->PID();
    16741674    CryptInfo &info = _encryption_pid_to_info[pid];
    16751675
    16761676    CryptStatus status = kEncUnknown;
    16771677
    1678     if (tspacket.ScramplingControl())
     1678    if (tspacket->ScramplingControl())
    16791679    {
    16801680        info.decrypted_packets = 0;
    16811681
  • libs/libmythtv/mpeg/streamlisteners.h

     
    4949class TSPacketListener
    5050{
    5151  public:
    52     virtual bool ProcessTSPacket(const TSPacket& tspacket) = 0;
     52    virtual bool ProcessTSPacket(const TSPacket* tspacket) = 0;
    5353
    5454  protected:
    5555    virtual ~TSPacketListener() { }
     
    5858class TSPacketListenerAV
    5959{
    6060  public:
    61     virtual bool ProcessVideoTSPacket(const TSPacket& tspacket) = 0;
    62     virtual bool ProcessAudioTSPacket(const TSPacket& tspacket) = 0;
     61    virtual bool ProcessVideoTSPacket(const TSPacket* tspacket) = 0;
     62    virtual bool ProcessAudioTSPacket(const TSPacket* tspacket) = 0;
    6363
    6464  protected:
    6565    virtual ~TSPacketListenerAV() { }
  • libs/libmythtv/mpeg/mpegstreamdata.h

     
    106106    virtual bool IsRedundant(uint pid, const PSIPTable&) const;
    107107    virtual bool HandleTables(uint pid, const PSIPTable &psip);
    108108    virtual void HandleTSTables(const TSPacket* tspacket);
    109     virtual bool ProcessTSPacket(const TSPacket& tspacket);
     109    virtual bool ProcessTSPacket(const TSPacket* tspacket);
    110110    virtual int  ProcessData(unsigned char *buffer, int len);
    111111    inline  void HandleAdaptationFieldControl(const TSPacket* tspacket);
    112112
     
    291291    void DeletePartialPES(uint pid);
    292292    void ProcessPAT(const ProgramAssociationTable *pat);
    293293    void ProcessPMT(const ProgramMapTable *pmt);
    294     void ProcessEncryptedPacket(const TSPacket&);
     294    void ProcessEncryptedPacket(const TSPacket*);
    295295
    296296    static int ResyncStream(unsigned char *buffer, int curr_pos, int len);
    297297
  • libs/libmythtv/iptvrecorder.cpp

     
    193193
    194194        // Cast current found TS Packet to TSPacket structure
    195195        const void *newData = data + tsPos + readIndex;
    196         ProcessTSPacket(*reinterpret_cast<const TSPacket*>(newData));
     196        ProcessTSPacket(reinterpret_cast<const TSPacket*>(newData));
    197197
    198198        // follow to next packet
    199199        readIndex += tsPos + TSPacket::SIZE;
    200200    }
    201201}
    202202
    203 void IPTVRecorder::ProcessTSPacket(const TSPacket& tspacket)
     203void IPTVRecorder::ProcessTSPacket(const TSPacket* tspacket)
    204204{
    205205    if (!_stream_data)
    206206        return;
    207207
    208     if (tspacket.TransportError() || tspacket.ScramplingControl())
     208    if (tspacket->TransportError() || tspacket->ScramplingControl())
    209209        return;
    210210
    211     if (tspacket.HasAdaptationField())
    212         _stream_data->HandleAdaptationFieldControl(&tspacket);
     211    if (tspacket->HasAdaptationField())
     212        _stream_data->HandleAdaptationFieldControl(tspacket);
    213213
    214     if (tspacket.HasPayload())
     214    if (tspacket->HasPayload())
    215215    {
    216         const unsigned int lpid = tspacket.PID();
     216        const unsigned int lpid = tspacket->PID();
    217217
    218218        // Pass or reject packets based on PID, and parse info from them
    219219        if (lpid == _stream_data->VideoPIDSingleProgram())
     
    222222            uint video_stream_type = pmt->StreamType(pmt->FindPID(lpid));
    223223
    224224            if (video_stream_type == StreamID::H264Video)
    225                 _buffer_packets = !FindH264Keyframes(&tspacket);
     225                _buffer_packets = !FindH264Keyframes(tspacket);
    226226            else if (StreamID::IsVideo(video_stream_type))
    227                 _buffer_packets = !FindMPEG2Keyframes(&tspacket);
     227                _buffer_packets = !FindMPEG2Keyframes(tspacket);
    228228
    229229            if ((video_stream_type != StreamID::H264Video) || _seen_sps)
    230230                BufferedWrite(tspacket);           
    231231        }
    232232        else if (_stream_data->IsAudioPID(lpid))
    233233        {
    234             _buffer_packets = !FindAudioKeyframes(&tspacket);
     234            _buffer_packets = !FindAudioKeyframes(tspacket);
    235235            BufferedWrite(tspacket);
    236236        }
    237237        else if (_stream_data->IsListeningPID(lpid))
    238             _stream_data->HandleTSTables(&tspacket);
     238            _stream_data->HandleTSTables(tspacket);
    239239        else if (_stream_data->IsWritingPID(lpid))
    240240            BufferedWrite(tspacket);
    241241    }
     
    270270
    271271    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    272272    pat->tsheader()->SetContinuityCounter(next);
    273     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader())));
     273    BufferedWrite(reinterpret_cast<const TSPacket*>(pat->tsheader()));
    274274}
    275275
    276276void IPTVRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
     
    280280
    281281    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
    282282    pmt->tsheader()->SetContinuityCounter(next);
    283     BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader())));
     283    BufferedWrite(reinterpret_cast<const TSPacket*>(pmt->tsheader()));
    284284}
    285285
    286286/* vim: set expandtab tabstop=4 shiftwidth=4: */