コード例 #1
0
bool OMXPlayerAudio::Decode(OMXPacket *pkt)
{
  if(!pkt)
    return false;

  /* last decoder reinit went wrong */
  if(!m_decoder || !m_pAudioCodec)
    return true;

  if(!m_omx_reader->IsActive(OMXSTREAM_AUDIO, pkt->stream_index))
    return true; 

  int channels = pkt->hints.channels;

  unsigned int old_bitrate = m_hints.bitrate;
  unsigned int new_bitrate = pkt->hints.bitrate;

  /* only check bitrate changes on CODEC_ID_DTS, CODEC_ID_AC3, CODEC_ID_EAC3 */
  if(m_hints.codec != CODEC_ID_DTS && m_hints.codec != CODEC_ID_AC3 && m_hints.codec != CODEC_ID_EAC3)
  {
    new_bitrate = old_bitrate = 0;
  }

  /* audio codec changed. reinit device and decoder */
  if(m_hints.codec         != pkt->hints.codec ||
     m_hints.channels      != channels ||
     m_hints.samplerate    != pkt->hints.samplerate ||
     old_bitrate           != new_bitrate ||
     m_hints.bitspersample != pkt->hints.bitspersample)
  {
    printf("C : %d %d %d %d %d\n", m_hints.codec, m_hints.channels, m_hints.samplerate, m_hints.bitrate, m_hints.bitspersample);
    printf("N : %d %d %d %d %d\n", pkt->hints.codec, channels, pkt->hints.samplerate, pkt->hints.bitrate, pkt->hints.bitspersample);

    m_av_clock->OMXPause();

    CloseDecoder();
    CloseAudioCodec();

    m_hints = pkt->hints;

    m_player_error = OpenAudioCodec();
    if(!m_player_error)
      return false;

    m_player_error = OpenDecoder();
    if(!m_player_error)
      return false;

    m_av_clock->OMXStateExecute();
    m_av_clock->OMXReset();
    m_av_clock->OMXResume();

  }

  if(!((int)m_decoder->GetSpace() > pkt->size))
    OMXClock::OMXSleep(10);

  if((int)m_decoder->GetSpace() > pkt->size)
  {
    if(pkt->dts != DVD_NOPTS_VALUE)
      m_iCurrentPts = pkt->dts;

    m_av_clock->SetPTS(m_iCurrentPts);

    const uint8_t *data_dec = pkt->data;
    int            data_len = pkt->size;

    if(!m_passthrough && !m_hw_decode)
    {
      while(data_len > 0)
      {
        int len = m_pAudioCodec->Decode((BYTE *)data_dec, data_len);
        if( (len < 0) || (len >  data_len) )
        {
          m_pAudioCodec->Reset();
          break;
        }

        data_dec+= len;
        data_len -= len;

        uint8_t *decoded;
        int decoded_size = m_pAudioCodec->GetData(&decoded);

        if(decoded_size <=0)
          continue;

        int ret = 0;

        if(m_bMpeg)
          ret = m_decoder->AddPackets(decoded, decoded_size, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
        else
          ret = m_decoder->AddPackets(decoded, decoded_size, m_iCurrentPts, m_iCurrentPts);

        if(ret != decoded_size)
        {
          printf("error ret %d decoded_size %d\n", ret, decoded_size);
        }

        int n = (m_hints.channels * 32 * m_hints.samplerate)>>3;
        if (n > 0 && m_iCurrentPts != DVD_NOPTS_VALUE)
          m_iCurrentPts += ((double)decoded_size * DVD_TIME_BASE) / n;

        HandleSyncError((((double)decoded_size * DVD_TIME_BASE) / n), m_iCurrentPts);
      }
    }
    else
    {
      if(m_bMpeg)
        m_decoder->AddPackets(pkt->data, pkt->size, DVD_NOPTS_VALUE, DVD_NOPTS_VALUE);
      else
        m_decoder->AddPackets(pkt->data, pkt->size, m_iCurrentPts, m_iCurrentPts);

      HandleSyncError(0, m_iCurrentPts);
    }

    m_av_clock->SetAudioClock(m_iCurrentPts);
    return true;
  }
コード例 #2
0
bool OMXPlayerAudio::Decode(DemuxPacket *pkt, bool bDropPacket)
{
  if(!pkt || m_bad_state || !m_pAudioCodec)
    return false;

  if(pkt->dts != DVD_NOPTS_VALUE)
    m_audioClock = pkt->dts;

  const uint8_t *data_dec = pkt->pData;
  int            data_len = pkt->iSize;

  if(!OMX_IS_RAW(m_format.m_dataFormat))
  {
    while(!m_bStop && data_len > 0)
    {
      int len = m_pAudioCodec->Decode((BYTE *)data_dec, data_len);
      if( (len < 0) || (len >  data_len) )
      {
        m_pAudioCodec->Reset();
        break;
      }

      data_dec+= len;
      data_len -= len;

      uint8_t *decoded;
      int decoded_size = m_pAudioCodec->GetData(&decoded);

      if(decoded_size <=0)
        continue;

      int ret = 0;

      m_audioStats.AddSampleBytes(decoded_size);

      if(CodecChange())
      {
        m_DecoderOpen = OpenDecoder();
        if(!m_DecoderOpen)
          return false;
      }

      while(!m_bStop)
      {
        HandlePlayspeed(bDropPacket);
        if(m_flush)
        {
          m_flush = false;
          break;
        }

        if(m_omxAudio.GetSpace() < (unsigned int)pkt->iSize)
        {
          Sleep(10);
          continue;
        }
        
        if(!bDropPacket)
        {
          // Zero out the frame data if we are supposed to silence the audio
          if(m_silence)
            memset(decoded, 0x0, decoded_size);

          ret = m_omxAudio.AddPackets(decoded, decoded_size, m_audioClock, m_audioClock);

          if(ret != decoded_size)
          {
            CLog::Log(LOGERROR, "error ret %d decoded_size %d\n", ret, decoded_size);
          }
        }

        int n = (m_nChannels * m_hints.bitspersample * m_hints.samplerate)>>3;
        if (n > 0)
          m_audioClock += ((double)decoded_size * DVD_TIME_BASE) / n;

        if(m_speed == DVD_PLAYSPEED_NORMAL)
          HandleSyncError((((double)decoded_size * DVD_TIME_BASE) / n));
        break;

      }
    }
  }
  else
  {
    if(CodecChange())
コード例 #3
0
void CDVDPlayerAudio::Process()
{
    CLog::Log(LOGNOTICE, "running thread: CDVDPlayerAudio::Process()");

    bool packetadded(false);

    DVDAudioFrame audioframe;
    m_audioStats.Start();

    while (!m_bStop)
    {
        int result = DecodeFrame(audioframe);

        //Drop when not playing normally
        if(m_speed   != DVD_PLAYSPEED_NORMAL
                && m_started == true)
        {
            result |= DECODE_FLAG_DROP;
        }

        UpdatePlayerInfo();

        if( result & DECODE_FLAG_ERROR )
        {
            CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Decode Error");
            continue;
        }

        if( result & DECODE_FLAG_TIMEOUT )
        {
            // Flush as the audio output may keep looping if we don't
            if(m_speed == DVD_PLAYSPEED_NORMAL && !m_stalled)
            {
                m_dvdAudio.Drain();
                m_dvdAudio.Flush();
                m_stalled = true;
            }

            continue;
        }

        if( result & DECODE_FLAG_ABORT )
        {
            CLog::Log(LOGDEBUG, "CDVDPlayerAudio::Process - Abort received, exiting thread");
            break;
        }

        if( audioframe.nb_frames == 0 )
            continue;

        packetadded = false;

        // we have succesfully decoded an audio frame, setup renderer to match
        if (!m_dvdAudio.IsValidFormat(audioframe))
        {
            if(m_speed)
                m_dvdAudio.Drain();

            m_dvdAudio.Destroy();

            if(m_speed)
                m_dvdAudio.Resume();
            else
                m_dvdAudio.Pause();

            if(!m_dvdAudio.Create(audioframe, m_streaminfo.codec, m_setsynctype == SYNC_RESAMPLE))
                CLog::Log(LOGERROR, "%s - failed to create audio renderer", __FUNCTION__);

            m_streaminfo.channels = audioframe.passthrough ? audioframe.encoded_channel_count : audioframe.channel_count;

            g_dataCacheCore.SignalAudioInfoChange();
        }

        // Zero out the frame data if we are supposed to silence the audio
        if (m_silence || (m_syncclock && !AE_IS_RAW_RAW(audioframe.data_format)))
        {
            int size = audioframe.nb_frames * audioframe.framesize / audioframe.planes;
            for (unsigned int i=0; i<audioframe.planes; i++)
                memset(audioframe.data[i], 0, size);
        }

        if(result & DECODE_FLAG_DROP)
        {
            // keep output times in sync
            m_dvdAudio.SetPlayingPts(m_audioClock);
        }
        else
        {
            SetSyncType(audioframe.passthrough);

            // add any packets play
            packetadded = OutputPacket(audioframe);

            // we are not running until something is cached in output device and
            // we still have a minimum level in the message queue
            if(m_stalled && m_dvdAudio.GetCacheTime() > 0.0 && m_messageQueue.GetLevel() > 5)
                m_stalled = false;
        }

        // signal to our parent that we have initialized
        if(m_started == false && !(result & DECODE_FLAG_DROP))
        {
            m_started = true;
            m_messageParent.Put(new CDVDMsgInt(CDVDMsg::PLAYER_STARTED, DVDPLAYER_AUDIO));
            m_errors.Flush();
        }

        if( m_dvdAudio.GetPlayingPts() == DVD_NOPTS_VALUE )
            continue;

        if( m_speed != DVD_PLAYSPEED_NORMAL )
            continue;

        if (packetadded)
            HandleSyncError(audioframe.duration);
    }
}