VirtualBox

Ignore:
Timestamp:
Mar 20, 2008 4:03:43 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28975
Message:

Frontends/VBoxHeadless: removed references to deprecated ffmpeg function img_convert() and replaced it with functions of our own to avoid new dependencies

Location:
trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp

    r7485 r7509  
    9292
    9393    LogFlow(("Creating FFmpegFB object %p, width=%lu, height=%lu\n",
    94              this, width, height));
     94             this, (unsigned long) width,  (unsigned long) height));
    9595    Assert(width % 2 == 0 && height % 2 == 0);
    9696    /* For temporary RGB frame we allocate enough memory to deal with
     
    154154            av_write_trailer(mpFormatContext);
    155155            /* free the streams */
    156             for(int i = 0; i < mpFormatContext->nb_streams; i++) {
     156            for(unsigned i = 0; i < mpFormatContext->nb_streams; i++) {
    157157                av_freep(&mpFormatContext->streams[i]->codec);
    158158                av_freep(&mpFormatContext->streams[i]);
     
    211211    avpicture_fill((AVPicture *) mFrame, mYUVBuffer, PIX_FMT_YUV420P,
    212212                   mFrameWidth, mFrameHeight);
    213     /* Fill in the AVPicture structure describing the MPEG frame
    214        framebuffer - in fact another representation of the same data */
    215     avpicture_fill(&mFramePicture, mYUVBuffer, PIX_FMT_YUV420P,
    216                    mFrameWidth, mFrameHeight);
    217213    /* Set the initial framebuffer size to the mpeg frame dimensions */
    218214    BOOL finished;
     
    256252    if (!width)
    257253        return E_POINTER;
    258     LogFlow(("FFmpeg::COMGETTER(Width): returning width %lu\n", mGuestWidth));
     254    LogFlow(("FFmpeg::COMGETTER(Width): returning width %lu\n",
     255              (unsigned long) mGuestWidth));
    259256    *width = mGuestWidth;
    260257    return S_OK;
     
    271268    if (!height)
    272269        return E_POINTER;
    273     LogFlow(("FFmpeg::COMGETTER(Height): returning height %lu\n", mGuestHeight));
     270    LogFlow(("FFmpeg::COMGETTER(Height): returning height %lu\n",
     271              (unsigned long) mGuestHeight));
    274272    *height = mGuestHeight;
    275273    return S_OK;
     
    292290    *bitsPerPixel = mBitsPerPixel;
    293291    LogFlow(("FFmpeg::COMGETTER(BitsPerPixel): returning depth %lu\n",
    294              *bitsPerPixel));
     292              (unsigned long) *bitsPerPixel));
    295293    return S_OK;
    296294}
     
    306304    if (!bytesPerLine)
    307305        return E_POINTER;
    308     LogFlow(("FFmpeg::COMGETTER(BytesPerLine): returning line size %lu\n", mBytesPerLine));
     306    LogFlow(("FFmpeg::COMGETTER(BytesPerLine): returning line size %lu\n",
     307              (unsigned long) mBytesPerLine));
    309308    *bytesPerLine = mBytesPerLine;
    310309    return S_OK;
     
    321320    if (!pixelFormat)
    322321        return E_POINTER;
    323     LogFlow(("FFmpeg::COMGETTER(PixelFormat): returning pixel format: %d\n",
    324              mPixelFormat));
     322    LogFlow(("FFmpeg::COMGETTER(PixelFormat): returning pixel format: %lu\n",
     323              (unsigned long) mPixelFormat));
    325324    *pixelFormat = mPixelFormat;
    326325    return S_OK;
     
    338337        return E_POINTER;
    339338    LogFlow(("FFmpeg::COMGETTER(UsesGuestVRAM): uses guest VRAM? %d\n",
    340              FALSE));
    341     *usesGuestVRAM = mRGBBuffer == NULL;
     339             mRGBBuffer == NULL));
     340    *usesGuestVRAM = (mRGBBuffer == NULL);
    342341    return S_OK;
    343342}
     
    418417
    419418    LogFlow(("FFmpeg::NotifyUpdate called: x=%lu, y=%lu, w=%lu, h=%lu\n",
    420              x, y, w, h));
     419              (unsigned long) x,  (unsigned long) y,  (unsigned long) w,
     420               (unsigned long) h));
    421421    if (!finished)
    422422        return E_POINTER;
     
    500500    if (!finished)
    501501        return E_POINTER;
    502     LogFlow(("FFmpeg::RequestResize called: pixelFormat=%d, vram=%lu, "
     502    LogFlow(("FFmpeg::RequestResize called: pixelFormat=%lu, vram=%lu, "
    503503             "bpp=%lu bpl=%lu, w=%lu, h=%lu\n",
    504              pixelFormat, vram, bitsPerPixel, bytesPerLine, w, h));
     504              (unsigned long) pixelFormat, (unsigned long) vram,
     505              (unsigned long) bitsPerPixel, (unsigned long) bytesPerLine,
     506              (unsigned long) w, (unsigned long) h));
    505507    /* For now, we are doing things synchronously */
    506508    *finished = true;
     
    550552        mBitsPerPixel = bitsPerPixel;
    551553        mRGBBuffer = 0;
    552         Log2(("FFmpeg::RequestResize: setting mBufferAddress to vram and mLineSize to %lu\n", mBytesPerLine));
     554        Log2(("FFmpeg::RequestResize: setting mBufferAddress to vram and mLineSize to %lu\n",
     555              (unsigned long) mBytesPerLine));
    553556    }
    554557    else
     
    563566        mRGBBuffer = reinterpret_cast<uint8_t *>(RTMemAlloc(mBytesPerLine * h));
    564567        AssertReturn(mRGBBuffer != 0, E_OUTOFMEMORY);
    565         Log2(("FFmpeg::RequestResize: alloc'ing mBufferAddress and mRGBBuffer to %p and mBytesPerLine to %lu\n", mBufferAddress,
    566               mBytesPerLine));
     568        Log2(("FFmpeg::RequestResize: alloc'ing mBufferAddress and mRGBBuffer to %p and mBytesPerLine to %lu\n",
     569              mBufferAddress, (unsigned long) mBytesPerLine));
    567570        mBufferAddress = mRGBBuffer;
    568571    }
    569572
    570     /* Fill in the structure describing the (intermediate) guest
    571        framebuffer so that ffmpeg can copy correctly between the two */
    572     avpicture_fill(&mGuestPicture, mTempRGBBuffer, mFFMPEGPixelFormat,
    573                    mFrameWidth, mFrameHeight);
    574573    /* Blank out the intermediate frame framebuffer */
    575574    memset(mTempRGBBuffer, 0, mFrameWidth * mFrameHeight * 4);
     
    847846{
    848847    Log2(("FFmpegFB::copy_to_intermediate_buffer: x=%lu, y=%lu, w=%lu, h=%lu\n",
    849           x, y, w, h));
     848          (unsigned long) x, (unsigned long) y, (unsigned long) w, (unsigned long) h));
    850849    /* Perform clipping and calculate the destination co-ordinates */
    851850    ULONG destX, destY, bpp;
     
    924923HRESULT FFmpegFB::do_rgb_to_yuv_conversion()
    925924{
    926     int rc = img_convert(&mFramePicture, PIX_FMT_YUV420P,
    927                          &mGuestPicture, mFFMPEGPixelFormat,
    928                          mFrameWidth, mFrameHeight);
    929     AssertMsg(rc >= 0, ("img_convert() failed.  rc=%d, mFFMPEGPixelFormat=%d\n"
    930                    "mFrameWidth=%u, mFrameHeight=%u\n", rc,
    931                    mFFMPEGPixelFormat, mFrameWidth, mFrameHeight));
    932     if (rc < 0)
    933         return E_UNEXPECTED;
     925    switch (mFFMPEGPixelFormat)
     926    {
     927        case PIX_FMT_RGBA32:
     928            if (!FFmpegWriteYUV420p<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight,
     929                                                      mYUVBuffer, mTempRGBBuffer))
     930                return E_UNEXPECTED;
     931            break;
     932        case PIX_FMT_RGB24:
     933            if (!FFmpegWriteYUV420p<FFmpegBGR24Iter>(mFrameWidth, mFrameHeight,
     934                                                     mYUVBuffer, mTempRGBBuffer))
     935                return E_UNEXPECTED;
     936            break;
     937        case PIX_FMT_RGB565:
     938            if (!FFmpegWriteYUV420p<FFmpegBGR565Iter>(mFrameWidth, mFrameHeight,
     939                                                      mYUVBuffer, mTempRGBBuffer))
     940                return E_UNEXPECTED;
     941            break;
     942        default:
     943            return E_UNEXPECTED;
     944    }
    934945    return S_OK;
    935946}
     
    9911002    png_structp png_ptr;
    9921003    png_infop info_ptr;
    993     AVPicture libPNGPicture;
    9941004    uint8_t *PNGBuffer;
    995     int rc;
    9961005    /* Work out the new file name - for some reason, we can't use
    9971006       the com::Utf8Str() directly, but have to copy it */
     
    10361045    if (row_pointers == 0)
    10371046        goto av_malloc_pointers_failed;
    1038     avpicture_fill(&libPNGPicture, PNGBuffer, PIX_FMT_RGB24,
    1039                    mFrameWidth, mFrameHeight);
    1040     rc = img_convert(&libPNGPicture, PIX_FMT_RGB24,
    1041                          &mGuestPicture, mFFMPEGPixelFormat,
    1042                          mFrameWidth, mFrameHeight);
    1043     if (rc < 0)
    1044         goto setjmp_exception;
     1047    switch (mFFMPEGPixelFormat)
     1048    {
     1049        case PIX_FMT_RGBA32:
     1050            if (!FFmpegWriteRGB24<FFmpegBGRA32Iter>(mFrameWidth, mFrameHeight,
     1051                                                    PNGBuffer, mTempRGBBuffer))
     1052                goto setjmp_exception;
     1053            break;
     1054        case PIX_FMT_RGB24:
     1055            if (!FFmpegWriteRGB24<FFmpegBGR24Iter>(mFrameWidth, mFrameHeight,
     1056                                                   PNGBuffer, mTempRGBBuffer))
     1057                goto setjmp_exception;
     1058            break;
     1059        case PIX_FMT_RGB565:
     1060            if (!FFmpegWriteRGB24<FFmpegBGR565Iter>(mFrameWidth, mFrameHeight,
     1061                                                    PNGBuffer, mTempRGBBuffer))
     1062                goto setjmp_exception;
     1063            break;
     1064        default:
     1065            goto setjmp_exception;
     1066    }
    10451067    /* libpng exception handling */
    10461068    if (setjmp(png_jmpbuf(png_ptr)))
  • trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h

    r7485 r7509  
    156156    /** Information for ffmpeg describing the current frame */
    157157    AVFrame *mFrame;
    158     /** An AVPicture structure containing information about the
    159       * guest framebuffer */
    160     AVPicture mGuestPicture;
    161158    /** ffmpeg pixel format of guest framebuffer */
    162159    int mFFMPEGPixelFormat;
    163     /** An AVPicture structure containing information about the
    164       * MPEG frame framebuffer */
    165     AVPicture mFramePicture;
    166160    /** Since we are building without exception support, we use this
    167161        to signal allocation failure in the constructor */
     
    186180};
    187181
     182/**
     183 * Iterator class for running through an BGRA32 image buffer and converting
     184 * it to RGB.
     185 */
     186class FFmpegBGRA32Iter
     187{
     188private:
     189    enum { PIX_SIZE = 4 };
     190public:
     191    FFmpegBGRA32Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer)
     192    {
     193        mPos = 0;
     194        mSize = aWidth * aHeight * PIX_SIZE;
     195        mBuffer = aBuffer;
     196    }
     197    /**
     198     * Convert the next pixel to RGB.
     199     * @returns true on success, false if we have reached the end of the buffer
     200     * @param   aRed    where to store the red value
     201     * @param   aGreen  where to store the green value
     202     * @param   aBlue   where to store the blue value
     203     */
     204    bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
     205    {
     206        bool rc = false;
     207        if (mPos + PIX_SIZE <= mSize)
     208        {
     209            *aRed = mBuffer[mPos + 2];
     210            *aGreen = mBuffer[mPos + 1];
     211            *aBlue = mBuffer[mPos];
     212            mPos += PIX_SIZE;
     213            rc = true;
     214        }
     215        return rc;
     216    }
     217
     218    /**
     219     * Skip forward by a certain number of pixels
     220     * @param aPixels  how many pixels to skip
     221     */
     222    void skip(unsigned aPixels)
     223    {
     224        mPos += PIX_SIZE * aPixels;
     225    }
     226private:
     227    /** Size of the picture buffer */
     228    unsigned mSize;
     229    /** Current position in the picture buffer */
     230    unsigned mPos;
     231    /** Address of the picture buffer */
     232    uint8_t *mBuffer;
     233};
     234
     235/**
     236 * Iterator class for running through an BGR24 image buffer and converting
     237 * it to RGB.
     238 */
     239class FFmpegBGR24Iter
     240{
     241private:
     242    enum { PIX_SIZE = 3 };
     243public:
     244    FFmpegBGR24Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer)
     245    {
     246        mPos = 0;
     247        mSize = aWidth * aHeight * PIX_SIZE;
     248        mBuffer = aBuffer;
     249    }
     250    /**
     251     * Convert the next pixel to RGB.
     252     * @returns true on success, false if we have reached the end of the buffer
     253     * @param   aRed    where to store the red value
     254     * @param   aGreen  where to store the green value
     255     * @param   aBlue   where to store the blue value
     256     */
     257    bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
     258    {
     259        bool rc = false;
     260        if (mPos + PIX_SIZE <= mSize)
     261        {
     262            *aRed = mBuffer[mPos + 2];
     263            *aGreen = mBuffer[mPos + 1];
     264            *aBlue = mBuffer[mPos];
     265            mPos += PIX_SIZE;
     266            rc = true;
     267        }
     268        return rc;
     269    }
     270
     271    /**
     272     * Skip forward by a certain number of pixels
     273     * @param aPixels  how many pixels to skip
     274     */
     275    void skip(unsigned aPixels)
     276    {
     277        mPos += PIX_SIZE * aPixels;
     278    }
     279private:
     280    /** Size of the picture buffer */
     281    unsigned mSize;
     282    /** Current position in the picture buffer */
     283    unsigned mPos;
     284    /** Address of the picture buffer */
     285    uint8_t *mBuffer;
     286};
     287
     288/**
     289 * Iterator class for running through an BGR565 image buffer and converting
     290 * it to RGB.
     291 */
     292class FFmpegBGR565Iter
     293{
     294private:
     295    enum { PIX_SIZE = 2 };
     296public:
     297    FFmpegBGR565Iter(unsigned aWidth, unsigned aHeight, uint8_t *aBuffer)
     298    {
     299        mPos = 0;
     300        mSize = aWidth * aHeight * PIX_SIZE;
     301        mBuffer = aBuffer;
     302    }
     303    /**
     304     * Convert the next pixel to RGB.
     305     * @returns true on success, false if we have reached the end of the buffer
     306     * @param   aRed    where to store the red value
     307     * @param   aGreen  where to store the green value
     308     * @param   aBlue   where to store the blue value
     309     */
     310    bool getRGB(unsigned *aRed, unsigned *aGreen, unsigned *aBlue)
     311    {
     312        bool rc = false;
     313        if (mPos + PIX_SIZE <= mSize)
     314        {
     315            unsigned uFull =   (((unsigned) mBuffer[mPos + 1]) << 8)
     316                             | ((unsigned) mBuffer[mPos]);
     317            *aRed = (uFull >> 8) & ~7;
     318            *aGreen = (uFull >> 3) & ~3 & 0xff;
     319            *aBlue = (uFull << 3) & ~7 & 0xff;
     320            mPos += PIX_SIZE;
     321            rc = true;
     322        }
     323        return rc;
     324    }
     325
     326    /**
     327     * Skip forward by a certain number of pixels
     328     * @param aPixels  how many pixels to skip
     329     */
     330    void skip(unsigned aPixels)
     331    {
     332        mPos += PIX_SIZE * aPixels;
     333    }
     334private:
     335    /** Size of the picture buffer */
     336    unsigned mSize;
     337    /** Current position in the picture buffer */
     338    unsigned mPos;
     339    /** Address of the picture buffer */
     340    uint8_t *mBuffer;
     341};
     342
     343
     344/**
     345 * Convert an image to YUV420p format
     346 * @returns true on success, false on failure
     347 * @param aWidth    width of image
     348 * @param aHeight   height of image
     349 * @param aDestBuf  an allocated memory buffer large enough to hold the
     350 *                  destination image (i.e. width * height * 12bits)
     351 * @param aSrcBuf   the source image as an array of bytes
     352 */
     353template <class T>
     354inline bool FFmpegWriteYUV420p(unsigned aWidth, unsigned aHeight, uint8_t *aDestBuf,
     355                        uint8_t *aSrcBuf)
     356{
     357    AssertReturn(0 == (aWidth & 1), false);
     358    AssertReturn(0 == (aHeight & 1), false);
     359    bool rc = true;
     360    T iter1(aWidth, aHeight, aSrcBuf);
     361    T iter2 = iter1;
     362    iter2.skip(aWidth);
     363    unsigned cPixels = aWidth * aHeight;
     364    unsigned offY = 0;
     365    unsigned offU = cPixels;
     366    unsigned offV = cPixels + cPixels / 4;
     367    for (unsigned i = 0; (i < aHeight / 2) && rc; ++i)
     368    {
     369        for (unsigned j = 0; (j < aWidth / 2) && rc; ++j)
     370        {
     371            unsigned red, green, blue, u, v;
     372            rc = iter1.getRGB(&red, &green, &blue);
     373            if (rc)
     374            {
     375                aDestBuf[offY] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
     376                u = (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
     377                v = (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
     378                rc = iter1.getRGB(&red, &green, &blue);
     379            }
     380            if (rc)
     381            {
     382                aDestBuf[offY + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
     383                u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
     384                v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
     385                rc = iter2.getRGB(&red, &green, &blue);
     386            }
     387            if (rc)
     388            {
     389                aDestBuf[offY + aWidth] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
     390                u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
     391                v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
     392                rc = iter2.getRGB(&red, &green, &blue);
     393            }
     394            if (rc)
     395            {
     396                aDestBuf[offY + aWidth + 1] = ((66 * red + 129 * green + 25 * blue + 128) >> 8) + 16;
     397                u += (((-38 * red - 74 * green + 112 * blue + 128) >> 8) + 128) / 4;
     398                v += (((112 * red - 94 * green - 18 * blue + 128) >> 8) + 128) / 4;
     399                aDestBuf[offU] = u;
     400                aDestBuf[offV] = v;
     401                offY += 2;
     402                ++offU;
     403                ++offV;
     404            }
     405        }
     406        if (rc)
     407        {
     408            iter1.skip(aWidth);
     409            iter2.skip(aWidth);
     410            offY += aWidth;
     411        }
     412    }
     413    return rc;
     414}
     415
     416
     417/**
     418 * Convert an image to RGB24 format
     419 * @returns true on success, false on failure
     420 * @param aWidth    width of image
     421 * @param aHeight   height of image
     422 * @param aDestBuf  an allocated memory buffer large enough to hold the
     423 *                  destination image (i.e. width * height * 12bits)
     424 * @param aSrcBuf   the source image as an array of bytes
     425 */
     426template <class T>
     427inline bool FFmpegWriteRGB24(unsigned aWidth, unsigned aHeight, uint8_t *aDestBuf,
     428                        uint8_t *aSrcBuf)
     429{
     430    enum { PIX_SIZE = 3 };
     431    bool rc = true;
     432    AssertReturn(0 == (aWidth & 1), false);
     433    AssertReturn(0 == (aHeight & 1), false);
     434    T iter(aWidth, aHeight, aSrcBuf);
     435    unsigned cPixels = aWidth * aHeight;
     436    for (unsigned i = 0; (i < cPixels) && rc; ++i)
     437    {
     438        unsigned red, green, blue;
     439        rc = iter.getRGB(&red, &green, &blue);
     440        if (rc)
     441        {
     442            aDestBuf[i * PIX_SIZE] = red;
     443            aDestBuf[i * PIX_SIZE + 1] = green;
     444            aDestBuf[i * PIX_SIZE + 2] = blue;
     445        }
     446    }
     447    return rc;
     448}
    188449
    189450#endif /* !_H_FFMPEGFB */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette