Ticket #11328: H264-keep-first-keyframe.patch

File H264-keep-first-keyframe.patch, 3.8 KB (added by jpoet, 14 years ago)

First cut

  • mythtv/libs/libmythtv/recorders/dtvrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
    index 0c30b10..0b438cd 100644
    a b void DTVRecorder::InitStreamData(void)  
    277277void DTVRecorder::BufferedWrite(const TSPacket &tspacket)
    278278{
    279279    // delay until first GOP to avoid decoder crash on res change
    280     if (_wait_for_keyframe_option && _first_keyframe<0)
     280    if (!_buffer_packets && _wait_for_keyframe_option && _first_keyframe<0)
    281281        return;
    282282
    283283    if (curRecording && timeOfFirstDataIsSet.testAndSetRelaxed(0,1))
    void DTVRecorder::HandleKeyframe(uint64_t frameNum, int64_t extra)  
    762762 */
    763763bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
    764764{
     765    bool haveBufferedData = !_payload_buffer.empty();
     766
     767    if (!tspacket->HasPayload()) // no payload to scan
     768        return !haveBufferedData;
     769
    765770    if (!ringBuffer)
    766771    {
    767772        LOG(VB_GENERAL, LOG_ERR, LOC + "FindH264Keyframes: No ringbuffer");
    768         return false;
    769     }
    770 
    771     bool haveBufferedData = !_payload_buffer.empty();
    772     if (!tspacket->HasPayload()) // no payload to scan
    773773        return !haveBufferedData;
     774    }
    774775
    775776    const bool payloadStart = tspacket->PayloadStart();
    776777    if (payloadStart)
    bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)  
    789790    bool hasKeyFrame = false;
    790791
    791792    // scan for PES packets and H.264 NAL units
    792     uint i = tspacket->AFCOffset();
    793     for (; i < TSPacket::kSize; i++)
     793    const uint pid = tspacket->PID();
     794    uint         i = tspacket->AFCOffset();
     795
     796    for (; i < TSPacket::kSize; ++i)
    794797    {
    795798        // special handling required when a new PES packet begins
    796799        if (payloadStart && !_pes_synced)
    bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)  
    879882                frameRate = m_h264_parser.frameRate();
    880883            }
    881884        }
    882     } // for (; i < TSPacket::kSize; i++)
     885    } // for (; i < TSPacket::kSize; ++i)
     886
     887    if (!(_pid_status[pid] & kPayloadStartSeen) && tspacket->HasPayload())
     888    {
     889        if (tspacket->PayloadStart())
     890        {
     891            LOG(VB_RECORD, LOG_INFO, LOC +
     892                QString("PID 0x%1 Found Payload Start").arg(pid,0,16));
     893
     894            _pid_status[pid] |= kPayloadStartSeen;
     895        }
     896    }
    883897
    884898    if (hasKeyFrame)
    885899    {
    bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)  
    892906        _frames_seen_count++;
    893907        if (!_wait_for_keyframe_option || _first_keyframe >= 0)
    894908            UpdateFramesWritten();
     909        else
     910        {
     911            /* Found a frame that is not a keyframe, and we want to
     912             * start on a keyframe. */
     913            _pid_status[pid] &= 0;
     914            _payload_buffer.clear();
     915        }
    895916    }
    896917
    897918    if ((aspectRatio > 0) && (aspectRatio != m_videoAspect))
    bool DTVRecorder::ProcessVideoTSPacket(const TSPacket &tspacket)  
    12871308    // Check for keyframes and count frames
    12881309    if (streamType == StreamID::H264Video)
    12891310    {
    1290         _buffer_packets = !FindH264Keyframes(&tspacket);
    1291         if (_wait_for_keyframe_option && !_seen_sps)
     1311        _buffer_packets = !FindH264Keyframes(&tspacket) &&
     1312                          (_pid_status[tspacket.PID()] & kPayloadStartSeen);
     1313        if (!_buffer_packets && _wait_for_keyframe_option && !_seen_sps)
    12921314            return true;
    12931315    }
    12941316    else
    bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket)  
    13291351    }
    13301352
    13311353    // Sync recording start to first keyframe
    1332     if (_wait_for_keyframe_option && _first_keyframe < 0)
     1354    if (!_buffer_packets && _wait_for_keyframe_option && _first_keyframe < 0)
    13331355        return true;
    13341356
    13351357    // Sync streams to the first Payload Unit Start Indicator