예제 #1
0
    void H264Packetizer::pushBuffer(const uint8_t* const inBuffer, size_t inSize, IMetadata& inMetadata)
    {
        
      
      
        
        std::vector<uint8_t>& outBuffer = m_outbuffer;
        
        outBuffer.clear();
        
        uint8_t nal_type = inBuffer[4] & 0x1F;
        int flags = 0;
        const int flags_size = 5;
        const int ts = inMetadata.timestampDelta;

        bool is_config = (nal_type == 7 || nal_type == 8);
        
        
        flags = FLV_CODECID_H264;
        auto output = m_output.lock();
        RTMPMetadata_t outMeta(inMetadata.timestampDelta);

        switch(nal_type) {
            case 7:
                if(m_sps.size() == 0) {
                    m_sps.resize(inSize-4);
                    memcpy(&m_sps[0], inBuffer+4, inSize-4);
                    
                }
                return;
            case 8:
                if(m_pps.size() == 0) {
                    m_pps.resize(inSize-4);
                    memcpy(&m_pps[0], inBuffer+4, inSize-4);
                }

                flags |= FLV_FRAME_KEY;
                break;
            case 5:
                flags |= FLV_FRAME_KEY;
                
                break;
            default:
                flags |= FLV_FRAME_INTER;
                
                
                break;
                
        }
        
        if(output) {
            std::vector<uint8_t> conf;
            
            if(is_config && m_sps.size() > 0 && m_pps.size() > 0 ) {
                conf = configurationFromSpsAndPps();
                inSize = conf.size();
            }
            outBuffer.reserve(inSize + flags_size);
            
            put_byte(outBuffer, flags);
            put_byte(outBuffer, !is_config);
            put_be24(outBuffer, 0);
            
            if(is_config) {
                // create modified SPS/PPS buffer
                if(m_sps.size() > 0 && m_pps.size() > 0 && !m_sentConfig) {
                    put_buff(outBuffer, &conf[0], conf.size());
                    m_sentConfig = true;
                } else {
                    return;
                }
            } else {
                put_buff(outBuffer, inBuffer, inSize);
            }
            
            static auto prev_time = std::chrono::steady_clock::now();
            auto now = std::chrono::steady_clock::now();
            
            auto m_micros = std::chrono::duration_cast<std::chrono::microseconds>(now - prev_time).count();
            static uint64_t total = 0;
            static uint64_t count = 0;
            
            total+=m_micros;
            count++;
            
            prev_time = now;
            outMeta.setData(ts, static_cast<int>(outBuffer.size()), FLV_TAG_TYPE_VIDEO, kVideoChannelStreamId);
            
            output->pushBuffer(&outBuffer[0], outBuffer.size(), outMeta);
        }
        
    }
예제 #2
0
    void H264Packetizer::pushBuffer(const uint8_t* const inBuffer, size_t inSize, IMetadata& inMetadata)
    {
        std::vector<uint8_t>& outBuffer = m_outbuffer;
        
        outBuffer.clear();
        
        uint8_t nal_type = inBuffer[4] & 0x1F;
        int flags = 0;
        const int flags_size = 5;
        int dts = inMetadata.dts ;
        int pts = inMetadata.pts + m_ctsOffset; // correct for pts < dts which some players (ffmpeg) don't like
        
        dts = dts > 0 ? dts : pts - m_ctsOffset ;
        
        bool is_config = (nal_type == 7 || nal_type == 8);
        
        flags = FLV_CODECID_H264;
        auto output = m_output.lock();

        switch(nal_type) {
            case 7:
                if(m_sps.size() == 0) {
                    m_sps.resize(inSize-4);
                    memcpy(&m_sps[0], inBuffer+4, inSize-4);
                }
                break;
            case 8:
                if(m_pps.size() == 0) {
                    m_pps.resize(inSize-4);
                    memcpy(&m_pps[0], inBuffer+4, inSize-4);
                }
                flags |= FLV_FRAME_KEY;
                break;
            case 5:
                flags |= FLV_FRAME_KEY;
                
                break;
            default:
                flags |= FLV_FRAME_INTER;
                
                
                break;
                
        }
        
        
        if(output) {
            
            RTMPMetadata_t outMeta(dts);
            std::vector<uint8_t> conf;
            
            if(is_config && m_sps.size() > 0 && m_pps.size() > 0 ) {
                conf = configurationFromSpsAndPps();
                inSize = conf.size();
            }
            outBuffer.reserve(inSize + flags_size);
            
            put_byte(outBuffer, flags);
            put_byte(outBuffer, !is_config);
            put_be24(outBuffer, pts - dts);             // Decoder delay
            
            if(is_config ) {
                // create modified SPS/PPS buffer
                if(m_sps.size() > 0 && m_pps.size() > 0 && !m_sentConfig && (flags & FLV_FRAME_KEY)) {
                    put_buff(outBuffer, &conf[0], conf.size());
                    m_sentConfig = true;
                } else {
                    return;
                }
            } else {
                put_buff(outBuffer, inBuffer, inSize);
            }
            
            outMeta.setData(dts, static_cast<int>(outBuffer.size()), RTMP_PT_VIDEO, kVideoChannelStreamId, nal_type == 5);
            
            output->pushBuffer(&outBuffer[0], outBuffer.size(), outMeta);
        }
        
    }