Пример #1
0
        public FilterInOut(string name, FilterContext filterContext)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("Required", nameof(name));
            }

            FilterContext = filterContext;

            Pointer = ffmpeg.avfilter_inout_alloc();

            if (Pointer == null)
            {
                throw new Exception("FilterInOut was not allocated");
            }

            Pointer->name       = ffmpeg.av_strdup(name);
            Pointer->filter_ctx = filterContext.Pointer;
            Pointer->pad_idx    = 0;
            Pointer->next       = null;
        }
Пример #2
0
        public static FilterGraph Create(
            Codec decoder,
            Codec encoder,
            string filterSpecification)
        {
            if (decoder is null)
            {
                throw new ArgumentNullException(nameof(decoder));
            }
            if (encoder is null)
            {
                throw new ArgumentNullException(nameof(encoder));
            }

            FilterContext bufferSource = default;
            FilterContext bufferSink   = default;

            var graph = new FilterGraph();

            if (decoder is VideoDecoder)
            {
                var format = new VideoFormatInfo(
                    decoder.Context.PixelFormat,
                    decoder.Context.Width,
                    decoder.Context.Height,
                    decoder.Context.TimeBase,
                    decoder.Context.AspectRatio
                    );

                bufferSource = graph.AddSource(format);

                bufferSink = graph.AddSink(Filter.FromName("buffersink"));

                bufferSink.SetOption("pix_fmts", (int)encoder.Context.PixelFormat.ToAVFormat());
            }
            else if (decoder is AudioDecoder audioDecoder)
            {
                if (audioDecoder.Context.ChannelLayout == ChannelLayout.Unknown)
                {
                    throw new Exception("Invalid ChannelLayout:" + audioDecoder.Context.ChannelLayout);

                    // decoder.Context.ChannelLayout = (ChannelLayout)ffmpeg.av_get_default_channel_layout(decoder.Context.ChannelCount);
                }

                bufferSource = graph.AddSource(new AudioFormatInfo(
                                                   sampleFormat: audioDecoder.Context.SampleFormat,
                                                   sampleRate: audioDecoder.Context.SampleRate,
                                                   channelCount: audioDecoder.Context.ChannelCount,
                                                   channelLayout: audioDecoder.Context.ChannelLayout
                                                   ));

                bufferSink = graph.AddSink(Filter.FromName("abuffersink"));

                // $"aresample={resampledAudioFormat.SampleRate},aformat=sample_fmts={sampleFormat}:channel_layouts=stereo,asetnsamples=n=1024:p=0"

                // var sampleFormatName = ffmpeg.av_get_sample_fmt_name(encoder.Context.SampleFormat.ToAVFormat());

                bufferSink.SetOption("sample_fmts", (int)encoder.Context.SampleFormat.ToAVFormat());
                bufferSink.SetOption("channel_layouts", (ulong)encoder.Context.ChannelLayout);
                bufferSink.SetOption("sample_rates", encoder.Context.SampleRate);
            }
            else
            {
                throw new Exception("Invalid codec");
            }


            graph.Outputs = new FilterInOut("in", bufferSource);
            graph.Inputs  = new FilterInOut("out", bufferSink);

            graph.bufferSource = bufferSource;
            graph.bufferSink   = bufferSink;

            if (filterSpecification != null)
            {
                graph.Parse(filterSpecification);
            }
            else
            {
                ffmpeg.avfilter_link(bufferSource.Pointer, 0, bufferSink.Pointer, 0);
            }

            graph.Initialize();

            return(graph);
        }