Example #1
0
void eServiceTS::recv_event(int evt)
{
	eDebug("eServiceTS::recv_event: %d", evt);
	switch (evt) {
	case eStreamThread::evtEOS:
		m_decodedemux->flush();
		m_event((iPlayableService*)this, evEOF);
		break;
	case eStreamThread::evtReadError:
	case eStreamThread::evtWriteError:
		m_decoder->pause();
		m_event((iPlayableService*)this, evEOF);
		break;
	case eStreamThread::evtSOS:
		m_event((iPlayableService*)this, evSOF);
		break;
	case eStreamThread::evtStreamInfo:
		bool wasnull = !m_audioInfo;
		m_streamthread->getAudioInfo(m_audioInfo);
		if (m_audioInfo)
			eDebug("[servicets] %d audiostreams found", m_audioInfo->audioStreams.size());
		if (m_audioInfo && wasnull) {
			int sel = getCurrentTrack();
			if (sel < 0)
				selectTrack(0);
			else if (m_audioInfo->audioStreams[sel].type != eDVBAudio::aMPEG)
				selectTrack(sel);
		}
		break;
	}
}
uint32_t        ADM_edAudioTrackFromVideo::getOutputFrequency(void)
{
    ADM_audioStreamTrack *trk=getCurrentTrack();
    if(!trk) 
    {
        ADM_warning("No audio track\n");
        return 0;
    }
    if(!trk->codec)
        return trk->wavheader.frequency;
    return trk->codec->getOutputFrequency();
}
Example #3
0
void eServiceWebTS::recv_event(int evt)
{
	eDebug("eServiceWebTS::recv_event: %d", evt);
	switch (evt) {
	case eStreamThreadWeb::evtEOS:
		m_decodedemux->flush();
		m_event((iPlayableService*)this, evEOF);
		break;
	case eStreamThreadWeb::evtReadError:
	case eStreamThreadWeb::evtWriteError:
		m_decoder->pause();
		m_event((iPlayableService*)this, evEOF);
		break;
	case eStreamThreadWeb::evtSOS:
		m_event((iPlayableService*)this, evSOF);
		break;
	case eStreamThreadWeb::evtStreamInfo:
		if (VPID != 0 && PID_SET == 0 && APID != 0)
		{
			PID_SET = 1;
			m_decodedemux->flush();
			if (H264)
				m_decoder->setVideoPID(VPID, eDVBVideo::MPEG4_H264);
			else
				m_decoder->setVideoPID(VPID, eDVBVideo::MPEG2);
			m_decoder->setAudioPID(APID, eDVBAudio::aMPEG);
			m_decoder->pause();
			m_event(this, evStart);
			m_decoder->play();

		}
		bool wasnull = !m_audioInfo;
		m_streamthread->getAudioInfo(m_audioInfo);
		//if (m_audioInfo)
		//	eDebug("[ServiceWebTS] %d audiostreams found", m_audioInfo->audioStreams.size());
		if (m_audioInfo && wasnull) {
			eDebug("[ServiceWebTS] %d audiostreams found", m_audioInfo->audioStreams.size());
			int sel = getCurrentTrack();
			if (sel < 0)
				selectTrack(0);
			else if (m_audioInfo->audioStreams[sel].type != eDVBAudio::aMPEG)
				selectTrack(sel);
		}
		break;
	}
}
Example #4
0
void AudioPlayer::setVolume(qreal value)
{
    volume_ = value;
    qreal modified_volume = value;
    if (replaygain_ != ReplayGainMode::None) {
        PTrack track = getCurrentTrack();
        if (track) {
            // gain = 10 ^ ((rg + pream) / 20)
            auto id_tag = replaygain_ == ReplayGainMode::Album ? "REPLAYGAIN_ALBUM_GAIN" : "REPLAYGAIN_TRACK_GAIN";
            QMap<QString, QString>::const_iterator it = track->metadata.find(id_tag);
            qreal rg = 1;
            if (it != track->metadata.end()) {
                QString track_rg = it.value();
                track_rg.chop(3);
                rg = track_rg.toDouble();
                rg = qPow(10, (preamp_with_rg_ + rg) / 20);
                qDebug() << "Got" << replaygain_ <<  "replaygain " << track_rg << "resulting in gain =" << rg;
            }
            modified_volume *= rg;
        }
    }
    audioOutput_->setVolume(modified_volume);
}
bool ADM_edAudioTrackFromVideo::getPCMPacket(float  *dest, uint32_t sizeMax, uint32_t *samples,uint64_t *odts)
{
uint32_t fillerSample=0;   // FIXME : Store & fix the DTS error correctly!!!!
uint32_t inSize;
bool drop=false;
static bool fail=false;
uint32_t outFrequency=getCurrentTrack()->codec->getOutputFrequency();
 vprintf("[PCMPacket]  request TRK %d:%x\n",myTrackNumber,(long int)getCurrentTrack());
again:
    *samples=0;
    ADM_audioStreamTrack *trk=getCurrentTrack();
    if(!trk) return false;
    // Do we already have a packet ?
    if(!packetBufferSize)
    {
        if(!refillPacketBuffer())
        {
            if(fail==false)
              ADM_warning("[Editor] Cannot refill audio\n");
            fail=true;
            return false;
        }
    }
    // We do now
    vprintf("[PCMPacket]  TRK %d Got %d samples, time code %08lu  lastDts=%08lu delta =%08ld\n",
                myTrackNumber,packetBufferSamples,packetBufferDts,lastDts,packetBufferDts-lastDts);
    fail=false;

    // Check if the Dts matches
    if(lastDts!=ADM_AUDIO_NO_DTS &&packetBufferDts!=ADM_AUDIO_NO_DTS)
    {
        if(abs((int64_t)(lastDts-packetBufferDts))>ADM_ALLOWED_DRIFT_US)
        {
            printf("[Composer::getPCMPacket] Track %d,%"PRIx64" : drift %d, computed :%"PRIu64" got %"PRIu64"\n",
                        (int)myTrackNumber,(uint64_t)trk,(int)(lastDts-packetBufferDts),lastDts,packetBufferDts);
            if(packetBufferDts<lastDts)
            {
                printf("[Composer::getPCMPacket] Track %d:%"PRIx64" : Dropping packet %"PRIu32" last =%"PRIu32"\n",myTrackNumber,(uint64_t)trk,(uint32_t)(lastDts/1000),(uint32_t)(packetBufferDts/1000));
                drop=true;
            }else 
            {
                // There is a "hole" in audio
                // Let's add some filler
                // Compute filler size
                *odts=lastDts;
                float f=packetBufferDts-lastDts; // in us
                f*=outFrequency;
                f/=1000000.;
                // in samples!
                uint32_t fillerSample=(uint32_t )(f+0.49);
                uint32_t mx=sizeMax/trk->wavheader.channels;
                
                if(mx<fillerSample) fillerSample=mx;
                // arbitrary cap, max 4kSample in one go
                // about 100 ms
                if(fillerSample>4*1024) 
                {
                    fillerSample=4*1024;
                }
                uint32_t start=fillerSample*sizeof(float)*trk->wavheader.channels;
                memset(dest,0,start);

                advanceDtsByCustomSample(fillerSample,outFrequency);
                dest+=fillerSample*trk->wavheader.channels;
                *samples=fillerSample;
                vprintf("[Composer::getPCMPacket] Track %d:%x  Adding %u padding samples, dts is now %lu\n",
                            myTrackNumber,(long  int)trk,fillerSample,lastDts);
                return true;
       }
      }
    }
    // If lastDts is not initialized....
    if(lastDts==ADM_AUDIO_NO_DTS) lastDts=packetBufferDts;
    
    //
    //  The packet is ok, decode it...
    //
    uint32_t nbOut=0; // Nb sample as seen by codec
    if(!trk->codec->run(packetBuffer, packetBufferSize, dest, &nbOut))
    {
            packetBufferSize=0; // consume
            ADM_warning(ADM_PRINT_ERROR,"[Composer::getPCMPacket] Track %d:%x : codec failed failed\n",
                            myTrackNumber,trk);
            return false;
    }
    packetBufferSize=0; // consume

    // Compute how much decoded sample to compare with what demuxer said
    uint32_t decodedSample=nbOut;
    decodedSample/=trk->wavheader.channels;
    if(!decodedSample) goto again;
#define ADM_MAX_JITTER 5000  // in samples, due to clock accuracy, it can be +er, -er, + er, -er etc etc
    if (abs((int64_t)(decodedSample-packetBufferSamples)) > ADM_MAX_JITTER)
    {
        ADM_warning("[Composer::getPCMPacket] Track %d:%x Demuxer was wrong %d vs %d samples!\n",
                    myTrackNumber,trk,packetBufferSamples,decodedSample);
    }
    
    // This packet has been dropped (too early packt), try the next one
    if(drop==true)
    {
        // TODO Check if the packet somehow overlaps, i.e. starts too early but finish ok
        goto again;
    }
    // Update infos
    *samples=(decodedSample);
    *odts=lastDts;
    advanceDtsByCustomSample(decodedSample,outFrequency);
    vprintf("[Composer::getPCMPacket] Track %d:%x Adding %u decoded, Adding %u filler sample, dts is now %lu\n",
                    myTrackNumber,(long int)trk,  decodedSample,fillerSample,lastDts);
    ADM_assert(sizeMax>=(fillerSample+decodedSample)*trk->wavheader.channels);
    return true;
}