[MPlayer-dev-eng] [PATCH] add AIC and ProRes422 binary codec support
Andrew Wason
rectalogic at rectalogic.com
Fri Jul 31 15:49:21 CEST 2009
This patch adds support for the QuickTime binary codecs for AIC (Apple
Intermediate Codec) and ProRes422, currently only on Mac though.
It requires the use of "-demuxer mov" since the lavf mov demuxer does
not fill in the ImageDescription.
I've only tested this on Mac, and in fact AIC will only work on Mac
since Apple doesn't even support AIC on any other platform. I think
more work will be needed in the binary codecs loader before ProRes
will work on Linux.
I had to change vd_qtvideo.c to use the QT decompression sequence APIs
(DecompressSequenceFrameS) instead of ImageCodecBandDecompress.
ImageCodecBandDecompress fails for both these codecs and Apple says it
is not intended to be called directly by applications. They recommend
using the decompression session APIs
(ICMDecompressionSessionDecodeFrame) or the older decompression
sequence APIs (DecompressSequenceFrameS).
I think changes will be needed in loader/qtx to support these QT
decompression APIs on Linux. So this patch is not ready for
primetime, but might be useful as a starting point.
Andrew
-------------- next part --------------
Index: libmpcodecs/vd_qtvideo.c
===================================================================
--- libmpcodecs/vd_qtvideo.c (revision 29461)
+++ libmpcodecs/vd_qtvideo.c (working copy)
@@ -27,17 +27,15 @@
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 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);
@@ -45,24 +43,25 @@
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 (*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,
@@ -73,6 +72,9 @@
void *baseAddr,
long rowBytes);
static OSErr (*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
@@ -87,12 +89,6 @@
#ifndef CONFIG_QUICKTIME
long 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();
@@ -117,21 +113,17 @@
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");
+ 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");
+ 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;
}
@@ -143,64 +135,6 @@
// 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);
-
//make a yuy2 gworld
OutBufferRect.top=0;
OutBufferRect.left=0;
@@ -219,7 +153,7 @@
}
#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);
+ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageDescription size: %ld\n",((ImageDescription*)(sh->ImageDesc))->idSize);
framedescHandle=(ImageDescriptionHandle)NewHandleClear(((ImageDescription*)(sh->ImageDesc))->idSize);
memcpy(*framedescHandle,sh->ImageDesc,((ImageDescription*)(sh->ImageDesc))->idSize);
dump_ImageDescription(*framedescHandle);
@@ -228,6 +162,7 @@
// 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
{
@@ -245,7 +180,7 @@
qt_imgfmt = 0x79343230;
break;
case IMGFMT_UYVY:
- qt_imgfmt = kUYVY422PixelFormat;
+ qt_imgfmt = k2vuyPixelFormat;
break;
case IMGFMT_YVYU:
qt_imgfmt = kYVYU422PixelFormat;
@@ -280,6 +215,18 @@
// uninit driver
static void uninit(sh_video_t *sh){
+ if(OutBufferGWorld) {
+ DisposeGWorld(OutBufferGWorld);
+ OutBufferGWorld = NULL;
+ }
+ if(framedescHandle) {
+ DisposeHandle((Handle)framedescHandle);
+ framedescHandle = NULL;
+ }
+ if(imageSeq) {
+ CDSequenceEnd(imageSeq);
+ imageSeq = 0;
+ }
#ifdef CONFIG_QUICKTIME
ExitMovies();
#endif
@@ -290,7 +237,7 @@
long result = 1;
int i;
mp_image_t* mpi;
- ComponentResult cres;
+ CodecFlags ignore;
if(len<=0) return NULL; // skipped frame
@@ -298,10 +245,6 @@
sh->disp_w, sh->disp_h);
if(!mpi) return NULL;
- decpar.data = (char*)data;
- decpar.bufferSize = len;
- (**framedescHandle).dataSize=len;
-
if(!codec_initialized){
result = QTNewGWorldFromPtr(
&OutBufferGWorld,
@@ -319,56 +262,14 @@
// 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;
- }
+ result = DecompressSequenceBegin(&imageSeq, framedescHandle, OutBufferGWorld,
+ NULL, NULL, NULL, srcCopy, NULL, 0,
+ codecNormalQuality, 0);
+ if(result) {
+ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"DecompressSequenceBegin result=%ld\n",65536-(result&0xffff));
+ return NULL;
}
-
-// 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;
}
@@ -380,12 +281,9 @@
}
#endif
- cres=ImageCodecBandDecompress(ci,&decpar);
-
- ++decpar.frameNumber;
-
- if(cres&0xFFFF){
- mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"ImageCodecBandDecompress cres=0x%X (-0x%X) %d\n",cres,-cres,cres);
+ result = DecompressSequenceFrameS(imageSeq, data, len, 0, &ignore, NULL);
+ if(result) {
+ mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"DecompressSequenceFrameS result=%ld\n",65536-(result&0xffff));
return NULL;
}
@@ -394,7 +292,8 @@
if((int)sh->context==0x73797639){ // Sorenson 16-bit YUV -> std YVU9
- 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;
Index: etc/codecs.conf
===================================================================
--- etc/codecs.conf (revision 29461)
+++ etc/codecs.conf (working copy)
@@ -2495,6 +2495,24 @@
out BGR32,BGR24,BGR8,Y800,RGB32,RGB24,RGB8
out YV12,YUY2
+videocodec qtaic
+ info "QuickTime AIC video decoder"
+ status untested
+ fourcc icod
+ driver qtvideo
+ dll "QuickTime.qts"
+ out UYVY
+
+videocodec qtprores
+ info "QuickTime ProRes 422 video decoder"
+ status untested
+ fourcc apcn
+ fourcc apch
+ fourcc apcs
+ driver qtvideo
+ dll "AppleProResDecoder.qtx"
+ out UYVY
+
; VSS codecs (http://vsofts.com/solutions.html):
videocodec vsslight
More information about the MPlayer-dev-eng
mailing list