[MPlayer-cvslog] r30899 - in trunk: libmpcodecs/vd_qtvideo.c loader/qtx/qtxsdk/components.h

sesse subversion at mplayerhq.hu
Mon Mar 15 13:05:57 CET 2010


Author: sesse
Date: Mon Mar 15 13:05:56 2010
New Revision: 30899

Log:
Use the high-level QuickTime decoding APIs (DecompressSequenceFrameS and
friends) instead of the unsupported, internal ones (ImageCodecBeginBand
etc.). This is a prerequisite for, among others, Apple ProRes 4:2:2 support,
and simplifies the file by quite a bit.

Tested on Linux with all existing QuickTime codecs I could get to work in the
first place; qt261, qtavui, qtsvq3 have no change. qtcvid appears to not give
bit-exact the same output as before, but it looks just the same in playback
to me. qt3ivx stops crashing on exit (so works better than before). With some
extra patches and a codecs.conf entry, ProRes 4:2:2 also works, including on
Linux.

Since codec initialization is now actually done on decoder init instead of on
first frame, fallback should also work a bit better (although usually, qtvideo
is last in the chain). Also made the decoder complain explicitly if the
demuxer data is not there (ie., the user tried to run without -demuxer mov).

This patch is a cleaned up version of what Andrew Wason (rectalogic A
rectalogic D com) posted to mplayer-dev-eng in June.

Modified:
   trunk/libmpcodecs/vd_qtvideo.c
   trunk/loader/qtx/qtxsdk/components.h

Modified: trunk/libmpcodecs/vd_qtvideo.c
==============================================================================
--- trunk/libmpcodecs/vd_qtvideo.c	Mon Mar 15 10:32:53 2010	(r30898)
+++ trunk/libmpcodecs/vd_qtvideo.c	Mon Mar 15 13:05:56 2010	(r30899)
@@ -44,18 +44,12 @@ static const vd_info_t info = {
 
 LIBVD_EXTERN(qtvideo)
 
-//static ComponentDescription desc; // for FindNextComponent()
-static ComponentInstance ci=NULL; // codec handle
-//static CodecInfo cinfo;	// for ImageCodecGetCodecInfo()
-//Component prev=NULL;
-//ComponentResult cres; //
-static CodecCapabilities codeccap; // for decpar
-static CodecDecompressParams decpar; // for ImageCodecPreDecompress()
-//static ImageSubCodecDecompressCapabilities icap; // for ImageCodecInitialize()
+static mp_image_t* mpi;
 static Rect OutBufferRect;              //the dimensions of our GWorld
 
 static GWorldPtr OutBufferGWorld = NULL;//a GWorld is some kind of description for a drawing environment
 static ImageDescriptionHandle framedescHandle;
+static ImageSequence imageSeq;
 
 #ifndef CONFIG_QUICKTIME
 HMODULE   WINAPI LoadLibraryA(LPCSTR);
@@ -63,24 +57,26 @@ FARPROC   WINAPI GetProcAddress(HMODULE,
 int       WINAPI FreeLibrary(HMODULE);
 static    HINSTANCE qtime_qts; // handle to the preloaded quicktime.qts
 static    HMODULE handler;
-static    Component (*FindNextComponent)(Component prev,ComponentDescription* desc);
-static    OSErr (*GetComponentInfo)(Component prev,ComponentDescription* desc,Handle h1,Handle h2,Handle h3);
-static    long (*CountComponents)(ComponentDescription* desc);
 static    OSErr (*InitializeQTML)(long flags);
 static    OSErr (*EnterMovies)(void);
-static    ComponentInstance (*OpenComponent)(Component c);
-static    ComponentResult (*ImageCodecInitialize)(ComponentInstance ci,
-                                 ImageSubCodecDecompressCapabilities * cap);
-static    ComponentResult (*ImageCodecBeginBand)(ComponentInstance      ci,
-                                 CodecDecompressParams * params,
-                                 ImageSubCodecDecompressRecord * drp,
-                                 long                   flags);
-static    ComponentResult (*ImageCodecGetCodecInfo)(ComponentInstance      ci,
-                                 CodecInfo *            info);
-static    ComponentResult (*ImageCodecPreDecompress)(ComponentInstance      ci,
-                                 CodecDecompressParams * params);
-static    ComponentResult (*ImageCodecBandDecompress)(ComponentInstance      ci,
-                                 CodecDecompressParams * params);
+static    OSErr (*ExitMovies)(void);
+static    OSErr (*DecompressSequenceBegin)(ImageSequence *seqID,
+                                           ImageDescriptionHandle desc,
+                                           CGrafPtr port,
+                                           /*GDHandle*/void* gdh,
+                                           const Rect *srcRect,
+                                           MatrixRecordPtr matrix,
+                                           short mode,
+                                           RgnHandle mask,
+                                           CodecFlags flags,
+                                           CodecQ accuracy,
+                                           DecompressorComponent codec);
+static   OSErr (*DecompressSequenceFrameS)(ImageSequence seqID,
+                                           Ptr data,
+                                           long dataSize,
+                                           CodecFlags inFlags,
+                                           CodecFlags *outFlags,
+                                           ICMCompletionProcRecordPtr asyncCompletionProc);
 static    PixMapHandle    (*GetGWorldPixMap)(GWorldPtr offscreenGWorld);
 static    OSErr           (*QTNewGWorldFromPtr)(GWorldPtr *gw,
 			       OSType pixelFormat,
@@ -91,6 +87,9 @@ static    OSErr           (*QTNewGWorldF
                                void *baseAddr,
                                long rowBytes);
 static    Handle          (*NewHandleClear)(Size byteCount);
+static    void            (*DisposeHandle)(Handle h);
+static    void            (*DisposeGWorld)(GWorldPtr offscreenGWorld);
+static    OSErr           (*CDSequenceEnd)(ImageSequence seqID);
 #endif /* #ifndef CONFIG_QUICKTIME */
 
 // to set/get/query special features/parameters
@@ -98,24 +97,18 @@ static int control(sh_video_t *sh,int cm
     return CONTROL_UNKNOWN;
 }
 
-static int codec_initialized=0;
-
 // init driver
 static int init(sh_video_t *sh){
 #ifndef CONFIG_QUICKTIME
     OSErr result = 1;
 #endif
-    ComponentResult cres;
-    ComponentDescription desc;
-    Component prev=NULL;
-    CodecInfo cinfo;	// for ImageCodecGetCodecInfo()
-    ImageSubCodecDecompressCapabilities icap; // for ImageCodecInitialize()
 
-    codec_initialized = 0;
-#ifdef CONFIG_QUICKTIME
-    EnterMovies();
-#else
+    if (sh->ImageDesc == NULL) {
+        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"sh->ImageDesc not set, cannot use binary QuickTime codecs (try -demuxer mov?)\n");
+        return 0;
+    }
 
+#ifndef CONFIG_QUICKTIME
 #ifdef WIN32_LOADER
     Setup_LDT_Keeper();
 #endif
@@ -135,89 +128,29 @@ static int init(sh_video_t *sh){
 
     InitializeQTML = (OSErr (*)(long))GetProcAddress(handler, "InitializeQTML");
     EnterMovies = (OSErr (*)(void))GetProcAddress(handler, "EnterMovies");
-    FindNextComponent = (Component (*)(Component,ComponentDescription*))GetProcAddress(handler, "FindNextComponent");
-    CountComponents = (long (*)(ComponentDescription*))GetProcAddress(handler, "CountComponents");
-    GetComponentInfo = (OSErr (*)(Component,ComponentDescription*,Handle,Handle,Handle))GetProcAddress(handler, "GetComponentInfo");
-    OpenComponent = (ComponentInstance (*)(Component))GetProcAddress(handler, "OpenComponent");
-    ImageCodecInitialize = (ComponentResult (*)(ComponentInstance,ImageSubCodecDecompressCapabilities *))GetProcAddress(handler, "ImageCodecInitialize");
-    ImageCodecGetCodecInfo = (ComponentResult (*)(ComponentInstance,CodecInfo *))GetProcAddress(handler, "ImageCodecGetCodecInfo");
-    ImageCodecBeginBand = (ComponentResult (*)(ComponentInstance,CodecDecompressParams *,ImageSubCodecDecompressRecord *,long))GetProcAddress(handler, "ImageCodecBeginBand");
-    ImageCodecPreDecompress = (ComponentResult (*)(ComponentInstance,CodecDecompressParams *))GetProcAddress(handler, "ImageCodecPreDecompress");
-    ImageCodecBandDecompress = (ComponentResult (*)(ComponentInstance,CodecDecompressParams *))GetProcAddress(handler, "ImageCodecBandDecompress");
+    ExitMovies = (OSErr (*)(void))GetProcAddress(handler, "ExitMovies");
+    DecompressSequenceBegin = (OSErr (*)(ImageSequence*,ImageDescriptionHandle,CGrafPtr,void *,const Rect *,MatrixRecordPtr,short,RgnHandle,CodecFlags,CodecQ,DecompressorComponent))GetProcAddress(handler, "DecompressSequenceBegin");
+    DecompressSequenceFrameS = (OSErr (*)(ImageSequence,Ptr,long,CodecFlags,CodecFlags*,ICMCompletionProcRecordPtr))GetProcAddress(handler, "DecompressSequenceFrameS");
     GetGWorldPixMap = (PixMapHandle (*)(GWorldPtr))GetProcAddress(handler, "GetGWorldPixMap");
     QTNewGWorldFromPtr = (OSErr(*)(GWorldPtr *,OSType,const Rect *,CTabHandle,void*,GWorldFlags,void *,long))GetProcAddress(handler, "QTNewGWorldFromPtr");
     NewHandleClear = (OSErr(*)(Size))GetProcAddress(handler, "NewHandleClear");
-    //     = GetProcAddress(handler, "");
+    DisposeHandle = (void (*)(Handle))GetProcAddress(handler, "DisposeHandle");
+    DisposeGWorld = (void (*)(GWorldPtr))GetProcAddress(handler, "DisposeGWorld");
+    CDSequenceEnd = (OSErr (*)(ImageSequence))GetProcAddress(handler, "CDSequenceEnd");
 
-    if(!InitializeQTML || !EnterMovies || !FindNextComponent || !ImageCodecBandDecompress){
+    if(!InitializeQTML || !EnterMovies || !DecompressSequenceBegin || !DecompressSequenceFrameS){
 	mp_msg(MSGT_DECVIDEO,MSGL_ERR,"invalid qtmlClient.dll!\n");
 	return 0;
     }
 
-    result=InitializeQTML(6+16);
-//    result=InitializeQTML(0);
+    result=InitializeQTML(kInitializeQTMLDisableDirectSound |
+                          kInitializeQTMLUseGDIFlag |
+                          kInitializeQTMLDisableDDClippers);
     mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"InitializeQTML returned %d\n",result);
-//    result=EnterMovies();
-//    printf("EnterMovies->%d\n",result);
 #endif /* CONFIG_QUICKTIME */
 
-#if 0
-    memset(&desc,0,sizeof(desc));
-    while((prev=FindNextComponent(prev,&desc))){
-	ComponentDescription desc2;
-	unsigned char* c1=&desc2.componentType;
-	unsigned char* c2=&desc2.componentSubType;
-	memset(&desc2,0,sizeof(desc2));
-//	printf("juhee %p (%p)\n",prev,&desc);
-	GetComponentInfo(prev,&desc2,NULL,NULL,NULL);
-	mp_msg(MSGT_DECVIDEO,MSGL_DGB2,"DESC: %c%c%c%c/%c%c%c%c [0x%X/0x%X] 0x%X\n",
-	    c1[3],c1[2],c1[1],c1[0],
-	    c2[3],c2[2],c2[1],c2[0],
-	    desc2.componentType,desc2.componentSubType,
-	    desc2.componentFlags);
-    }
-#endif
-
-
-    memset(&desc,0,sizeof(desc));
-    desc.componentType= (((unsigned char)'i')<<24)|
-			(((unsigned char)'m')<<16)|
-			(((unsigned char)'d')<<8)|
-			(((unsigned char)'c'));
-#if 0
-    desc.componentSubType=
-		    (((unsigned char)'S'<<24))|
-			(((unsigned char)'V')<<16)|
-			(((unsigned char)'Q')<<8)|
-			(((unsigned char)'3'));
-#else
-    desc.componentSubType = bswap_32(sh->format);
-#endif
-    desc.componentManufacturer=0;
-    desc.componentFlags=0;
-    desc.componentFlagsMask=0;
-
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"Count = %ld\n",CountComponents(&desc));
-    prev=FindNextComponent(NULL,&desc);
-    if(!prev){
-	mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Cannot find requested component\n");
-	return 0;
-    }
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"Found it! ID = %p\n",prev);
-
-    ci=OpenComponent(prev);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ci=%p\n",ci);
-
-    memset(&icap,0,sizeof(icap));
-    cres=ImageCodecInitialize(ci,&icap);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecInitialize->%#x  size=%d (%d)\n",cres,icap.recordSize,icap.decompressRecordSize);
-
-    memset(&cinfo,0,sizeof(cinfo));
-    cres=ImageCodecGetCodecInfo(ci,&cinfo);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"Flags: compr: 0x%X  decomp: 0x%X format: 0x%X\n",
-	cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"Codec name: %.*s\n",((unsigned char*)&cinfo.typeName)[0],
-	((unsigned char*)&cinfo.typeName)+1);
+    result=EnterMovies();
+    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"EnterMovies returned %d\n",result);
 
     //make a yuy2 gworld
     OutBufferRect.top=0;
@@ -227,27 +160,14 @@ static int init(sh_video_t *sh){
 
     //Fill the imagedescription for our SVQ3 frame
     //we can probably get this from Demuxer
-#if 0
-    framedescHandle=(ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)+200);
-    printf("framedescHandle=%p  *p=%p\n",framedescHandle,*framedescHandle);
-{ FILE* f=fopen("/root/.wine/fake_windows/IDesc","r");
-  if(!f) printf("filenot found: IDesc\n");
-  fread(*framedescHandle,sizeof(ImageDescription)+200,1,f);
-  fclose(f);
-}
-#else
     if(!sh->ImageDesc) sh->ImageDesc=(sh->bih+1); // hack for SVQ3-in-AVI
     mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageDescription size: %d\n",((ImageDescription*)(sh->ImageDesc))->idSize);
     framedescHandle=(ImageDescriptionHandle)NewHandleClear(((ImageDescription*)(sh->ImageDesc))->idSize);
     memcpy(*framedescHandle,sh->ImageDesc,((ImageDescription*)(sh->ImageDesc))->idSize);
     dump_ImageDescription(*framedescHandle);
-#endif
-//Find codecscomponent for video decompression
-//    result = FindCodec ('SVQ1',anyCodec,&compressor,&decompressor );
-//    printf("FindCodec SVQ1 returned:%i compressor: 0x%X decompressor: 0x%X\n",result,compressor,decompressor);
 
+    (**framedescHandle).cType = bswap_32(sh->format);
     sh->context = (void *)kYUVSPixelFormat;
-#if 1
     {
 	int imgfmt = sh->codec->outfmt[sh->outfmtidx];
 	int qt_imgfmt;
@@ -263,7 +183,7 @@ static int init(sh_video_t *sh){
 	    qt_imgfmt = 0x79343230;
 	    break;
 	case IMGFMT_UYVY:
-	    qt_imgfmt = kUYVY422PixelFormat;
+	    qt_imgfmt = k2vuyPixelFormat;
 	    break;
 	case IMGFMT_YVYU:
 	    qt_imgfmt = kYVYU422PixelFormat;
@@ -289,45 +209,13 @@ static int init(sh_video_t *sh){
     sh->context = (void *)qt_imgfmt;
     if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,imgfmt)) return 0;
     }
-#else
-    if(!mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_YUY2)) return 0;
-#endif
-
-    return 1;
-}
-
-// uninit driver
-static void uninit(sh_video_t *sh){
-#ifdef CONFIG_QUICKTIME
-    ExitMovies();
-#endif
-}
-
-// decode a frame
-static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
-    OSErr result = 1;
-    int i;
-    mp_image_t* mpi;
-    ComponentResult cres;
-
-    if(len<=0) return NULL; // skipped frame
 
     mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_PRESERVE,
 	sh->disp_w, sh->disp_h);
-    if(!mpi) return NULL;
-
-#ifdef WIN32_LOADER
-    Setup_FS_Segment();
-#endif
-
-    decpar.data = (char*)data;
-    decpar.bufferSize = len;
-    (**framedescHandle).dataSize=len;
+    if(!mpi) return 0;
 
-if(!codec_initialized){
     result = QTNewGWorldFromPtr(
         &OutBufferGWorld,
-//        kYUVSPixelFormat, //pixel format of new GWorld == YUY2
 	(OSType)sh->context,
         &OutBufferRect,   //we should benchmark if yvu9 is faster for svq3, too
         0,
@@ -335,88 +223,63 @@ if(!codec_initialized){
         0,
         mpi->planes[0],
         mpi->stride[0]);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"NewGWorldFromPtr returned:%d\n",result);
-//    if (65536-(result&0xFFFF) != 10000)
-//	return NULL;
-
-//    printf("IDesc=%d\n",sizeof(ImageDescription));
-
-    decpar.imageDescription = framedescHandle;
-    decpar.startLine=0;
-    decpar.stopLine=(**framedescHandle).height;
-    decpar.frameNumber = 1; //1
-//    decpar.conditionFlags=0xFFD; // first
-//    decpar.callerFlags=0x2001; // first
-    decpar.matrixFlags = 0;
-    decpar.matrixType = 0;
-    decpar.matrix = 0;
-    decpar.capabilities=&codeccap;
-//    decpar.accuracy = 0x1680000; //codecNormalQuality;
-    decpar.accuracy = codecNormalQuality;
-//    decpar.port = OutBufferGWorld;
-//    decpar.preferredOffscreenPixelSize=17207;
-
-//    decpar.sequenceID=malloc(1000);
-//    memset(decpar.sequenceID,0,1000);
-
-//    SrcRect.top=17207;
-//    SrcRect.left=0;
-//    SrcRect.right=0;//image_width;
-//    SrcRect.bottom=0;//image_height;
-
-//    decpar.srcRect = SrcRect;
-    decpar.srcRect = OutBufferRect;
-
-    decpar.transferMode = srcCopy;
-    decpar.dstPixMap = **GetGWorldPixMap( OutBufferGWorld);//destPixmap;
-
-    cres=ImageCodecPreDecompress(ci,&decpar);
-    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecPreDecompress cres=0x%X\n",cres);
-
-    if(decpar.wantedDestinationPixelTypes)
-    { OSType *p=*(decpar.wantedDestinationPixelTypes);
-      if(p) while(*p){
-          mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"supported csp: 0x%08X %.4s\n",*p,(char *)p);
-	  ++p;
-      }
+    if (result) {
+        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"QTNewGWorldFromPtr result=%d\n",result);
+        return 0;
     }
 
+    result = DecompressSequenceBegin(&imageSeq, framedescHandle, (CGrafPtr)OutBufferGWorld,
+                                     NULL, NULL, NULL, srcCopy,  NULL, 0,
+                                     codecNormalQuality, 0);
+    if(result) {
+        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"DecompressSequenceBegin result=%d\n",result);
+        return 0;
+    }
 
-//    decpar.conditionFlags=0x10FFF; // first
-//    decpar.preferredOffscreenPixelSize=17207;
-
-//    decpar.conditionFlags=0x10FFD; // first
-
-//	cres=ImageCodecPreDecompress(ci,&decpar);
-//    printf("ImageCodecPreDecompress cres=0x%X\n",cres);
-
-
-    codec_initialized=1;
+    return 1;
 }
 
-#if 0
-    if(decpar.frameNumber==124){
-	decpar.frameNumber=1;
-	cres=ImageCodecPreDecompress(ci,&decpar);
-	mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecPreDecompress cres=0x%lX\n",cres);
+// uninit driver
+static void uninit(sh_video_t *sh){
+    OSErr result;
+    if(OutBufferGWorld) {
+        DisposeGWorld(OutBufferGWorld);
+        OutBufferGWorld = NULL;
     }
-#endif
+    if(framedescHandle) {
+        DisposeHandle((Handle)framedescHandle);
+        framedescHandle = NULL;
+    }
+    if(imageSeq) {
+        CDSequenceEnd(imageSeq);
+        imageSeq = 0;
+    }
+    result=ExitMovies();
+    mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ExitMovies returned %d\n",result);
+}
 
-    cres=ImageCodecBandDecompress(ci,&decpar);
+// decode a frame
+static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
+    OSErr result = 1;
+    CodecFlags ignore;
 
-    ++decpar.frameNumber;
+    if(len<=0) return NULL; // skipped frame
 
-    if(cres) {
-	mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecBandDecompress cres=0x%X (-0x%X) %d\n",cres,-cres,cres);
-	return NULL;
-    }
+#ifdef WIN32_LOADER
+    Setup_FS_Segment();
+#endif
 
-//    for(i=0;i<8;i++)
-//	printf("img_base[%d]=%p\n",i,((int*)decpar.dstPixMap.baseAddr)[i]);
+    result = DecompressSequenceFrameS(imageSeq, data, len, 0, &ignore, NULL);
+    if(result) {
+        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"DecompressSequenceFrameS result=0x%d\n",result);
+        return NULL;
+    }
 
 if((int)sh->context==0x73797639){	// Sorenson 16-bit YUV -> std YVU9
+    int i;
 
-    short *src0=(short *)((char*)decpar.dstPixMap.baseAddr+0x20);
+    PixMap dstPixMap = **GetGWorldPixMap(OutBufferGWorld);
+    short *src0=(short *)((char*)dstPixMap.baseAddr+0x20);
 
     for(i=0;i<mpi->h;i++){
 	int x;

Modified: trunk/loader/qtx/qtxsdk/components.h
==============================================================================
--- trunk/loader/qtx/qtxsdk/components.h	Mon Mar 15 10:32:53 2010	(r30898)
+++ trunk/loader/qtx/qtxsdk/components.h	Mon Mar 15 13:05:56 2010	(r30899)
@@ -29,6 +29,14 @@ typedef int32_t                         
 typedef void *GlobalsPtr;
 typedef void **Globals;
 
+enum {
+    kInitializeQTMLNoSoundFlag = (1L << 0),
+    kInitializeQTMLUseGDIFlag = (1L << 1),
+    kInitializeQTMLDisableDirectSound = (1L << 2),
+    kInitializeQTMLUseExclusiveFullScreenModeFlag = (1L << 3),
+    kInitializeQTMLDisableDDClippers = (1L << 4)
+};
+
 //==================== COMPONENTS ===========================
 
 struct __attribute__((__packed__)) ComponentParameters {


More information about the MPlayer-cvslog mailing list