Exemplo n.º 1
0
static GstFlowReturn
vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
    GstClockTime timestamp, GstClockTime duration)
{
#ifdef USE_TREMOLO
  vorbis_sample_t *pcm;
#else
  vorbis_sample_t **pcm;
#endif
  guint sample_count;
  GstBuffer *out = NULL;
  GstFlowReturn result;
  GstMapInfo map;
  gsize size;

  if (G_UNLIKELY (!vd->initialized)) {
    result = vorbis_dec_handle_header_caps (vd);
    if (result != GST_FLOW_OK)
      goto not_initialized;
  }

  /* normal data packet */
  /* FIXME, we can skip decoding if the packet is outside of the
   * segment, this is however not very trivial as we need a previous
   * packet to decode the current one so we must be careful not to
   * throw away too much. For now we decode everything and clip right
   * before pushing data. */

#ifdef USE_TREMOLO
  if (G_UNLIKELY (vorbis_dsp_synthesis (&vd->vd, packet, 1)))
    goto could_not_read;
#else
  if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
    goto could_not_read;

  if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0))
    goto not_accepted;
#endif

  /* assume all goes well here */
  result = GST_FLOW_OK;

  /* count samples ready for reading */
#ifdef USE_TREMOLO
  if ((sample_count = vorbis_dsp_pcmout (&vd->vd, NULL, 0)) == 0)
#else
  if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
    goto done;
#endif

  size = sample_count * vd->info.bpf;
  GST_LOG_OBJECT (vd, "%d samples ready for reading, size %" G_GSIZE_FORMAT,
      sample_count, size);

  /* alloc buffer for it */
  out = gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (vd), size);

  gst_buffer_map (out, &map, GST_MAP_WRITE);
  /* get samples ready for reading now, should be sample_count */
#ifdef USE_TREMOLO
  if (G_UNLIKELY (vorbis_dsp_pcmout (&vd->vd, map.data, sample_count) !=
          sample_count))
#else
  if (G_UNLIKELY (vorbis_synthesis_pcmout (&vd->vd, &pcm) != sample_count))
#endif
    goto wrong_samples;

#ifdef USE_TREMOLO
  if (vd->info.channels < 9)
    gst_audio_reorder_channels (map.data, map.size, GST_VORBIS_AUDIO_FORMAT,
        vd->info.channels, gst_vorbis_channel_positions[vd->info.channels - 1],
        gst_vorbis_default_channel_positions[vd->info.channels - 1]);
#else
  /* copy samples in buffer */
  vd->copy_samples ((vorbis_sample_t *) map.data, pcm,
      sample_count, vd->info.channels);
#endif

  GST_LOG_OBJECT (vd, "have output size of %" G_GSIZE_FORMAT, size);
  gst_buffer_unmap (out, &map);

done:
  /* whether or not data produced, consume one frame and advance time */
  result = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), out, 1);

#ifdef USE_TREMOLO
  vorbis_dsp_read (&vd->vd, sample_count);
#else
  vorbis_synthesis_read (&vd->vd, sample_count);
#endif

  return result;

  /* ERRORS */
not_initialized:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("no header sent yet"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
could_not_read:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("couldn't read data packet"));
    return GST_FLOW_ERROR;
  }
not_accepted:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("vorbis decoder did not accept data packet"));
    return GST_FLOW_ERROR;
  }
wrong_samples:
  {
    gst_buffer_unref (out);
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("vorbis decoder reported wrong number of samples"));
    return GST_FLOW_ERROR;
  }
}
Exemplo n.º 2
0
static GstFlowReturn
vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
    GstClockTime timestamp, GstClockTime duration)
{
#ifdef USE_TREMOLO
  vorbis_sample_t *pcm;
#else
  vorbis_sample_t **pcm;
#endif
  guint sample_count;
  GstBuffer *out = NULL;
  GstFlowReturn result, newresult;
  gint size;

  if (G_UNLIKELY (!vd->initialized)) {
    result = vorbis_dec_handle_header_caps (vd);
    if (result != GST_FLOW_OK)
      goto not_initialized;
  }

  /* normal data packet */
  /* FIXME, we can skip decoding if the packet is outside of the
   * segment, this is however not very trivial as we need a previous
   * packet to decode the current one so we must be careful not to
   * throw away too much. For now we decode everything and clip right
   * before pushing data. */

#ifdef USE_TREMOLO
  if (G_UNLIKELY (vorbis_dsp_synthesis (&vd->vd, packet, 1)))
    goto could_not_read;
#else
  if (G_UNLIKELY (vorbis_synthesis (&vd->vb, packet)))
    goto could_not_read;

  if (G_UNLIKELY (vorbis_synthesis_blockin (&vd->vd, &vd->vb) < 0))
    goto not_accepted;
#endif

  /* assume all goes well here */
  result = GST_FLOW_OK;

  /* count samples ready for reading */
#ifdef USE_TREMOLO
  if ((sample_count = vorbis_dsp_pcmout (&vd->vd, NULL, 0)) == 0)
#else
  if ((sample_count = vorbis_synthesis_pcmout (&vd->vd, NULL)) == 0)
    goto done;
#endif

  size = sample_count * vd->vi.channels * vd->width;
  GST_LOG_OBJECT (vd, "%d samples ready for reading, size %d", sample_count,
      size);

  /* alloc buffer for it */
  result =
      gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (vd),
      GST_BUFFER_OFFSET_NONE, size,
      GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (vd)), &out);
  if (G_UNLIKELY (result != GST_FLOW_OK))
    goto done;

  /* get samples ready for reading now, should be sample_count */
#ifdef USE_TREMOLO
  pcm = GST_BUFFER_DATA (out);
  if (G_UNLIKELY (vorbis_dsp_pcmout (&vd->vd, pcm, sample_count) !=
          sample_count))
#else
  if (G_UNLIKELY (vorbis_synthesis_pcmout (&vd->vd, &pcm) != sample_count))
#endif
    goto wrong_samples;

#ifndef USE_TREMOLO
  /* copy samples in buffer */
  vd->copy_samples ((vorbis_sample_t *) GST_BUFFER_DATA (out), pcm,
      sample_count, vd->vi.channels, vd->width);
#endif

  GST_LOG_OBJECT (vd, "setting output size to %d", size);
  GST_BUFFER_SIZE (out) = size;

done:
  /* whether or not data produced, consume one frame and advance time */
  newresult = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (vd), out, 1);
  if (G_UNLIKELY (newresult != GST_FLOW_OK))
    result = newresult;

#ifdef USE_TREMOLO
  vorbis_dsp_read (&vd->vd, sample_count);
#else
  vorbis_synthesis_read (&vd->vd, sample_count);
#endif

  return result;

  /* ERRORS */
not_initialized:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("no header sent yet"));
    return GST_FLOW_NOT_NEGOTIATED;
  }
could_not_read:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("couldn't read data packet"));
    return GST_FLOW_ERROR;
  }
not_accepted:
  {
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("vorbis decoder did not accept data packet"));
    return GST_FLOW_ERROR;
  }
wrong_samples:
  {
    gst_buffer_unref (out);
    GST_ELEMENT_ERROR (GST_ELEMENT (vd), STREAM, DECODE,
        (NULL), ("vorbis decoder reported wrong number of samples"));
    return GST_FLOW_ERROR;
  }
}