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

📄 sdl_quartzvideo.m

📁 网络MPEG4IP流媒体开发源代码
💻 M
📖 第 1 页 / 共 4 页
字号:
    attr[i++] = NSOpenGLPFAScreenMask;    attr[i++] = CGDisplayIDToOpenGLDisplayMask (display_id);    attr[i] = 0;    fmt = [ [ NSOpenGLPixelFormat alloc ] initWithAttributes:attr ];    if (fmt == nil) {        SDL_SetError ("Failed creating OpenGL pixel format");        return 0;    }    gl_context = [ [ NSOpenGLContext alloc ] initWithFormat:fmt                                               shareContext:nil];    if (gl_context == nil) {        SDL_SetError ("Failed creating OpenGL context");        return 0;    }    /* Convince SDL that the GL "driver" is loaded */    this->gl_config.driver_loaded = 1;    [ fmt release ];    return 1;}static void QZ_TearDownOpenGL (_THIS) {    [ NSOpenGLContext clearCurrentContext ];    [ gl_context clearDrawable ];    [ gl_context release ];}/* SDL OpenGL functions */static int    QZ_GL_LoadLibrary    (_THIS, const char *location) {    this->gl_config.driver_loaded = 1;    return 1;}static void*  QZ_GL_GetProcAddress (_THIS, const char *proc) {    /* We may want to cache the bundleRef at some point */    CFBundleRef bundle;    CFURLRef bundleURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,                                                        CFSTR("/System/Library/Frameworks/OpenGL.framework"), kCFURLPOSIXPathStyle, true);    CFStringRef functionName = CFStringCreateWithCString        (kCFAllocatorDefault, proc, kCFStringEncodingASCII);    void *function;    bundle = CFBundleCreate (kCFAllocatorDefault, bundleURL);    assert (bundle != NULL);    function = CFBundleGetFunctionPointerForName (bundle, functionName);    CFRelease ( bundleURL );    CFRelease ( functionName );    CFRelease ( bundle );    return function;}static int    QZ_GL_GetAttribute   (_THIS, SDL_GLattr attrib, int* value) {    GLenum attr = 0;    QZ_GL_MakeCurrent (this);    switch (attrib) {        case SDL_GL_RED_SIZE: attr = GL_RED_BITS;   break;        case SDL_GL_BLUE_SIZE: attr = GL_BLUE_BITS;  break;        case SDL_GL_GREEN_SIZE: attr = GL_GREEN_BITS; break;        case SDL_GL_ALPHA_SIZE: attr = GL_ALPHA_BITS; break;        case SDL_GL_DOUBLEBUFFER: attr = GL_DOUBLEBUFFER; break;        case SDL_GL_DEPTH_SIZE: attr = GL_DEPTH_BITS;  break;        case SDL_GL_STENCIL_SIZE: attr = GL_STENCIL_BITS; break;        case SDL_GL_ACCUM_RED_SIZE: attr = GL_ACCUM_RED_BITS; break;        case SDL_GL_ACCUM_GREEN_SIZE: attr = GL_ACCUM_GREEN_BITS; break;        case SDL_GL_ACCUM_BLUE_SIZE: attr = GL_ACCUM_BLUE_BITS; break;        case SDL_GL_ACCUM_ALPHA_SIZE: attr = GL_ACCUM_ALPHA_BITS; break;        case SDL_GL_STEREO: attr = GL_STEREO; break;        case SDL_GL_BUFFER_SIZE:        {            GLint bits = 0;            GLint component;            /* there doesn't seem to be a single flag in OpenGL for this! */            glGetIntegerv (GL_RED_BITS, &component);   bits += component;            glGetIntegerv (GL_GREEN_BITS,&component);  bits += component;            glGetIntegerv (GL_BLUE_BITS, &component);  bits += component;            glGetIntegerv (GL_ALPHA_BITS, &component); bits += component;            *value = bits;        }        return 0;    }    glGetIntegerv (attr, (GLint *)value);    return 0;}static int    QZ_GL_MakeCurrent    (_THIS) {    [ gl_context makeCurrentContext ];    return 0;}static void   QZ_GL_SwapBuffers    (_THIS) {    [ gl_context flushBuffer ];}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 *dstrect) {    OSErr err;    CodecFlags flags;    if (dstrect->x != 0 || dstrect->y != 0) {        SDL_SetError ("Need a dstrect at (0,0)");        return -1;    }    if (dstrect->w != yuv_width || dstrect->h != yuv_height) {        Fixed scale_x, scale_y;        scale_x = FixDiv ( Long2Fix (dstrect->w), Long2Fix (overlay->w) );        scale_y = FixDiv ( Long2Fix (dstrect->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 = dstrect->w;        yuv_height = dstrect->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();    free (overlay->hwfuncs);    free (overlay->pitches);    free (overlay->pixels);    if (SDL_VideoSurface->flags & SDL_FULLSCREEN) {        [ qz_window close ];        qz_window = nil;    }    free (yuv_matrix);    DisposeHandle ((Handle)yuv_idh);}#include "SDL_yuvfuncs.h"/* 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)static 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) 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:[ [ SDL_QuartzWindowView 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*) 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**) malloc (sizeof(*pixels) * 3);        pitches = (Uint16*) malloc (sizeof(*pitches) * 3);        if (pixels == NULL || pitches == NULL) {            SDL_OutOfMemory();            return NULL;        }        yuv_pixmap = (PlanarPixmapInfoYUV420*)            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 = offset;        yuv_pixmap->componentInfoY.rowBytes = width;        offset += width * height;        pixels[plane2] = (Uint8*)yuv_pixmap + offset;        pitches[plane2] = width / 2;        yuv_pixmap->componentInfoCb.offset = offset;        yuv_pixmap->componentInfoCb.rowBytes = width / 2;        offset += (width * height / 4);        pixels[plane3] = (Uint8*)yuv_pixmap + offset;        pitches[plane3] = width / 2;        yuv_pixmap->componentInfoCr.offset = offset;        yuv_pixmap->componentInfoCr.rowBytes = width / 2;        overlay->pixels = pixels;        overlay->pitches = pitches;    }    overlay->hwfuncs = 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 + -