示例#1
0
    void
    AACPacketizer::pushBuffer(const uint8_t* const inBuffer, size_t inSize, IMetadata& metadata)
    {
        const auto now = std::chrono::steady_clock::now();
        const uint64_t bufferDuration(metadata.timestampDelta * 1000000.);
        const double nowmicros (std::chrono::duration_cast<std::chrono::microseconds>(now - m_epoch).count());
        
        
        const auto micros = std::floor(nowmicros / double(bufferDuration)) * bufferDuration;
        
        std::vector<uint8_t> & outBuffer = m_outbuffer;
        
        outBuffer.clear();
        
        int flags = 0;
        const int flags_size = 2;
        
        //static int prev_ts = 0;
        
        int ts = micros / 1000; // m_audioTs * 1000.;//

        
        auto output = m_output.lock();
        RTMPMetadata_t outMeta(metadata.timestampDelta);
        
        if(output) {
        
            flags = FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
        
        
            outBuffer.reserve(inSize + flags_size);
        
            put_byte(outBuffer, flags);
            put_byte(outBuffer, m_sentAudioConfig);
            if(!m_sentAudioConfig) {
                
                m_sentAudioConfig = true;
                const char hdr[2] = { 0x12,0x10 };
                put_buff(outBuffer, (uint8_t*)hdr, 2);
                
            } else {
                
                put_buff(outBuffer, inBuffer, inSize);
                m_audioTs += metadata.timestampDelta;
                
            }

            outMeta.setData(ts, static_cast<int>(outBuffer.size()), FLV_TAG_TYPE_AUDIO, kAudioChannelStreamId);
            
            output->pushBuffer(&outBuffer[0], outBuffer.size(), outMeta);
        }

    }
    void
    AACPacketizer::pushBuffer(const uint8_t* const inBuffer, size_t inSize, IMetadata& metadata)
    {
        std::vector<uint8_t> & outBuffer = m_outbuffer;

        outBuffer.clear();

        int flvStereoOrMono = (m_channelCount == 2 ? FLV_STEREO : FLV_MONO);
        int flvSampleRate = FLV_SAMPLERATE_44100HZ; // default
        if (m_sampleRate == 22050.0) {
            flvSampleRate = FLV_SAMPLERATE_22050HZ;
        }

        int flags = 0;
        const int flags_size = 2;


        int ts = metadata.timestampDelta + m_ctsOffset ;
//        DLog("AAC: %06d", ts);
        
        auto output = m_output.lock();

        RTMPMetadata_t outMeta(ts);

        if(inSize == 2 && !m_asc[0] && !m_asc[1]) {
            m_asc[0] = inBuffer[0];
            m_asc[1] = inBuffer[1];
        }

        if(output) {

            flags = FLV_CODECID_AAC | flvSampleRate | FLV_SAMPLESSIZE_16BIT | flvStereoOrMono;

            outBuffer.reserve(inSize + flags_size);

            put_byte(outBuffer, flags);
            put_byte(outBuffer, m_sentAudioConfig);

            if(!m_sentAudioConfig) {
                m_sentAudioConfig = true;
                put_buff(outBuffer, (uint8_t*)m_asc, sizeof(m_asc));

            } else {
                put_buff(outBuffer, inBuffer, inSize);
            }

            outMeta.setData(ts, static_cast<int>(outBuffer.size()), RTMP_PT_AUDIO, kAudioChannelStreamId, false);

            output->pushBuffer(&outBuffer[0], outBuffer.size(), outMeta);
        }

    }
示例#3
0
    void
    AACPacketizer::pushBuffer(const uint8_t* const inBuffer, size_t inSize, IMetadata& metadata)
    {
        std::vector<uint8_t> & outBuffer = m_outbuffer;
        
        outBuffer.clear();
        
        int flags = 0;
        const int flags_size = 2;
    
        
        int ts = metadata.timestampDelta;
        
        auto output = m_output.lock();
        
        RTMPMetadata_t outMeta(metadata.timestampDelta);
        
        if(inSize == 2 && !m_asc[0] && !m_asc[1]) {
            m_asc[0] = inBuffer[0];
            m_asc[1] = inBuffer[1];
        }
        
        if(output) {
        
            flags = FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | FLV_SAMPLESSIZE_16BIT | FLV_STEREO;
           
            outBuffer.reserve(inSize + flags_size);
            
            put_byte(outBuffer, flags);
            put_byte(outBuffer, m_sentAudioConfig);

            if(!m_sentAudioConfig) {
                m_sentAudioConfig = true;
                put_buff(outBuffer, (uint8_t*)m_asc, sizeof(m_asc));
                
            } else {
                
                put_buff(outBuffer, inBuffer, inSize);
                m_audioTs += metadata.timestampDelta;
                
            }

            outMeta.setData(ts, static_cast<int>(outBuffer.size()), FLV_TAG_TYPE_AUDIO, kAudioChannelStreamId);
            
            output->pushBuffer(&outBuffer[0], outBuffer.size(), outMeta);
        }

    }
    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);
        }
        
    }
    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);
        }
        
    }