summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-16 01:49:39 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-12-16 01:49:39 +0000
commit8dc0ce2adeea383c89cc96e305ab0a7c3d06f7fa (patch)
treeba3f14497f333f5bfd69b23fa89b618969473b8f
parent6b9defb1fb52947379d39150cd669fc7d589307d (diff)
downloadmpv-8dc0ce2adeea383c89cc96e305ab0a7c3d06f7fa.tar.bz2
mpv-8dc0ce2adeea383c89cc96e305ab0a7c3d06f7fa.tar.xz
Sorenson 1/3 encoding just for fun :)
ve_qtvideo code by Sascha Sommer SVQ3 support hack by /me git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@8472 b3059339-0415-0410-9bf9-f77b7e298cf2
-rw-r--r--cfg-mencoder.h2
-rw-r--r--libmpcodecs/Makefile2
-rw-r--r--libmpcodecs/vd_qtvideo.c2
-rw-r--r--libmpcodecs/ve.c2
-rw-r--r--libmpcodecs/ve_qtvideo.c325
-rw-r--r--mencoder.c3
6 files changed, 335 insertions, 1 deletions
diff --git a/cfg-mencoder.h b/cfg-mencoder.h
index 2bc9f6a59d..2e547b8e0b 100644
--- a/cfg-mencoder.h
+++ b/cfg-mencoder.h
@@ -59,6 +59,7 @@ struct config ovc_conf[]={
{"vfw", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_VFW, NULL},
{"libdv", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_LIBDV, NULL},
{"xvid", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_XVID, NULL},
+ {"qtvideo", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_QTVIDEO, NULL},
{"help", "\nAvailable codecs:\n"
" copy - frame copy, without re-encoding. doesn't work with filters!\n"
" frameno - special audio-only file for 3-pass encoding, see DOCS!\n"
@@ -71,6 +72,7 @@ struct config ovc_conf[]={
#endif
#ifdef USE_WIN32DLL
" vfw - using VfW DLLs, currently only AVID is supported\n"
+ " qtvideo - using Quickime DLLs, currently only SVQ1/3 are supported\n"
#endif
#ifdef HAVE_LIBDV095
" libdv - DV encoding using libdv v0.9.5\n"
diff --git a/libmpcodecs/Makefile b/libmpcodecs/Makefile
index 6b1074b095..f376015e30 100644
--- a/libmpcodecs/Makefile
+++ b/libmpcodecs/Makefile
@@ -15,7 +15,7 @@ VIDEO_SRCS_OPT=vd_realvid.c vd_ffmpeg.c vd_dshow.c vd_dmo.c vd_vfw.c vd_vfwex.c
VIDEO_SRCS=dec_video.c vd.c $(VIDEO_SRCS_NAT) $(VIDEO_SRCS_LIB) $(VIDEO_SRCS_OPT)
VFILTER_SRCS=vf.c vf_vo.c vf_crop.c vf_expand.c vf_pp.c vf_scale.c vf_format.c vf_yuy2.c vf_flip.c vf_rgb2bgr.c vf_rotate.c vf_mirror.c vf_palette.c vf_lavc.c vf_dvbscale.c vf_cropdetect.c vf_test.c vf_noise.c vf_yvu9.c vf_rectangle.c vf_lavcdeint.c vf_eq.c vf_eq2.c vf_halfpack.c vf_dint.c vf_1bpp.c vf_bmovl.c vf_2xsai.c vf_unsharp.c vf_swapuv.c vf_il.c vf_boxblur.c vf_sab.c vf_smartblur.c vf_perspective.c
-ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c ve_xvid.c
+ENCODER_SRCS=ve.c ve_divx4.c ve_lavc.c ve_vfw.c ve_rawrgb.c ve_libdv.c ve_xvid.c ve_qtvideo.c
NATIVE_SRCS=native/RTjpegN.c native/cinepak.c native/cyuv.c native/fli.c native/minilzo.c native/msvidc.c native/nuppelvideo.c native/qtrle.c native/qtrpza.c native/qtsmc.c native/roqav.c native/xa_gsm.c native/svq1.c
diff --git a/libmpcodecs/vd_qtvideo.c b/libmpcodecs/vd_qtvideo.c
index 6bb39952fc..041ca070b1 100644
--- a/libmpcodecs/vd_qtvideo.c
+++ b/libmpcodecs/vd_qtvideo.c
@@ -206,9 +206,11 @@ static int init(sh_video_t *sh){
fclose(f);
}
#else
+ if(!sh->ImageDesc) sh->ImageDesc=(sh->bih+1); // hack for SVQ3-in-AVI
printf("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 );
diff --git a/libmpcodecs/ve.c b/libmpcodecs/ve.c
index 1dee6ac7c5..70041c3dde 100644
--- a/libmpcodecs/ve.c
+++ b/libmpcodecs/ve.c
@@ -15,6 +15,7 @@ extern vf_info_t ve_info_vfw;
extern vf_info_t ve_info_rawrgb;
extern vf_info_t ve_info_libdv;
extern vf_info_t ve_info_xvid;
+extern vf_info_t ve_info_qtvideo;
static vf_info_t* encoder_list[]={
#ifdef HAVE_DIVX4ENCORE
@@ -25,6 +26,7 @@ static vf_info_t* encoder_list[]={
#endif
#ifdef USE_WIN32DLL
&ve_info_vfw,
+ &ve_info_qtvideo,
#endif
#ifdef HAVE_LIBDV095
&ve_info_libdv,
diff --git a/libmpcodecs/ve_qtvideo.c b/libmpcodecs/ve_qtvideo.c
new file mode 100644
index 0000000000..d9d1356c50
--- /dev/null
+++ b/libmpcodecs/ve_qtvideo.c
@@ -0,0 +1,325 @@
+/*qt video encoder using win32 libs
+ released under gnu gpl
+ (C)Sascha Sommer */
+
+#define MAX_IDSIZE 0x6F
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../config.h"
+#include "../mp_msg.h"
+#include "../bswap.h"
+
+#ifdef USE_QTX_CODECS
+#include "../loader/qtx/qtxsdk/components.h"
+#include "wine/windef.h"
+
+#include "codec-cfg.h"
+#include "stream.h"
+#include "demuxer.h"
+#include "stheader.h"
+
+#include "aviwrite.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+HMODULE WINAPI LoadLibraryA(LPCSTR);
+FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR);
+int WINAPI FreeLibrary(HMODULE);
+static HMODULE handler;
+
+static OSErr (*FindCodec)(CodecType cType,
+ CodecComponent specCodec,
+ CompressorComponent * compressor,
+ DecompressorComponent * decompressor);
+static OSErr (*InitializeQTML)(long flags);
+static PixMapHandle (*GetGWorldPixMap)(GWorldPtr offscreenGWorld);
+static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
+ OSType pixelFormat,
+ const Rect *boundsRect,
+ CTabHandle cTable,
+ /*GDHandle*/void* aGDevice, /*unused anyway*/
+ GWorldFlags flags,
+ void *baseAddr,
+ long rowBytes);
+static OSErr (*NewHandleClear)(Size byteCount);
+static OSErr (*CompressSequenceBegin) (
+ ImageSequence *seqID,
+ PixMapHandle src,
+ PixMapHandle prev,
+ const Rect *srcRect,
+ const Rect *prevRect,
+ short colorDepth,
+ CodecType cType,
+ CompressorComponent codec,
+ CodecQ spatialQuality,
+ CodecQ temporalQuality,
+ long keyFrameRate,
+ CTabHandle ctable,
+ CodecFlags flags,
+ ImageDescriptionHandle desc );
+
+static OSErr (*CompressSequenceFrame) (
+ ImageSequence seqID,
+ PixMapHandle src,
+ const Rect *srcRect,
+ CodecFlags flags,
+ Ptr data,
+ long *dataSize,
+ UInt8 *similarity,
+ ICMCompletionProcRecordPtr asyncCompletionProc );
+
+static OSErr (*GetMaxCompressionSize)(PixMapHandle src,
+ const Rect *srcRect,
+ short colorDepth,
+ CodecQ quality,
+ CodecType cType,
+ CompressorComponent codec,
+ long *size );
+static OSErr (*CDSequenceEnd)( ImageSequence seqID );
+static Component (*FindNextComponent)(Component prev,ComponentDescription* desc);
+static long (*CountComponents)(ComponentDescription* desc);
+static OSErr (*GetComponentInfo)(Component prev,ComponentDescription* desc,Handle h1,Handle h2,Handle h3);
+
+
+extern void mencoder_write_chunk(aviwrite_stream_t *s,int len,unsigned int flags);
+
+
+//static int format=mmioFOURCC('S','V','Q','1');
+static int format=mmioFOURCC('S','V','Q','3');
+
+
+
+//static void *frame_in; //input frame
+static void *frame_prev; //previous frame
+static void *frame_comp; //compressed frame
+static GWorldPtr frame_GWorld_in = NULL;//a GWorld is some kind of description for a drawing environment
+static GWorldPtr frame_GWorld_prev = NULL;
+static Rect FrameRect;
+
+static CompressorComponent compressor;
+static DecompressorComponent decompressor;
+static ImageDescriptionHandle desc;
+static ImageSequence seq;
+
+
+
+
+
+struct vf_priv_s {
+ aviwrite_stream_t* mux;
+ //dv_encoder_t* enc;
+
+};
+#define mux_v (vf->priv->mux)
+
+//===========================================================================//
+
+static int config(struct vf_instance_s* vf,
+ int width, int height, int d_width, int d_height,
+ unsigned int flags, unsigned int outfmt){
+ OSErr cres;
+ ComponentDescription cdesc;
+ mux_v->bih->biWidth=width;
+ mux_v->bih->biHeight=height;
+ mux_v->bih->biSizeImage=width*height*2;
+
+
+
+ memset(&desc,0,sizeof(cdesc));
+ cdesc.componentType= (((unsigned char)'i')<<24)|
+ (((unsigned char)'m')<<16)|
+ (((unsigned char)'c')<<8)|
+ (((unsigned char)'o'));
+
+ cdesc.componentSubType=bswap_32(format);
+ cdesc.componentManufacturer=0;
+ cdesc.componentFlags=0;
+ cdesc.componentFlagsMask=0;
+
+
+ printf("Count = %d\n",CountComponents(&cdesc));
+ compressor=FindNextComponent(NULL,&cdesc);
+ if(!compressor){
+ printf("Cannot find requested component\n");
+ return(0);
+ }
+ printf("Found it! ID = 0x%X\n",compressor);
+
+// cres= FindCodec (fourcc,anyCodec,&compressor,&decompressor );
+// printf("FindCodec returned:%i compressor: 0x%X decompressor: 0x%X\n",cres&0xFFFF,compressor,decompressor);
+
+ return 1;
+}
+
+static int control(struct vf_instance_s* vf, int request, void* data){
+
+ return CONTROL_UNKNOWN;
+}
+
+static int query_format(struct vf_instance_s* vf, unsigned int fmt){
+ if(fmt==IMGFMT_YUY2) return 3;
+ return 0;
+}
+
+static int codec_inited = 0;
+
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
+
+ OSErr cres;
+ long framesizemax;
+ UInt8 similarity;
+ long compressedsize;
+ int in_format=kYUVSPixelFormat;
+ int width = mpi->width;
+ int height = mpi->height;
+ int stride = width*2;
+if(!codec_inited){
+ FrameRect.top=0;
+ FrameRect.left=0;
+ FrameRect.right=width;
+ FrameRect.bottom=height;
+ cres = QTNewGWorldFromPtr(
+ &frame_GWorld_in,
+ in_format,
+ &FrameRect,
+ 0,
+ 0,
+ 0,
+ mpi->planes[0],
+ stride);
+ printf("NewGWorldFromPtr returned:%i\n",cres&0xFFFF);
+ //dunno what todo about this
+ frame_prev = malloc(stride * height);
+ cres = QTNewGWorldFromPtr(
+ &frame_GWorld_prev,
+ in_format,
+ &FrameRect,
+ 0,
+ 0,
+ 0,
+ frame_prev,
+ stride);
+ printf("height:%i width:%i stride:%i\n",height,width,stride);
+ printf("NewGWorldFromPtr returned:%i\n",cres&0xFFFF);
+ cres= GetMaxCompressionSize (
+ GetGWorldPixMap(frame_GWorld_in),
+ &FrameRect,
+ 24,
+ codecNormalQuality,
+ bswap_32(format),
+ compressor,
+ &framesizemax );
+ printf("GetMaxCompressionSize returned:%i : MaxSize:%i\n",cres&0xFFFF,framesizemax);
+ frame_comp=malloc(framesizemax);
+ desc = (ImageDescriptionHandle)NewHandleClear(MAX_IDSIZE); //memory where the desc will be stored
+ (*desc)->idSize=MAX_IDSIZE;
+
+ cres= CompressSequenceBegin (
+ &seq,
+ GetGWorldPixMap( frame_GWorld_in),
+ GetGWorldPixMap( frame_GWorld_prev),
+ &FrameRect,
+ &FrameRect,
+ 24, // color depth
+ bswap_32(format), // fourcc
+ compressor, // codec component
+ codecNormalQuality, //codecNormalQuality,
+ codecMaxQuality, //codecNormalQuality,
+ 10*25, // keyframe rate
+ 0,
+ 0,
+ desc);
+ printf("CompressSequenceBegin returned:%i\n",cres&0xFFFF);
+ printf("Sequence ID:%i\n",seq);
+
+ dump_ImageDescription(*desc);
+ codec_inited++;
+}
+ cres = CompressSequenceFrame (
+ seq,
+ GetGWorldPixMap(frame_GWorld_in),
+ &FrameRect,
+ 0,
+ (char*)mux_v->buffer,
+ &compressedsize,
+ &similarity,
+ 0);
+
+ if(cres&0xFFFF)printf("CompressSequenceFrame returned:%i\n",cres&0xFFFF);
+ printf("Size %i->%i \n",stride*height,compressedsize);
+#if 0
+ printf("Ratio: %i:1\n",(stride*height)/compressedsize);
+#endif
+ mencoder_write_chunk(mux_v, compressedsize , 0x10);
+
+ if(((*desc)->idSize)>MAX_IDSIZE){
+ printf("FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc)->idSize));
+ } else {
+ // according to QT docs, imagedescription may be changed while encoding
+ // a frame (even its size may (and does!) change!)
+ memcpy(mux_v->bih+1,*desc,(*desc)->idSize);
+ }
+
+ return 1;
+}
+
+//===========================================================================//
+
+static int vf_open(vf_instance_t *vf, char* args){
+ OSErr cres = 1;
+ vf->config=config;
+ vf->control=control;
+ vf->query_format=query_format;
+ vf->put_image=put_image;
+ vf->priv=malloc(sizeof(struct vf_priv_s));
+ memset(vf->priv,0,sizeof(struct vf_priv_s));
+ vf->priv->mux=(aviwrite_stream_t*)args;
+
+ mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+MAX_IDSIZE);
+ mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+MAX_IDSIZE;
+ mux_v->bih->biWidth=0;
+ mux_v->bih->biHeight=0;
+ mux_v->bih->biCompression=format;
+ mux_v->bih->biPlanes=1;
+ mux_v->bih->biBitCount=24;
+
+
+ Setup_LDT_Keeper();
+ handler = LoadLibraryA("qtmlClient.dll");
+ InitializeQTML = GetProcAddress(handler, "InitializeQTML");
+ GetGWorldPixMap = GetProcAddress(handler, "GetGWorldPixMap");
+ QTNewGWorldFromPtr = GetProcAddress(handler, "QTNewGWorldFromPtr");
+ NewHandleClear = GetProcAddress(handler, "NewHandleClear");
+ FindCodec = GetProcAddress(handler,"FindCodec");
+ CompressSequenceBegin = GetProcAddress(handler,"CompressSequenceBegin");
+ CompressSequenceFrame = GetProcAddress(handler,"CompressSequenceFrame");
+ GetMaxCompressionSize = GetProcAddress(handler,"GetMaxCompressionSize");
+ CDSequenceEnd = GetProcAddress(handler,"CDSequenceEnd");
+ FindNextComponent = GetProcAddress(handler, "FindNextComponent");
+ CountComponents = GetProcAddress(handler, "CountComponents");
+ GetComponentInfo = GetProcAddress(handler, "GetComponentInfo");
+ if(!InitializeQTML ||!CompressSequenceBegin){
+ printf("invalid qt DLL!\n");
+ return 0;
+ }
+ //printf("%i,%i,%i\n",mmioFOURCC('S','V','Q','1'),'SVQ1',bswap_32(mmioFOURCC('S','V','Q','1')));
+ cres=InitializeQTML(6+16);
+ printf("InitializeQTML returned %i\n",cres);
+ return 1;
+}
+
+vf_info_t ve_info_qtvideo = {
+ "Quicktime video encoder using win32 DLLs",
+ "qtvideo",
+ "Sascha Sommer",
+ "for internal use by mencoder",
+ vf_open
+};
+
+//===========================================================================//
+#endif
diff --git a/mencoder.c b/mencoder.c
index 91ef4c28c6..cea4278430 100644
--- a/mencoder.c
+++ b/mencoder.c
@@ -7,6 +7,7 @@
#define VCODEC_VFW 7
#define VCODEC_LIBDV 8
#define VCODEC_XVID 9
+#define VCODEC_QTVIDEO 10
#define ACODEC_COPY 0
#define ACODEC_PCM 1
@@ -659,6 +660,8 @@ default:
sh_video->vfilter=vf_open_encoder(NULL,"libdv",(char *)mux_v); break;
case VCODEC_XVID:
sh_video->vfilter=vf_open_encoder(NULL,"xvid",(char *)mux_v); break;
+ case VCODEC_QTVIDEO:
+ sh_video->vfilter=vf_open_encoder(NULL,"qtvideo",(char *)mux_v); break;
}
if(!mux_v->bih || !sh_video->vfilter){
mp_msg(MSGT_MENCODER,MSGL_FATAL,MSGTR_EncoderOpenFailed);