• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            Image Stride (Windows)

            轉載自:http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa473780(v=vs.85).aspx

            When a video image is stored in memory, the memory buffer might contain extra padding bytes after each row of pixels. The padding bytes affect how the image is stored in memory, but do not affect how the image is displayed.

            The stride is the number of bytes from one row of pixels in memory to the next row of pixels in memory. Stride is also called pitch. If padding bytes are present, the stride is wider than the width of the image, as shown in the following illustration.

            Diagram showing an image plus padding.

            Two buffers that contain video frames with equal dimensions can have two different strides. If you process a video image, you must take the stride into account.

            In addition, there are two ways that an image can be arranged in memory. In a top-down image, the top row of pixels in the image appears first in memory. In a bottom-up image, the last row of pixels appears first in memory. The following illustration shows the difference between a top-down image and a bottom-up image.

            Diagram showing top-down and bottom-up images.

            A bottom-up image has a negative stride, because stride is defined as the number of bytes need to move down a row of pixels, relative to the displayed image. YUV images should always be top-down, and any image that is contained in a Direct3D surface must be top-down. RGB images in system memory are usually bottom-up.

            Video transforms in particular need to handle buffers with mismatched strides, because the input buffer might not match the output buffer. For example, suppose that you want to convert a source image and write the result to a destination image. Assume that both images have the same width and height, but might not have the same pixel format or the same image stride.

            The following example code shows a generalized approach for writing this kind of function. This is not a complete working example, because it abstracts many of the specific details.

            void ProcessVideoImage(
                BYTE*       pDestScanLine0,     
                LONG        lDestStride,        
                const BYTE* pSrcScanLine0,      
                LONG        lSrcStride,         
                DWORD       dwWidthInPixels,     
                DWORD       dwHeightInPixels
                )
            {
                for (DWORD y = 0; y < dwHeightInPixels; y++)
                {
                    SOURCE_PIXEL_TYPE *pSrcPixel = (SOURCE_PIXEL_TYPE*)pDestScanLine0;
                    DEST_PIXEL_TYPE *pDestPixel = (DEST_PIXEL_TYPE*)pSrcScanLine0;
            
                    for (DWORD x = 0; x < dwWidthInPixels; x +=2)
                    {
                        pDestPixel[x] = TransformPixelValue(pSrcPixel[x]);
                    }
                    pDestScanLine0 += lDestStride;
                    pSrcScanLine0 += lSrcStride;
                }
            }
            
            

            This function takes six parameters:

            • A pointer to the start of scan line 0 in the destination image.
            • The stride of the destination image.
            • A pointer to the start of scan line 0 in the source image.
            • The stride of the source image.
            • The width of the image in pixels.
            • The height of the image in pixels.

            The general idea is to process one row at a time, iterating over each pixel in the row. Assume that SOURCE_PIXEL_TYPE and DEST_PIXEL_TYPE are structures representing the pixel layout for the source and destination images, respectively. (For example, 32-bit RGB uses the RGBQUAD structure. Not every pixel format has a predefined structure.) Casting the array pointer to the structure type enables you to access the RGB or YUV components of each pixel. At the start of each row, the function stores a pointer to the row. At the end of the row, it increments the pointer by the width of the image stride, which advances the pointer to the next row.

            This example calls a hypothetical function named TransformPixelValue for each pixel. This could be any function that calculates a target pixel from a source pixel. Of course, the exact details will depend on the particular task. For example, if you have a planar YUV format, you must access the chroma planes independently from the luma plane; with interlaced video, you might need to process the fields separately; and so forth.

            To give a more concrete example, the following code converts a 32-bit RGB image into an AYUV image. The RGB pixels are accessed using an RGBQUAD structure, and the AYUV pixels are accessed using a DXVA2_AYUVSample8 structure structure.

            //-------------------------------------------------------------------
            // Name: RGB32_To_AYUV
            // Description: Converts an image from RGB32 to AYUV
            //-------------------------------------------------------------------
            void RGB32_To_AYUV(
                BYTE*       pDest,
                LONG        lDestStride,
                const BYTE* pSrc,
                LONG        lSrcStride,
                DWORD       dwWidthInPixels,
                DWORD       dwHeightInPixels
                )
            {
                for (DWORD y = 0; y < dwHeightInPixels; y++)
                {
                    RGBQUAD             *pSrcPixel = (RGBQUAD*)pSrc;
                    DXVA2_AYUVSample8   *pDestPixel = (DXVA2_AYUVSample8*)pDest;
                    
                    for (DWORD x = 0; x < dwWidthInPixels; x++)
                    {
                        pDestPixel[x].Alpha = 0x80;
                        pDestPixel[x].Y = RGBtoY(pSrcPixel[x]);   
                        pDestPixel[x].Cb = RGBtoU(pSrcPixel[x]);   
                        pDestPixel[x].Cr = RGBtoV(pSrcPixel[x]);   
                    }
                    pDest += lDestStride;
                    pSrc += lSrcStride;
                }
            }
            
            

            The next example converts a 32-bit RGB image to a YV12 image. This example shows how to handle a planar YUV format. (YV12 is a planar 4:2:0 format.) In this example, the function maintains three separate pointers for the three planes in the target image. However, the basic approach is the same as the previous example.

            void RGB32_To_YV12(
                BYTE*       pDest,
                LONG        lDestStride,
                const BYTE* pSrc,
                LONG        lSrcStride,
                DWORD       dwWidthInPixels,
                DWORD       dwHeightInPixels
                )
            {
                assert(dwWidthInPixels % 2 == 0);
                assert(dwHeightInPixels % 2 == 0);
            
                const BYTE *pSrcRow = pSrc;
                
                BYTE *pDestY = pDest;
            
                // Calculate the offsets for the V and U planes.
            
                // In YV12, each chroma plane has half the stride and half the height  
                // as the Y plane.
                BYTE *pDestV = pDest + (lDestStride * dwHeightInPixels);
                BYTE *pDestU = pDest + 
                               (lDestStride * dwHeightInPixels) + 
                               ((lDestStride * dwHeightInPixels) / 4);
            
                // Convert the Y plane.
                for (DWORD y = 0; y < dwHeightInPixels; y++)
                {
                    RGBQUAD *pSrcPixel = (RGBQUAD*)pSrcRow;
                    
                    for (DWORD x = 0; x < dwWidthInPixels; x++)
                    {
                        pDestY[x] = RGBtoY(pSrcPixel[x]);    // Y0
                    }
                    pDestY += lDestStride;
                    pSrcRow += lSrcStride;
                }
            
                // Convert the V and U planes.
            
                // YV12 is a 4:2:0 format, so each chroma sample is derived from four 
                // RGB pixels.
                pSrcRow = pSrc;
                for (DWORD y = 0; y < dwHeightInPixels; y += 2)
                {
                    RGBQUAD *pSrcPixel = (RGBQUAD*)pSrcRow;
                    RGBQUAD *pNextSrcRow = (RGBQUAD*)(pSrcRow + lSrcStride);
            
                    BYTE *pbV = pDestV;
                    BYTE *pbU = pDestU;
            
                    for (DWORD x = 0; x < dwWidthInPixels; x += 2)
                    {
                        // Use a simple average to downsample the chroma.
            
                        *pbV++ = ( RGBtoV(pSrcPixel[x]) +
                                   RGBtoV(pSrcPixel[x + 1]) +       
                                   RGBtoV(pNextSrcRow[x]) +         
                                   RGBtoV(pNextSrcRow[x + 1]) ) / 4;        
            
                        *pbU++ = ( RGBtoU(pSrcPixel[x]) +
                                   RGBtoU(pSrcPixel[x + 1]) +       
                                   RGBtoU(pNextSrcRow[x]) +         
                                   RGBtoU(pNextSrcRow[x + 1]) ) / 4;    
                    }
                    pDestV += lDestStride / 2;
                    pDestU += lDestStride / 2;
                    
                    // Skip two lines on the source image.
                    pSrcRow += (lSrcStride * 2);
                }
            }
            
            

            In all of these examples, it is assumed that the application has already determined the image stride. You can sometimes get this information from the media buffer. Otherwise, you must calculate it based on the video format. For more information about calculating image stride and working with media buffers for video, see Uncompressed Video Buffers.

            Related topics

            Video Media Types
            Media Types

            posted on 2013-01-25 10:07 楊粼波 閱讀(943) 評論(0)  編輯 收藏 引用

            久久天天日天天操综合伊人av| 国产高清美女一级a毛片久久w| 久久久久高潮综合影院| 热RE99久久精品国产66热| 色妞色综合久久夜夜| 97久久久精品综合88久久| 久久亚洲国产精品123区| 久久丫忘忧草产品| 国产69精品久久久久777| 国产欧美久久久精品影院| 国产国产成人精品久久| 精品综合久久久久久98| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 97久久国产综合精品女不卡| 国内精品久久久人妻中文字幕| 日韩亚洲欧美久久久www综合网| 狠狠精品久久久无码中文字幕| 91久久九九无码成人网站| 久久夜色精品国产噜噜亚洲AV| 久久综合亚洲色HEZYO国产| 国产精品久久永久免费| 人妻精品久久无码区| 国内精品久久久久久久久电影网| 久久精品国产色蜜蜜麻豆| 国产一久久香蕉国产线看观看 | 久久精品人人槡人妻人人玩AV | 精品一二三区久久aaa片| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 久久久久亚洲AV片无码下载蜜桃| 亚洲综合久久综合激情久久 | 久久精品免费一区二区| 色综合久久久久综合99| 久久精品夜色噜噜亚洲A∨| 精品久久久久久国产| 久久久久亚洲av无码专区喷水 | 久久精品国产亚洲AV香蕉| 色诱久久av| 一级做a爰片久久毛片免费陪| 青青热久久国产久精品| 亚洲欧美日韩精品久久亚洲区| 欧美成a人片免费看久久|