/// <summary> /// create by format name,e.g. "mp4" ".mp4" /// </summary> /// <param name="name"></param> public OutFormat(string name) { unsafe { name = name.Trim().TrimStart('.'); if (!string.IsNullOrEmpty(name)) { void * ofmtOpaque = null; AVOutputFormat *oformat; while ((oformat = ffmpeg.av_muxer_iterate(&ofmtOpaque)) != null) { OutFormat format = new OutFormat(oformat); // e.g. format.Name == "mov,mp4,m4a,3gp,3g2,mj2" string[] names = format.Name.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var item in names) { if (item == name.ToLower()) { pOutputFormat = oformat; return; } } } } throw new FFmpegException(ffmpeg.AVERROR_MUXER_NOT_FOUND); } }
public MediaStream(Stream baseStream, bool write = false, AVOutputFormat *outputFormat = null) { if (write && !baseStream.CanWrite) { throw new ArgumentException($"流不能被写入,请确保Stream.CanWrite为true"); } if (baseStream.CanRead) { procRead = Read; } if (write && baseStream.CanWrite) { procWrite = Write; } if (baseStream.CanSeek) { procSeek = Seek; } this.baseStream = baseStream; try { formatContext = FF.avformat_alloc_context(); var buffer = (byte *)FF.av_malloc((IntPtr)bufferLength); ioContext = FF.avio_alloc_context(buffer, bufferLength, write, null, procRead, procWrite, procSeek); if (write) { formatContext->Oformat = outputFormat; } formatContext->Pb = ioContext; } catch { Dispose(); throw; } }
/// <summary> /// <see cref="AVOutputFormat"/> adapter. /// </summary> /// <param name="pAVOutputFormat"></param> public OutFormat(IntPtr pAVOutputFormat) { if (pAVOutputFormat == IntPtr.Zero) { throw new FFmpegException(FFmpegException.NullReference); } pOutputFormat = (AVOutputFormat *)pAVOutputFormat; }
public void SetOutputFormat(AVOutputFormat *format) { if (fmtContext->oformat != null) { throw new InvalidOperationException("Output format already set"); } fmtContext->oformat = format; }
private OutputFormat(AVOutputFormat *ptr) { if (ptr == null) { throw new ArgumentNullException(nameof(ptr)); } _ptr = ptr; }
internal unsafe OutFormat(AVOutputFormat *oformat) { if (oformat == null) { throw new FFmpegException(FFmpegException.NullReference); } pOutputFormat = oformat; }
public void Open() { FFmpegLoader.EnsureLoaded(); if (closed) { throw new InvalidOperationException("Cannot reopen closed video writer"); fixed(AVFormatContext **fctx = &ctx) avformat_alloc_output_context2(fctx, null, null, Filename); this.fmt = ctx->oformat; if (fmt->video_codec != AVCodecID.AV_CODEC_ID_NONE) { AddStream(ref videoStream, ref videoCodec, fmt->video_codec); hasVideo = true; } if (fmt->audio_codec != AVCodecID.AV_CODEC_ID_NONE) { AddStream(ref audioStream, ref audioCodec, fmt->audio_codec); hasAudio = true; } int ret; if (hasVideo) { OpenVideo(); } if (hasAudio) { OpenAudio(); } // av_dump_format(ctx, 0, Filename, 1); ret = avio_open(&ctx->pb, Filename, AVIO_FLAG_WRITE); if (ret < 0) { throw new FFmpegException("Could not open file for writing", ret); } ret = avformat_write_header(ctx, null); if (ret < 0) { throw new FFmpegException("Could not write file header", ret); } }
public VideoWriter(ILogger logger, string filename, int width, int height, AVPixelFormat webcamPixelFormat, StreamerSettings settings) { _logger = logger; _fps = settings.FPS; _videoFlipperConverter = new VideoFlipperConverter(width, height, webcamPixelFormat, settings); _h264Codec = ffmpeg.avcodec_find_encoder_by_name("h264_omx"); if (_h264Codec == null) { _logger.LogError("Don't using hardware-accelerated h264 encoder, falling back to software one."); _h264Codec = ffmpeg.avcodec_find_encoder_by_name("libx264"); } if (_h264Codec == null) { throw new InvalidOperationException("Codec not found."); } fixed(AVFormatContext **occ = &_h264AvFormatContext) { AVOutputFormat *fmt = ffmpeg.av_guess_format("mp4", null, null); ffmpeg.avformat_alloc_output_context2(occ, fmt, null, null); _h264Stream = ffmpeg.avformat_new_stream(_h264AvFormatContext, _h264Codec); _h264Stream->codec->width = width; _h264Stream->codec->height = height; _h264Stream->codec->time_base = new AVRational { num = 1, den = _fps }; _h264Stream->codec->pix_fmt = AVPixelFormat.AV_PIX_FMT_YUV420P; _h264Stream->codec->bit_rate = 1_500_000; ffmpeg.av_opt_set(_h264Stream->codec->priv_data, "preset", "veryslow", 0); if ((_h264AvFormatContext->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) != 0) // Some formats require a global header. { _h264Stream->codec->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER; } ffmpeg.avcodec_open2(_h264Stream->codec, _h264Codec, null).ThrowExceptionIfError(); _h264Stream->time_base = new AVRational() { num = 1, den = _fps }; ffmpeg.avio_open(&_h264AvFormatContext->pb, filename, ffmpeg.AVIO_FLAG_WRITE); ffmpeg.avformat_write_header(_h264AvFormatContext, null).ThrowExceptionIfError(); } }
public Muxer(FormatId format) : base(format) { if (format == FormatId.M4a) { format = FormatId.Mp4; } AVOutputFormat *fmt = ffmpeg.av_guess_format(format.ToString().ToLower(), null, format.ToMime()); if (fmt == null) { throw new Exception("Could not guess format:" + format.ToMime() + "|" + format.ToString().ToLower()); } Context.Pointer->oformat = fmt; // Console.WriteLine("OUTPUT:" + Marshal.PtrToStringAnsi((IntPtr)fmt->long_name)); }
public MediaWriter AddEncoder(Encoder encoder) { if (readyEncoders != null) { throw new InvalidOperationException($"该{nameof(MediaWriter)}对象已经初始化"); } if (outputFormat == null) { var desc = FF.avcodec_descriptor_get(encoder.ID); if (desc == null) { throw new InvalidOperationException("无法获得编码器的短名称描述"); } outputFormat = FF.av_guess_format(desc->Name, null, null); if (outputFormat == null) { throw new InvalidOperationException("无法确定媒体的输出格式"); } formatContext->Oformat = outputFormat; } var stream = FF.avformat_new_stream(formatContext, encoder.codec); if (stream == null) { throw new InvalidOperationException("无法创建流"); } // stream->TimeBase = encoder.codecContext->TimeBase; int result = FF.avcodec_parameters_from_context(stream->Codecpar, encoder.codecContext); if (result < 0) { throw new FFmpegException(result); } encoder.stream = stream; encoders.Add(encoder); return(this); }
// set output format from file extension public void SetOutputFormat(AVCodecID codecId, int width, int height, AVPixelFormat pixelFormat, int compression) { type = AVMediaType.AVMEDIA_TYPE_VIDEO; AVOutputFormat *outputFormat = ffmpeg.av_guess_format(null, path, null); if (outputFormat == null) { throw new ApplicationException("Failed to guess output format for extension " + path); } string name = Marshal.PtrToStringAnsi((IntPtr)outputFormat->name); string lname = Marshal.PtrToStringAnsi((IntPtr)outputFormat->long_name); string extlist = Marshal.PtrToStringAnsi((IntPtr)outputFormat->extensions); if (codecId == AVCodecID.AV_CODEC_ID_NONE) { codecId = ffmpeg.av_guess_codec(outputFormat, null, path, null, AVMediaType.AVMEDIA_TYPE_VIDEO); } outputFormat->video_codec = codecId; SetupOutput(outputFormat, codecId, width, height, pixelFormat, compression); }
public void SetOutputFormat(AVCodecID codecId, int sampleRate, int sampleCount, AVSampleFormat sampleFormat) { type = AVMediaType.AVMEDIA_TYPE_AUDIO; AVOutputFormat *outputFormat = ffmpeg.av_guess_format(null, path, null); if (outputFormat == null) { throw new ApplicationException("Failed to guess output format for extension " + path); } string name = Marshal.PtrToStringAnsi((IntPtr)outputFormat->name); string lname = Marshal.PtrToStringAnsi((IntPtr)outputFormat->long_name); string extlist = Marshal.PtrToStringAnsi((IntPtr)outputFormat->extensions); if (codecId == AVCodecID.AV_CODEC_ID_NONE) { codecId = ffmpeg.av_guess_codec(outputFormat, null, path, null, AVMediaType.AVMEDIA_TYPE_AUDIO); } outputFormat->audio_codec = codecId; SetupOutput(outputFormat, codecId, sampleRate, sampleCount, sampleFormat); }
public static extern AVCodecID av_guess_codec(AVOutputFormat *fmt, string short_name, string filename, string mime_type, AVMediaType type);
/// <summary> /// 创建一个编码模式的媒体写入器 /// </summary> /// <param name="outputStream">输出的流</param> /// <param name="mediaName">根据"mp3","flac","h264"等多媒体的短名称自动推断编码器</param> public MediaWriter(Stream outputStream, string mediaName = null) : base(outputStream, true, FF.av_guess_format(mediaName, null, null)) { outputFormat = formatContext->Oformat; }
//public AVCodecID AudioCodecID => remuxing ? inputFmtCtx->AudioCodecId : outputFormat->AudioCodec; //public AVCodecID VideoCodecID => remuxing ? inputFmtCtx->VideoCodecId : outputFormat->VideoCodec; /// <summary> /// 创建一个编码模式的媒体写入器 /// </summary> /// <param name="file">输出的文件路径</param> /// <param name="ignoreExtension">如果为true,则不会根据文件扩展名自动推断编码器</param> public MediaWriter(string file, bool ignoreExtension = false) : base(File.Open(file, FileMode.Create, FileAccess.Write), true, FF.av_guess_format(null, ignoreExtension ? null : file, null)) { outputFormat = formatContext->Oformat; }
public static extern void av_register_output_format(AVOutputFormat *format);
public static extern int avdevice_list_output_sinks(AVOutputFormat * @device, [MarshalAs(UnmanagedType.LPStr)] string @device_name, AVDictionary * @device_options, AVDeviceInfoList ** @device_list);
public extern static AVOutputFormat *av_output_audio_device_next(AVOutputFormat *d);
public MediaRemuxer(string file, params Codec[] codecs) : base(File.Open(file, FileMode.Create, FileAccess.Write), true, FF.av_guess_format(null, file, null)) { outputFormat = formatContext->Oformat; NewStreams(codecs); }
public static OutputFormat FromNative(AVOutputFormat *ptr) => new OutputFormat(ptr);
public static extern int avformat_query_codec(AVOutputFormat *ofmt, AVCodecID codec_id, int std_compliance);
public static extern AVOutputFormat *av_oformat_next(AVOutputFormat *f);
public static extern int avformat_alloc_output_context2(ref AVFormatContext *ctx, AVOutputFormat *oformat, string format_name, string filename);
public static void Main(string[] argv) { //ffmpeg.av_register_all(); if (argv.Length != 2) { //fprintf(stderr, "%s <in> <out>\n", argv[0]); return; } // Allocate and init re-usable frames AVCodecContext * fileCodecContext, audioCodecContext; AVFormatContext *formatContext, outContext; AVStream * out_audioStream; SwrContext * swrContext; int streamId; // input file string file = argv[0]; int res = ffmpeg.avformat_open_input(&formatContext, file, null, null); if (res != 0) { die("avformat_open_input"); } res = ffmpeg.avformat_find_stream_info(formatContext, null); if (res < 0) { die("avformat_find_stream_info"); } AVCodec *codec; res = ffmpeg.av_find_best_stream(formatContext, AVMediaType.AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0); if (res < 0) { return; // die("av_find_best_stream"); } streamId = res; fileCodecContext = ffmpeg.avcodec_alloc_context3(codec); AVCodecParameters *cp = null; ffmpeg.avcodec_parameters_to_context(fileCodecContext, formatContext->streams[streamId]->codecpar); res = ffmpeg.avcodec_open2(fileCodecContext, codec, null); if (res < 0) { die("avcodec_open2"); } in_audioStream = formatContext->streams[streamId]; // output file //string outfile = Path.Combine(Path.GetTempPath(), $"{Path.GetFileNameWithoutExtension(argv[0])}.pcm"); //AVOutputFormat* fmt = fmt = ffmpeg.av_guess_format("s16le", null, null); string outfile = argv[1]; AVOutputFormat *fmt = fmt = ffmpeg.av_guess_format(null, outfile, null); if (fmt == null) { die("av_guess_format"); } outContext = ffmpeg.avformat_alloc_context(); outContext->oformat = fmt; out_audioStream = add_audio_stream(outContext, fmt->audio_codec, in_audioStream->codec->sample_rate); open_audio(outContext, out_audioStream); out_audioStream->time_base = in_audioStream->time_base; res = ffmpeg.avio_open2(&outContext->pb, outfile, ffmpeg.AVIO_FLAG_WRITE, null, null); if (res < 0) { die("url_fopen"); } ffmpeg.avformat_write_header(outContext, null); AVCodec *ocodec; res = ffmpeg.av_find_best_stream(outContext, AVMediaType.AVMEDIA_TYPE_AUDIO, -1, -1, &ocodec, 0); audioCodecContext = ffmpeg.avcodec_alloc_context3(ocodec); ffmpeg.avcodec_parameters_to_context(audioCodecContext, out_audioStream->codecpar); res = ffmpeg.avcodec_open2(audioCodecContext, ocodec, null); if (res < 0) { die("avcodec_open2"); } // resampling swrContext = ffmpeg.swr_alloc(); ffmpeg.av_opt_set_channel_layout(swrContext, "in_channel_layout", (long)fileCodecContext->channel_layout, 0); ffmpeg.av_opt_set_channel_layout(swrContext, "out_channel_layout", (long)audioCodecContext->channel_layout, 0); ffmpeg.av_opt_set_int(swrContext, "in_sample_rate", fileCodecContext->sample_rate, 0); ffmpeg.av_opt_set_int(swrContext, "out_sample_rate", audioCodecContext->sample_rate, 0); ffmpeg.av_opt_set_sample_fmt(swrContext, "in_sample_fmt", fileCodecContext->sample_fmt, 0); ffmpeg.av_opt_set_sample_fmt(swrContext, "out_sample_fmt", audioCodecContext->sample_fmt, 0); res = ffmpeg.swr_init(swrContext); if (res < 0) { die("swr_init"); } AVFrame *audioFrameDecoded = ffmpeg.av_frame_alloc(); if (audioFrameDecoded == null) { die("Could not allocate audio frame"); } audioFrameDecoded->format = (int)fileCodecContext->sample_fmt; audioFrameDecoded->channel_layout = fileCodecContext->channel_layout; audioFrameDecoded->channels = fileCodecContext->channels; audioFrameDecoded->sample_rate = fileCodecContext->sample_rate; AVFrame *audioFrameConverted = ffmpeg.av_frame_alloc(); if (audioFrameConverted == null) { die("Could not allocate audio frame"); } audioFrameConverted->nb_samples = audioCodecContext->frame_size; audioFrameConverted->format = (int)audioCodecContext->sample_fmt; audioFrameConverted->channel_layout = audioCodecContext->channel_layout; audioFrameConverted->channels = audioCodecContext->channels; audioFrameConverted->sample_rate = audioCodecContext->sample_rate; if (audioFrameConverted->nb_samples <= 0) { audioFrameConverted->nb_samples = 32; } AVPacket inPacket; ffmpeg.av_init_packet(&inPacket); inPacket.data = null; inPacket.size = 0; int frameFinished = 0; for (; ;) { if (ffmpeg.av_read_frame(formatContext, &inPacket) < 0) { break; } if (inPacket.stream_index == streamId) { int len = Decode(fileCodecContext, audioFrameDecoded, ref frameFinished, &inPacket); if (len == ffmpeg.AVERROR_EOF) { break; } if (frameFinished != 0) { // Convert byte *convertedData = null; if (ffmpeg.av_samples_alloc(&convertedData, null, audioCodecContext->channels, audioFrameConverted->nb_samples, audioCodecContext->sample_fmt, 0) < 0) { die("Could not allocate samples"); } int outSamples = 0; fixed(byte **tmp = (byte *[])audioFrameDecoded->data) { outSamples = ffmpeg.swr_convert(swrContext, null, 0, //&convertedData, //audioFrameConverted->nb_samples, tmp, audioFrameDecoded->nb_samples); } if (outSamples < 0) { die("Could not convert"); } for (; ;) { outSamples = ffmpeg.swr_get_out_samples(swrContext, 0); if ((outSamples < audioCodecContext->frame_size * audioCodecContext->channels) || audioCodecContext->frame_size == 0 && (outSamples < audioFrameConverted->nb_samples * audioCodecContext->channels)) { break; // see comments, thanks to @dajuric for fixing this } outSamples = ffmpeg.swr_convert(swrContext, &convertedData, audioFrameConverted->nb_samples, null, 0); int buffer_size = ffmpeg.av_samples_get_buffer_size(null, audioCodecContext->channels, audioFrameConverted->nb_samples, audioCodecContext->sample_fmt, 0); if (buffer_size < 0) { die("Invalid buffer size"); } if (ffmpeg.avcodec_fill_audio_frame(audioFrameConverted, audioCodecContext->channels, audioCodecContext->sample_fmt, convertedData, buffer_size, 0) < 0) { die("Could not fill frame"); } AVPacket outPacket; ffmpeg.av_init_packet(&outPacket); outPacket.data = null; outPacket.size = 0; if (Encode(audioCodecContext, &outPacket, audioFrameConverted, ref frameFinished) < 0) { die("Error encoding audio frame"); } //outPacket.flags |= ffmpeg.AV_PKT_FLAG_KEY; outPacket.stream_index = out_audioStream->index; //outPacket.data = audio_outbuf; outPacket.dts = audioFrameDecoded->pkt_dts; outPacket.pts = audioFrameDecoded->pkt_pts; ffmpeg.av_packet_rescale_ts(&outPacket, in_audioStream->time_base, out_audioStream->time_base); if (frameFinished != 0) { if (ffmpeg.av_interleaved_write_frame(outContext, &outPacket) != 0) { die("Error while writing audio frame"); } ffmpeg.av_packet_unref(&outPacket); } } } } } EncodeFlush(audioCodecContext); DecodeFlush(fileCodecContext, &inPacket); ffmpeg.swr_close(swrContext); ffmpeg.swr_free(&swrContext); ffmpeg.av_frame_free(&audioFrameConverted); ffmpeg.av_frame_free(&audioFrameDecoded); ffmpeg.av_packet_unref(&inPacket); ffmpeg.av_write_trailer(outContext); ffmpeg.avio_close(outContext->pb); ffmpeg.avcodec_close(fileCodecContext); ffmpeg.avcodec_free_context(&fileCodecContext); ffmpeg.avformat_close_input(&formatContext); return; }
public OutputFormat(AVOutputFormat *pointer) { this.pointer = pointer; }
internal static OutputFormat?FromNativeOrNull(AVOutputFormat *ptr) => ptr != null ? new OutputFormat?(new OutputFormat(ptr)) : null;
unsafe void CameraInit() { int res; ofmt = null; ifmt_ctx = null; ofmt_ctx = null; avdic = null; string fullDName = "video=" + selectedDeviceName; AVInputFormat *fmt = ffmpeg.av_find_input_format("dshow"); string resString = vidWidth.ToString() + "x" + vidHeight.ToString(); ifmt_ctx = ffmpeg.avformat_alloc_context(); fixed(AVDictionary **pAVdic = &avdic) { res = ffmpeg.av_dict_set(pAVdic, "video_size", resString, 0); res = ffmpeg.av_dict_set(pAVdic, "pixel_format", "yuyv422", 0); fixed(AVFormatContext **pFmtCxt = &ifmt_ctx) { res = ffmpeg.avformat_open_input(pFmtCxt, fullDName, fmt, pAVdic); } ffmpeg.av_dict_free(pAVdic); } if (res < 0) { Debug.Print("Unable to open input device!"); return; } res = ffmpeg.avformat_find_stream_info(ifmt_ctx, null); ffmpeg.av_dump_format(ifmt_ctx, 0, fullDName, 0); yuy2Frame = ffmpeg.av_frame_alloc(); if (yuy2Frame == null) { Debug.Print("Could not allocate video frame!"); } yuy2Frame->format = (int)AVPixelFormat.AV_PIX_FMT_YUYV422; yuy2Frame->width = c->width; yuy2Frame->height = c->height; res = ffmpeg.av_frame_get_buffer(yuy2Frame, 32); if (res < 0) { Debug.Print("Could not allocate video frame data!"); } gbrFrame = ffmpeg.av_frame_alloc(); gbrFrame->format = (int)AVPixelFormat.AV_PIX_FMT_BGR24; gbrFrame->width = vidWidth; gbrFrame->height = vidHeight; res = ffmpeg.av_frame_get_buffer(gbrFrame, 32); gbr_swctx = ffmpeg.sws_getContext(yuy2Frame->width, yuy2Frame->height, (AVPixelFormat)yuy2Frame->format, gbrFrame->width, gbrFrame->height, (AVPixelFormat)gbrFrame->format, 4, null, null, null); if (gbr_swctx == null) { Debug.Print("Error getting sws context!"); } yuv_swctx = ffmpeg.sws_getContext(yuy2Frame->width, yuy2Frame->height, (AVPixelFormat)yuy2Frame->format, frame->width, frame->height, (AVPixelFormat)frame->format, 4, null, null, null); if (gbr_swctx == null) { Debug.Print("Error getting sws context!"); } }
public static extern AVOutputFormat *av_output_video_device_next(AVOutputFormat * @d);
public MediaRemuxer(Stream outputStream, string mediaName = null, params Codec[] codecs) : base(outputStream, true, FF.av_guess_format(mediaName, null, null)) { outputFormat = formatContext->Oformat; NewStreams(codecs); }
internal OutFormat(AVOutputFormat *oformat) : this((IntPtr)oformat) { }