⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_quartzyuv.m

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 M
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2003  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"#include "SDL_QuartzVideo.h"#include "SDL_QuartzWindow.h"#include "../SDL_yuvfuncs.h"#define yuv_idh (this->hidden->yuv_idh)#define yuv_matrix (this->hidden->yuv_matrix)#define yuv_codec (this->hidden->yuv_codec)#define yuv_seq (this->hidden->yuv_seq)#define yuv_pixmap (this->hidden->yuv_pixmap)#define yuv_data (this->hidden->yuv_data)#define yuv_width (this->hidden->yuv_width)#define yuv_height (this->hidden->yuv_height)#define yuv_port (this->hidden->yuv_port)static int QZ_LockYUV (_THIS, SDL_Overlay *overlay) {    return 0;}static void QZ_UnlockYUV (_THIS, SDL_Overlay *overlay) {    ;}static int QZ_DisplayYUV (_THIS, SDL_Overlay *overlay, SDL_Rect *src, SDL_Rect *dst) {    OSErr err;    CodecFlags flags;    if (dst->x != 0 || dst->y != 0) {        SDL_SetError ("Need a dst at (0,0)");        return -1;    }    if (dst->w != yuv_width || dst->h != yuv_height) {        Fixed scale_x, scale_y;        scale_x = FixDiv ( Long2Fix (dst->w), Long2Fix (overlay->w) );        scale_y = FixDiv ( Long2Fix (dst->h), Long2Fix (overlay->h) );        SetIdentityMatrix (yuv_matrix);        ScaleMatrix (yuv_matrix, scale_x, scale_y, Long2Fix (0), Long2Fix (0));        SetDSequenceMatrix (yuv_seq, yuv_matrix);        yuv_width = dst->w;        yuv_height = dst->h;    }    if( ( err = DecompressSequenceFrameS(                                         yuv_seq,                                         (void*)yuv_pixmap,                                         sizeof (PlanarPixmapInfoYUV420),                                         codecFlagUseImageBuffer, &flags, nil ) != noErr ) )    {        SDL_SetError ("DecompressSequenceFrameS failed");    }    return err != noErr;}static void QZ_FreeHWYUV (_THIS, SDL_Overlay *overlay) {    CDSequenceEnd (yuv_seq);    ExitMovies();    SDL_free (overlay->hwfuncs);    SDL_free (overlay->pitches);    SDL_free (overlay->pixels);    if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {        [ qz_window close ];        qz_window = nil;    }    SDL_free (yuv_matrix);    DisposeHandle ((Handle)yuv_idh);}/* check for 16 byte alignment, bail otherwise */#define CHECK_ALIGN(x) do { if ((Uint32)x & 15) { SDL_SetError("Alignment error"); return NULL; } } while(0)/* align a byte offset, return how much to add to make it a multiple of 16 */#define ALIGN(x) ((16 - (x & 15)) & 15)SDL_Overlay* QZ_CreateYUVOverlay (_THIS, int width, int height,                                         Uint32 format, SDL_Surface *display) {    Uint32 codec;    OSStatus err;    CGrafPtr port;    SDL_Overlay *overlay;    if (format == SDL_YV12_OVERLAY ||        format == SDL_IYUV_OVERLAY) {        codec = kYUV420CodecType;    }    else {        SDL_SetError ("Hardware: unsupported video format");        return NULL;    }    yuv_idh = (ImageDescriptionHandle) NewHandleClear (sizeof(ImageDescription));    if (yuv_idh == NULL) {        SDL_OutOfMemory();        return NULL;    }    yuv_matrix = (MatrixRecordPtr) SDL_malloc (sizeof(MatrixRecord));    if (yuv_matrix == NULL) {        SDL_OutOfMemory();        return NULL;    }    if ( EnterMovies() != noErr ) {        SDL_SetError ("Could not init QuickTime for YUV playback");        return NULL;    }    err = FindCodec (codec, bestSpeedCodec, nil, &yuv_codec);    if (err != noErr) {        SDL_SetError ("Could not find QuickTime codec for format");        return NULL;    }    if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {        /*          Acceleration requires a window to be present.          A CGrafPtr that points to the screen isn't good enough        */        NSRect content = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);        qz_window = [ [ SDL_QuartzWindow alloc ]                            initWithContentRect:content                            styleMask:NSBorderlessWindowMask                            backing:NSBackingStoreBuffered defer:NO ];        if (qz_window == nil) {            SDL_SetError ("Could not create the Cocoa window");            return NULL;        }        [ qz_window setContentView:[ [ NSQuickDrawView alloc ] init ] ];        [ qz_window setReleasedWhenClosed:YES ];        [ qz_window center ];        [ qz_window setAcceptsMouseMovedEvents:YES ];        [ qz_window setLevel:CGShieldingWindowLevel() ];        [ qz_window makeKeyAndOrderFront:nil ];        port = [ [ qz_window contentView ] qdPort ];        SetPort (port);                /*            BUG: would like to remove white flash when window kicks in            {                Rect r;                SetRect (&r, 0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);                PaintRect (&r);                QDFlushPortBuffer (port, nil);            }        */    }    else {        port = [ window_view qdPort ];        SetPort (port);    }        SetIdentityMatrix (yuv_matrix);        HLock ((Handle)yuv_idh);        (**yuv_idh).idSize = sizeof(ImageDescription);    (**yuv_idh).cType  = codec;    (**yuv_idh).version = 1;    (**yuv_idh).revisionLevel = 0;    (**yuv_idh).width = width;    (**yuv_idh).height = height;    (**yuv_idh).hRes = Long2Fix(72);    (**yuv_idh).vRes = Long2Fix(72);    (**yuv_idh).spatialQuality = codecLosslessQuality;    (**yuv_idh).frameCount = 1;    (**yuv_idh).clutID = -1;    (**yuv_idh).dataSize = 0;    (**yuv_idh).depth = 24;        HUnlock ((Handle)yuv_idh);        err = DecompressSequenceBeginS (                                    &yuv_seq,                                    yuv_idh,                                    NULL,                                    0,                                    port,                                    NULL,                                    NULL,                                    yuv_matrix,                                    0,                                    NULL,                                    codecFlagUseImageBuffer,                                    codecLosslessQuality,                                    yuv_codec);        if (err != noErr) {        SDL_SetError ("Error trying to start YUV codec.");        return NULL;    }        overlay = (SDL_Overlay*) SDL_malloc (sizeof(*overlay));    if (overlay == NULL) {        SDL_OutOfMemory();        return NULL;    }        overlay->format      = format;    overlay->w           = width;    overlay->h           = height;    overlay->planes      = 3;    overlay->hw_overlay  = 1;    {        int      offset;        Uint8  **pixels;        Uint16  *pitches;        int      plane2, plane3;        if (format == SDL_IYUV_OVERLAY) {            plane2 = 1; /* Native codec format */            plane3 = 2;        }        else if (format == SDL_YV12_OVERLAY) {            /* switch the U and V planes */            plane2 = 2; /* U plane maps to plane 3 */            plane3 = 1; /* V plane maps to plane 2 */        }        else {            SDL_SetError("Unsupported YUV format");            return NULL;        }        pixels = (Uint8**) SDL_malloc (sizeof(*pixels) * 3);        pitches = (Uint16*) SDL_malloc (sizeof(*pitches) * 3);        if (pixels == NULL || pitches == NULL) {            SDL_OutOfMemory();            return NULL;        }        /* Fix: jc.bertin@free.fr           PlanarPixmapInfoYUV420 is a big-endian struct */        yuv_pixmap = (PlanarPixmapInfoYUV420*)            SDL_malloc (sizeof(PlanarPixmapInfoYUV420) +                    (width * height * 2));        if (yuv_pixmap == NULL) {            SDL_OutOfMemory ();            return NULL;        }        /* CHECK_ALIGN(yuv_pixmap); */        offset  = sizeof(PlanarPixmapInfoYUV420);        /* offset += ALIGN(offset); */        /* CHECK_ALIGN(offset); */        pixels[0] = (Uint8*)yuv_pixmap + offset;        /* CHECK_ALIGN(pixels[0]); */        pitches[0] = width;        yuv_pixmap->componentInfoY.offset = EndianS32_NtoB(offset);        yuv_pixmap->componentInfoY.rowBytes = EndianU32_NtoB(width);        offset += width * height;        pixels[plane2] = (Uint8*)yuv_pixmap + offset;        pitches[plane2] = width / 2;        yuv_pixmap->componentInfoCb.offset = EndianS32_NtoB(offset);        yuv_pixmap->componentInfoCb.rowBytes = EndianU32_NtoB(width / 2);        offset += (width * height / 4);        pixels[plane3] = (Uint8*)yuv_pixmap + offset;        pitches[plane3] = width / 2;        yuv_pixmap->componentInfoCr.offset = EndianS32_NtoB(offset);        yuv_pixmap->componentInfoCr.rowBytes = EndianU32_NtoB(width / 2);        overlay->pixels = pixels;        overlay->pitches = pitches;    }    overlay->hwfuncs = SDL_malloc (sizeof(*overlay->hwfuncs));    if (overlay->hwfuncs == NULL) {        SDL_OutOfMemory();        return NULL;    }        overlay->hwfuncs->Lock    = QZ_LockYUV;    overlay->hwfuncs->Unlock  = QZ_UnlockYUV;    overlay->hwfuncs->Display = QZ_DisplayYUV;    overlay->hwfuncs->FreeHW  = QZ_FreeHWYUV;    yuv_width = overlay->w;    yuv_height = overlay->h;        return overlay;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -