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