Esempio n. 1
0
        /// <summary>
        /// Extracts the programs from the input and creates associations between programs and streams.
        /// </summary>
        /// <param name="ic">The ic.</param>
        /// <param name="streams">The streams.</param>
        /// <returns>The program information</returns>
        private static List <ProgramInfo> ExtractPrograms(AVFormatContext *ic, ReadOnlyDictionary <int, StreamInfo> streams)
        {
            var result = new List <ProgramInfo>();

            if (ic->programs == null)
            {
                return(result);
            }

            for (var i = 0; i < ic->nb_programs; i++)
            {
                var p = ic->programs[i];

                var program = new ProgramInfo
                {
                    Metadata      = new ReadOnlyDictionary <string, string>(FFDictionary.ToDictionary(p->metadata)),
                    ProgramId     = p->id,
                    ProgramNumber = p->program_num,
                };

                var associatedStreams = new List <StreamInfo>();
                for (var s = 0; s < p->nb_stream_indexes; s++)
                {
                    var streamIndex = (int)p->stream_index[s];
                    if (streams.ContainsKey(streamIndex))
                    {
                        associatedStreams.Add(streams[streamIndex]);
                    }
                }

                program.Streams = new ReadOnlyCollection <StreamInfo>(associatedStreams);

                result.Add(program);
            }

            return(result);
        }
Esempio n. 2
0
        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();
                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->Flags   = AVFmtFlag.CustomIO;
                }
                formatContext->Pb = ioContext;
            } catch {
                Dispose();
                throw;
            }
        }
Esempio n. 3
0
        private void Initialize()
        {
            AVCodecContext *codecCtxPtr;

            try
            {
                if (vStream != null)
                {
                    codecCtxPtr = vCodecCtx;
                    avcodec_free_context(&codecCtxPtr);
                }
            } catch (Exception e) { Log("Error[" + (-1).ToString("D4") + "], Msg: " + e.Message + "\n" + e.StackTrace); }

            try
            {
                if (fmtCtx != null)
                {
                    AVFormatContext *fmtCtxPtr = fmtCtx;
                    avformat_close_input(&fmtCtxPtr);
                }
                fmtCtx  = null;
                vStream = null;
            } catch (Exception e) { Log("Error[" + (-1).ToString("D4") + "], Msg: " + e.Message + "\n" + e.StackTrace); }
        }
Esempio n. 4
0
    public VideoStreamDecoder(string fileName, AVHWDeviceType HWDeviceType = AVHWDeviceType.AV_HWDEVICE_TYPE_NONE)
    {
        _pFormatContext = ffmpeg.avformat_alloc_context();

        if (_pFormatContext == null)
        {
            throw new Exception("Could not allocate the format context");
        }

        _receivedFrame = ffmpeg.av_frame_alloc();
        var pFormatContext = _pFormatContext;

        ffmpeg.avformat_open_input(&pFormatContext, fileName, null, null);
        ffmpeg.avformat_find_stream_info(_pFormatContext, null);

        AVCodec *codec = null;

        _streamIndex =
            ffmpeg.av_find_best_stream(_pFormatContext, AVMediaType.AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
        _pCodecContext = ffmpeg.avcodec_alloc_context3(codec);

        if (HWDeviceType != AVHWDeviceType.AV_HWDEVICE_TYPE_NONE)
        {
            ffmpeg.av_hwdevice_ctx_create(&_pCodecContext->hw_device_ctx, HWDeviceType, null, null, 0);
        }

        ffmpeg.avcodec_parameters_to_context(_pCodecContext, _pFormatContext->streams[_streamIndex]->codecpar);
        ffmpeg.avcodec_open2(_pCodecContext, codec, null);

        CodecName   = ffmpeg.avcodec_get_name(codec->id);
        FrameSize   = new Size(_pCodecContext->width, _pCodecContext->height);
        PixelFormat = _pCodecContext->pix_fmt;

        _pPacket = ffmpeg.av_packet_alloc();
        _pFrame  = ffmpeg.av_frame_alloc();
    }
Esempio n. 5
0
        public void Test1()
        {
            MediaDictionary2 options = MediaDictionary2.Empty;

            Output.WriteLine($"{((IntPtr)options._handle).ToInt64()}");
            Output.WriteLine($"={((IntPtr)(AVDictionary**)options).ToInt64()}");
            options.Add("protocol_whitelist", "file");
            options.Add("key", "value");
            options.Add("protocol_blacklist", "cache");
            Output.WriteLine($"{((IntPtr)options._handle).ToInt64()}");
            Output.WriteLine($"={((IntPtr)(AVDictionary**)options).ToInt64()}");
            var file = "111.mp4";
            AVFormatContext * pFormatContext  = null;
            AVFormatContext **ppFormatContext = &pFormatContext;
            var ret1 = ffmpeg.avformat_alloc_output_context2(ppFormatContext, OutFormat.Get("mpeg"), null, file);
            var ret2 = ffmpeg.avio_open2(&pFormatContext->pb, file, ffmpeg.AVIO_FLAG_WRITE, null, options);

            Output.WriteLine($"{((IntPtr)options._handle).ToInt64()}");
            Output.WriteLine($"={((IntPtr)(AVDictionary**)options).ToInt64()}");
            Output.WriteLine($"+{((IntPtr)(*(AVDictionary**)options)).ToInt64()}");
            Assert.True(options.Count == 1);
            Assert.Equal("key", options.First().Key);
            Assert.Equal("value", options.First().Value);
        }
 /// <inheritdoc />
 public unsafe void OnAudioFrameDecoded(AVFrame *audioFrame, AVFormatContext *context) =>
 Parent?.RaiseAudioFrameDecodedEvent(audioFrame, context);
 /// <inheritdoc />
 public unsafe void OnPacketRead(AVPacket *packet, AVFormatContext *context) =>
 Parent?.RaisePacketReadEvent(packet, context);
Esempio n. 8
0
        static int OpenOutputFile(string filename)
        {
            AVStream *      out_stream;
            AVStream *      in_stream;
            AVCodecContext *dec_ctx;
            AVCodecContext *enc_ctx;
            AVCodec *       encoder;
            int             ret;

            ofmt_ctx = null;

            fixed(AVFormatContext **ctx = &ofmt_ctx)
            {
                ffmpeg.avformat_alloc_output_context2(ctx, null, null, filename);
            }

            if (null == ofmt_ctx)
            {
                ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Could not create output context\n");
                return(ffmpeg.AVERROR_UNKNOWN);
            }
            for (int i = 0; i < ifmt_ctx->nb_streams; i++)
            {
                out_stream = ffmpeg.avformat_new_stream(ofmt_ctx, null);
                if (out_stream == null)
                {
                    ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Failed allocating output stream\n");
                    return(ffmpeg.AVERROR_UNKNOWN);
                }

                in_stream = ifmt_ctx->streams[i];
                dec_ctx   = in_stream->codec;
                enc_ctx   = out_stream->codec;

                if (dec_ctx->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    encoder = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_H264);
                    if (null == encoder)
                    {
                        ffmpeg.av_log(null, ffmpeg.AV_LOG_FATAL, "Neccessary encoder not found\n");
                        return(ffmpeg.AVERROR_INVALIDDATA);
                    }

                    enc_ctx->height = dec_ctx->height;
                    enc_ctx->width  = dec_ctx->width;
                    enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;

                    enc_ctx->pix_fmt = encoder->pix_fmts[0];

                    enc_ctx->time_base = dec_ctx->time_base;

                    // enc_ctx->me_range = 25;
                    // enc_ctx->max_qdiff = 4;
                    enc_ctx->qmin = 10;
                    enc_ctx->qmax = 51;
                    // enc_ctx->qcompress = 0.6;
                    // enc_ctx->refs = 3;
                    enc_ctx->max_b_frames  = 3;
                    enc_ctx->gop_size      = 250;
                    enc_ctx->bit_rate      = 500000;
                    enc_ctx->time_base.num = dec_ctx->time_base.num;
                    enc_ctx->time_base.den = dec_ctx->time_base.den;

                    ret = ffmpeg.avcodec_open2(enc_ctx, encoder, null);
                    if (ret < 0)
                    {
                        ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n");
                        return(ret);
                    }

                    //ffmpeg.av_opt_set(ofmt_ctx->priv_data, "preset", "superfast", 0);
                    //ffmpeg.av_opt_set(ofmt_ctx->priv_data, "tune", "zerolatency", 0);
                    ffmpeg.av_opt_set_int(ofmt_ctx->priv_data, "hls_time", 5, ffmpeg.AV_OPT_SEARCH_CHILDREN);
                    ffmpeg.av_opt_set_int(ofmt_ctx->priv_data, "hls_list_size", 10, ffmpeg.AV_OPT_SEARCH_CHILDREN);
                }
                else if (dec_ctx->codec_type == AVMediaType.AVMEDIA_TYPE_UNKNOWN)
                {
                    ffmpeg.av_log(null, ffmpeg.AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n");
                    return(ffmpeg.AVERROR_INVALIDDATA);
                }
                else if (dec_ctx->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO)
                {
                    encoder = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_AAC);
                    enc_ctx->sample_rate    = dec_ctx->sample_rate;
                    enc_ctx->channel_layout = dec_ctx->channel_layout;
                    enc_ctx->channels       = ffmpeg.av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
                    enc_ctx->sample_fmt     = encoder->sample_fmts[0];
                    AVRational ar = new AVRational();
                    ar.num = 1;
                    ar.den = enc_ctx->sample_rate;

                    //{ 1, enc_ctx->sample_rate };
                    enc_ctx->time_base = ar;

                    ret = ffmpeg.avcodec_open2(enc_ctx, encoder, null);
                    if (ret < 0)
                    {
                        ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n");
                        return(ret);
                    }
                }
                else
                {
                    ret = ffmpeg.avcodec_parameters_to_context(ofmt_ctx->streams[i]->codec, ofmt_ctx->streams[i]->codecpar);
                    //ret = ffmpeg.avcodec_copy_context(ofmt_ctx->streams[i]->codec, ifmt_ctx->streams[i]->codec);
                    if (ret < 0)
                    {
                        ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Copying stream context failed\n");
                        return(ret);
                    }

                    ret = ffmpeg.avcodec_parameters_from_context(ifmt_ctx->streams[i]->codecpar, ifmt_ctx->streams[i]->codec);
                    if (ret < 0)
                    {
                        ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Copying stream context failed\n");
                        return(ret);
                    }
                }
                if ((ofmt_ctx->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) > 0)
                {
                    enc_ctx->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
                }
            }
            ffmpeg.av_dump_format(ofmt_ctx, 0, filename, 1);

            // if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
            ret = ffmpeg.avio_open(&ofmt_ctx->pb, filename, ffmpeg.AVIO_FLAG_WRITE);
            if (ret < 0)
            {
                ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Could not open output file '%s'");
                return(ret);
            }
            // }
            /* init muxer, write output file header */
            ret = ffmpeg.avformat_write_header(ofmt_ctx, null);
            if (ret < 0)
            {
                ffmpeg.av_log(null, ffmpeg.AV_LOG_ERROR, "Error occurred when opening output file\n");
                return(ret);
            }
            return(0);
        }
Esempio n. 9
0
        private void DoStart()
        {
            var vss = Source;

            if (!_modeAudio)
            {
                vss = Tokenise(vss);
            }

            AVDictionary *options = null;

            if (_inputFormat == null)
            {
                ffmpeg.av_dict_set(&options, "analyzeduration", _analyzeDuration.ToString(), 0);



                string prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal));
                switch (prefix)
                {
                case "http":
                case "mmsh":
                case "mms":
                    ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0);
                    ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0);

                    if (_cookies != "")
                    {
                        ffmpeg.av_dict_set(&options, "cookies", _cookies, 0);
                    }

                    if (_headers != "")
                    {
                        ffmpeg.av_dict_set(&options, "headers", _headers, 0);
                    }
                    if (_userAgent != "")
                    {
                        ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0);
                    }
                    break;

                case "tcp":
                case "udp":
                case "rtp":
                case "sdp":
                case "mmst":
                case "ftp":
                    ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0);
                    break;

                case "rtsp":
                case "rtmp":
                    ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0);
                    if (_userAgent != "")
                    {
                        ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0);
                    }
                    break;
                }

                ffmpeg.av_dict_set(&options, "rtsp_transport", RTSPmode, 0);
            }

            ffmpeg.av_dict_set(&options, "rtbufsize", "10000000", 0);

            var lo = _options.Split(Environment.NewLine.ToCharArray());

            foreach (var nv in lo)
            {
                if (!string.IsNullOrEmpty(nv))
                {
                    var i = nv.IndexOf('=');
                    if (i > -1)
                    {
                        var n = nv.Substring(0, i).Trim();
                        var v = nv.Substring(i + 1).Trim();
                        if (!string.IsNullOrEmpty(n) && !string.IsNullOrEmpty(v))
                        {
                            int j;
                            if (int.TryParse(v, out j))
                            {
                                ffmpeg.av_dict_set_int(&options, n, j, 0);
                            }
                            else
                            {
                                ffmpeg.av_dict_set(&options, n, v, 0);
                            }
                        }
                    }
                }
            }


            _stopReadingFrames = false;
            try
            {
                Program.FfmpegMutex.WaitOne();
                var pFormatContext = ffmpeg.avformat_alloc_context();
                _lastPacket = DateTime.UtcNow;


                _interruptCallback        = InterruptCb;
                _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

                pFormatContext->interrupt_callback.callback = _interruptCallbackAddress;
                pFormatContext->interrupt_callback.opaque   = null;


                if (ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options) != 0)
                {
                    throw new ApplicationException(@"Could not open source");
                }
                _formatContext = pFormatContext;


                SetupFormat();
            }
            catch (Exception ex)
            {
                ErrorHandler?.Invoke(ex.Message);
                _res = ReasonToFinishPlaying.VideoSourceError;
                PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
                AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
            }
            finally
            {
                try
                {
                    Program.FfmpegMutex.ReleaseMutex();
                }
                catch
                {
                }
            }
            _starting = false;
        }
Esempio n. 10
0
        /// <summary>
        /// Extracts the stream infos from the input.
        /// </summary>
        /// <param name="inputContext">The input context.</param>
        /// <returns>The list of stream infos.</returns>
        private static List <StreamInfo> ExtractStreams(AVFormatContext *inputContext)
        {
            var result = new List <StreamInfo>(32);

            if (inputContext->streams == null)
            {
                return(result);
            }

            for (var i = 0; i < inputContext->nb_streams; i++)
            {
                var s = inputContext->streams[i];

                var codecContext = ffmpeg.avcodec_alloc_context3(null);
                ffmpeg.avcodec_parameters_to_context(codecContext, s->codecpar);

                // Fields which are missing from AVCodecParameters need to be taken
                // from the stream's AVCodecContext
                codecContext->properties   = s->codec->properties;
                codecContext->codec        = s->codec->codec;
                codecContext->qmin         = s->codec->qmin;
                codecContext->qmax         = s->codec->qmax;
                codecContext->coded_width  = s->codec->coded_height;
                codecContext->coded_height = s->codec->coded_width;

                var bitsPerSample = codecContext->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO ?
                                    ffmpeg.av_get_bits_per_sample(codecContext->codec_id) : 0;

                var dar      = s->display_aspect_ratio;
                var sar      = s->sample_aspect_ratio;
                var codecSar = s->codecpar->sample_aspect_ratio;

                if (sar.num != 0 && (sar.num != codecSar.num || sar.den != codecSar.den))
                {
                    ffmpeg.av_reduce(
                        &dar.num,
                        &dar.den,
                        s->codecpar->width * sar.num,
                        s->codecpar->height * sar.den,
                        1024 * 1024);
                }

                var stream = new StreamInfo
                {
                    StreamId            = s->id,
                    StreamIndex         = s->index,
                    Metadata            = FFDictionary.ToDictionary(s->metadata),
                    CodecType           = codecContext->codec_type,
                    CodecTypeName       = ffmpeg.av_get_media_type_string(codecContext->codec_type),
                    Codec               = codecContext->codec_id,
                    CodecName           = ffmpeg.avcodec_get_name(codecContext->codec_id),
                    CodecProfile        = ffmpeg.avcodec_profile_name(codecContext->codec_id, codecContext->profile),
                    ReferenceFrameCount = codecContext->refs,
                    CodecTag            = codecContext->codec_tag,
                    PixelFormat         = codecContext->pix_fmt,
                    FieldOrder          = codecContext->field_order,
                    IsInterlaced        = codecContext->field_order != AVFieldOrder.AV_FIELD_PROGRESSIVE &&
                                          codecContext->field_order != AVFieldOrder.AV_FIELD_UNKNOWN,
                    ColorRange        = codecContext->color_range,
                    PixelWidth        = codecContext->width,
                    PixelHeight       = codecContext->height,
                    HasClosedCaptions = (codecContext->properties & ffmpeg.FF_CODEC_PROPERTY_CLOSED_CAPTIONS) != 0,
                    IsLossless        = (codecContext->properties & ffmpeg.FF_CODEC_PROPERTY_LOSSLESS) != 0,
                    BitRate           = bitsPerSample > 0 ?
                                        bitsPerSample * codecContext->channels * codecContext->sample_rate :
                                        codecContext->bit_rate,
                    MaxBitRate         = codecContext->rc_max_rate,
                    InfoFrameCount     = s->codec_info_nb_frames,
                    TimeBase           = s->time_base,
                    SampleFormat       = codecContext->sample_fmt,
                    SampleRate         = codecContext->sample_rate,
                    DisplayAspectRatio = dar,
                    SampleAspectRatio  = sar,
                    Disposition        = s->disposition,
                    StartTime          = s->start_time.ToTimeSpan(s->time_base),
                    Duration           = s->duration.ToTimeSpan(s->time_base),
                    FPS = s->avg_frame_rate.ToDouble(),
                    TBR = s->r_frame_rate.ToDouble(),
                    TBN = 1d / s->time_base.ToDouble(),
                    TBC = 1d / s->codec->time_base.ToDouble()
                };

                // Extract valid hardware configurations
                stream.HardwareDevices  = HardwareAccelerator.GetCompatibleDevices(stream.Codec);
                stream.HardwareDecoders = GetHardwareDecoders(stream.Codec);

                // TODO: I chose not to include Side data but I could easily do so
                // https://ffmpeg.org/doxygen/3.2/dump_8c_source.html
                // See function: dump_sidedata
                ffmpeg.avcodec_free_context(&codecContext);

                result.Add(stream);
            }

            return(result);
        }
Esempio n. 11
0
        /// <summary>
        /// Opens this media.
        /// </summary>
        /// <remarks>
        /// Once the media is open, the collection of <see cref="Streams"/> is populated.
        /// </remarks>
        public void Open(string url, long startPosition = 0, long length = -1)
        {
            FFmpegUtils.EnsurePlatformSupport();
            if (isDisposed)
            {
                throw new ObjectDisposedException(nameof(FFmpegMedia));
            }
            if (IsOpen)
            {
                // TODO: log?
                throw new InvalidOperationException(@"Media is already open.");
            }

            if (startPosition != 0 && length != -1)
            {
                url = $@"subfile,,start,{startPosition},end,{startPosition + length},,:{url}";
            }

            var pFormatContext = ffmpeg.avformat_alloc_context();
            var ret            = ffmpeg.avformat_open_input(&pFormatContext, url, null, null);

            if (ret < 0)
            {
                Logger.Error($"Could not open file. Error code={ret.ToString("X8")}");
                Logger.Error(GetErrorMessage(ret));
                throw new ApplicationException(@"Could not open file.");
            }

            ret = ffmpeg.avformat_find_stream_info(pFormatContext, null);
            if (ret < 0)
            {
                Logger.Error($"Could not find stream info. Error code={ret.ToString("X8")}");
                Logger.Error(GetErrorMessage(ret));
                throw new ApplicationException(@"Could not find stream info.");
            }

            AVFormatContext = pFormatContext;
            Duration        = TimeSpan.FromSeconds((double)AVFormatContext->duration / ffmpeg.AV_TIME_BASE);
            Url             = url;

            // Get the streams
            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                var stream = FFmpegStream.Create(pFormatContext->streams[i], this);
                streams.Add(stream);
            }

            pDecodedFrame = ffmpeg.av_frame_alloc();
            if (pDecodedFrame == null)
            {
                throw new ApplicationException("Couldn't allocate a frame for decoding.");
            }

            pCpuCopyFrame = ffmpeg.av_frame_alloc();
            if (pCpuCopyFrame == null)
            {
                throw new ApplicationException("Couldn't allocate a frame for hardware decoding.");
            }

            // dispose cached video image from previous file
            ClearStreamInfo();
        }
Esempio n. 12
0
        /// <summary>
        /// Initializes the internal transcoder -- This create the input, processing, and output blocks that make
        /// up the video and audio decoding stream.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="inputFormatName">Name of the input format. Leave null or empty to detect automatically</param>
        /// <param name="referer">The referer. Leave null or empty to skip setting it</param>
        /// <param name="userAgent">The user agent. Leave null or empty to skip setting it.</param>
        /// <exception cref="FileFormatException"></exception>
        /// <exception cref="Exception">Could not find stream info
        /// or
        /// Media must contain at least a video or and audio stream</exception>
        /// <exception cref="System.Exception">Could not open file
        /// or
        /// Could not find stream info
        /// or
        /// Media must contain a video stream
        /// or
        /// Media must contain an audio stream
        /// or
        /// Unsupported codec
        /// or
        /// Could not initialize the output conversion context
        /// or
        /// Could not create output codec context from input
        /// or
        /// Could not open codec</exception>
        private void InitializeMedia(string filePath, string inputFormatName, string referer, string userAgent)
        {
            // Create the input format context by opening the file
            InputFormatContext = ffmpeg.avformat_alloc_context();

            AVDictionary* optionsDict = null;

            if (string.IsNullOrWhiteSpace(userAgent) == false)
                ffmpeg.av_dict_set(&optionsDict, "user-agent", userAgent, 0);

            if (string.IsNullOrWhiteSpace(referer) == false)
                ffmpeg.av_dict_set(&optionsDict, "headers", $"Referer:{referer}", 0);

            ffmpeg.av_dict_set_int(&optionsDict, "usetoc", 1, 0);

            { // for m3u8 (HLS) streaming
                // TODO: maybe detect here if it is streaming? I need to test if this negatively affects filesystem files or network files as opposed to RTSP streams and HLS streams
                ffmpeg.av_dict_set_int(&optionsDict, "multiple_requests", 1, 0);
                ffmpeg.av_dict_set_int(&optionsDict, "reconnect", 1, 0);
                ffmpeg.av_dict_set_int(&optionsDict, "reconnect_at_eof", 1, 0);
                ffmpeg.av_dict_set_int(&optionsDict, "reconnect_streamed", 1, 0);
                ffmpeg.av_dict_set_int(&optionsDict, "reconnect_delay_max", (int)Constants.WaitForPlaybackReadyStateTimeout.TotalMilliseconds, 0);
            }


            AVInputFormat* inputFormat = null;

            if (string.IsNullOrWhiteSpace(inputFormatName) == false)
            inputFormat = ffmpeg.av_find_input_format(inputFormatName);

            fixed (AVFormatContext** inputFormatContextRef = &InputFormatContext)
            {
                if (ffmpeg.avformat_open_input(inputFormatContextRef, filePath, inputFormat, &optionsDict) != 0)
                    throw new FileFormatException(string.Format("Could not open stream or file '{0}'", filePath));
            }

            InputFormatContext->iformat->flags |= ffmpeg.AVFMT_FLAG_NOBUFFER;
            InputFormatContext->iformat->flags |= ffmpeg.AVFMT_FLAG_NOFILLIN;

            ffmpeg.av_dict_free(&optionsDict);
            
            // Extract the stream info headers from the file
            if (ffmpeg.avformat_find_stream_info(InputFormatContext, null) != 0)
                throw new Exception("Could not find stream info");

            // search for the audio and video streams
            for (int i = 0; i < InputFormatContext->nb_streams; i++)
            {
                var codecType = InputFormatContext->streams[i]->codec->codec_type;

                if (codecType == AVMediaType.AVMEDIA_TYPE_VIDEO && InputVideoStream == null)
                {
                    InputVideoStream = InputFormatContext->streams[i];
                    continue;
                }

                if (codecType == AVMediaType.AVMEDIA_TYPE_AUDIO && InputAudioStream == null)
                {
                    InputAudioStream = InputFormatContext->streams[i];
                    continue;
                }
            }

            if (InputVideoStream != null)
            {
                this.InitializeVideo();
                this.HasVideo = VideoBitrate > 0 || VideoFrameRate > 0M || VideoFrameWidth > 0 || VideoFrameHeight > 0;
            }

            if (InputAudioStream != null)
            {
                this.InitializeAudio();
                this.HasAudio = AudioBytesPerSample > 0;
            }

            if (HasAudio == false && HasVideo == false)
            {
                throw new Exception("Media must contain at least a video or and audio stream");
            }
            else
            {
                // General Properties here

                NaturalDuration = Convert.ToDecimal(Convert.ToDouble(InputFormatContext->duration) / Convert.ToDouble(ffmpeg.AV_TIME_BASE));
                IsLiveStream = Helper.IsNoPtsValue(InputFormatContext->duration);
                StartTime = Convert.ToDecimal(Convert.ToDouble(InputFormatContext->start_time) / Convert.ToDouble(ffmpeg.AV_TIME_BASE));
                EndTime = StartTime + NaturalDuration;

                RealtimeClock.Seek(StartTime);
            }
        }
Esempio n. 13
0
        public MediaFile(String path, bool tryFrames = true)
        {
            pFormatCtx = ffmpeg.avformat_alloc_context();

            var formatCtx = pFormatCtx;

            ffmpeg.avformat_open_input(&formatCtx, path, null, null).ThrowExceptionIfError();

            ffmpeg.avformat_find_stream_info(pFormatCtx, null).ThrowExceptionIfError();

            AVStream *pStream = null;

            for (var i = 0; i < pFormatCtx->nb_streams; i++)
            {
                if (pFormatCtx->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    pStream = pFormatCtx->streams[i];
                    break;
                }
            }

            if (pStream == null)
            {
                throw new InvalidOperationException("Could not found video stream.");
            }

            streamIndex = pStream->index;
            pCodecCtx   = pStream->codec;

            var codecId = pCodecCtx->codec_id;
            var pCodec  = ffmpeg.avcodec_find_decoder(codecId);

            if (pCodec == null)
            {
                throw new InvalidOperationException("Unsupported codec.");
            }

            filepath = path;

            ffmpeg.avcodec_open2(pCodecCtx, pCodec, null).ThrowExceptionIfError();

            CodecName = ffmpeg.avcodec_get_name(codecId);

            pPacket = ffmpeg.av_packet_alloc();
            pFrame  = ffmpeg.av_frame_alloc();

            width       = pCodecCtx->width;
            height      = pCodecCtx->height;
            totalFrames = tryFrames ? TryGetFrameCount() : pStream->nb_frames;

            var pixFmt = pCodecCtx->pix_fmt;

            if (pixFmt == AVPixelFormat.AV_PIX_FMT_NONE)
            {
                pixFmt = AVPixelFormat.AV_PIX_FMT_YUV420P;
            }

            var destPixFmt = AVPixelFormat.AV_PIX_FMT_BGR24;

            scaleCtx = ffmpeg.sws_getContext(width, height, pixFmt,
                                             width, height, destPixFmt,
                                             ffmpeg.SWS_BICUBIC, null, null, null);

            var rgbBufSize = ffmpeg.av_image_get_buffer_size(destPixFmt, width, height, 1);

            rgbFrameBuffer = Marshal.AllocHGlobal(rgbBufSize);

            rgbBuf      = new byte_ptrArray4();
            dstLinesize = new int_array4();
            ffmpeg.av_image_fill_arrays(ref rgbBuf, ref dstLinesize, (byte *)rgbFrameBuffer, destPixFmt, width, height, 1);
        }
Esempio n. 14
0
        /// <summary>
        /// Disposes all active objects and opens a file or url
        /// </summary>
        /// <param name="url">path of the media file</param>
        public void OpenFileOrUrl(string url)
        {
            this.Dispose();

            // Initialize instance of AVUTIL, AVCODEC, AVFORMAT
            ffmpeg.av_register_all();
            ffmpeg.avcodec_register_all();
            ffmpeg.avformat_network_init();

            // Open source file
            AVFormatContext* pFormatContext = ffmpeg.avformat_alloc_context();
            if (ffmpeg.avformat_open_input(&pFormatContext, url, null, null) != 0)
                throw new Exception("File or URL not found!");

            if (ffmpeg.avformat_find_stream_info(pFormatContext, null) != 0)
                throw new Exception("No stream information found!");

            // Collect general media information
            this.Filename = new String(pFormatContext->filename);
            this.Metadata = ToDictionary(pFormatContext->metadata);
            this.Duration = ToTimeSpan(pFormatContext->duration);
            this.BitRate = pFormatContext->bit_rate;

            // Collect information about streams
            bool isFirstVideoStream = true;
            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                #region Read stream information
                FFmpegStreamInfo info = new FFmpegStreamInfo();
                info.AVStream = pFormatContext->streams[i];
                info.Index = pFormatContext->streams[i]->index;
                switch (pFormatContext->streams[i]->codec->codec_type)
                {
                    case AVMediaType.AVMEDIA_TYPE_VIDEO:
                        info.StreamType = FFmpegStreamType.Video;
                        info.Video_Width = pFormatContext->streams[i]->codec->width;
                        info.Video_Height = pFormatContext->streams[i]->codec->height;
                        info.Video_FPS = ToDouble(pFormatContext->streams[i]->codec->framerate);
                        if (isFirstVideoStream)
                        {
                            this.VideoResolution = new Size(info.Video_Width, info.Video_Height);
                            isFirstVideoStream = false;
                        }
                        break;
                    case AVMediaType.AVMEDIA_TYPE_AUDIO:
                        info.StreamType = FFmpegStreamType.Audio;
                        info.Audio_SampleRate = pFormatContext->streams[i]->codec->sample_rate;
                        info.Audio_Channels = pFormatContext->streams[i]->codec->channels;
                        break;
                    case AVMediaType.AVMEDIA_TYPE_SUBTITLE:
                        info.StreamType = FFmpegStreamType.Subtitle;
                        break;
                    default:
                        info.StreamType = FFmpegStreamType.Unknown;
                        break;
                }
                info.MetaData = ToDictionary(pFormatContext->streams[i]->metadata);
                if (info.MetaData.ContainsKey("language")) info.Language = info.MetaData["language"];
                info.BitRate = pFormatContext->streams[i]->codec->bit_rate;
                info.FourCC = ToFourCCString(pFormatContext->streams[i]->codec->codec_tag);
                info.CodecName = getAvCodecName(pFormatContext->streams[i]->codec->codec_id);
                this.Streams.Add(info);
                #endregion
            }

            this.AVFormatContext = pFormatContext;
            _isDisposed = false;
        }
Esempio n. 15
0
        public void Open(string FileName)
        {
            DecoderConfig.Init();

            AVFormatContext* pFormatContext = FFmpegInvoke.avformat_alloc_context();
            _pFormatContext = pFormatContext;

            if (FFmpegInvoke.avformat_open_input(&pFormatContext, FileName, null, null) != 0)
                throw new Exception("Could not open file");

            if (FFmpegInvoke.avformat_find_stream_info(pFormatContext, null) != 0)
                throw new Exception("Could not find stream info");

            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                if (pFormatContext->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    _pStream = pFormatContext->streams[i];
                    break;
                }
            }

            if (_pStream == null)
                throw new Exception("Could not found video stream");
            AVCodecContext codecContext = *(_pStream->codec);
            codecContext.workaround_bugs = FFmpegInvoke.FF_BUG_AUTODETECT;

            _frameduration = 1 / q2d(_pStream->r_frame_rate);
            FrameCount = _pStream->nb_frames;
            Duration = (float)pFormatContext->duration / FFmpegInvoke.AV_TIME_BASE;
            Width = codecContext.width;
            Height = codecContext.height;

            AVPixelFormat sourcePixFmt = codecContext.pix_fmt;
            AVCodecID codecId = codecContext.codec_id;
            var convertToPixFmt = AVPixelFormat.AV_PIX_FMT_RGB24;
            _pConvertContext = FFmpegInvoke.sws_getContext(Width, Height, sourcePixFmt,
                                                                       Width, Height, convertToPixFmt,
                                                                       FFmpegInvoke.SWS_FAST_BILINEAR, null, null, null);

            if (_pConvertContext == null)
                throw new Exception("Could not initialize the conversion context");

            _pConvertedFrame = (AVPicture*)FFmpegInvoke.avcodec_alloc_frame();
            int convertedFrameBufferSize = FFmpegInvoke.avpicture_get_size(convertToPixFmt, Width, Height);
            _pConvertedFrameBuffer = (byte*)FFmpegInvoke.av_malloc((uint)convertedFrameBufferSize);
            FFmpegInvoke.avpicture_fill(_pConvertedFrame, _pConvertedFrameBuffer, convertToPixFmt, Width, Height);

            AVCodec* pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
            if (pCodec == null)
                throw new Exception("Unsupported codec");

            if (FFmpegInvoke.avcodec_open2(_pStream->codec, pCodec, null) < 0)
                throw new Exception("Could not open codec");

            _pDecodedFrame = FFmpegInvoke.avcodec_alloc_frame();

            _packet = new AVPacket();

            fixed (AVPacket* pPacket = &_packet)
            {
                FFmpegInvoke.av_init_packet(pPacket);
            }

            _opened = true;
        }
Esempio n. 16
0
        public void Close()
        {
            if (!_opened)
                return;
            FFmpegInvoke.av_free(_pConvertedFrame);
            FFmpegInvoke.av_free(_pConvertedFrameBuffer);
            FFmpegInvoke.sws_freeContext(_pConvertContext);

            FFmpegInvoke.av_free(_pDecodedFrame);
            FFmpegInvoke.avcodec_close(_pStream->codec);
            fixed (AVFormatContext** pFormatContext = &_pFormatContext)
            {
                FFmpegInvoke.avformat_close_input(pFormatContext);
            }

            _videoClock = 0;
            _pFormatContext = null;
            _pStream = null;
            _pDecodedFrame = null;
            _pConvertedFrame = null;
            _pConvertedFrameBuffer = null;
            _pConvertContext = null;
            _opened = false;
        }
Esempio n. 17
0
        public void CreateOutput()
        {
            AVFormatContext *outputFmtCtx;

            AudioIndex = -1;
            VideoIndex = -1;
            string           filename    = @"C:\Users\admin\Desktop\output223423423.avi";
            AVFormatContext *inputFmtCtx = _fmt_ctx;

            if (ffmpeg.avformat_alloc_output_context2(&outputFmtCtx, null, null, filename) < 0) //음수가 나오면 에러인거야...
            {
                Console.WriteLine("파일 생성 못해!!!");
            }
            var oCodec = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_H264);

            for (int index = 0; index < inputFmtCtx->nb_streams; index++)
            {
                AVStream *      in_stream    = inputFmtCtx->streams[index];
                AVCodecContext *in_codec_ctx = in_stream->codec;
                in_codec_ctx = ffmpeg.avcodec_alloc_context3(inputFmtCtx->data_codec);
                AVStream *out_stream = ffmpeg.avformat_new_stream(outputFmtCtx, null);

                if (out_stream == null)
                {
                    Console.WriteLine("OUTPUT 스트림 NULL");
                }

                //
                AVCodecContext *outCodecContext = out_stream->codec;
                outCodecContext->codec = oCodec;
                outCodecContext        = ffmpeg.avcodec_alloc_context3(oCodec);

                outCodecContext->height = 500;
                outCodecContext->width  = 600;
                //  outCodecContext->sample_aspect_ratio = videoInfo.Sample_aspect_ratio;
                outCodecContext->pix_fmt   = AVPixelFormat.AV_PIX_FMT_YUV420P;
                outCodecContext->time_base = new AVRational {
                    num = 1, den = 15
                };
                //   outCodecContext->framerate = ffmpeg.av_inv_q(videoInfo.Framerate);

                //context를 설정해야 뭔가 쓸수잇오.....


                if (ffmpeg.avcodec_parameters_from_context(out_stream->codecpar, outCodecContext) < 0)
                {
                    Console.WriteLine("copy 못해에!!!");
                }

                out_stream->time_base = in_stream->time_base;

                outCodecContext->codec_tag = 0;


                if ((outputFmtCtx->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) == 0)
                {
                    outCodecContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
                }
                //  ffmpeg.avcodec_open2(outCodecContext, oCodec, null).ThrowExceptionIfError();

                VideoIndex = 0;
                AudioIndex = 1;
                ffmpeg.av_dump_format(outputFmtCtx, 0, filename, 1);

                if ((outputFmtCtx->oformat->flags & ffmpeg.AVFMT_NOFILE) == 0)
                {
                    // This actually open the file
                    if (ffmpeg.avio_open(&outputFmtCtx->pb, filename, ffmpeg.AVIO_FLAG_WRITE) < 0)
                    {
                        Console.WriteLine("못만들오...");
                    }
                }
                if (ffmpeg.avformat_write_header(outputFmtCtx, null) < 0)
                {
                    Console.WriteLine("헤더를 못써...\n");
                }
            }
            ffmpeg.av_write_trailer(outputFmtCtx);
            ffmpeg.avio_closep(&outputFmtCtx->pb);
            ffmpeg.avformat_free_context(outputFmtCtx);
        }
Esempio n. 18
0
 private InputContainer(AVFormatContext *formatContext)
     : base(formatContext)
 {
 }
Esempio n. 19
0
        /// <summary>
        /// Releases all managed and unmanaged resources
        /// </summary>
        public void Dispose()
        {
            if (IsCancellationPending)
                return;

            this.IsCancellationPending = true;

            this.VideoRenderTimer.Stop();

            if (this.AudioRenderer != null)
            {
                if (this.AudioRenderer.HasInitialized)
                    this.AudioRenderer.Stop();

                this.AudioRenderer.Dispose();
                this.AudioRenderer = null;
            }

            if (MediaFrameExtractorThread != null)
            {
                MediaFrameExtractorThread.Join();
                MediaFrameExtractorThread = null;
            }

            if (MediaFramesExtractedDone != null)
            {
                try
                {
                    MediaFramesExtractedDone.Dispose();
                    MediaFramesExtractedDone = null;
                }
                finally { }
            }

            if (PrimaryFramesCache != null)
            {
                PrimaryFramesCache.Clear();
                PrimaryFramesCache = null;
            }

            if (SecondaryFramesCache != null)
            {
                SecondaryFramesCache.Clear();
                SecondaryFramesCache = null;
            }

            if (VideoCodecContext != null)
            {
                fixed (AVCodecContext** videoCodecContextRef = &VideoCodecContext)
                {
                    ffmpeg.avcodec_close(VideoCodecContext);
                    ffmpeg.avcodec_free_context(videoCodecContextRef);
                    VideoCodecContext = null;
                }
            }

            if (AudioCodecContext != null)
            {
                fixed (AVCodecContext** audioCodecContextRef = &AudioCodecContext)
                {
                    ffmpeg.avcodec_close(AudioCodecContext);
                    ffmpeg.avcodec_free_context(audioCodecContextRef);
                    AudioCodecContext = null;
                }
            }

            if (VideoResampler != null)
            {
                ffmpeg.sws_freeContext(VideoResampler);
                VideoResampler = null;
            }

            if (AudioResampler != null)
            {
                fixed (SwrContext** audioResamplerRef = &AudioResampler)
                {
                    ffmpeg.swr_close(AudioResampler);
                    ffmpeg.swr_free(audioResamplerRef);
                    AudioResampler = null;
                }
            }

            if (InputFormatContext != null)
            {
                fixed (AVFormatContext** inputFormatContextRef = &InputFormatContext)
                {
                    ffmpeg.avformat_close_input(inputFormatContextRef);
                    ffmpeg.avformat_free_context(InputFormatContext);
                    InputFormatContext = null;
                }
            }

            if (DecodedPictureHolder != null)
            {
                ffmpeg.av_free(DecodedPictureHolder);
                DecodedPictureHolder = null;
            }

            if (DecodedWaveHolder != null)
            {
                ffmpeg.av_free(DecodedWaveHolder);
                DecodedWaveHolder = null;
            }

        }
Esempio n. 20
0
        public void testSet()
        {
            FFmpegBinariesHelper.RegisterFFmpegBinaries();
            ffmpeg.avdevice_register_all();
            var fmt_ctx = _fmt_ctx;

            fmt_ctx = ffmpeg.avformat_alloc_context();

            AVInputFormat *iformat = ffmpeg.av_find_input_format("dshow");
            string         device  = "video=USB3. 0 capture:audio=디지털 오디오 인터페이스(5- USB3. 0 capture)";


            var a          = ffmpeg.avformat_open_input(&fmt_ctx, device, iformat, null); //음수이면 파일 안열려..그런 장치 없어!!
            var b          = ffmpeg.avformat_find_stream_info(fmt_ctx, null);             //Stream을 찾을수 없어...
            int videoIndex = -1;
            int audioIndex = -1;

            _fmt_ctx = fmt_ctx;
            AVFormatContext *outputFmtCtx;

            AudioIndex = -1;
            VideoIndex = -1;
            string           filename    = @"C:\Users\admin\Desktop\output223423423.avi";
            AVFormatContext *inputFmtCtx = _fmt_ctx;

            if (ffmpeg.avformat_alloc_output_context2(&outputFmtCtx, null, null, filename) < 0)     //음수가 나오면 에러인거야...
            {
                Console.WriteLine("파일 생성 못해!!!");
            }
            var oCodec = ffmpeg.avcodec_find_encoder(AVCodecID.AV_CODEC_ID_MPEG4);

            for (int index = 0; index < inputFmtCtx->nb_streams; index++)
            {
                AVStream *      in_stream    = inputFmtCtx->streams[index];
                AVCodecContext *in_codec_ctx = in_stream->codec;
                in_codec_ctx = ffmpeg.avcodec_alloc_context3(inputFmtCtx->data_codec);
                AVStream *out_stream = ffmpeg.avformat_new_stream(outputFmtCtx, null);

                if (out_stream == null)
                {
                    Console.WriteLine("OUTPUT 스트림 NULL");
                }

                //
                AVCodecContext *outCodecContext = out_stream->codec;
                outCodecContext->codec = oCodec;
                outCodecContext        = ffmpeg.avcodec_alloc_context3(oCodec);

                outCodecContext->height = 500;
                outCodecContext->width  = 600;
                //  outCodecContext->sample_aspect_ratio = videoInfo.Sample_aspect_ratio;
                outCodecContext->pix_fmt   = AVPixelFormat.AV_PIX_FMT_YUV420P;
                outCodecContext->time_base = new AVRational {
                    num = 1, den = 15
                };
                //   outCodecContext->framerate = ffmpeg.av_inv_q(videoInfo.Framerate);

                //context를 설정해야 뭔가 쓸수잇오.....


                if (ffmpeg.avcodec_parameters_from_context(out_stream->codecpar, outCodecContext) < 0)
                {
                    Console.WriteLine("copy 못해에!!!");
                }

                out_stream->time_base = in_stream->time_base;

                outCodecContext->codec_tag = 0;


                if ((outputFmtCtx->oformat->flags & ffmpeg.AVFMT_GLOBALHEADER) == 0)
                {
                    outCodecContext->flags |= ffmpeg.AV_CODEC_FLAG_GLOBAL_HEADER;
                }
                //  ffmpeg.avcodec_open2(outCodecContext, oCodec, null).ThrowExceptionIfError();

                VideoIndex = 0;
                AudioIndex = 1;
                ffmpeg.av_dump_format(outputFmtCtx, 0, filename, 1);

                if ((outputFmtCtx->oformat->flags & ffmpeg.AVFMT_NOFILE) == 0)
                {
                    // This actually open the file
                    if (ffmpeg.avio_open(&outputFmtCtx->pb, filename, ffmpeg.AVIO_FLAG_WRITE) < 0)
                    {
                        Console.WriteLine("못만들오...");
                    }
                }
                if (ffmpeg.avformat_write_header(outputFmtCtx, null) < 0)
                {
                    Console.WriteLine("헤더를 못써...\n");
                }
            }
            //ffmpeg.av_write_trailer(outputFmtCtx);
            //ffmpeg.avio_closep(&outputFmtCtx->pb);
            //ffmpeg.avformat_free_context(outputFmtCtx);

            //nb_streams : 요소 몇갠지..!!! 내가 찾은거에서 뭐있는지
            for (int index = 0; index < fmt_ctx->nb_streams; index++)
            {
                var avCodecContext = fmt_ctx->streams[index]->codec;
                if (avCodecContext->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    videoIndex = index;
                }
                else if (avCodecContext->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO)
                {
                    audioIndex = index;
                    Console.WriteLine(audioIndex + "***");
                }
                if (avCodecContext->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    videoIndex = index;
                    Console.WriteLine($"====================={avCodecContext->codec_type}======================");
                    //Console.WriteLine(avCodecContext->bit_rate); //W * H *FPS
                    //Console.WriteLine(avCodecContext->codec_id);
                    //Console.WriteLine(avCodecContext->width);
                    //Console.WriteLine(avCodecContext->coded_width);
                    //Console.WriteLine(avCodecContext->height);
                    //Console.WriteLine(avCodecContext->coded_height);
                    //Console.WriteLine(avCodecContext->pts_correction_num_faulty_pts);
                    //Console.WriteLine(avCodecContext->pts_correction_last_dts);
                    //Console.WriteLine(avCodecContext->pts_correction_last_pts);
                    Console.WriteLine();
                }
                else if (avCodecContext->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO)
                {
                    audioIndex = index;
                    Console.WriteLine($"====================={avCodecContext->codec_type}======================");
                    //Console.WriteLine(avCodecContext->bit_rate); //W * H *FPS
                    //Console.WriteLine(avCodecContext->codec_id);
                    //Console.WriteLine($"Channels :  {avCodecContext->channels}");
                    //Console.WriteLine(avCodecContext->width);
                    //Console.WriteLine(avCodecContext->coded_width);
                    //Console.WriteLine(avCodecContext->height);
                    //Console.WriteLine(avCodecContext->coded_height);
                    //Console.WriteLine(avCodecContext->pts_correction_num_faulty_pts);
                    //Console.WriteLine(avCodecContext->pts_correction_last_dts);
                    //Console.WriteLine(avCodecContext->pts_correction_last_pts);
                }
            }

            int      ret;
            AVPacket pkt;
            int      out_stream_index;

            while (true)
            {
                ret = ffmpeg.av_read_frame(fmt_ctx, &pkt); //ret == 0 이면

                if (ret == ffmpeg.AVERROR_EOF)
                {
                    Console.WriteLine("frame end");
                    break;
                }

                if (pkt.stream_index == videoIndex)
                {
                    Console.WriteLine("Video Packet");
                }
                else if (pkt.stream_index == audioIndex)
                {
                    Console.WriteLine("Audio Packet");
                }

                AVStream *in_stream = fmt_ctx->streams[pkt.stream_index];
                out_stream_index = (pkt.stream_index == videoIndex) ? videoIndex : audioIndex;
                AVStream *out_stream = outputFmtCtx->streams[out_stream_index];

                ffmpeg.av_packet_rescale_ts(&pkt, in_stream->time_base, out_stream->time_base);


                pkt.stream_index = out_stream_index;

                if (ffmpeg.av_interleaved_write_frame(outputFmtCtx, &pkt) < 0)
                {
                    Console.WriteLine("!!!!!!!!@#####!@#!@#!");
                    break;
                }

                ffmpeg.av_packet_unref(&pkt); //옛날엔 av_free_packet()
            }

            ffmpeg.av_write_trailer(outputFmtCtx);
        }
Esempio n. 21
0
 public static extern void avdevice_capabilities_free(AVDeviceCapabilitiesQuery ** @caps, AVFormatContext * @s);
Esempio n. 22
0
        public unsafe H264Decoder(List <byte[]> nalUnits)
        {
            if (!initialized)
            {
                ffmpeg.av_register_all();
                initialized = true;
            }
            int localStreamSuffix = streamSuffix;

            streamSuffix++;

            int dataSize = 0;

            foreach (byte[] nalUnit in nalUnits)
            {
                dataSize += nalUnit.Length + startSequence.Length;
            }

            byte *dat = (byte *)ffmpeg.av_malloc((ulong)dataSize);


            fixed(byte *start = startSequence)
            {
                foreach (byte[] nalUnit in nalUnits)
                {
                    fixed(byte *dataPtr = nalUnit)
                    {
                        UnmanagedMemory.CopyMemory(dat, start, (uint)startSequence.Length);
                        dat += startSequence.Length;
                        UnmanagedMemory.CopyMemory(dat, dataPtr, (uint)nalUnit.Length);
                        dat += nalUnit.Length;
                    }
                }

                dat -= dataSize;
            }

            AVFormatContext *icLocal = ffmpeg.avformat_alloc_context();

            ic = icLocal;

            avio_alloc_context_write_packet_func writeCallback;

            writeCallback.Pointer = IntPtr.Zero;
            avio_alloc_context_seek_func seekCallback;

            seekCallback.Pointer = IntPtr.Zero;
            avio_alloc_context_read_packet_func readCallback;

            readCallback.Pointer = IntPtr.Zero;

            icLocal->pb = ffmpeg.avio_alloc_context(dat, bufferSize, 0, null, readCallback, writeCallback, seekCallback);

            if (icLocal->pb == null)
            {
                throw new Exception("Failed to allocate ffmpeg context.");
            }

            // Need to probe buffer for input format unless you already know it
            AVProbeData probe_data;

            probe_data.buf_size = dataSize;
            probe_data.filename = (byte *)Marshal.StringToHGlobalAnsi($"stream_{localStreamSuffix}");
            probe_data.buf      = (byte *)UnmanagedMemory.Alloc(probe_data.buf_size);
            UnmanagedMemory.CopyMemory(probe_data.buf, dat, (uint)probe_data.buf_size);

            AVInputFormat *pAVInputFormat = ffmpeg.av_probe_input_format(&probe_data, 1);

            if (pAVInputFormat == null)
            {
                pAVInputFormat = ffmpeg.av_probe_input_format(&probe_data, 0);
            }

            // cleanup
            UnmanagedMemory.DeAlloc((IntPtr)probe_data.buf, probe_data.buf_size);
            probe_data.buf = null;

            pAVInputFormat->flags |= ffmpeg.AVFMT_NOFILE;

            ffmpeg.avformat_open_input(&icLocal, $"stream_{localStreamSuffix}", pAVInputFormat, null);

            for (int i = 0; i < icLocal->nb_streams; i++)
            {
                AVCodecContext *enc = icLocal->streams[i]->codec;

                if (AVMediaType.AVMEDIA_TYPE_VIDEO == enc->codec_type)
                {
                    AVCodec *codec = ffmpeg.avcodec_find_decoder(enc->codec_id);

                    if (codec == null || ffmpeg.avcodec_open2(enc, codec, null) < 0)
                    {
                        //Console.WriteLine("Cannot find codec");
                    }

                    video_st = icLocal->streams[i];
                }
            }

            //Init picture
            yuv_image         = ffmpeg.av_frame_alloc();
            yuv_image->format = -1; //We do not know the format of the raw decoded image
        }
Esempio n. 23
0
 public static extern int avdevice_list_devices(AVFormatContext * @s, AVDeviceInfoList ** @device_list);
Esempio n. 24
0
        public int Init(string fileName, System.Windows.Controls.Image image, System.Windows.Controls.Image Dimage, System.Windows.Controls.Label startTime, System.Windows.Controls.Slider slider, System.Windows.Controls.Slider slider2)
        {
            ffmpeg.avcodec_register_all();

            AVFormatContext *pFormatCtx;

            pFormatCtx      = ffmpeg.avformat_alloc_context();
            this.pFormatCtx = pFormatCtx;

            ffmpeg.avformat_open_input(&pFormatCtx, fileName, null, null);
            ffmpeg.avformat_find_stream_info(pFormatCtx, null);

            for (int i = 0; i < pFormatCtx->nb_streams; i++)
            {
                if (pFormatCtx->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    videoIndex = i;
                    Console.WriteLine("video.............." + videoIndex);
                }
                if (pFormatCtx->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO)
                {
                    audioIndex = i;
                    Console.WriteLine("audio.............." + audioIndex);
                }
            }

            if (videoIndex == -1)
            {
                Console.WriteLine("Couldn't find a video stream.");
                return(-1);
            }
            if (audioIndex == -1)
            {
                Console.WriteLine("Couldn't find a audio stream.");
                return(-1);
            }

            if (videoIndex > -1)
            {
                pCodecCtxVideo = pFormatCtx->streams[videoIndex]->codec;
                pCodecVideo    = ffmpeg.avcodec_find_decoder(pCodecCtxVideo->codec_id);

                if (pCodecVideo == null)
                {
                    return(-1);
                }

                pCodecCtxVideo->codec_id = pCodecVideo->id;
                pCodecCtxVideo->lowres   = 0;

                if (pCodecCtxVideo->lowres > pCodecVideo->max_lowres)
                {
                    pCodecCtxVideo->lowres = pCodecVideo->max_lowres;
                }

                pCodecCtxVideo->idct_algo         = ffmpeg.FF_IDCT_AUTO;
                pCodecCtxVideo->error_concealment = 3;

                if (ffmpeg.avcodec_open2(pCodecCtxVideo, pCodecVideo, null) < 0)
                {
                    return(-1);
                }
                Console.WriteLine("Find a video stream. channel = " + videoIndex);

                frameSize = new System.Windows.Size(pCodecCtxVideo->width, pCodecCtxVideo->height);
                double frameRate = ffmpeg.av_q2d(pFormatCtx->streams[videoIndex]->r_frame_rate);
                frameGap = (int)(1000 / frameRate);

                double frameWidth  = frameSize.Width;
                double frameHeight = frameSize.Height;

                //fsrcnn = FSRCNN_construct();
                //FSRCNN_init(fsrcnn, (int)frameHeight, (int)frameWidth);

                image.Dispatcher.BeginInvoke((Action)(() =>
                {
                    slider2.Visibility = System.Windows.Visibility.Visible;
                    if (frameWidth >= 1000)
                    {
                        ((MainWindow)System.Windows.Application.Current.MainWindow).WindowState = WindowState.Maximized;
                        double tempRate = ((MainWindow)System.Windows.Application.Current.MainWindow).Width / frameWidth;
                        frameWidth = ((MainWindow)System.Windows.Application.Current.MainWindow).Width;
                        frameHeight *= tempRate;
                    }
                    ((MainWindow)System.Windows.Application.Current.MainWindow).Width = frameWidth;
                    ((MainWindow)System.Windows.Application.Current.MainWindow).Height = frameHeight + 140;

                    image.Width = frameWidth;
                    image.Height = frameHeight;
                    Dimage.Width = frameWidth;
                    Dimage.Height = frameHeight;
                    grid3.Width = frameWidth;
                    grid.Width = frameWidth;
                    grid2.Width = frameWidth;
                    slider.Width = frameWidth - 140;
                    slider2.Width = frameWidth - 140;


                    if (initCheck == false)
                    {
                        originalHeight = ((MainWindow)System.Windows.Application.Current.MainWindow).Height;
                        originalWidth = ((MainWindow)System.Windows.Application.Current.MainWindow).Width;
                        ((MainWindow)System.Windows.Application.Current.MainWindow).Width = 800;
                        ((MainWindow)System.Windows.Application.Current.MainWindow).Height = 800 * (originalHeight / originalWidth);
                    }

                    ((MainWindow)System.Windows.Application.Current.MainWindow).SizeChanged += new SizeChangedEventHandler(Window_SizeChanged);
                }));

                pFrameVideo = ffmpeg.av_frame_alloc();
                swsCtxVideo = new SwsContext *[4];
                for (int i = 0; i < scalerNum; i++)
                {
                    swsCtxVideo[i] = ffmpeg.sws_getContext(
                        (int)frameSize.Width,
                        (int)frameSize.Height,
                        pCodecCtxVideo->pix_fmt,
                        (int)frameSize.Width,
                        (int)frameSize.Height,
                        AVPixelFormat.AV_PIX_FMT_BGR24,
                        ffmpeg.SWS_FAST_BILINEAR, null, null, null);
                }
            }
            if (audioIndex > -1)
            {
                pCodecAudio   = ffmpeg.avcodec_find_decoder(pFormatCtx->streams[audioIndex]->codecpar->codec_id);
                pCodeCtxAudio = ffmpeg.avcodec_alloc_context3(pCodecAudio);
                ffmpeg.avcodec_parameters_to_context(pCodeCtxAudio, pFormatCtx->streams[audioIndex]->codecpar);

                if (pCodecAudio == null)
                {
                    return(-1);
                }
                if (ffmpeg.avcodec_open2(pCodeCtxAudio, pCodecAudio, null) < 0)
                {
                    return(-1);
                }
                Console.WriteLine("Find a audio stream. channel = " + audioIndex);

                sdlAudio = new SDLAudio();
                sdlAudio.SDL_Init(pCodeCtxAudio);

                pFrameAudio = ffmpeg.av_frame_alloc();
                swrCtxAudio = ffmpeg.swr_alloc();

                ffmpeg.av_opt_set_channel_layout(swrCtxAudio, "in_channel_layout", (long)pCodeCtxAudio->channel_layout, 0);
                ffmpeg.av_opt_set_channel_layout(swrCtxAudio, "out_channel_layout", (long)pCodeCtxAudio->channel_layout, 0);
                ffmpeg.av_opt_set_int(swrCtxAudio, "in_sample_rate", pCodeCtxAudio->sample_rate, 0);
                ffmpeg.av_opt_set_int(swrCtxAudio, "out_sample_rate", pCodeCtxAudio->sample_rate, 0);
                ffmpeg.av_opt_set_sample_fmt(swrCtxAudio, "in_sample_fmt", pCodeCtxAudio->sample_fmt, 0);
                ffmpeg.av_opt_set_sample_fmt(swrCtxAudio, "out_sample_fmt", AVSampleFormat.AV_SAMPLE_FMT_FLT, 0);
                ffmpeg.swr_init(swrCtxAudio);
            }

            this.image     = image;
            this.Dimage    = Dimage;
            entirePlayTime = pFormatCtx->duration;
            this.startTime = startTime;
            this.slider    = slider;


            scalerId = 0;
            rasterId = 0;

            videoPool = new PacketPool();
            audioPool = new PacketPool();
            fPool     = new FrameBuffer(frameSize);

            isEOF = false;
            state = State.Init;

            decodeSeek = false;
            srSeek     = false;
            drawSeek   = false;
            scaleSeek  = new bool[scalerNum];
            for (int i = 0; i < scalerNum; i++)
            {
                scaleSeek[i] = false;
            }
            rasterSeek = new bool[rasterNum];
            for (int i = 0; i < rasterNum; i++)
            {
                rasterSeek[i] = false;
            }

            gmfn = new GMFN();

            return(0);
        }
Esempio n. 25
0
        private void Open(string fileName, int width, int height, AVCodecID videoCodec, int framerate, AVCodecID audioCodec)
        {
            CreatedDate  = DateTime.UtcNow;
            Filename     = fileName;
            _abort       = false;
            _ignoreAudio = false;

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                IsTimelapse = framerate != 0;

                if (((width & 1) != 0) || ((height & 1) != 0))
                {
                    throw new ArgumentException("Video file resolution must be a multiple of two.");
                }
            }

            int i;

            _lastPacket = DateTime.UtcNow;
            var outputFormat = ffmpeg.av_guess_format(null, fileName, null);

            if (outputFormat == null)
            {
                switch (videoCodec)
                {
                default:
                case AVCodecID.AV_CODEC_ID_MPEG1VIDEO:
                    outputFormat = ffmpeg.av_guess_format("mpeg1video", null, null);
                    break;
                }
            }

            _formatContext = ffmpeg.avformat_alloc_context();

            if (_formatContext == null)
            {
                throw new Exception("Cannot allocate format context.");
            }

            _interruptCallback        = InterruptCb;
            _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

            _formatContext->interrupt_callback.callback = _interruptCallbackAddress;
            _formatContext->interrupt_callback.opaque   = null;



            _formatContext->oformat = outputFormat;

            AVDictionary *opts = null;

            if (audioCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                AddAudioStream(audioCodec);
                OpenAudio();
            }

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                _width  = width;
                _height = height;
                //_bitRate = videoBitRate;
                _framerate           = framerate;
                _isConstantFramerate = framerate > 0;

                AddVideoStream(videoCodec);
                OpenVideo();

                if (videoCodec == AVCodecID.AV_CODEC_ID_MPEG1VIDEO)
                {
                    ffmpeg.av_dict_set(&opts, "pkt_size", "1316", 0);
                    ffmpeg.av_dict_set(&opts, "buffer_size", "65535", 0);

                    //ffmpeg.av_dict_set(&opts, "crf", "30", 0);
                }
            }


            if (movflags != "")
            {
                ffmpeg.av_dict_set(&opts, "movflags", movflags, 0);
            }


            if ((outputFormat->flags & ffmpeg.AVFMT_NOFILE) != ffmpeg.AVFMT_NOFILE)
            {
                i = ffmpeg.avio_open2(&_formatContext->pb, fileName, ffmpeg.AVIO_FLAG_WRITE, null, &opts);
                if (i < 0)
                {
                    throw new Exception("Cannot create the video file. (" + i + ")");
                }
            }

            i = ffmpeg.avformat_write_header(_formatContext, null);
            if (i < 0)
            {
                throw new Exception("Cannot write header - check disk space (" + i + ")");
            }

            ffmpeg.av_dict_free(&opts);

            _frameNumber        = 0;
            _recordingStartTime = DateTime.UtcNow;
            _opened             = true;
        }
Esempio n. 26
0
        // sets up libavformat state: creates the AVFormatContext, the frames, etc. to start decoding, but does not actually start the decodingLoop
        private void prepareDecoding()
        {
            const int context_buffer_size = 4096;

            // the first call to FFmpeg will throw an exception if the libraries cannot be found
            // this will be safely handled in StartDecoding()
            var fcPtr = ffmpeg.avformat_alloc_context();

            formatContext        = fcPtr;
            contextBuffer        = (byte *)ffmpeg.av_malloc(context_buffer_size);
            managedContextBuffer = new byte[context_buffer_size];
            readPacketCallback   = readPacket;
            seekCallback         = streamSeekCallbacks;
            formatContext->pb    = ffmpeg.avio_alloc_context(contextBuffer, context_buffer_size, 0, (void *)handle.Handle, readPacketCallback, null, seekCallback);

            int openInputResult = ffmpeg.avformat_open_input(&fcPtr, "dummy", null, null);

            inputOpened = openInputResult >= 0;
            if (!inputOpened)
            {
                throw new InvalidOperationException($"Error opening file or stream: {getErrorMessage(openInputResult)}");
            }

            int findStreamInfoResult = ffmpeg.avformat_find_stream_info(formatContext, null);

            if (findStreamInfoResult < 0)
            {
                throw new InvalidOperationException($"Error finding stream info: {getErrorMessage(findStreamInfoResult)}");
            }

            var nStreams = formatContext->nb_streams;

            for (var i = 0; i < nStreams; ++i)
            {
                stream = formatContext->streams[i];

                codecParams = *stream->codecpar;

                if (codecParams.codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    duration = stream->duration <= 0 ? formatContext->duration : stream->duration;

                    timeBaseInSeconds = stream->time_base.GetValue();
                    var codecPtr = ffmpeg.avcodec_find_decoder(codecParams.codec_id);
                    if (codecPtr == null)
                    {
                        throw new InvalidOperationException($"Couldn't find codec with id: {codecParams.codec_id}");
                    }

                    int openCodecResult = ffmpeg.avcodec_open2(stream->codec, codecPtr, null);
                    if (openCodecResult < 0)
                    {
                        throw new InvalidOperationException($"Error trying to open codec with id {codecParams.codec_id}: {getErrorMessage(openCodecResult)}");
                    }

                    break;
                }
            }

            prepareFilters();
        }
Esempio n. 27
0
        public void Close()
        {
            try
            {
                Program.FfmpegMutex.WaitOne();
                _recordingEndTime = DateTime.UtcNow;
                if (_formatContext != null)
                {
                    if (!IsStreaming)
                    {
                        if (_opened)
                        {
                            Flush();
                        }

                        if (_formatContext->pb != null)
                        {
                            ffmpeg.av_write_trailer(_formatContext);
                        }
                    }
                    if (_formatContext->pb != null)
                    {
                        var pinprt = &(_formatContext->pb);
                        ffmpeg.avio_closep(pinprt);
                        _formatContext->pb = null;
                    }

                    _audioBuffer = null;


                    if (_videoFrame != null)
                    {
                        ffmpeg.avpicture_free((AVPicture *)_videoFrame);
                        fixed(AVFrame **pinprt = &(_videoFrame))
                        {
                            ffmpeg.av_frame_free(pinprt);
                            _videoFrame = null;
                        }
                    }

                    if (_audioFrame != null)
                    {
                        fixed(AVFrame **pinprt = &(_audioFrame))
                        {
                            ffmpeg.av_frame_free(pinprt);
                            _audioFrame = null;
                        }
                    }

                    if (_videoCodecContext != null)
                    {
                        ffmpeg.avcodec_close(_videoCodecContext);
                        fixed(AVCodecContext **c = &_videoCodecContext)
                        {
                            ffmpeg.avcodec_free_context(c);
                        }
                    }

                    if (_audioCodecContext != null)
                    {
                        ffmpeg.avcodec_close(_audioCodecContext);
                        fixed(AVCodecContext **c = &_audioCodecContext)
                        {
                            ffmpeg.avcodec_free_context(c);
                        }
                    }

                    if (_formatContext->streams != null)
                    {
                        int j = (int)_formatContext->nb_streams;
                        for (var i = j - 1; i >= 0; i--)
                        {
                            AVStream *stream = _formatContext->streams[i];
                            if (stream != null && stream->codec != null && stream->codec->codec != null)
                            {
                                stream->discard = AVDiscard.AVDISCARD_ALL;
                                ffmpeg.av_freep(&stream);
                            }
                        }
                    }


                    _videoStream = null;
                    _audioStream = null;

                    fixed(AVFormatContext **pinprt = &(_formatContext))
                    {
                        ffmpeg.av_freep(pinprt);
                    }
                    _formatContext = null;
                }

                if (_swsContext != null)
                {
                    ffmpeg.sws_freeContext(_swsContext);
                    _swsContext = null;
                }
                if (_swrContext != null)
                {
                    ffmpeg.swr_close(_swrContext);
                    _swrContext = null;
                }


                try
                {
                    FileInfo fi = new FileInfo(Filename);
                    SizeBytes = fi.Length;
                }
                catch
                {
                    SizeBytes = 0;
                }


                _opened = false;
            }
            finally
            {
                try
                {
                    Program.FfmpegMutex.ReleaseMutex();
                }
                catch
                {
                }
            }
        }
Esempio n. 28
0
        private void ReadFrames()
        {
            AVFrame *   pConvertedFrame       = null;
            sbyte *     pConvertedFrameBuffer = null;
            SwsContext *pConvertContext       = null;

            BufferedWaveProvider waveProvider  = null;
            SampleChannel        sampleChannel = null;

            bool audioInited = false;
            bool videoInited = false;
            var  packet      = new AVPacket();

            do
            {
                ffmpeg.av_init_packet(&packet);

                AVFrame *frame = ffmpeg.av_frame_alloc();
                ffmpeg.av_frame_unref(frame);

                if (ffmpeg.av_read_frame(_formatContext, &packet) < 0)
                {
                    _stopReadingFrames = true;
                    _res = ReasonToFinishPlaying.VideoSourceError;
                    break;
                }

                if ((packet.flags & ffmpeg.AV_PKT_FLAG_CORRUPT) == ffmpeg.AV_PKT_FLAG_CORRUPT)
                {
                    break;
                }

                AVPacket packetTemp = packet;
                var      nf         = NewFrame;
                var      da         = DataAvailable;

                _lastPacket = DateTime.UtcNow;
                if (_audioStream != null && packetTemp.stream_index == _audioStream->index)
                {
                    if (HasAudioStream != null)
                    {
                        HasAudioStream?.Invoke(this, EventArgs.Empty);
                        HasAudioStream = null;
                    }
                    if (da != null)
                    {
                        int  s       = 0;
                        var  buffer  = new sbyte[_audioCodecContext->sample_rate * 2];
                        var  tbuffer = new sbyte[_audioCodecContext->sample_rate * 2];
                        bool b       = false;

                        fixed(sbyte **outPtrs = new sbyte *[32])
                        {
                            fixed(sbyte *bPtr = &tbuffer[0])
                            {
                                outPtrs[0] = bPtr;
                                do
                                {
                                    int gotFrame = 0;
                                    int inUsed   = ffmpeg.avcodec_decode_audio4(_audioCodecContext, frame, &gotFrame,
                                                                                &packetTemp);

                                    if (inUsed < 0 || gotFrame == 0)
                                    {
                                        b = true;
                                        break;
                                    }

                                    int numSamplesOut = ffmpeg.swr_convert(_swrContext,
                                                                           outPtrs,
                                                                           _audioCodecContext->sample_rate,
                                                                           &frame->data0,
                                                                           frame->nb_samples);

                                    var l = numSamplesOut * 2 * _audioCodecContext->channels;
                                    Buffer.BlockCopy(tbuffer, 0, buffer, s, l);
                                    s += l;


                                    packetTemp.data += inUsed;
                                    packetTemp.size -= inUsed;
                                } while (packetTemp.size > 0);
                            }
                        }

                        if (b)
                        {
                            break;
                        }

                        ffmpeg.av_free_packet(&packet);
                        ffmpeg.av_frame_free(&frame);


                        if (!audioInited)
                        {
                            audioInited     = true;
                            RecordingFormat = new WaveFormat(_audioCodecContext->sample_rate, 16,
                                                             _audioCodecContext->channels);
                            waveProvider = new BufferedWaveProvider(RecordingFormat)
                            {
                                DiscardOnBufferOverflow = true,
                                BufferDuration          =
                                    TimeSpan.FromMilliseconds(500)
                            };
                            sampleChannel = new SampleChannel(waveProvider);

                            sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter;
                        }

                        byte[] ba = new byte[s];
                        Buffer.BlockCopy(buffer, 0, ba, 0, s);


                        waveProvider.AddSamples(ba, 0, s);

                        var sampleBuffer = new float[s];
                        int read         = sampleChannel.Read(sampleBuffer, 0, s);


                        da(this, new DataAvailableEventArgs(ba, read));


                        if (Listening)
                        {
                            WaveOutProvider?.AddSamples(ba, 0, read);
                        }
                    }
                }

                if (nf != null && _videoStream != null && packet.stream_index == _videoStream->index)
                {
                    int frameFinished = 0;
                    //decode video frame

                    int ret = ffmpeg.avcodec_decode_video2(_codecContext, frame, &frameFinished, &packetTemp);
                    if (ret < 0)
                    {
                        ffmpeg.av_free_packet(&packet);
                        ffmpeg.av_frame_free(&frame);
                        break;
                    }

                    if (frameFinished == 1)
                    {
                        if (!videoInited)
                        {
                            videoInited     = true;
                            pConvertedFrame = ffmpeg.av_frame_alloc();
                            var convertedFrameBufferSize = ffmpeg.avpicture_get_size(AVPixelFormat.AV_PIX_FMT_BGR24,
                                                                                     _codecContext->width, _codecContext->height);

                            pConvertedFrameBuffer = (sbyte *)ffmpeg.av_malloc((ulong)convertedFrameBufferSize);

                            ffmpeg.avpicture_fill((AVPicture *)pConvertedFrame, pConvertedFrameBuffer,
                                                  AVPixelFormat.AV_PIX_FMT_BGR24, _codecContext->width, _codecContext->height);

                            pConvertContext = ffmpeg.sws_getContext(_codecContext->width, _codecContext->height,
                                                                    _codecContext->pix_fmt, _codecContext->width, _codecContext->height,
                                                                    AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_FAST_BILINEAR, null, null, null);
                        }
                        var src       = &frame->data0;
                        var dst       = &pConvertedFrame->data0;
                        var srcStride = frame->linesize;
                        var dstStride = pConvertedFrame->linesize;
                        ffmpeg.sws_scale(pConvertContext, src, srcStride, 0, _codecContext->height, dst, dstStride);

                        var convertedFrameAddress = pConvertedFrame->data0;
                        if (convertedFrameAddress != null)
                        {
                            var imageBufferPtr = new IntPtr(convertedFrameAddress);

                            var linesize = dstStride[0];

                            if (frame->decode_error_flags > 0)
                            {
                                ffmpeg.av_free_packet(&packet);
                                ffmpeg.av_frame_free(&frame);
                                break;
                            }

                            using (
                                var mat = new Bitmap(_codecContext->width, _codecContext->height, linesize,
                                                     PixelFormat.Format24bppRgb, imageBufferPtr))
                            {
                                var nfe = new NewFrameEventArgs((Bitmap)mat.Clone());
                                nf.Invoke(this, nfe);
                            }

                            _lastVideoFrame = DateTime.UtcNow;
                        }
                    }
                }

                if (_videoStream != null)
                {
                    if ((DateTime.UtcNow - _lastVideoFrame).TotalMilliseconds > _timeout)
                    {
                        _res = ReasonToFinishPlaying.DeviceLost;
                        _stopReadingFrames = true;
                    }
                }

                ffmpeg.av_free_packet(&packet);
                ffmpeg.av_frame_free(&frame);
            } while (!_stopReadingFrames && !MainForm.ShuttingDown);


            try
            {
                Program.FfmpegMutex.WaitOne();

                if (pConvertedFrame != null)
                {
                    ffmpeg.av_free(pConvertedFrame);
                }

                if (pConvertedFrameBuffer != null)
                {
                    ffmpeg.av_free(pConvertedFrameBuffer);
                }

                if (_formatContext != null)
                {
                    if (_formatContext->streams != null)
                    {
                        int j = (int)_formatContext->nb_streams;
                        for (var i = j - 1; i >= 0; i--)
                        {
                            AVStream *stream = _formatContext->streams[i];

                            if (stream != null && stream->codec != null && stream->codec->codec != null)
                            {
                                stream->discard = AVDiscard.AVDISCARD_ALL;
                                ffmpeg.avcodec_close(stream->codec);
                            }
                        }
                    }
                    fixed(AVFormatContext **f = &_formatContext)
                    {
                        ffmpeg.avformat_close_input(f);
                    }
                    _formatContext = null;
                }

                _videoStream       = null;
                _audioStream       = null;
                _audioCodecContext = null;
                _codecContext      = null;

                if (_swrContext != null)
                {
                    fixed(SwrContext **s = &_swrContext)
                    {
                        ffmpeg.swr_free(s);
                    }
                    _swrContext = null;
                }

                if (pConvertContext != null)
                {
                    ffmpeg.sws_freeContext(pConvertContext);
                }

                if (sampleChannel != null)
                {
                    sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter;
                    sampleChannel = null;
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, "Media Stream (close)");
            }
            finally
            {
                try
                {
                    Program.FfmpegMutex.ReleaseMutex();
                }
                catch
                {
                }
            }

            PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
            AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
        }
Esempio n. 29
0
        // sets up libavformat state: creates the AVFormatContext, the frames, etc. to start decoding, but does not actually start the decodingLoop
        private void prepareDecoding()
        {
            const int context_buffer_size = 4096;

            var fcPtr = ffmpeg.avformat_alloc_context();

            formatContext        = fcPtr;
            contextBuffer        = (byte *)ffmpeg.av_malloc(context_buffer_size);
            managedContextBuffer = new byte[context_buffer_size];
            readPacketCallback   = readPacket;
            seekCallback         = seek;
            formatContext->pb    = ffmpeg.avio_alloc_context(contextBuffer, context_buffer_size, 0, null, readPacketCallback, null, seekCallback);
            if (ffmpeg.avformat_open_input(&fcPtr, "dummy", null, null) < 0)
            {
                throw new Exception("Error opening file.");
            }

            if (ffmpeg.avformat_find_stream_info(formatContext, null) < 0)
            {
                throw new Exception("Could not find stream info.");
            }

            var nStreams = formatContext->nb_streams;

            for (var i = 0; i < nStreams; ++i)
            {
                stream = formatContext->streams[i];

                codecParams = *stream->codecpar;
                if (codecParams.codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    timeBaseInSeconds = stream->time_base.GetValue();
                    var codecPtr = ffmpeg.avcodec_find_decoder(codecParams.codec_id);
                    if (codecPtr == null)
                    {
                        throw new Exception("Could not find codec.");
                    }

                    if (ffmpeg.avcodec_open2(stream->codec, codecPtr, null) < 0)
                    {
                        throw new Exception("Could not open codec.");
                    }

                    frame    = ffmpeg.av_frame_alloc();
                    frameRgb = ffmpeg.av_frame_alloc();

                    uncompressedFrameSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_RGBA, codecParams.width, codecParams.height, 1);
                    frameRgbBufferPtr     = Marshal.AllocHGlobal(uncompressedFrameSize);

                    var dataArr4     = *(byte_ptrArray4 *)&frameRgb->data;
                    var linesizeArr4 = *(int_array4 *)&frameRgb->linesize;
                    var result       = ffmpeg.av_image_fill_arrays(ref dataArr4, ref linesizeArr4, (byte *)frameRgbBufferPtr, AVPixelFormat.AV_PIX_FMT_RGBA, codecParams.width, codecParams.height, 1);
                    if (result < 0)
                    {
                        throw new Exception("Could not fill image arrays");
                    }

                    for (uint j = 0; j < byte_ptrArray4.Size; ++j)
                    {
                        frameRgb->data[j]     = dataArr4[j];
                        frameRgb->linesize[j] = linesizeArr4[j];
                    }

                    break;
                }
            }
        }
Esempio n. 30
0
        private static unsafe void Main(string[] args)
        {
            Console.WriteLine("Runnung in {0}-bit mode.", Environment.Is64BitProcess ? "64" : "32");

            // register path to ffmpeg
            switch (Environment.OSVersion.Platform)
            {
            case PlatformID.Win32NT:
            case PlatformID.Win32S:
            case PlatformID.Win32Windows:
                string ffmpegPath = string.Format(@"../../../FFmpeg/bin/windows/{0}", Environment.Is64BitProcess ? "x64" : "x86");
                InteropHelper.RegisterLibrariesSearchPath(ffmpegPath);
                break;

            case PlatformID.Unix:
            case PlatformID.MacOSX:
                string libraryPath = Environment.GetEnvironmentVariable(InteropHelper.LD_LIBRARY_PATH);
                InteropHelper.RegisterLibrariesSearchPath(libraryPath);
                break;
            }

            // decode 100 frame from url or path

            //string url = @"../../sample_mpeg4.mp4";
            string url = @"http://hubblesource.stsci.edu/sources/video/clips/details/images/centaur_1.mpg";

            FFmpegInvoke.av_register_all();
            FFmpegInvoke.avcodec_register_all();
            FFmpegInvoke.avformat_network_init();


            AVFormatContext *pFormatContext = FFmpegInvoke.avformat_alloc_context();

            if (FFmpegInvoke.avformat_open_input(&pFormatContext, url, null, null) != 0)
            {
                throw new Exception("Could not open file");
            }

            if (FFmpegInvoke.avformat_find_stream_info(pFormatContext, null) != 0)
            {
                throw new Exception("Could not find stream info");
            }

            AVStream *pStream = null;

            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                if (pFormatContext->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    pStream = pFormatContext->streams[i];
                    break;
                }
            }
            if (pStream == null)
            {
                throw new Exception("Could not found video stream");
            }

            AVCodecContext codecContext    = *(pStream->codec);
            int            width           = codecContext.width;
            int            height          = codecContext.height;
            AVPixelFormat  sourcePixFmt    = codecContext.pix_fmt;
            AVCodecID      codecId         = codecContext.codec_id;
            var            convertToPixFmt = AVPixelFormat.PIX_FMT_BGR24;
            SwsContext *   pConvertContext = FFmpegInvoke.sws_getContext(width, height, sourcePixFmt,
                                                                         width, height, convertToPixFmt,
                                                                         FFmpegInvoke.SWS_FAST_BILINEAR, null, null, null);

            if (pConvertContext == null)
            {
                throw new Exception("Could not initialize the conversion context");
            }

            var pConvertedFrame          = (AVPicture *)FFmpegInvoke.avcodec_alloc_frame();
            int convertedFrameBufferSize = FFmpegInvoke.avpicture_get_size(convertToPixFmt, width, height);
            var pConvertedFrameBuffer    = (byte *)FFmpegInvoke.av_malloc((uint)convertedFrameBufferSize);

            FFmpegInvoke.avpicture_fill(pConvertedFrame, pConvertedFrameBuffer, convertToPixFmt, width, height);

            AVCodec *pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);

            if (pCodec == null)
            {
                throw new Exception("Unsupported codec");
            }

            // Reusing codec context from stream info,
            // as an alternative way it could look like this: (but it works not for all kind of codecs)
            // AVCodecContext* pCodecContext = FFmpegInvoke.avcodec_alloc_context3(pCodec);
            AVCodecContext *pCodecContext = &codecContext;

            if ((pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) == FFmpegInvoke.CODEC_CAP_TRUNCATED)
            {
                pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;
            }

            if (FFmpegInvoke.avcodec_open2(pCodecContext, pCodec, null) < 0)
            {
                throw new Exception("Could not open codec");
            }

            AVFrame *pDecodedFrame = FFmpegInvoke.avcodec_alloc_frame();

            var       packet  = new AVPacket();
            AVPacket *pPacket = &packet;

            FFmpegInvoke.av_init_packet(pPacket);

            int frameNumber = 0;

            while (frameNumber < 100)
            {
                if (FFmpegInvoke.av_read_frame(pFormatContext, pPacket) < 0)
                {
                    throw new Exception("Could not read frame");
                }

                if (pPacket->stream_index != pStream->index)
                {
                    continue;
                }

                int gotPicture = 0;
                int size       = FFmpegInvoke.avcodec_decode_video2(pCodecContext, pDecodedFrame, &gotPicture, pPacket);
                if (size < 0)
                {
                    throw new Exception(string.Format("Error while decoding frame {0}", frameNumber));
                }

                if (gotPicture == 1)
                {
                    Console.WriteLine("frame: {0}", frameNumber);

                    byte **src = &pDecodedFrame->data_0;
                    byte **dst = &pConvertedFrame->data_0;
                    FFmpegInvoke.sws_scale(pConvertContext, src, pDecodedFrame->linesize, 0,
                                           height, dst, pConvertedFrame->linesize);

                    byte *convertedFrameAddress = pConvertedFrame->data_0;

                    var imageBufferPtr = new IntPtr(convertedFrameAddress);

                    int linesize = pConvertedFrame->linesize[0];
                    using (var bitmap = new Bitmap(width, height, linesize, PixelFormat.Format24bppRgb, imageBufferPtr))
                    {
                        bitmap.Save(@"frame.buffer.jpg", ImageFormat.Jpeg);
                    }

                    frameNumber++;

                    System.Threading.Thread.Sleep(1000);
                }
            }

            FFmpegInvoke.av_free(pConvertedFrame);
            FFmpegInvoke.av_free(pConvertedFrameBuffer);
            FFmpegInvoke.sws_freeContext(pConvertContext);

            FFmpegInvoke.av_free(pDecodedFrame);
            FFmpegInvoke.avcodec_close(pCodecContext);
            FFmpegInvoke.avformat_close_input(&pFormatContext);
        }
Esempio n. 31
0
 internal protected InputFormatContext(AVFormatContext *ptr, bool isOwner) : base(ptr, isOwner)
 {
 }
 /// <inheritdoc />
 public unsafe void OnVideoFrameDecoded(AVFrame *videoFrame, AVFormatContext *context) =>
 Parent?.RaiseVideoFrameDecodedEvent(videoFrame, context);
Esempio n. 33
0
        private void DoStart()
        {
            var vss = Source;

            if (!IsAudio)
            {
                vss = Tokenise(vss);
            }

            if (string.IsNullOrEmpty(vss))
            {
                ErrorHandler?.Invoke("Source not found");
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
                _starting = false;
                return;
            }

            AVDictionary *options = null;

            if (_inputFormat == null)
            {
                var prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal));
                ffmpeg.av_dict_set_int(&options, "rw_timeout", _timeoutMicroSeconds, 0);
                ffmpeg.av_dict_set_int(&options, "tcp_nodelay", 1, 0);
                switch (prefix)
                {
                case "https":
                case "http":
                case "mmsh":
                case "mms":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);

                    if (!string.IsNullOrEmpty(_cookies))
                    {
                        ffmpeg.av_dict_set(&options, "cookies", _cookies, 0);
                    }
                    if (!string.IsNullOrEmpty(_headers))
                    {
                        ffmpeg.av_dict_set(&options, "headers", _headers, 0);
                    }
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    break;

                case "rtsp":
                case "rtmp":
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    if (!string.IsNullOrEmpty(_modeRTSP))
                    {
                        ffmpeg.av_dict_set(&options, "rtsp_transport", _modeRTSP, 0);
                    }
                    ffmpeg.av_dict_set(&options, "rtsp_flags", "prefer_tcp", 0);
                    break;

                default:
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "tcp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "udp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;
                }
                ffmpeg.av_dict_set_int(&options, "buffer_size", BUFSIZE, 0);
            }
            //ffmpeg.av_dict_set_int(&options, "rtbufsize", BUFSIZE, 0);

            var lo = _options.Split(Environment.NewLine.ToCharArray());

            foreach (var nv in lo)
            {
                if (!string.IsNullOrEmpty(nv))
                {
                    var i = nv.IndexOf('=');
                    if (i > -1)
                    {
                        var n = nv.Substring(0, i).Trim();
                        var v = nv.Substring(i + 1).Trim();
                        if (!string.IsNullOrEmpty(n) && !string.IsNullOrEmpty(v))
                        {
                            int j;
                            if (int.TryParse(v, out j))
                            {
                                ffmpeg.av_dict_set_int(&options, n, j, 0);
                            }
                            else
                            {
                                ffmpeg.av_dict_set(&options, n, v, 0);
                            }
                        }
                    }
                }
            }


            _abort = false;
            try
            {
                Program.MutexHelper.Wait();
                var pFormatContext = ffmpeg.avformat_alloc_context();
                _lastPacket = DateTime.UtcNow;


                _interruptCallback        = InterruptCb;
                _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

                _aviocb = new AVIOInterruptCB_callback_func
                {
                    Pointer = _interruptCallbackAddress
                };
                pFormatContext->interrupt_callback.callback = _aviocb;
                pFormatContext->interrupt_callback.opaque   = null;
                pFormatContext->max_analyze_duration        = 0; //0 = auto

                var t = _timeoutMicroSeconds;
                _timeoutMicroSeconds = Math.Max(_timeoutMicroSeconds, 15000000);

                Throw("OPEN_INPUT", ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options));
                _formatContext = pFormatContext;

                SetupFormat();

                _timeoutMicroSeconds = t;
            }
            catch (Exception ex)
            {
                ErrorHandler?.Invoke(ex.Message);
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
            }
            finally
            {
                try
                {
                    Program.MutexHelper.Release();
                }
                catch
                {
                }
            }

            _starting = false;
        }
 /// <inheritdoc />
 public unsafe void OnSubtitleDecoded(AVSubtitle *subtitle, AVFormatContext *context) =>
 Parent?.RaiseSubtitleDecodedEvent(subtitle, context);
Esempio n. 35
0
        private void CleanUp()
        {
            try
            {
                Program.MutexHelper.Wait();

                if (pConvertedFrameBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pConvertedFrameBuffer);
                    pConvertedFrameBuffer = IntPtr.Zero;
                }

                if (_formatContext != null)
                {
                    if (_formatContext->streams != null)
                    {
                        var j = (int)_formatContext->nb_streams;
                        for (var i = j - 1; i >= 0; i--)
                        {
                            var stream = _formatContext->streams[i];

                            if (stream != null && stream->codec != null && stream->codec->codec != null)
                            {
                                stream->discard = AVDiscard.AVDISCARD_ALL;
                                ffmpeg.avcodec_close(stream->codec);
                            }
                        }
                    }
                    fixed(AVFormatContext **f = &_formatContext)
                    {
                        ffmpeg.avformat_close_input(f);
                    }

                    _formatContext = null;
                }

                if (_hwDeviceCtx != null)
                {
                    var f = _hwDeviceCtx;
                    ffmpeg.av_buffer_unref(&f);
                    _hwDeviceCtx = null;
                }

                _videoStream       = null;
                _audioStream       = null;
                _audioCodecContext = null;
                _videoCodecContext = null;

                if (_swrContext != null)
                {
                    fixed(SwrContext **s = &_swrContext)
                    {
                        ffmpeg.swr_free(s);
                    }

                    _swrContext = null;
                }

                if (pConvertContext != null)
                {
                    ffmpeg.sws_freeContext(pConvertContext);
                    pConvertContext = null;
                }

                if (sampleChannel != null)
                {
                    sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter;
                    sampleChannel = null;
                }
            }
            catch (Exception ex)
            {
                Logger.LogException(ex, SourceName + ": Media Stream (close)");
            }
            finally
            {
                try
                {
                    Program.MutexHelper.Release();
                }
                catch
                {
                }
            }

            PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
            AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res));
        }