private unsafe void Button_Test_Click(object sender, RoutedEventArgs e)
        {
            Bitmap bitmap = CreateTestBitmap();

            AVFrame* inFrame = FFmpegInvoke.avcodec_alloc_frame();
            if (inFrame == null) throw new Exception("Could not allocate video frame");
            inFrame->width = bitmap.Width;
            inFrame->height = bitmap.Height;
            inFrame->format = (int)AVPixelFormat.AV_PIX_FMT_BGR24;

            int ret1 = FFmpegInvoke.av_image_alloc(&inFrame->data_0, inFrame->linesize, bitmap.Width, bitmap.Height, AVPixelFormat.AV_PIX_FMT_BGR24, 32);
            if (ret1 < 0) throw new Exception("Could not allocate raw picture buffer");

            VideoHelper.UpdateFrame(inFrame, bitmap);
            VideoConverter converterToYuv = new VideoConverter(AVPixelFormat.AV_PIX_FMT_YUV420P);
            var data = converterToYuv.ConvertFrame(inFrame);

            var bitmap2 = VideoHelper.CreateBitmap(data, bitmap.Width, bitmap.Height);

            SetImageSource(bitmap2);
        }
        public VideoEncoder(int width, int height, int fps)
        {
            _converter = new VideoConverter(CODEC_PIXEL_FORMAT);

            AVCodec* codec = FFmpegInvoke.avcodec_find_encoder(CODEC_ID);
            if (codec == null) throw new Exception("Codec not found");

            _codec_context = FFmpegInvoke.avcodec_alloc_context3(codec);
            if (_codec_context == null) throw new Exception("Could not allocate video codec context");

            _codec_context->bit_rate = 50000;
            _codec_context->width = width;
            _codec_context->height = height;
            _codec_context->time_base = new AVRational() { num = 1, den = fps };
            _codec_context->gop_size = 10; // emit one intra frame every ten frames
            _codec_context->max_b_frames = 1;
            _codec_context->pix_fmt = CODEC_PIXEL_FORMAT;
            FFmpegInvoke.av_opt_set(_codec_context->priv_data, "preset", "fast", 0);
            if (FFmpegInvoke.avcodec_open2(_codec_context, codec, null) < 0) throw new Exception("Could not open codec");

            _avFrameYUV = FFmpegInvoke.avcodec_alloc_frame();
            if (_avFrameYUV == null) throw new Exception("Could not allocate video frame");
            _avFrameYUV->format = (int)CODEC_PIXEL_FORMAT;
            _avFrameYUV->width = width;
            _avFrameYUV->height = height;

            var ret1 = FFmpegInvoke.av_image_alloc(&_avFrameYUV->data_0, _avFrameYUV->linesize, width, height, CODEC_PIXEL_FORMAT, 32);
            if (ret1 < 0) throw new Exception("Could not allocate raw picture buffer");

            _avFrameBGR = FFmpegInvoke.avcodec_alloc_frame();
            if (_avFrameBGR == null) throw new Exception("Could not allocate video frame");
            _avFrameBGR->format = (int)INPUT_PIXEL_FORMAT;
            _avFrameBGR->width = width;
            _avFrameBGR->height = height;

            var ret2 = FFmpegInvoke.av_image_alloc(&_avFrameBGR->data_0, _avFrameBGR->linesize, width, height, INPUT_PIXEL_FORMAT, 32);
            if (ret2 < 0) throw new Exception("Could not allocate raw picture buffer");
        }
        public VideoEncoder(int width, int height, int fps)
        {
            _converter = new VideoConverter(CODEC_PIXEL_FORMAT);

            AVCodec *codec = FFmpegInvoke.avcodec_find_encoder(CODEC_ID);

            if (codec == null)
            {
                throw new Exception("Codec not found");
            }

            _codec_context = FFmpegInvoke.avcodec_alloc_context3(codec);
            if (_codec_context == null)
            {
                throw new Exception("Could not allocate video codec context");
            }

            _codec_context->bit_rate  = 50000;
            _codec_context->width     = width;
            _codec_context->height    = height;
            _codec_context->time_base = new AVRational()
            {
                num = 1, den = fps
            };
            _codec_context->gop_size     = 10; // emit one intra frame every ten frames
            _codec_context->max_b_frames = 1;
            _codec_context->pix_fmt      = CODEC_PIXEL_FORMAT;
            FFmpegInvoke.av_opt_set(_codec_context->priv_data, "preset", "fast", 0);
            if (FFmpegInvoke.avcodec_open2(_codec_context, codec, null) < 0)
            {
                throw new Exception("Could not open codec");
            }

            _avFrameYUV = FFmpegInvoke.avcodec_alloc_frame();
            if (_avFrameYUV == null)
            {
                throw new Exception("Could not allocate video frame");
            }
            _avFrameYUV->format = (int)CODEC_PIXEL_FORMAT;
            _avFrameYUV->width  = width;
            _avFrameYUV->height = height;

            var ret1 = FFmpegInvoke.av_image_alloc(&_avFrameYUV->data_0, _avFrameYUV->linesize, width, height, CODEC_PIXEL_FORMAT, 32);

            if (ret1 < 0)
            {
                throw new Exception("Could not allocate raw picture buffer");
            }

            _avFrameBGR = FFmpegInvoke.avcodec_alloc_frame();
            if (_avFrameBGR == null)
            {
                throw new Exception("Could not allocate video frame");
            }
            _avFrameBGR->format = (int)INPUT_PIXEL_FORMAT;
            _avFrameBGR->width  = width;
            _avFrameBGR->height = height;

            var ret2 = FFmpegInvoke.av_image_alloc(&_avFrameBGR->data_0, _avFrameBGR->linesize, width, height, INPUT_PIXEL_FORMAT, 32);

            if (ret2 < 0)
            {
                throw new Exception("Could not allocate raw picture buffer");
            }
        }