예제 #1
0
        public IAVStream GetAVStream(string fileName)
        {
            if (fileName == string.Empty)
            {
                throw new Exception("No Input file");
            }

            FileInfo info        = new FileInfo(fileName);
            string   file        = info.FullName;
            IntPtr   fileContext = IntPtr.Zero;
            int      ret         = AV.avformat_open_input(out fileContext, file, IntPtr.Zero, IntPtr.Zero);

            if (ret < 0)
            {
                throw new InvalidOperationException("can not open input file");
            }

            ret = AV.avformat_find_stream_info(fileContext, IntPtr.Zero);
            if (ret < 0)
            {
                throw new InvalidOperationException("can not find stream info");
            }

            return(new AVStream(fileContext));
        }
예제 #2
0
        public AVStream(IntPtr fileContext)
        {
            rawFormatCtx = fileContext;
            pFormatCtx   = new NativeGetter <AV.AVFormatContext>(fileContext).Get();
            for (var i = 0; i < pFormatCtx.nb_streams; i++)
            {
                var    stream       = new NativeGetter <AV.AVStream>(pFormatCtx.Streams[i]).Get();
                var    codecContext = new NativeGetter <AV.AVCodecContext>(stream.codec).Get();
                IntPtr codec        = AV.avcodec_find_decoder(codecContext.codec_id);
                if (codec != IntPtr.Zero)
                {
                    var codecHandle = new NativeGetter <AV.AVCodec>(codec).Get();
                    if ((codecHandle.capabilities & AV.CODEC_FLAG_TRUNCATED) != 0)
                    {
                        codecContext.flags |= AV.CODEC_FLAG_TRUNCATED;
                        new NativeSetter <AV.AVCodecContext>(stream.codec).Set(codecContext);
                    }

                    int ret = AV.avcodec_open2(stream.codec, codec, IntPtr.Zero);
                    if (ret < 0)
                    {
                        throw new Exception("Can not open codec for type " + codecContext.codec_type.ToString());
                    }

                    decoderTable.Add(i, stream.codec);
                    mediaTypeTable.Add(i, codecContext.codec_type);
                }
            }
        }
예제 #3
0
        public void Close()
        {
            Marshal.FreeHGlobal(Packet);

            if (rawData != IntPtr.Zero)
            {
                AV.av_free(rawData);
            }
        }
예제 #4
0
 public void Close()
 {
     foreach (var decoder in decoderTable)
     {
         AV.avcodec_close(decoder.Value);
     }
     if (rawFormatCtx != null)
     {
         AV.avformat_free_context(rawFormatCtx);
     }
 }
예제 #5
0
        internal override IntPtr DoDecode()
        {
            int    size    = 0;
            IntPtr rawData = AV.avcodec_alloc_frame();
            int    ret     = AV.avcodec_decode_audio4(Codec,
                                                      rawData,
                                                      out size,
                                                      Packet);

            if (ret <= 0 || size == 0)
            {
                AV.av_free(rawData);
                return(IntPtr.Zero);
            }
            return(rawData);
        }
예제 #6
0
        internal override IntPtr DoDecode()
        {
            IntPtr rawData = AV.avcodec_alloc_frame();

            int finish = 0;;
            int ret    = AV.avcodec_decode_video2(Codec,
                                                  rawData,
                                                  out finish,
                                                  Packet);

            if (ret < 0)
            {
                AV.av_free(rawData);
                return(IntPtr.Zero);
            }
            return(rawData);
        }
예제 #7
0
        private void ConvertAudioSample(ref WaveDataType input, IntPtr sample)
        {
            int    ret;
            IntPtr swr = AV.swr_alloc_set_opts(IntPtr.Zero,
                                               AV.av_get_default_channel_layout(codecCtx.channels),
                                               AV.AVSampleFormat.AV_SAMPLE_FMT_S16,
                                               codecCtx.sample_rate,
                                               AV.av_get_default_channel_layout(codecCtx.channels),
                                               codecCtx.sample_fmt,
                                               codecCtx.sample_rate,
                                               0,
                                               IntPtr.Zero);

            ret = AV.swr_init(swr);

            int needed_buf_size = AV.av_samples_get_buffer_size(IntPtr.Zero,
                                                                codecCtx.channels,
                                                                input.nb_samples,
                                                                AV.AVSampleFormat.AV_SAMPLE_FMT_S16, 0);
            IntPtr pOutput  = Marshal.AllocCoTaskMem(needed_buf_size);
            IntPtr ppOutput = Marshal.AllocCoTaskMem(Marshal.SizeOf(pOutput));

            Marshal.WriteIntPtr(ppOutput, pOutput);

            int len = AV.swr_convert(swr, ppOutput, input.nb_samples, sample, input.nb_samples);

            int output_len = len * 2 * AV.av_get_bytes_per_sample(AV.AVSampleFormat.AV_SAMPLE_FMT_S16);

            input.managedData = new byte[output_len];
            Marshal.Copy(pOutput, input.managedData, 0, output_len);

            Marshal.FreeCoTaskMem(pOutput);
            Marshal.FreeCoTaskMem(ppOutput);

            IntPtr ppSwr = Marshal.AllocCoTaskMem(Marshal.SizeOf(swr));

            Marshal.WriteIntPtr(ppSwr, swr);
            AV.swr_free(ppSwr);
            Marshal.FreeCoTaskMem(ppSwr);

            input.bit_per_sample = AV.av_get_bits_per_sample_fmt(AV.AVSampleFormat.AV_SAMPLE_FMT_S16);
            input.channel        = codecCtx.channels;
            input.fmt            = AV.AVSampleFormat.AV_SAMPLE_FMT_S16;
            input.size           = needed_buf_size;
        }
예제 #8
0
        public bool Decode()
        {
            if (rawData != IntPtr.Zero)
            {
                AV.av_free(rawData);
            }

            rawData = DoDecode();
            if (rawData != IntPtr.Zero)
            {
                avFrame = new NativeGetter <AV.AVFrame>(rawData).Get();
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #9
0
        private void ConvertToBitmap(ref VideoFrameType t)
        {
            var frame = avFrame;
            //FFmpeg.AVFrame final = gcnew AvFrame(PIX_FMT_BGR24, this->size);
            IntPtr final = AV.avcodec_alloc_frame();

            AV.AVFrame finalFrame = new NativeGetter <AV.AVFrame>(final).Get();

            var dst_fmt = AV.AVPixelFormat.AV_PIX_FMT_BGR24;

            int count = AV.avpicture_get_size(dst_fmt, codecCtx.width, codecCtx.height);

            IntPtr bufferArr = Marshal.AllocHGlobal(count);

            AV.avpicture_fill(final, bufferArr, dst_fmt, codecCtx.width, codecCtx.height);

            IntPtr swsContext = AV.sws_getContext(codecCtx.width, codecCtx.height, codecCtx.pix_fmt,
                                                  codecCtx.width, codecCtx.height, dst_fmt, AV.SWS_BICUBIC, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            if (swsContext == IntPtr.Zero)
            {
                throw new Exception();
            }

            finalFrame = new NativeGetter <AV.AVFrame>(final).Get();
            AV.sws_scale(swsContext, frame.data, frame.linesize, 0, codecCtx.height, finalFrame.data, finalFrame.linesize);

            new NativeSetter <AV.AVFrame>(final).Set(finalFrame);
            // Array::Reverse(bufferArr);

            byte[] buffer = new byte[count];
            Marshal.Copy(bufferArr, buffer, 0, count);
            AV.av_free(final);
            Marshal.FreeHGlobal(bufferArr);


            t.width        = codecCtx.width;
            t.height       = codecCtx.height;
            t.SourceFormat = codecCtx.pix_fmt;
            t.DestFormat   = dst_fmt;
            t.managedData  = buffer;
            t.linesize     = finalFrame.linesize[0];
        }
예제 #10
0
        public IAVFrame GetNext()
        {
            IAVFrame frame   = null;
            IntPtr   pPacket = Marshal.AllocHGlobal(Marshal.SizeOf(new AV.AVPacket()));

            if (AV.av_read_frame(rawFormatCtx, pPacket) != 0)
            {
                Marshal.FreeHGlobal(pPacket);
                pPacket = IntPtr.Zero;
                return(null);
            }


            AV.AVPacket packet = new NativeGetter <AV.AVPacket>(pPacket).Get();
            if (!decoderTable.ContainsKey(packet.stream_index) ||
                !mediaTypeTable.ContainsKey(packet.stream_index))
            {
                Marshal.FreeHGlobal(pPacket);
                pPacket = IntPtr.Zero;
                return(null);
            }

            var codec = decoderTable[packet.stream_index];
            var type  = mediaTypeTable[packet.stream_index];

            switch (type)
            {
            case AV.AVMediaType.AVMEDIA_TYPE_AUDIO:
                frame = new AudioFrame(pPacket, codec);
                return(frame);

            case AV.AVMediaType.AVMEDIA_TYPE_VIDEO:
                frame = new VideoFrame(pPacket, codec);
                return(frame);

            default:
                throw new Exception("Not support media type " + type.ToString());
            }
            return(null);
        }
예제 #11
0
 static bool cmp_audio_fmts(AV.AVSampleFormat fmt1, UInt64 channel_count1,
            AV.AVSampleFormat fmt2, UInt64 channel_count2)
 {
     /* If channel count == 1, planar and non-planar formats are the same */
     if (channel_count1 == 1 && channel_count2 == 1)
         return AV.av_get_packed_sample_fmt(fmt1) != AV.av_get_packed_sample_fmt(fmt2);
     else
         return channel_count1 != channel_count2 || fmt1 != fmt2;
 }
예제 #12
0
 private void InitCodecs()
 {
     AV.av_register_all();
     AV.avcodec_register_all();
 }