void ReplayAudioBufferPlayout::fill_packet(
    IOAudioPacket *apkt, 
    Rational speed
) {
    /* 
     * synthesize enough data for each channel to fill apkt 
     * note that we don't do any synthesis on channels that do not exist
     * in the apkt.
     */
    for (channel_data &ch : channel_map) {
        while (ch.fifo->fill_samples( ) < apkt->size_samples( )) {
            if (ch.channel_no < apkt->channels( )) {            
                synthesize_samples(ch);
            }
            ch.pos_offset += speed;
        }
        
        if (ch.channel_no < apkt->channels( )) {
            ch.fifo->fill_channel(apkt, ch.channel_no);
        }
    }
}
Beispiel #2
0
static OMX_ERRORTYPE
decode_buffer (const void * ap_obj)
{
  mp3d_prc_t * p_obj = (mp3d_prc_t *) ap_obj;
  unsigned char * p_guardzone = NULL;
  int status = 0;

  assert (p_obj->p_outhdr_);

  /* Check if there is any remaining PCM data from a previous run of the
   * decoding loop that needs to be synthesised */
  if ((0 != p_obj->next_synth_sample_
       && p_obj->next_synth_sample_ < p_obj->synth_.pcm.length)
      && (p_obj->p_outhdr_->nFilledLen < p_obj->p_outhdr_->nAllocLen))
    {
      p_obj->next_synth_sample_
        = synthesize_samples (p_obj, p_obj->next_synth_sample_);
    }

  while (p_obj->p_outhdr_)
    {

      /* The input bucket must be filled if it becomes empty or if
       * it's the first execution of the loop.
       */

      if ((NULL == p_obj->stream_.buffer
           || MAD_ERROR_BUFLEN == p_obj->stream_.error)
          && p_obj->p_inhdr_ != NULL)
        {
          size_t read_size = 0;
          unsigned char * p_read_start = NULL;
          p_obj->remaining_ = 0;

          if (p_obj->stream_.next_frame != NULL)
            {
              p_obj->remaining_
                = p_obj->stream_.bufend - p_obj->stream_.next_frame;
              memmove (p_obj->in_buff_, p_obj->stream_.next_frame,
                       p_obj->remaining_);
              p_read_start = p_obj->in_buff_ + p_obj->remaining_;
              read_size = INPUT_BUFFER_SIZE - p_obj->remaining_;
            }
          else
            {
              read_size = INPUT_BUFFER_SIZE;
              p_read_start = p_obj->in_buff_;
              p_obj->remaining_ = 0;
            }

          /* Fill-in the buffer. If an error occurs print a message
           * and leave the decoding loop. If the end of stream is
           * reached we also leave the loop but the return status is
           * left untouched.
           */
          read_size = read_from_omx_buffer (p_obj, p_read_start, read_size,
                                            p_obj->p_inhdr_);
          if (read_size == 0)
            {
              if ((p_obj->p_inhdr_->nFlags & OMX_BUFFERFLAG_EOS) != 0)
                {
                  TIZ_TRACE (handleOf (p_obj), "end of input stream");
                  status = 2;
                }
              else
                {
                  TIZ_TRACE (handleOf (p_obj), "read_size <= 0");
                  status = 1;
                }
              break;
            }

          /* TODO */
          /*       if(BstdFileEofP (BstdFile)) */
          /*         { */
          /*           p_guardzone = p_read_start + read_size; */
          /*           memset (p_guardzone, 0, MAD_BUFFER_GUARD); */
          /*           read_size += MAD_BUFFER_GUARD; */
          /*         } */

          /* Pipe the new buffer content to libmad's stream decoder
           * facility.
           */
          mad_stream_buffer (&p_obj->stream_, p_obj->in_buff_,
                             read_size + p_obj->remaining_);
          p_obj->stream_.error = 0;
        }

      if (mad_frame_decode (&p_obj->frame_, &p_obj->stream_) == -1)
        {
          if (MAD_RECOVERABLE (p_obj->stream_.error))
            {
              if (p_obj->stream_.error != MAD_ERROR_LOSTSYNC
                  || p_obj->stream_.this_frame != p_guardzone)
                {
                  TIZ_TRACE (handleOf (p_obj),
                             "recoverable frame level error (%s)",
                             mad_stream_errorstr (&p_obj->stream_));
                }
              continue;
            }
          else
            {
              if (p_obj->stream_.error == MAD_ERROR_BUFLEN)
                {
                  if (!p_obj->p_inhdr_)
                    {
                      TIZ_TRACE (handleOf (p_obj),
                                 "p_obj->stream_.error==MAD_ERROR_BUFLEN "
                                 "p_obj->p_inhdr_=[NULL]");
                      break;
                    }
                  else
                    {
                      TIZ_TRACE (handleOf (p_obj),
                                 "p_obj->stream_.error==MAD_ERROR_BUFLEN "
                                 "p_obj->p_inhdr_=[%p] nFilledLen [%d]",
                                 p_obj->p_inhdr_, p_obj->p_inhdr_->nFilledLen);
                      continue;
                    }
                }
              else
                {
                  TIZ_TRACE (handleOf (p_obj),
                             "unrecoverable frame level error (%s).",
                             mad_stream_errorstr (&p_obj->stream_));
                  status = 2;
                  break;
                }
            }
        }

      /* The characteristics of the stream's first frame is printed The first
       * frame is representative of the entire stream.
       */
      if (0 == p_obj->frame_count_)
        {
          store_stream_metadata (p_obj, &(p_obj->frame_.header));
        }

      p_obj->frame_count_++;
      mad_timer_add (&p_obj->timer_, p_obj->frame_.header.duration);

      /* Once decoded the frame is synthesized to PCM samples. No errors
       * are reported by mad_synth_frame();
       */
      mad_synth_frame (&p_obj->synth_, &p_obj->frame_);

      p_obj->next_synth_sample_
        = synthesize_samples (p_obj, p_obj->next_synth_sample_);
    }

  (void) status;
  /* TODO */
  /*   if (p_obj->p_outhdr_ != NULL */
  /*       && p_obj->p_outhdr_->nFilledLen != 0 */
  /*       && status == 2) */
  /*     { */
  /*       const tiz_srv_t *p_parent = ap_obj; */
  /*       void *p_krn = tiz_get_krn (p_parent->p_hdl_); */

  /*       p_obj->eos_ = true; */
  /*       p_obj->p_outhdr_->nFlags |= OMX_BUFFERFLAG_EOS; */
  /*       TIZ_LOG (TIZ_PRIORITY_TRACE, handleOf (p_obj), */
  /*                        "Releasing output buffer [%p] ..." */
  /*                        "nFilledLen = [%d] OMX_BUFFERFLAG_EOS", */
  /*                        p_obj->p_outhdr_, p_obj->p_outhdr_->nFilledLen); */
  /*       tiz_krn_release_buffer (tiz_get_krn (handleOf (ap_obj)), 1,
   * p_obj->p_outhdr_); */
  /*       /\* p_obj->p_outhdr_ = NULL; *\/ */
  /*     } */

  return OMX_ErrorNone;
}