AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, int perms) { AVFilterBufferRef *samplesref; int channels = av_frame_get_channels(frame); int64_t layout = av_frame_get_channel_layout(frame); if(av_frame_get_channels(frame) > 8) // libavfilter does not suport more than 8 channels FIXME, remove once libavfilter is fixed return NULL; if (layout && av_get_channel_layout_nb_channels(layout) != av_frame_get_channels(frame)) { av_log(0, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); return NULL; } samplesref = avfilter_get_audio_buffer_ref_from_arrays_channels( (uint8_t **)frame->data, frame->linesize[0], perms, frame->nb_samples, frame->format, channels, layout); if (!samplesref) return NULL; if (avfilter_copy_frame_props(samplesref, frame) < 0) { samplesref->buf->data[0] = NULL; avfilter_unref_bufferp(&samplesref); } return samplesref; }
string AudioSamples::channelsLayoutString() const { if (!m_raw) return ""; char buf[128] = {0}; av_get_channel_layout_string(buf, sizeof(buf), av_frame_get_channels(m_raw), av_frame_get_channel_layout(m_raw)); return string(buf); }
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, int perms) { AVFilterBufferRef *picref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms, frame->nb_samples, frame->format, av_frame_get_channel_layout(frame)); if (!picref) return NULL; avfilter_copy_frame_props(picref, frame); return picref; }
static void print_frame(const AVFrame *frame) { const int n = frame->nb_samples * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame)); const uint16_t *p = (uint16_t*)frame->data[0]; const uint16_t *p_end = p + n; while (p < p_end) { fputc(*p & 0xff, stdout); fputc(*p>>8 & 0xff, stdout); p++; } fflush(stdout); }
AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame, int perms) { AVFilterBufferRef *samplesref = avfilter_get_audio_buffer_ref_from_arrays((uint8_t **)frame->data, frame->linesize[0], perms, frame->nb_samples, frame->format, av_frame_get_channel_layout(frame)); if (!samplesref) return NULL; if (avfilter_copy_frame_props(samplesref, frame) < 0) { samplesref->buf->data[0] = NULL; avfilter_unref_bufferp(&samplesref); } return samplesref; }
static gboolean settings_changed (GstFFMpegAudDec * ffmpegdec, AVFrame * frame) { GstAudioFormat format; gint channels = av_get_channel_layout_nb_channels (av_frame_get_channel_layout (frame)); format = gst_ffmpeg_smpfmt_to_audioformat (frame->format); if (format == GST_AUDIO_FORMAT_UNKNOWN) return TRUE; return !(ffmpegdec->info.rate == av_frame_get_sample_rate (frame) && ffmpegdec->info.channels == channels && ffmpegdec->info.finfo->format == format); }
void emit_frame(const AVFrame *frame) { const int n = frame->nb_samples * av_get_channel_layout_nb_channels(av_frame_get_channel_layout(frame)); const uint16_t *p = (uint16_t*)frame->data[0]; const uint16_t *p_end = p + n; #if 0 while (p < p_end) { fputc(*p & 0xff, stdout); fputc(*p>>8 & 0xff, stdout); p++; } #else static int a = 0; a += n; int64_t dur = av_frame_get_pkt_duration(frame); // in AVStream->time_base units double seconds = (double(dur) * timebase.num) / timebase.den; static double s = 0; s += seconds; printf("another %d samples, %f seconds, respective totals %d %f\n", n, seconds, a, s); #endif fflush(stdout); }
static gboolean gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec, AVCodecContext * context, AVFrame * frame, gboolean force) { GstFFMpegAudDecClass *oclass; GstAudioFormat format; gint channels; GstAudioChannelPosition pos[64] = { 0, }; oclass = (GstFFMpegAudDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); format = gst_ffmpeg_smpfmt_to_audioformat (frame->format); if (format == GST_AUDIO_FORMAT_UNKNOWN) goto no_caps; channels = av_get_channel_layout_nb_channels (av_frame_get_channel_layout (frame)); if (channels == 0) channels = av_frame_get_channels (frame); if (channels == 0) goto no_caps; if (!force && !settings_changed (ffmpegdec, frame)) return TRUE; GST_DEBUG_OBJECT (ffmpegdec, "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)", ffmpegdec->info.rate, ffmpegdec->info.channels, ffmpegdec->info.finfo->format, av_frame_get_sample_rate (frame), channels, format); gst_ffmpeg_channel_layout_to_gst (av_frame_get_channel_layout (frame), channels, pos); memcpy (ffmpegdec->ffmpeg_layout, pos, sizeof (GstAudioChannelPosition) * channels); /* Get GStreamer channel layout */ gst_audio_channel_positions_to_valid_order (pos, channels); ffmpegdec->needs_reorder = memcmp (pos, ffmpegdec->ffmpeg_layout, sizeof (pos[0]) * channels) != 0; gst_audio_info_set_format (&ffmpegdec->info, format, av_frame_get_sample_rate (frame), channels, pos); if (!gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (ffmpegdec), &ffmpegdec->info)) goto caps_failed; return TRUE; /* ERRORS */ no_caps: { #ifdef HAVE_LIBAV_UNINSTALLED /* using internal ffmpeg snapshot */ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, ("Could not find GStreamer caps mapping for libav codec '%s'.", oclass->in_plugin->name), (NULL)); #else /* using external ffmpeg */ GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, ("Could not find GStreamer caps mapping for libav codec '%s', and " "you are using an external libavcodec. This is most likely due to " "a packaging problem and/or libavcodec having been upgraded to a " "version that is not compatible with this version of " "gstreamer-libav. Make sure your gstreamer-libav and libavcodec " "packages come from the same source/repository.", oclass->in_plugin->name), (NULL)); #endif return FALSE; } caps_failed: { GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL), ("Could not set caps for libav decoder (%s), not fixed?", oclass->in_plugin->name)); memset (&ffmpegdec->info, 0, sizeof (ffmpegdec->info)); return FALSE; } }
int64_t AudioSamples::channelsLayout() const { return m_raw ? av_frame_get_channel_layout(m_raw) : 0; }