Пример #1
0
        protected override IEnumerable <(FFmpegCodec codec, AVHWDeviceType hwDeviceType)> GetAvailableDecoders(
            AVInputFormat *inputFormat,
            AVCodecID codecId,
            HardwareVideoDecoder targetHwDecoders
            )
        {
            if (targetHwDecoders.HasFlagFast(HardwareVideoDecoder.MediaCodec))
            {
                string formatName = Marshal.PtrToStringAnsi((IntPtr)inputFormat->name);

                switch (formatName)
                {
                // MediaCodec doesn't return correct timestamps when playing back AVI files
                // which results in the video running at ~30% less FPS than it's supposed to.
                case "avi":
                {
                    Logger.Log($"Disabling HW decoding for this video because of unsupported input format: ${formatName}");
                    targetHwDecoders &= ~HardwareVideoDecoder.MediaCodec;
                    break;
                }
                }
            }

            return(base.GetAvailableDecoders(inputFormat, codecId, targetHwDecoders));
        }
Пример #2
0
        /// <summary>
        /// Gets the available hardware decoder codecs for the given codec id (codec family).
        /// </summary>
        /// <param name="codecFamily">The codec family.</param>
        /// <returns>A list of hardware-enabled decoder codec names.</returns>
        private static List <string> GetHardwareDecoders(AVCodecID codecFamily)
        {
            var result = new List <string>(16);

            foreach (var c in Library.AllCodecs)
            {
                if (ffmpeg.av_codec_is_decoder(c) == 0)
                {
                    continue;
                }

                if (c->id != codecFamily)
                {
                    continue;
                }

                if ((c->capabilities & ffmpeg.AV_CODEC_CAP_HARDWARE) != 0 ||
                    (c->capabilities & ffmpeg.AV_CODEC_CAP_HYBRID) != 0)
                {
                    result.Add(Utilities.PtrToStringUTF8(c->name));
                }
            }

            return(result);
        }
Пример #3
0
        public void Core(CodecId codecId, AVCodecID avCodecId, ImageFormat format)
        {
            Assert.Equal((int)format, (int)codecId);

            Assert.Equal(codecId, avCodecId.ToCodecId());
            Assert.Equal(avCodecId, codecId.ToAVCodecID());
        }
Пример #4
0
        public VideoEncoder(AVCodecID codecID, int frameWidth, int frameHeight, int framesPerSecond)
        {
            _frameWidth  = frameWidth;
            _frameHeight = frameHeight;

            _videoCodec = ffmpeg.avcodec_find_encoder(codecID);
            if (_videoCodec == null)
            {
                throw new ApplicationException($"Codec encoder could not be found for {codecID}.");
            }

            _videoCodecContext = ffmpeg.avcodec_alloc_context3(_videoCodec);
            if (_videoCodecContext == null)
            {
                throw new ApplicationException("Failed to allocated codec context.");
            }

            _videoCodecContext->width         = frameWidth;
            _videoCodecContext->height        = frameHeight;
            _videoCodecContext->time_base.den = 30;
            _videoCodecContext->time_base.num = 1;
            _videoCodecContext->pix_fmt       = AVPixelFormat.AV_PIX_FMT_YUV420P;

            ffmpeg.avcodec_open2(_videoCodecContext, _videoCodec, null).ThrowExceptionIfError();
        }
Пример #5
0
        public static MediaEncoder CreateEncode(AVCodecID codecId, int flags, Action <MediaCodec> setBeforeOpen = null, MediaDictionary opts = null)
        {
            MediaEncoder encode = new MediaEncoder(codecId);

            encode.Initialize(setBeforeOpen, flags, opts);
            return(encode);
        }
Пример #6
0
 /// <summary>
 /// Create and init video encode
 /// </summary>
 /// <param name="videoCodec"></param>
 /// <param name="flags"><see cref="MediaFormat.Flags"/></param>
 /// <param name="width">width pixel, must be greater than 0</param>
 /// <param name="height">height pixel, must be greater than 0</param>
 /// <param name="fps">fps, must be greater than 0</param>
 /// <param name="bitRate">default is auto bit rate, must be greater than or equal to 0</param>
 /// <param name="format">default is first supported pixel format</param>
 /// <returns></returns>
 public static MediaEncoder CreateVideoEncode(AVCodecID videoCodec, int flags, int width, int height, int fps, long bitRate = 0, AVPixelFormat format = AVPixelFormat.AV_PIX_FMT_NONE)
 {
     return(CreateEncode(videoCodec, flags, _ =>
     {
         AVCodecContext *pCodecContext = _;
         if (width <= 0 || height <= 0 || fps <= 0 || bitRate < 0)
         {
             throw new FFmpegException(FFmpegException.NonNegative);
         }
         if (_.SupportedPixelFmts.Count() <= 0)
         {
             throw new FFmpegException(FFmpegException.NotSupportCodecId);
         }
         if (format == AVPixelFormat.AV_PIX_FMT_NONE)
         {
             format = _.SupportedPixelFmts[0];
         }
         else if (_.SupportedPixelFmts.Where(__ => __ == format).Count() <= 0)
         {
             throw new FFmpegException(FFmpegException.NotSupportFormat);
         }
         pCodecContext->width = width;
         pCodecContext->height = height;
         pCodecContext->time_base = new AVRational {
             num = 1, den = fps
         };
         pCodecContext->pix_fmt = format;
         pCodecContext->bit_rate = bitRate;
     }));
 }
Пример #7
0
 /// <summary>
 /// Find decoder by id
 /// <para>
 /// Must call <see cref="Initialize(Action{MediaCodec}, int, MediaDictionary)"/> before decode
 /// </para>
 /// </summary>
 /// <param name="codecId">codec id</param>
 public MediaDecode(AVCodecID codecId) : this(ffmpeg.avcodec_find_decoder(codecId))
 {
     if (pCodec == null && codecId != AVCodecID.AV_CODEC_ID_NONE)
     {
         throw new FFmpegException(ffmpeg.AVERROR_DECODER_NOT_FOUND);
     }
 }
Пример #8
0
        private static unsafe AVStream *add_audio_stream(AVFormatContext *oc, AVCodecID codec_id, int sample_rate = 44100)
        {
            AVCodecContext *c;
            AVCodec *       encoder = ffmpeg.avcodec_find_encoder(codec_id);
            AVStream *      st      = ffmpeg.avformat_new_stream(oc, encoder);

            if (st == null)
            {
                die("av_new_stream");
            }

            c             = st->codec;
            c->codec_id   = codec_id;
            c->codec_type = AVMediaType.AVMEDIA_TYPE_AUDIO;

            /* put sample parameters */
            c->bit_rate       = 64000;
            c->sample_rate    = sample_rate;
            c->channels       = 2;
            c->sample_fmt     = encoder->sample_fmts[0];
            c->channel_layout = ffmpeg.AV_CH_LAYOUT_STEREO;

            // some formats want stream headers to be separate
            if ((oc->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) != 0)
            {
                c->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
            }

            return(st);
        }
Пример #9
0
        public void Core(CodecId codecId, AVCodecID avCodecId, FormatId format)
        {
            // Assert.Equal((int)codecId, (int)format);

            Assert.Equal(codecId, avCodecId.ToCodecId());
            Assert.Equal(avCodecId, codecId.ToAVCodecID());
        }
Пример #10
0
        private void AddVideoStream(AVCodecID codecId)
        {
            GetVideoCodec(codecId);

            _videoStream = ffmpeg.avformat_new_stream(_formatContext, null);
            if (_videoStream == null)
            {
                throw new Exception("Failed creating new video stream.");
            }

            _videoStream->time_base.num = _videoCodecContext->time_base.num;
            _videoStream->time_base.den = _videoCodecContext->time_base.den;

            if (_videoCodecContext->extradata_size > 0)
            {
                _videoStream->codecpar->extradata_size = _videoCodecContext->extradata_size;
                _videoStream->codecpar->extradata      = (byte *)ffmpeg.av_malloc((ulong)_videoCodecContext->extradata_size + ffmpeg.AV_INPUT_BUFFER_PADDING_SIZE);

                var j = 0;
                while (j++ < _videoCodecContext->extradata_size)
                {
                    *(_videoStream->codecpar->extradata + j) = *(_videoCodecContext->extradata + j);
                }
            }
        }
Пример #11
0
 /// <summary>
 /// Find encoder by id
 /// <para>
 /// Must call <see cref="Initialize(Action{MediaCodec}, int, MediaDictionary)"/> before encode
 /// </para>
 /// </summary>
 /// <param name="codecId">codec id</param>
 public MediaEncoder(AVCodecID codecId)
 {
     if ((pCodec = ffmpeg.avcodec_find_encoder(codecId)) == null && codecId != AVCodecID.AV_CODEC_ID_NONE)
     {
         throw new FFmpegException(ffmpeg.AVERROR_ENCODER_NOT_FOUND);
     }
 }
Пример #12
0
        /// <summary>
        /// Gets the supported hardware decoder device types for the given codec.
        /// </summary>
        /// <param name="codecId">The codec identifier.</param>
        /// <returns>
        /// A list of hardware device decoders compatible with the codec
        /// </returns>
        public static List <HardwareDeviceInfo> GetCompatibleDevices(AVCodecID codecId)
        {
            const int AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX = 0x01;
            var       codec       = ffmpeg.avcodec_find_decoder(codecId);
            var       result      = new List <HardwareDeviceInfo>(64);
            var       configIndex = 0;

            // skip unsupported configs
            if (codec == null || codecId == AVCodecID.AV_CODEC_ID_NONE)
            {
                return(result);
            }

            while (true)
            {
                var config = ffmpeg.avcodec_get_hw_config(codec, configIndex);
                if (config == null)
                {
                    break;
                }

                if ((config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX) != 0 &&
                    config->device_type != AVHWDeviceType.AV_HWDEVICE_TYPE_NONE)
                {
                    result.Add(new HardwareDeviceInfo(config));
                }

                configIndex++;
            }

            return(result);
        }
Пример #13
0
 /// <summary>
 /// Find decoder by id
 /// <para>
 /// Must call <see cref="Initialize(Action{MediaCodec}, int, MediaDictionary)"/> before decode
 /// </para>
 /// </summary>
 /// <param name="codecId">codec id</param>
 public MediaDecoder(AVCodecID codecId)
 {
     if ((pCodec = ffmpeg.avcodec_find_decoder(codecId)) == null)
     {
         throw new FFmpegException(ffmpeg.AVERROR_DECODER_NOT_FOUND);
     }
 }
Пример #14
0
        public FFmpegContext(AVCodecID codecId)
        {
            _codec = ffmpeg.avcodec_find_decoder(codecId);
            if (_codec == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, $"Codec wasn't found. Make sure you have the {codecId} codec present in your FFmpeg installation.");

                return;
            }

            _context = ffmpeg.avcodec_alloc_context3(_codec);
            if (_context == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec context couldn't be allocated.");

                return;
            }

            if (ffmpeg.avcodec_open2(_context, _codec, null) != 0)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec couldn't be opened.");

                return;
            }

            _packet = ffmpeg.av_packet_alloc();
            if (_packet == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Packet couldn't be allocated.");

                return;
            }

            _decodeFrame = Marshal.GetDelegateForFunctionPointer <AVCodec_decode>(_codec->decode.Pointer);
        }
Пример #15
0
        public static MediaDecode CreateDecode(AVCodecID codecId, Action <MediaCodec> setBeforeOpen = null, MediaDictionary opts = null)
        {
            MediaDecode encode = new MediaDecode(codecId);

            encode.Initialize(setBeforeOpen, 0, opts);
            return(encode);
        }
Пример #16
0
        public AudioEncoder(OutputContext outputContext, AVCodecID codecID, int outputSampleRate = -1, int outputChannels = 2, long outputBitRate = 160000)
        {
            try
            {
                Output = outputContext;

                AVCodec *codec;
                if ((codec = ffmpeg.avcodec_find_encoder(codecID)) == null)
                {
                    throw new FFmpegException(ffmpeg.AVERROR_UNKNOWN, "Failed to find encoder codec.");
                }
                var stream = Output.CreateNewStream(codec);
                if ((codecContext = ffmpeg.avcodec_alloc_context3(codec)) == null)
                {
                    throw new FFmpegException(ffmpeg.AVERROR(ffmpeg.ENOMEM), "Failed to allocate encoder context.");
                }
                codecContext->channels       = outputChannels;
                codecContext->channel_layout = (ulong)ffmpeg.av_get_default_channel_layout(codecContext->channels);
                var supportedSampleRates = GetSupportedSampleRates();
                if (supportedSampleRates == null || supportedSampleRates.Contains(outputSampleRate))
                {
                    if (outputSampleRate == -1)
                    {
                        throw new ArgumentException("Failed to determine sample rate.");
                    }
                    codecContext->sample_rate = outputSampleRate;
                }
                else
                {
                    // Use closest available sample rate
                    codecContext->sample_rate = supportedSampleRates
                                                .OrderBy(rate => Math.Abs(rate - outputSampleRate))
                                                .First();
                }
                codecContext->sample_fmt = codec->sample_fmts[0];
                codecContext->bit_rate   = outputBitRate;
                stream->time_base.num    = 1;
                stream->time_base.den    = codecContext->sample_rate;
                if (Output.OutputFormatHasFlag(ffmpeg.AVFMT_GLOBALHEADER))
                {
                    codecContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
                }

                int ret;
                if ((ret = ffmpeg.avcodec_open2(codecContext, codec, null)) < 0)
                {
                    throw new FFmpegException(ret, "Failed to open encoder context.");
                }
                if ((ret = ffmpeg.avcodec_parameters_from_context(stream->codecpar, codecContext)) < 0)
                {
                    throw new FFmpegException(ret, "Failed to copy encoder context parameters to stream.");
                }
            }
            catch (Exception) when(this.DisposeOnException())
            {
            }
        }
Пример #17
0
        public void Core(CodecId codecId, AVCodecID avCodecId)
        {
            var i = (int)codecId;

            Assert.True(i >= 100_000 && i <= 100_999);

            Assert.Equal(codecId, avCodecId.ToCodecId());
            Assert.Equal(avCodecId, codecId.ToAVCodecID());
        }
Пример #18
0
        public static bool IsSupportedFormat(AVCodecID codecID, AVPixelFormat pixelFormat, AVRational frameRate)
        {
            var codec        = GetEncoder(codecID);
            var pixelFormats = GetSupportedPixelFormats(codec);
            var frameRates   = GetSupportedFrameRates(codec);

            return((pixelFormats?.Contains(pixelFormat) ?? true) &&
                   (frameRates?.Contains(frameRate) ?? true));
        }
Пример #19
0
        public static AudioFormat MatchSupportedFormat(AVCodecID codecID, AudioFormat format)
        {
            var codec          = CheckCodec(GetEncoder(codecID));
            var sampleFormats  = GetSupportedSampleFormats(codec);
            var sampleRates    = GetSupportedSampleRates(codec);
            var channelLayouts = GetSupportedChannelLayouts(codec);

            return(format.Match(sampleRates, sampleFormats, channelLayouts));
        }
Пример #20
0
        /// <summary>
        /// Retrieves a dictionary with the options for the specified codec.
        /// Port of filter_codec_opts
        /// </summary>
        /// <param name="codecId">The codec identifier.</param>
        /// <param name="format">The format.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="codec">The codec.</param>
        /// <returns>The filtered options</returns>
        internal unsafe FFDictionary FilterOptions(AVCodecID codecId, AVFormatContext *format, AVStream *stream, AVCodec *codec)
        {
            var result = new FFDictionary();

            if (codec == null)
            {
                codec = (format->oformat != null) ?
                        ffmpeg.avcodec_find_encoder(codecId) : ffmpeg.avcodec_find_decoder(codecId);
            }

            var codecClass = ffmpeg.avcodec_get_class();

            var flags = format->oformat != null ?
                        ffmpeg.AV_OPT_FLAG_ENCODING_PARAM : ffmpeg.AV_OPT_FLAG_DECODING_PARAM;

            var streamType = (char)0;

            switch (stream->codecpar->codec_type)
            {
            case AVMediaType.AVMEDIA_TYPE_VIDEO:
                streamType = 'v';
                flags     |= ffmpeg.AV_OPT_FLAG_VIDEO_PARAM;
                break;

            case AVMediaType.AVMEDIA_TYPE_AUDIO:
                streamType = 'a';
                flags     |= ffmpeg.AV_OPT_FLAG_AUDIO_PARAM;
                break;

            case AVMediaType.AVMEDIA_TYPE_SUBTITLE:
                streamType = 's';
                flags     |= ffmpeg.AV_OPT_FLAG_SUBTITLE_PARAM;
                break;
            }

            foreach (var optionItem in Options)
            {
                // Inline port of check_stream_specifier
                var matched = ffmpeg.avformat_match_stream_specifier(format, stream, optionItem.StreamSpecifier.ToString()) > 0;
                if (matched == false)
                {
                    continue;
                }

                if (ffmpeg.av_opt_find(&codecClass, optionItem.Key, null, flags, ffmpeg.AV_OPT_SEARCH_FAKE_OBJ) != null || codec == null ||
                    (codec->priv_class != null && ffmpeg.av_opt_find(&codec->priv_class, optionItem.Key, null, flags, ffmpeg.AV_OPT_SEARCH_FAKE_OBJ) != null))
                {
                    result[optionItem.Key] = optionItem.Value;
                }
                else if (optionItem.StreamSpecifier.StreamSuffix[0] == streamType && ffmpeg.av_opt_find(&codecClass, optionItem.Key, null, flags, ffmpeg.AV_OPT_SEARCH_FAKE_OBJ) != null)
                {
                    result[optionItem.Key] = optionItem.Value;
                }
            }

            return(result);
        }
Пример #21
0
        internal static AVCodec *GetEncoder(AVCodecID codecID)
        {
            AVCodec *codec = FF.avcodec_find_encoder(codecID);

            if (codec == null)
            {
                throw new ArgumentException($"未能找到编码器:{codecID}", nameof(codecID));
            }
            return(codec);
        }
Пример #22
0
        protected Format(AVCodecID eCodecID, IntPtr pAVCC, byte nThreads, AVFieldOrder eFieldsOrder)
            : this()
        {
            helper.Initialize();
            _pCodec     = NULL;
            nBufferSize = 0;
            int nResult = 0;

            _bEncode        = false;
            pAVCodecContext = pAVCC;
            _bAVCodecContextAllocationInternal = false;
            AVMediaType eAVMediaType = AVMediaType.AVMEDIA_TYPE_UNKNOWN;

            if (NULL != pAVCodecContext)
            {
                stAVCodecContext = (AVCodecContext)Marshal.PtrToStructure(pAVCodecContext, typeof(AVCodecContext));
                eAVMediaType     = stAVCodecContext.codec_type;
            }

            if (AVMediaType.AVMEDIA_TYPE_UNKNOWN == eAVMediaType)
            {
                if (CodecIDRawGet() != eCodecID)
                {
                    //if (AVCodecID.CODEC_ID_H264_MOBILE == eCodecID)
                    //	eCodecID = AVCodecID.CODEC_ID_H264;
                    if (NULL == (_pCodec = Functions.avcodec_find_encoder(eCodecID)))
                    {
                        throw new Exception("can't find codec " + eCodecID.ToString());
                    }
                }
                if (NULL == pAVCodecContext)
                {
                    //lock (helper._oSyncRootGlobal)
                    {
                        pAVCodecContext = Functions.avcodec_alloc_context3(_pCodec);
                        _bAVCodecContextAllocationInternal = true;
                    }
                }
                else
                {
                    //lock (helper._oSyncRootGlobal)
                    nResult = Functions.avcodec_get_context_defaults3(pAVCodecContext, _pCodec);
                }
                stAVCodecContext          = (AVCodecContext)Marshal.PtrToStructure(pAVCodecContext, typeof(AVCodecContext));
                stAVCodecContext.codec_id = eCodecID;
                _bEncode = true;
            }
            if (1 > nThreads)
            {
                nThreads = (byte)Environment.ProcessorCount;
            }
            stAVCodecContext.thread_count = nThreads;
            stAVCodecContext.field_order  = eFieldsOrder;
            Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
        }
Пример #23
0
        public FFmpegContext(AVCodecID codecId)
        {
            _codec   = ffmpeg.avcodec_find_decoder(codecId);
            _context = ffmpeg.avcodec_alloc_context3(_codec);

            ffmpeg.avcodec_open2(_context, _codec, null);

            _packet = ffmpeg.av_packet_alloc();

            _decodeFrame = Marshal.GetDelegateForFunctionPointer <AVCodec_decode>(_codec->decode.Pointer);
        }
Пример #24
0
        public static bool IsSupportedFormat(AVCodecID codecID, AudioFormat format)
        {
            var codec          = CheckCodec(GetEncoder(codecID));
            var sampleFormats  = GetSupportedSampleFormats(codec);
            var sampleRates    = GetSupportedSampleRates(codec);
            var channelLayouts = GetSupportedChannelLayouts(codec);

            return((sampleFormats?.Contains(format.SampleFormat) ?? true) &&
                   (sampleRates?.Contains(format.SampleRate) ?? true) &&
                   (channelLayouts?.Contains(format.ChannelLayout) ?? true));
        }
Пример #25
0
        public FFmpegContext(AVCodecID codecId)
        {
            _codec = FFmpegApi.avcodec_find_decoder(codecId);
            if (_codec == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, $"Codec wasn't found. Make sure you have the {codecId} codec present in your FFmpeg installation.");

                return;
            }

            _context = FFmpegApi.avcodec_alloc_context3(_codec);
            if (_context == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec context couldn't be allocated.");

                return;
            }

            if (FFmpegApi.avcodec_open2(_context, _codec, null) != 0)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Codec couldn't be opened.");

                return;
            }

            _packet = FFmpegApi.av_packet_alloc();
            if (_packet == null)
            {
                Logger.Error?.PrintMsg(LogClass.FFmpeg, "Packet couldn't be allocated.");

                return;
            }

            int avCodecRawVersion   = FFmpegApi.avcodec_version();
            int avCodecMajorVersion = avCodecRawVersion >> 16;
            int avCodecMinorVersion = (avCodecRawVersion >> 8) & 0xFF;

            // libavcodec 59.24 changed AvCodec to move its private API and also move the codec function to an union.
            if (avCodecMajorVersion > 59 || (avCodecMajorVersion == 59 && avCodecMinorVersion > 24))
            {
                _decodeFrame = Marshal.GetDelegateForFunctionPointer <FFCodec.AVCodec_decode>(((FFCodec *)_codec)->CodecCallback);
            }
            // libavcodec 59.x changed AvCodec private API layout.
            else if (avCodecMajorVersion == 59)
            {
                _decodeFrame = Marshal.GetDelegateForFunctionPointer <FFCodec.AVCodec_decode>(((FFCodecLegacy <AVCodec> *)_codec)->Decode);
            }
            // libavcodec 58.x and lower
            else
            {
                _decodeFrame = Marshal.GetDelegateForFunctionPointer <FFCodec.AVCodec_decode>(((FFCodecLegacy <AVCodecLegacy> *)_codec)->Decode);
            }
        }
Пример #26
0
 internal static unsafe byte[] Parse(AVCodecID codecId, byte* extradata, int size)
 {
     switch (codecId)
     {
         case AVCodecID.AV_CODEC_ID_H264:
             return ParseH264(extradata, size);
         case AVCodecID.AV_CODEC_ID_HEVC:
             return ParseH265(extradata, size);
         default:
             return null;
     }
 }
Пример #27
0
 public Codec(AVCodecID codecID, bool encode = true)
 {
     if (encode)
     {
         codec = GetEncoder(codecID);
     }
     else
     {
         codec = GetDecoder(codecID);
     }
     Name     = Marshal.PtrToStringAnsi((IntPtr)codec->Name);
     FullName = Marshal.PtrToStringAnsi((IntPtr)codec->LongName) ?? Name;
 }
Пример #28
0
        private void AddVideoStream(AVCodecID codecId)
        {
            GetVideoCodec(codecId);

            _videoStream = ffmpeg.avformat_new_stream(_formatContext, null);
            if (_videoStream == null)
            {
                throw new Exception("Failed creating new video stream.");
            }

            _videoStream->time_base.num = _videoCodecContext->time_base.num;
            _videoStream->time_base.den = _videoCodecContext->time_base.den;
        }
Пример #29
0
        private static void EnsureCodecInitialized(AVCodecID CodecId)
        {
            if (IsInitialized)
            {
                Uninitialize();
            }

            Codec   = ffmpeg.avcodec_find_decoder(CodecId);
            Context = ffmpeg.avcodec_alloc_context3(Codec);
            Frame   = ffmpeg.av_frame_alloc();

            ffmpeg.avcodec_open2(Context, Codec, null);

            IsInitialized = true;
        }
Пример #30
0
        private void GetVideoCodec(AVCodecID baseCodec)
        {
            if (baseCodec == AVCodecID.AV_CODEC_ID_H264)
            {
                if (Hwnvidia && MainForm.Conf.GPU.nVidia)
                {
                    _avPixelFormat = AVPixelFormat.AV_PIX_FMT_YUV420P;
                    _videoCodec    = ffmpeg.avcodec_find_encoder_by_name("nvenc_h264");
                    if (_videoCodec != null)
                    {
                        if (TryOpenVideoCodec(baseCodec))
                        {
                            Logger.LogMessage("using Nvidia hardware encoder");
                            return;
                        }
                    }
                }

                if (_hwqsv && MainForm.Conf.GPU.QuickSync)
                {
                    _avPixelFormat = AVPixelFormat.AV_PIX_FMT_NV12;
                    _videoCodec    = ffmpeg.avcodec_find_encoder_by_name("h264_qsv");
                    if (_videoCodec != null)
                    {
                        if (TryOpenVideoCodec(baseCodec))
                        {
                            Logger.LogMessage("using Intel QSV hardware encoder");
                            return;
                        }
                        Logger.LogMessage("Install Intel Media Server Studio and restart iSpy to use QSV");
                        _hwqsv = false;
                    }
                }
            }

            _avPixelFormat = AVPixelFormat.AV_PIX_FMT_YUV420P;
            _videoCodec    = ffmpeg.avcodec_find_encoder(baseCodec);

            if (TryOpenVideoCodec(baseCodec))
            {
                Logger.LogMessage("using software encoder");
                return;
            }

            Logger.LogMessage("could not open any encoder codec");
            throw new Exception("Failed opening any codec");
        }
Пример #31
0
 public static extern AVCodecDescriptor* avcodec_descriptor_get(AVCodecID id);
Пример #32
0
 public static extern AVMediaType avcodec_get_type(AVCodecID codec_id);
Пример #33
0
 public static extern String avcodec_get_name(AVCodecID id);
Пример #34
0
 public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, IntPtr pAVCC, byte nThreads)
     : this(nWidth, nHeight, eCodecID, ePixelFormat, pAVCC, nThreads, 800000)
 { }
Пример #35
0
 public static extern AVCodec* avcodec_find_encoder(AVCodecID id);
Пример #36
0
 public static extern int avformat_query_codec(AVOutputFormat* ofmt, AVCodecID codec_id, int std_compliance);
Пример #37
0
 public static extern string avcodec_profile_name(AVCodecID @codec_id, int @profile);
Пример #38
0
			public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, IntPtr pAVCC)
				: this(nWidth, nHeight, eCodecID, ePixelFormat, pAVCC, 0)
			{ }
Пример #39
0
public static extern System.Int32 av_get_exact_bits_per_sample(
	AVCodecID codec_id);
Пример #40
0
public static extern IntPtr/* AVCodec*  */ avcodec_find_encoder(
	AVCodecID id);
Пример #41
0
 public static extern int av_codec_get_tag2(AVCodecTag** @tags, AVCodecID @id, uint* @tag);
Пример #42
0
            public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, byte nThreads, uint nBitRate)
				: this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, NULL, nThreads, nBitRate)
			{ }
Пример #43
0
 private static string getAvCodecName(AVCodecID id)
 {
     var ptr = avcodec_get_name(id);
     return Marshal.PtrToStringAnsi((IntPtr)ptr);
 }
Пример #44
0
 private unsafe extern static byte* avcodec_get_name(AVCodecID id);
Пример #45
0
 public static extern int av_codec_get_tag(AVCodecTag** tags, AVCodecID id);
Пример #46
0
            public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, IntPtr pAVCC)
				: this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, pAVCC, 0)
			{
			}
Пример #47
0
 public static extern int av_codec_get_tag2(AVCodecTag** tags, AVCodecID id, int* tag);
Пример #48
0
public static extern IntPtr/* AVCodecDescriptor*  */ avcodec_descriptor_get(
	AVCodecID id);
Пример #49
0
			public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, IntPtr pAVCC, byte nThreads)
				: this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, pAVCC, 0, 128000)
			{ }
Пример #50
0
            public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, byte nThreads, uint nBitRate)
				: this(nWidth, nHeight, eCodecID, ePixelFormat, NULL, nThreads, nBitRate)
			{ }
Пример #51
0
			public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, IntPtr pAVCC, byte nThreads, uint nBitRate)
				: base(eCodecID, pAVCC, nThreads)
			{
				int nResult = 0;
				_ahTransformContexts = new Dictionary<Video, TransformContext>();
                nBufferSize = Functions.avpicture_get_size(ePixelFormat, nWidth, nHeight);
                _nBitsPerPixel = (ushort)(nBufferSize * 8 / (nWidth * nHeight));
				if (_bEncode)
				{
					stAVCodecContext.codec_type = AVMediaType.AVMEDIA_TYPE_VIDEO;
					stAVCodecContext.width = nWidth;
					stAVCodecContext.height = nHeight;
					stAVCodecContext.pix_fmt = ePixelFormat;
					stAVCodecContext.time_base.num = 1;
					stAVCodecContext.time_base.den = 25; //FPS
                    stAVCodecContext.bit_rate = (int)(int.MaxValue < nBitRate ? int.MaxValue : nBitRate); //чем больше, тем лучше качество
					if (NULL != _pCodec)
					{
						switch (eCodecID)
						{
							case AVCodecID.CODEC_ID_H264:
								stAVCodecContext.gop_size = 250; //кол-во неключевых кадров между ключевыми. чем больше, тем легче для CPU
								stAVCodecContext.max_b_frames = 2;
								stAVCodecContext.keyint_min = 25; //минимальное кол-во неключевых кадров между ключевыми

                                //stAVCodecContext.flags |= (int)(CodecFlags.CODEC_FLAG_LOOP_FILTER | CodecFlags.CODEC_FLAG_4MV | CodecFlags.CODEC_FLAG_GLOBAL_HEADER);
                                //stAVCodecContext.flags2 |= (int)CodecFlags.CODEC_FLAG2_MIXED_REFS;
                                //stAVCodecContext.me_cmp |= (int)MotionCompare.FF_CMP_CHROMA;
                                //stAVCodecContext.max_qdiff = 4;
                                //stAVCodecContext.i_quant_factor = 0.71F;
                                //stAVCodecContext.qcompress = 0.6F; 
                                //stAVCodecContext.gop_size = 250; //кол-во неключевых кадров между ключевыми. чем больше, тем легче для CPU
                                //stAVCodecContext.max_b_frames = 2;
                                //stAVCodecContext.keyint_min = 25; //минимальное кол-во неключевых кадров между ключевыми
								if (0 > (nResult = Functions.av_opt_set(stAVCodecContext.priv_data, new StringBuilder("profile"), new StringBuilder("baseline"), 1)))
									throw new Exception(helper.ErrorDescriptionGet(nResult));
								if (0 > (nResult = Functions.av_opt_set(stAVCodecContext.priv_data, new StringBuilder("preset"), new StringBuilder("slow"), 0)))
									throw new Exception(helper.ErrorDescriptionGet(nResult));
								if (0 > (nResult = Functions.av_opt_set(stAVCodecContext.priv_data, new StringBuilder("tune"), new StringBuilder("zerolatency"), 0))) //film,zerolatency,etc.
									throw new Exception(helper.ErrorDescriptionGet(nResult));

								break;
							case AVCodecID.CODEC_ID_MPEG2VIDEO:
								stAVCodecContext.max_b_frames = 2;
								break;
							case AVCodecID.CODEC_ID_MPEG1VIDEO:
								stAVCodecContext.mb_decision = 2;
								break;
                            default:
                                break;
						}
						Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
						////lock (helper._oSyncRootGlobal)
						{
							if (0 > (nResult = Functions.avcodec_open2(pAVCodecContext, _pCodec, NULL)))
							{
								base.Dispose();
								throw new Exception("can't open video codec:" + eCodecID.ToString() + "[" + helper.ErrorDescriptionGet(nResult) + "]");
							}
						}
					}
					else
						Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
				}
				else
				{
					////lock (helper._oSyncRootGlobal)
					{
						if (CodecIDRawGet() != eCodecID && 0 > Functions.avcodec_open2(pAVCodecContext, Functions.avcodec_find_decoder(eCodecID), NULL))
							if (CodecIDRawGet() != eCodecID && 0 > Functions.avcodec_open2(pAVCodecContext, Functions.avcodec_find_decoder(eCodecID), NULL))
							{
								base.Dispose();
								throw new Exception("can't open video codec:" + eCodecID.ToString());
							}
					}
				}
			}
Пример #52
0
		protected Format(AVCodecID eCodecID, IntPtr pAVCC, byte nThreads)
		{
            helper.Initialize();
			_pCodec = NULL;
			nBufferSize = 0;
			int nResult = 0;
			_bEncode = false;
			pAVCodecContext = pAVCC;
			_bAVCodecContextAllocationInternal = false;
			AVMediaType eAVMediaType = AVMediaType.AVMEDIA_TYPE_UNKNOWN;
			if (NULL != pAVCodecContext)
			{
				stAVCodecContext = (AVCodecContext)Marshal.PtrToStructure(pAVCodecContext, typeof(AVCodecContext));
				eAVMediaType = stAVCodecContext.codec_type;
			}

			if (AVMediaType.AVMEDIA_TYPE_UNKNOWN == eAVMediaType)
			{
				if (CodecIDRawGet() != eCodecID)
				{
					//if (AVCodecID.CODEC_ID_H264_MOBILE == eCodecID)
					//	eCodecID = AVCodecID.CODEC_ID_H264;
					if (NULL == (_pCodec = Functions.avcodec_find_encoder(eCodecID)))
						throw new Exception("can't find codec " + eCodecID.ToString());
				}
				if (NULL == pAVCodecContext)
				{
					//lock (helper._oSyncRootGlobal)
					{
						pAVCodecContext = Functions.avcodec_alloc_context3(_pCodec);
						_bAVCodecContextAllocationInternal = true;
					}
				}
				else
				{
					//lock (helper._oSyncRootGlobal)
						nResult = Functions.avcodec_get_context_defaults3(pAVCodecContext, _pCodec);
				}
				stAVCodecContext = (AVCodecContext)Marshal.PtrToStructure(pAVCodecContext, typeof(AVCodecContext));
				stAVCodecContext.codec_id = eCodecID;
				_bEncode = true;
			}
			if(1 > nThreads)
				nThreads = (byte)Environment.ProcessorCount;
			stAVCodecContext.thread_count = nThreads;
			Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
		}
Пример #53
0
 public static extern uint av_codec_get_tag(AVCodecTag** @tags, AVCodecID @id);
Пример #54
0
            public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, IntPtr pAVCC, byte nThreads, uint nBitRate)
				: base(eCodecID, pAVCC, nThreads)
			{
				//_pBytesStream = NULL;
				_ahTransformContexts = new Dictionary<Audio, TransformContext>();
                nBitsPerSample = Functions.av_get_bits_per_sample_fmt(eSampleFormat);
                if(1 > nBitsPerSample)
				    throw new Exception("unknown sample format");
                if (_bEncode)
				{
					stAVCodecContext.codec_type = AVMediaType.AVMEDIA_TYPE_AUDIO;
                    stAVCodecContext.sample_fmt = eSampleFormat;
                    stAVCodecContext.sample_rate = nSamplesRate;
                    stAVCodecContext.time_base.num = 1;
                    stAVCodecContext.time_base.den = nSamplesRate;
                    stAVCodecContext.channels = nChannelsQty;

					if (NULL == _pCodec)
						stAVCodecContext.bit_rate = nSamplesRate * nBitsPerSample * nChannelsQty;
                    else
                        stAVCodecContext.bit_rate = (int)(int.MaxValue < nBitRate ? int.MaxValue : nBitRate); //чем больше, тем лучше качество
                    Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
					if (NULL != _pCodec)
					{
						if (0 > Functions.avcodec_open2(pAVCodecContext, _pCodec, NULL))
						{
							base.Dispose();
							throw new Exception("can't open audio codec 1:" + eCodecID.ToString());
						}
					}
				}
				else
				{
					//audio test
					//lock (helper._oSyncRootGlobal)
					{
						if (0 > Functions.avcodec_open2(pAVCodecContext, Functions.avcodec_find_decoder(eCodecID), NULL))
							if (0 > Functions.avcodec_open2(pAVCodecContext, Functions.avcodec_find_decoder(eCodecID), NULL))
							{
								base.Dispose();
								throw new Exception("can't open audio codec 2:" + eCodecID.ToString());
							}
					}
					//nBufferSize = 192000 * 2;
				}
                aByteStream = null;
				stAVCodecContext = (AVCodecContext)Marshal.PtrToStructure(pAVCodecContext, typeof(AVCodecContext));
                nBufferSize = Functions.av_samples_get_buffer_size(NULL, nChannelsQty, 0 < stAVCodecContext.frame_size? stAVCodecContext.frame_size : nSamplesRate / 25, eSampleFormat, 0);// stAVCodecContext.bit_rate / 8;
                if(1 > stAVCodecContext.channel_layout)
                    stAVCodecContext.channel_layout = (ulong)Functions.av_get_default_channel_layout(nChannelsQty);
				Marshal.StructureToPtr(stAVCodecContext, pAVCodecContext, true);
			}
Пример #55
0
 public static extern AVCodecParserContext* av_parser_init(AVCodecID codec_id);
Пример #56
0
public static extern System.Int32 av_codec_get_tag2(
	IntPtr/* IntPtr*  */ tags, 
	AVCodecID id, 
	IntPtr/* System.UInt32*  */ tag);
Пример #57
0
 public static extern int av_get_bits_per_sample(AVCodecID codec_id);
Пример #58
0
public static extern System.Int32 avformat_query_codec(
	IntPtr/* AVOutputFormat*  */ ofmt, 
	AVCodecID codec_id, 
	[MarshalAs(UnmanagedType.I4)]
	System.Int32 std_compliance);
Пример #59
0
 public static extern AVCodec* avcodec_find_decoder(AVCodecID @id);
Пример #60
0
public static extern System.UInt32 av_codec_get_tag(
	IntPtr/* IntPtr*  */ tags, 
	AVCodecID id);