static GstFlowReturn
gst_speex_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
{
  GstFlowReturn res;
  GstSpeexDec *dec;

  /* no fancy draining */
  if (G_UNLIKELY (!buf))
    return GST_FLOW_OK;

  dec = GST_SPEEX_DEC (bdec);

  /* If we have the streamheader and vorbiscomment from the caps already
   * ignore them here */
  if (dec->streamheader && dec->vorbiscomment) {
    if (GST_BUFFER_SIZE (dec->streamheader) == GST_BUFFER_SIZE (buf)
        && memcmp (GST_BUFFER_DATA (dec->streamheader), GST_BUFFER_DATA (buf),
            GST_BUFFER_SIZE (buf)) == 0) {
      GST_DEBUG_OBJECT (dec, "found streamheader");
      gst_audio_decoder_finish_frame (bdec, NULL, 1);
      res = GST_FLOW_OK;
    } else if (GST_BUFFER_SIZE (dec->vorbiscomment) == GST_BUFFER_SIZE (buf)
        && memcmp (GST_BUFFER_DATA (dec->vorbiscomment), GST_BUFFER_DATA (buf),
            GST_BUFFER_SIZE (buf)) == 0) {
      GST_DEBUG_OBJECT (dec, "found vorbiscomments");
      gst_audio_decoder_finish_frame (bdec, NULL, 1);
      res = GST_FLOW_OK;
    } else {
      res = gst_speex_dec_parse_data (dec, buf);
    }
  } else {
    /* Otherwise fall back to packet counting and assume that the
     * first two packets are the headers. */
    switch (dec->packetno) {
      case 0:
        GST_DEBUG_OBJECT (dec, "counted streamheader");
        res = gst_speex_dec_parse_header (dec, buf);
        gst_audio_decoder_finish_frame (bdec, NULL, 1);
        break;
      case 1:
        GST_DEBUG_OBJECT (dec, "counted vorbiscomments");
        res = gst_speex_dec_parse_comments (dec, buf);
        gst_audio_decoder_finish_frame (bdec, NULL, 1);
        break;
      default:
      {
        res = gst_speex_dec_parse_data (dec, buf);
        break;
      }
    }
  }

  dec->packetno++;

  return res;
}
示例#2
0
static GstFlowReturn
gst_speex_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
{
  GstFlowReturn res = GST_FLOW_OK;
  GstSpeexDec *dec;
  gboolean header_packet = FALSE;

  /* no fancy draining */
  if (G_UNLIKELY (!buf))
    return GST_FLOW_OK;

  dec = GST_SPEEX_DEC (bdec);

  switch (dec->packetno) {
    case 0:
      GST_DEBUG_OBJECT (dec, "expecting streamheader");
      header_packet = TRUE;
      if (!memcmp_buffers (dec->streamheader, buf)) {
        res = gst_speex_dec_parse_header (dec, buf);
        if (res == GST_FLOW_NO_HEADER) {
          header_packet = FALSE;
          GST_INFO_OBJECT (dec, "No streamheader in first buffer");
          if (dec->streamheader == NULL) {
            GST_ERROR_OBJECT (dec, "Can't proceed without a header");
            return GST_FLOW_ERROR;
          } else {
            GST_INFO_OBJECT (dec, "Using streamheader from caps");
          }
        }
        /* we prefer "inband" streamheaders to the ones in caps */
        if (res == GST_FLOW_OK) {
          GST_DEBUG_OBJECT (dec, "found streamheader");
          gst_buffer_replace (&dec->streamheader, buf);
        }
      }
      break;
    case 1:
      GST_DEBUG_OBJECT (dec, "expecting vorbiscomment");
      header_packet = TRUE;
      if (!memcmp_buffers (dec->vorbiscomment, buf)) {
        res = gst_speex_dec_parse_comments (dec, buf);
        if (res == GST_FLOW_NO_HEADER) {
          header_packet = FALSE;
          GST_INFO_OBJECT (dec, "No vorbisheader in second buffer");
        }
        if (res == GST_FLOW_OK) {
          GST_DEBUG_OBJECT (dec, "found vorbiscomment");
          gst_buffer_replace (&dec->vorbiscomment, buf);
        }
      }
      break;
    default:
      break;
  }

  if (header_packet)
    gst_audio_decoder_finish_frame (bdec, NULL, 1);
  else
    res = gst_speex_dec_parse_data (dec, buf);

  dec->packetno++;

  return res;
}