示例#1
0
            public void ProcessImage(IntPtr pSrcFrameInfo, FFmpeg.AVFrame srcFrameInfo)
            {
                int ret;

                _yDataBytes.Clear();
                _pSrcFrameInfo = pSrcFrameInfo;
                _srcFrameInfo  = srcFrameInfo;

                FFmpeg.AVPixelFormat dstPixelFormat = _dstAVPixelFormat[(int)DstPixelFormat];

                if (_srcCodecContext.pix_fmt == dstPixelFormat)
                {
                    return;
                }

                if (_pSwsContext == IntPtr.Zero)
                {
                    _pSwsContext = FFmpeg.SwScale.sws_getContext(
                        _srcFrameInfo.width, _srcFrameInfo.height, _srcCodecContext.pix_fmt,
                        DstSize.Width, DstSize.Height, dstPixelFormat,
                        ResizeMethod, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

                    if (_pSwsContext == IntPtr.Zero)
                    {
                        throw new Exception("Failed to create SwScale context");
                    }


                    _dstFrameBytesLength = FFmpeg.avpicture_get_size((int)dstPixelFormat, DstSize.Width, DstSize.Height);
                    _pDstFrameBytes      = Marshal.AllocHGlobal(_dstFrameBytesLength);
                    RtlZeroMemory(_pDstFrameBytes, _dstFrameBytesLength);

                    _pDstFrameInfo = FFmpeg.avcodec_alloc_frame();
                    ret            = FFmpeg.avpicture_fill(_pDstFrameInfo, _pDstFrameBytes, dstPixelFormat, DstSize.Width, DstSize.Height);
                    if (ret < 0)
                    {
                        throw new Exception("Failed to fill picture: " + ret.ToString());
                    }
                    Marshal.WriteInt32(_pDstFrameInfo, _marshalOffset_AVFrame_width, DstSize.Width);
                    Marshal.WriteInt32(_pDstFrameInfo, _marshalOffset_AVFrame_height, DstSize.Height);
                    Marshal.WriteInt32(_pDstFrameInfo, _marshalOffset_AVFrame_interlaced_frame, _srcFrameInfo.interlaced_frame);
                    _dstFrameInfo = (FFmpeg.AVFrame)Marshal.PtrToStructure(_pDstFrameInfo, typeof(FFmpeg.AVFrame));
                }

                //FFmpeg.av_log_set_callback(new FFmpeg.AVLogCallback(AVLogCallback));

                IntPtr pScaleSrcData     = _pSrcFrameInfo + _marshalOffset_AVFrame_data;
                IntPtr pScaleSrcLineSize = _pSrcFrameInfo + _marshalOffset_AVFrame_linesize;
                IntPtr pScaleDstData     = _pDstFrameInfo + _marshalOffset_AVFrame_data;
                IntPtr pScaleDstLineSize = _pDstFrameInfo + _marshalOffset_AVFrame_linesize;

                ret = FFmpeg.SwScale.sws_scale(_pSwsContext, pScaleSrcData, pScaleSrcLineSize, 0, _srcFrameInfo.height, pScaleDstData, pScaleDstLineSize);
                if (ret < 0)
                {
                    throw new Exception("Failed to scale frame: " + ret.ToString());
                }
            }
示例#2
0
            // Specify -1 to get full interlaced frame
            public ImageProcessing.YData GetYData(int fieldIndex = -1)
            {
                FFmpeg.AVFrame frameInfo = _dstFrameInfo;

                FFmpeg.AVPixelFormat dstPixelFormat = _dstAVPixelFormat[(int)DstPixelFormat];
                if (_srcCodecContext.pix_fmt == dstPixelFormat)
                {
                    frameInfo = _srcFrameInfo;
                }

                int width  = frameInfo.width;
                int height = frameInfo.height;
                int stride = frameInfo.linesize[0];

                byte[] data = null;

                if ((fieldIndex != -1) && (frameInfo.interlaced_frame != 0))
                {
                    height /= _srcCodecContext.ticks_per_frame;
                }

                if (!_yDataBytes.TryGetValue(fieldIndex, out data))
                {
                    if ((fieldIndex != -1) && (frameInfo.interlaced_frame != 0))
                    {
                        int dstSize = stride * height;
                        data = new byte[dstSize];

                        int firstRow = fieldIndex;
                        if (frameInfo.top_field_first != 0)
                        {
                            firstRow = _srcCodecContext.ticks_per_frame - fieldIndex;
                        }

                        IntPtr pFrameBytes = frameInfo.data[0] + (stride * firstRow);
                        int    srcStride   = stride * _srcCodecContext.ticks_per_frame;

                        for (int dstOffset = 0; dstOffset < dstSize; dstOffset += stride)
                        {
                            Marshal.Copy(pFrameBytes, data, dstOffset, stride);
                            pFrameBytes += srcStride;
                        }
                    }
                    else
                    {
                        data = new byte[stride * frameInfo.height];

                        IntPtr pFrameBytes = frameInfo.data[0];

                        Marshal.Copy(frameInfo.data[0], data, 0, stride * frameInfo.height);
                    }
                    _yDataBytes.Add(fieldIndex, data);
                }

                return(new ImageProcessing.YData(width, height, stride, data));
            }
示例#3
0
            // Specify -1 to get full interlaced frame
            public Bitmap GetImage(int fieldIndex = -1)
            {
                FFmpeg.AVFrame frameInfo = _dstFrameInfo;

                FFmpeg.AVPixelFormat dstPixelFormat = _dstAVPixelFormat[(int)DstPixelFormat];
                if (_srcCodecContext.pix_fmt == dstPixelFormat)
                {
                    frameInfo = _srcFrameInfo;
                }

                if (DstPixelFormat == PixelFormat.RGB24)
                {
                    IntPtr pFrameBytes      = frameInfo.data[0];
                    int    frameBytesLength = frameInfo.linesize[0] * frameInfo.height;

                    if ((fieldIndex != -1) && (frameInfo.interlaced_frame != 0))
                    {
                        var height    = DstSize.Height / _srcCodecContext.ticks_per_frame;
                        var image     = new System.Drawing.Bitmap(DstSize.Width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        var imageData = image.LockBits(new System.Drawing.Rectangle(0, 0, DstSize.Width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, image.PixelFormat);

                        int firstRow = fieldIndex;
                        if (frameInfo.top_field_first != 0)
                        {
                            firstRow = _srcCodecContext.ticks_per_frame - fieldIndex;
                        }

                        int    stride   = frameInfo.linesize[0];
                        int    srcSride = stride * _srcCodecContext.ticks_per_frame;
                        IntPtr pSrc     = pFrameBytes + (stride * firstRow);
                        int    pDst     = 0;
                        int    pDstEnd  = pDst + (stride * height);

                        while (pDst < pDstEnd)
                        {
                            memcpy(imageData.Scan0 + pDst, pSrc, frameInfo.linesize[0]);
                            pSrc += srcSride;
                            pDst += stride;
                        }

                        image.UnlockBits(imageData);
                        return(image);
                    }
                    else
                    {
                        var image     = new System.Drawing.Bitmap(DstSize.Width, DstSize.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                        var imageData = image.LockBits(new System.Drawing.Rectangle(0, 0, DstSize.Width, DstSize.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, image.PixelFormat);

                        memcpy(imageData.Scan0, pFrameBytes, frameBytesLength);

                        image.UnlockBits(imageData);
                        return(image);
                    }
                }
                else if (DstPixelFormat == PixelFormat.Y)
                {
                    var yData = GetYData(fieldIndex);
                    return(yData.GetBitmap());
                }
                return(null);
            }