コード例 #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutputStream{TFrame}"/> class.
 /// </summary>
 /// <param name="stream">The multimedia stream.</param>
 /// <param name="owner">The container that owns the stream.</param>
 public OutputStream(AVStream *stream, OutputContainer owner)
     : base(stream)
 {
     OwnerFile = owner;
     packet    = MediaPacket.AllocateEmpty();
 }
コード例 #2
0
        /// <summary>
        /// Creates a new video stream for the specified <see cref="OutputContainer"/>.
        /// </summary>
        /// <param name="container">The media container.</param>
        /// <param name="config">The stream settings.</param>
        /// <returns>The new video stream.</returns>
        public static OutputStream <VideoFrame> CreateVideo(OutputContainer container, VideoEncoderSettings config)
        {
            var codecId = config.Codec == VideoCodec.Default ? container.Pointer->oformat->video_codec : (AVCodecID)config.Codec;

            if (codecId == AVCodecID.AV_CODEC_ID_NONE)
            {
                throw new InvalidOperationException("The media container doesn't support video!");
            }

            var codec = ffmpeg.avcodec_find_encoder(codecId);

            if (codec == null)
            {
                throw new InvalidOperationException($"Cannot find an encoder with the {codecId}!");
            }

            if (codec->type != AVMediaType.AVMEDIA_TYPE_VIDEO)
            {
                throw new InvalidOperationException($"The {codecId} encoder doesn't support video!");
            }

            var videoStream = ffmpeg.avformat_new_stream(container.Pointer, codec);

            videoStream->time_base = new AVRational {
                num = 1, den = config.Framerate
            };
            var codecContext = videoStream->codec;

            codecContext->codec_id   = codecId;
            codecContext->codec_type = AVMediaType.AVMEDIA_TYPE_VIDEO;

            codecContext->width  = config.VideoWidth;
            codecContext->height = config.VideoHeight;

            codecContext->time_base = videoStream->time_base;
            codecContext->gop_size  = config.KeyframeRate;
            codecContext->pix_fmt   = (AVPixelFormat)config.VideoFormat;

            if ((container.Pointer->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) != 0)
            {
                codecContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
            }

            var dict = new FFDictionary(config.CodecOptions);

            if (config.CRF.HasValue && config.Codec.IsMatch(VideoCodec.H264, VideoCodec.H265, VideoCodec.VP9, VideoCodec.VP8))
            {
                dict["crf"] = config.CRF.Value.ToString();
            }
            else
            {
                codecContext->bit_rate = config.Bitrate;
            }

            if (config.Codec.IsMatch(VideoCodec.H264, VideoCodec.H265))
            {
                dict["preset"] = config.EncoderPreset.GetDescription();
            }

            var ptr = dict.Pointer;

            ffmpeg.avcodec_open2(codecContext, codec, &ptr);

            dict.Update(ptr);

            return(new OutputStream <VideoFrame>(videoStream, container));
        }