Ejemplo n.º 1
0
        /// <summary>
        /// <para>Convert a raw frame to NV12.</para>
        /// <para>Used to convert fourcc formats to NV12.</para>
        ///
        /// </summary>
        /// <param name="srcFourcc">One of NV12 RGB3 RGB4 UYVY YUY2 YV12 BGR3 BGR4 P411 P422 I420_IYUV</param>
        /// <param name="nv12pitch">output pitch in bytes</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="inFrameptr"></param>
        /// <param name="nv12">Y output plane destination</param>
        /// <param name="nv12uv">UV output plane destination</param>
        public unsafe void ConvertToNV12FrameSurface(FourCC srcFourcc, int nv12pitch, int width, int height, byte *inFrameptr, byte *nv12, byte *nv12uv)
        {
            NativeResizeConvertStatus sts = NativeResizeConvertStatus.NativeStatusNoErr;

            roisizea.height = height;
            roisizea.width  = width;
            switch (srcFourcc)
            {
            //case FourCC.A2RGB10:
            //    break;
            //case FourCC.ARGB16:
            //    break;

            case FourCC.NV12:
                //memmove(nv12, inFrameptr, height * width);
                //memmove(nv12uv, inFrameptr + height * width, height * width / 2);

                for (int j = 0; j < height; j++)
                {
                    // Marshal.Copy(uncompressed, i * framelen + j * w, e.Frames[ix].Data.Y + e.Frames[ix].Data.Pitch * j, w);
                    FastMemcpyMemmove.memcpy(nv12 + nv12pitch * j, inFrameptr + width * j, width);
                }
                for (int j = 0; j < height / 2; j++)
                {
                    FastMemcpyMemmove.memcpy(nv12uv + nv12pitch * j, inFrameptr + width * height + width * j, width);
                }
                //  Marshal.Copy(uncompressed, i * framelen + j * w + h * w, e.Frames[ix].Data.UV + e.Frames[ix].Data.Pitch * j, w);


                break;
            //case FourCC.NV16:
            //    break;
            //case FourCC.P010:
            //    break;
            //case FourCC.P210:
            //    break;
            //case FourCC.P8:
            //    break;
            //case FourCC.P8_TEXTURE:
            //    break;
            //case FourCC.R16:
            //    break;



            case FourCC.BGR3:
                sts = NV12Convert.BGR3ToNV12(inFrameptr, width * 3, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                break;

            case FourCC.BGR4:      // this was not supported originally due to lack of support in intel IPP

                sts = NV12Convert.BGR4ToNV12(inFrameptr, width * 4, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                break;

            case FourCC.IYUV:
                pointers[0] = inFrameptr;
                pointers[1] = inFrameptr + height * width;
                pointers[2] = inFrameptr + height * width + height * width / 2 / 2;
                intarr[0]   = width;
                intarr[1]   = width / 2;
                intarr[2]   = width / 2;
                fixed(byte **p1 = pointers)
                fixed(int *p2 = intarr)
                {
                    sts = NV12Convert.IYUVToNV12(p1, p2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                }
                break;

            case FourCC.P411:

                pointers[0] = inFrameptr;
                pointers[1] = inFrameptr + height * width;
                pointers[2] = inFrameptr + height * width + height * width / 4;
                intarr[0]   = width;
                intarr[1]   = width / 4;
                intarr[2]   = width / 4;
                fixed(byte **p1 = pointers)
                fixed(int *p2 = intarr)
                {
                    sts = NV12Convert.P411ToNV12(p1, p2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                }
                break;

            case FourCC.P422:
                pointers[0] = inFrameptr;
                pointers[1] = inFrameptr + height * width;
                pointers[2] = inFrameptr + height * width + height * width / 2;
                intarr[0]   = width;
                intarr[1]   = width / 2;
                intarr[2]   = width / 2;
                fixed(byte **p1 = pointers)
                fixed(int *p2 = intarr)
                {
                    sts = NV12Convert.P422ToNV12(p1, p2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                }
                break;

            case FourCC.RGB3:
                sts = NV12Convert.RGB3ToNV12(inFrameptr, width * 3, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                break;

            case FourCC.RGB4:
                sts = NV12Convert.RGB4ToNV12(inFrameptr, width * 4, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                break;


            case FourCC.YUY2:
                sts = NV12Convert.YUY2ToNV12(inFrameptr, width * 2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);

                break;

            case FourCC.YV12:
                //YVU
                // YCbCr == YUV
                pointers[0] = inFrameptr;
                pointers[1] = inFrameptr + height * width;
                pointers[2] = inFrameptr + height * width + height * width / 2 / 2;
                intarr[0]   = width;
                intarr[1]   = width / 2;
                intarr[2]   = width / 2;

                fixed(byte **p1 = pointers)
                fixed(int *p2 = intarr)
                sts           = NV12Convert.YV12ToNV12(p1, p2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);

                break;

            case FourCC.UYVY:

                // sts = NV12Convert.ippiCbYCr422ToYCbCr420_8u_C2P2R(inFrameptr, width * 2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                sts = NV12Convert.UYVYToNV12(inFrameptr, width * 2, nv12, nv12pitch, nv12uv, nv12pitch, roisizea);
                break;

            default:
                break;
            }
            if (sts != NativeResizeConvertStatus.NativeStatusNoErr)
            {
                throw new Exception("FourCC convert error:" + sts.ToString());
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Convert an NV12 frame to another fourcc format
        /// </summary>
        /// <param name="destFourcc">One of NV12 RGB3 RGB4 UYVY YUY2 YV12 BGR3 P411 P422 I420_IYUV</param>
        /// <param name="Y">Y plane of NV12 input</param>
        /// <param name="UV">UV plane of NV12 input</param>
        /// <param name="outputFramePtr">where output frame goes</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="outputLen"></param>
        /// <param name="srcPitch">Pitch of the source NV12</param>
        /// <param name="dstPitch">Pitch of the dest frame</param>
        /// <param name="alpha">Only used for formats with sn alpha plane: RGB4, ...</param>
        public unsafe void ConvertFromNV12(FourCC destFourcc, byte *Y, byte *UV, byte *outputFramePtr, int width, int height, int outputLen, int srcPitch = 0, int dstPitch = 0, byte alpha = 255)
        {
            int bitsPerPixel = VideoUtility.GetBitsPerPixel(destFourcc);
            // int dstpitch = bitsPerPixel * width / 8;
            int compactFrameSize = width * height * bitsPerPixel / 8;

            Trace.Assert(outputLen == compactFrameSize);



            //byte* nv12uv = nv12 + width * height;


            roisize.height = height;
            roisize.width  = width;

            NativeResizeConvertStatus sts = NativeResizeConvertStatus.NativeStatusNoErr;



            if (srcPitch == 0)
            {
                srcPitch = width * 1;
            }

            if (dstPitch == 0)
            {
                dstPitch = width * VideoUtility.GetPackedPitchMultiplier(destFourcc);
            }


            switch (destFourcc)
            {
            case FourCC.BGR3:
                sts = NV12Convert.NV12ToBGR3(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize);
                break;

            case FourCC.BGR4:
                sts = NV12Convert.NV12ToBGR4(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize, alpha);
                break;


            case FourCC.RGB4:
                sts = NV12Convert.NV12ToRGB4(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize, alpha);
                break;

            case FourCC.RGB3:
                sts = NV12Convert.NV12ToRGB3(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize);
                break;



            case FourCC.YUY2:
                sts = NV12Convert.NV12ToYUY2(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize);

                break;

            case FourCC.YV12:
                pdst[0] = outputFramePtr;
                // This seems wrong, backwards, maybe a bug in IPP 7.x
                // indicies should be 1,2 not 2,1
                //manual check indicates this is what works correctly 2/22/15
                pdst[2]    = outputFramePtr + height * width;
                pdst[1]    = outputFramePtr + height * width + height * width / 2 / 2;
                dststep[0] = dstPitch;
                dststep[1] = dstPitch / 2;
                dststep[2] = dstPitch / 2;

                fixed(byte **p1 = pdst)
                fixed(int *p2 = dststep)
                sts           = NV12Convert.NV12ToYV12(Y, srcPitch, UV, srcPitch, p1, p2, roisize);

                break;

            case FourCC.UYVY:
                sts = NV12Convert.NV12ToUYVY(Y, srcPitch, UV, srcPitch, outputFramePtr, dstPitch, roisize);
                break;

            case FourCC.I420_IYUV:
                pdst[0]    = outputFramePtr;
                pdst[1]    = outputFramePtr + height * width;
                pdst[2]    = outputFramePtr + height * width + height * width / 2 / 2;
                dststep[0] = dstPitch;
                dststep[1] = dstPitch / 2;
                dststep[2] = dstPitch / 2;

                fixed(byte **p1 = pdst)
                fixed(int *p2 = dststep)
                sts           = NV12Convert.NV12ToYV12(Y, srcPitch, UV, srcPitch, p1, p2, roisize);

                break;

            case FourCC.P411:

                pdst[0]    = outputFramePtr;
                pdst[1]    = outputFramePtr + height * width;
                pdst[2]    = outputFramePtr + height * width + height * width / 4;
                dststep[0] = dstPitch;
                dststep[1] = dstPitch / 4;
                dststep[2] = dstPitch / 4;

                fixed(byte **p1 = pdst)
                fixed(int *p2 = dststep)
                sts           = NV12Convert.NV12ToP411(Y, srcPitch, UV, srcPitch, p1, p2, roisize);

                break;

            case FourCC.P422:
                pdst[0]    = outputFramePtr;
                pdst[1]    = outputFramePtr + height * width;
                pdst[2]    = outputFramePtr + height * width + height * width / 2;
                dststep[0] = dstPitch;
                dststep[1] = dstPitch / 2;
                dststep[2] = dstPitch / 2;

                fixed(byte **p1 = pdst)
                fixed(int *p2 = dststep)
                sts           = NV12Convert.NV12ToP422(Y, srcPitch, UV, srcPitch, p1, p2, roisize);

                break;

            case FourCC.NV12:

                // XXX nonono
                // does not work for pitch!=width  !!
                //memmove(outputFramePtr, Y, height * width);
                //memmove(outputFramePtr + height * width, UV, height * width / 2);
                for (int i = 0; i < height; i++)
                {
                    FastMemcpyMemmove.memcpy(outputFramePtr + i * dstPitch, Y + i * srcPitch, width);
                }
                outputFramePtr += height * dstPitch;
                for (int i = 0; i < height / 2; i++)
                {
                    FastMemcpyMemmove.memcpy(outputFramePtr + i * dstPitch, UV + i * srcPitch, width);
                }
                break;

            default:
                throw new Exception("fourcc conversion not supported, contact Lime Video  support for options");
            }

            if (sts != NativeResizeConvertStatus.NativeStatusNoErr)
            {
                throw new Exception("FourCC convert error:" + sts.ToString());
            }
        }