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)); }
/// <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); }
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()); }
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(); }
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); }
/// <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; })); }
/// <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); } }
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); }
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()); }
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); } } }
/// <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); } }
/// <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); }
/// <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); } }
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); }
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); }
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()) { } }
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()); }
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)); }
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)); }
/// <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); }
internal static AVCodec *GetEncoder(AVCodecID codecID) { AVCodec *codec = FF.avcodec_find_encoder(codecID); if (codec == null) { throw new ArgumentException($"未能找到编码器:{codecID}", nameof(codecID)); } return(codec); }
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); }
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); }
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)); }
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); } }
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; } }
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; }
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; }
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; }
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"); }
public static extern AVCodecDescriptor* avcodec_descriptor_get(AVCodecID id);
public static extern AVMediaType avcodec_get_type(AVCodecID codec_id);
public static extern String avcodec_get_name(AVCodecID id);
public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, IntPtr pAVCC, byte nThreads) : this(nWidth, nHeight, eCodecID, ePixelFormat, pAVCC, nThreads, 800000) { }
public static extern AVCodec* avcodec_find_encoder(AVCodecID id);
public static extern int avformat_query_codec(AVOutputFormat* ofmt, AVCodecID codec_id, int std_compliance);
public static extern string avcodec_profile_name(AVCodecID @codec_id, int @profile);
public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, IntPtr pAVCC) : this(nWidth, nHeight, eCodecID, ePixelFormat, pAVCC, 0) { }
public static extern System.Int32 av_get_exact_bits_per_sample( AVCodecID codec_id);
public static extern IntPtr/* AVCodec* */ avcodec_find_encoder( AVCodecID id);
public static extern int av_codec_get_tag2(AVCodecTag** @tags, AVCodecID @id, uint* @tag);
public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, byte nThreads, uint nBitRate) : this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, NULL, nThreads, nBitRate) { }
private static string getAvCodecName(AVCodecID id) { var ptr = avcodec_get_name(id); return Marshal.PtrToStringAnsi((IntPtr)ptr); }
private unsafe extern static byte* avcodec_get_name(AVCodecID id);
public static extern int av_codec_get_tag(AVCodecTag** tags, AVCodecID id);
public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, IntPtr pAVCC) : this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, pAVCC, 0) { }
public static extern int av_codec_get_tag2(AVCodecTag** tags, AVCodecID id, int* tag);
public static extern IntPtr/* AVCodecDescriptor* */ avcodec_descriptor_get( AVCodecID id);
public Audio(int nSamplesRate, int nChannelsQty, AVCodecID eCodecID, AVSampleFormat eSampleFormat, IntPtr pAVCC, byte nThreads) : this(nSamplesRate, nChannelsQty, eCodecID, eSampleFormat, pAVCC, 0, 128000) { }
public Video(ushort nWidth, ushort nHeight, AVCodecID eCodecID, PixelFormat ePixelFormat, byte nThreads, uint nBitRate) : this(nWidth, nHeight, eCodecID, ePixelFormat, NULL, nThreads, nBitRate) { }
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()); } } } }
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); }
public static extern uint av_codec_get_tag(AVCodecTag** @tags, AVCodecID @id);
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); }
public static extern AVCodecParserContext* av_parser_init(AVCodecID codec_id);
public static extern System.Int32 av_codec_get_tag2( IntPtr/* IntPtr* */ tags, AVCodecID id, IntPtr/* System.UInt32* */ tag);
public static extern int av_get_bits_per_sample(AVCodecID codec_id);
public static extern System.Int32 avformat_query_codec( IntPtr/* AVOutputFormat* */ ofmt, AVCodecID codec_id, [MarshalAs(UnmanagedType.I4)] System.Int32 std_compliance);
public static extern AVCodec* avcodec_find_decoder(AVCodecID @id);
public static extern System.UInt32 av_codec_get_tag( IntPtr/* IntPtr* */ tags, AVCodecID id);