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