/// <summary> /// Creates a frame source object given the raw FFmpeg frame reference. /// </summary> /// <param name="framePointer">The raw FFmpeg frame pointer.</param> /// <returns>The media frame</returns> protected override unsafe MediaFrame CreateFrameSource(IntPtr framePointer) { // Validate the audio frame var frame = (AVFrame *)framePointer; if (frame == null || (*frame).extended_data == null || frame->channels <= 0 || frame->nb_samples <= 0 || frame->sample_rate <= 0) { return(null); } if (string.IsNullOrWhiteSpace(FilterString) == false) { InitializeFilterGraph(frame); } AVFrame *outputFrame = null; // Filtergraph can be changed by issuing a ChangeMedia command if (FilterGraph != null) { // Allocate the output frame outputFrame = MediaFrame.CloneAVFrame(frame); var result = ffmpeg.av_buffersrc_add_frame(SourceFilter, outputFrame); while (result >= 0) { result = ffmpeg.av_buffersink_get_frame_flags(SinkFilter, outputFrame, 0); } if (outputFrame->nb_samples <= 0) { // If we don't have a valid output frame simply release it and // return the original input frame MediaFrame.ReleaseAVFrame(outputFrame); outputFrame = frame; } else { // the output frame is the new valid frame (output frame). // threfore, we need to release the original MediaFrame.ReleaseAVFrame(frame); } } else { outputFrame = frame; } // Check if the output frame is valid if (outputFrame->nb_samples <= 0) { return(null); } var frameHolder = new AudioFrame(outputFrame, this); return(frameHolder); }
/// <summary> /// Creates a frame source object given the raw FFmpeg frame reference. /// </summary> /// <param name="frame">The raw FFmpeg frame pointer.</param> /// <returns>The media frame</returns> protected override unsafe MediaFrame CreateFrameSource(ref AVFrame *frame) { if (string.IsNullOrWhiteSpace(FilterString) == false) { InitializeFilterGraph(frame); } AVFrame *outputFrame = null; // TODO: Support real-time changes in Audio Filtergraph by checking if MediaOptions.AudioFilterGraph has changed // Maybe expose the AudioFilterGraph string as a MediaElement Control Property if (FilterGraph != null) { // Allocate the output frame outputFrame = ffmpeg.av_frame_clone(frame); var result = ffmpeg.av_buffersrc_add_frame(SourceFilter, outputFrame); while (result >= 0) { result = ffmpeg.av_buffersink_get_frame_flags(SinkFilter, outputFrame, 0); } if (outputFrame->nb_samples <= 0) { // If we don't have a valid output frame simply release it and // return the original input frame RC.Current.Remove(outputFrame); ffmpeg.av_frame_free(&outputFrame); outputFrame = frame; } else { // the output frame is the new valid frame (output frame). // threfore, we need to release the original RC.Current.Remove(frame); var framePtr = frame; ffmpeg.av_frame_free(&framePtr); } } else { outputFrame = frame; } // Check if the output frame is valid if (outputFrame->nb_samples <= 0) { return(null); } var frameHolder = new AudioFrame(outputFrame, this); return(frameHolder); }
/// <summary> /// Creates a frame source object given the raw FFmpeg frame reference. /// </summary> /// <param name="frame">The raw FFmpeg frame pointer.</param> /// <returns></returns> protected override unsafe MediaFrame CreateFrameSource(AVFrame *frame) { var frameHolder = new AudioFrame(frame, this); return(frameHolder); }