typo fixes
[mplayer/greg.git] / libmpcodecs / ve_vfw.c
blob7dfc84a29cd8f8427270d194b87fa8baf4e660ea
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <inttypes.h>
7 #include "config.h"
8 #ifdef USE_WIN32DLL
10 #include "mp_msg.h"
11 #include "help_mp.h"
13 #include "codec-cfg.h"
14 //#include "stream.h"
15 //#include "demuxer.h"
16 //#include "stheader.h"
18 #include "loader.h"
19 //#include "wine/mmreg.h"
20 #include "wine/vfw.h"
21 #include "wine/avifmt.h"
23 #include "img_format.h"
24 #include "mp_image.h"
25 #include "vf.h"
27 #include "muxer.h"
29 //===========================================================================//
31 static char *vfw_param_codec = NULL;
33 #include "m_option.h"
35 m_option_t vfwopts_conf[]={
36 {"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL},
37 {NULL, NULL, 0, 0, 0, 0, NULL}
40 struct vf_priv_s {
41 muxer_stream_t* mux;
42 BITMAPINFOHEADER* bih;
45 static HIC encoder_hic;
46 static void* encoder_buf=NULL;
47 static int encoder_buf_size=0;
48 static int encoder_frameno=0;
50 //int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih)
51 static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc)
53 HRESULT ret;
54 BITMAPINFOHEADER* output_bih=NULL;
55 int temp_len;
57 //sh_video = malloc(sizeof(sh_video_t));
59 mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n");
61 // memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER));
62 // output_bih->biSize = sizeof(BITMAPINFOHEADER);
64 // encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS);
65 encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS);
66 if(!encoder_hic){
67 mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n");
68 return NULL;
70 mp_msg(MSGT_WIN32,MSGL_INFO,"HIC: %x\n", encoder_hic);
72 #if 1
74 ICINFO icinfo;
76 ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO));
77 mp_msg(MSGT_WIN32,MSGL_INFO,"%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO));
78 mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorType, icinfo.fccType);
79 mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorSubtype, icinfo.fccHandler);
80 mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_CompressorFlags,
81 icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM);
82 //printf("Compressor name: %s\n", icinfo.szName);
83 //printf("Compressor description: %s\n", icinfo.szDescription);
85 mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Flags);
86 if (icinfo.dwFlags & VIDCF_QUALITY)
87 mp_msg(MSGT_WIN32,MSGL_INFO,MSGTR_MPCODECS_Quality);
88 if (icinfo.dwFlags & VIDCF_FASTTEMPORALD)
89 mp_msg(MSGT_WIN32,MSGL_INFO," fast-decompr");
90 if (icinfo.dwFlags & VIDCF_QUALITYTIME)
91 mp_msg(MSGT_WIN32,MSGL_INFO," temp-quality");
92 mp_msg(MSGT_WIN32,MSGL_INFO,"\n");
94 #endif
96 temp_len = ICCompressGetFormatSize(encoder_hic, input_bih);
97 mp_msg(MSGT_WIN32,MSGL_INFO,"ICCompressGetFormatSize ret: %d\n", temp_len);
99 if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER);
101 output_bih = malloc(temp_len+4);
102 memset(output_bih,0,temp_len);
103 output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER);
105 return output_bih;
108 static int vfw_start_encoder(BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih){
109 HRESULT ret;
110 int temp_len=output_bih->biSize;
111 int i;
113 ret = ICCompressGetFormat(encoder_hic, input_bih, output_bih);
114 if(ret < 0){
115 unsigned char* temp=(unsigned char*)output_bih;
116 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressGetFormat failed: Error %d (0x%X)\n", (int)ret, (int)ret);
117 for (i=0; i < temp_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", temp[i]);
118 return 0;
120 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressGetFormat OK\n");
122 if (temp_len > sizeof(BITMAPINFOHEADER))
124 unsigned char* temp=(unsigned char*)output_bih;
125 mp_msg(MSGT_WIN32, MSGL_V, "Extra info in o_bih (%d bytes)!\n",
126 temp_len-sizeof(BITMAPINFOHEADER));
127 for(i=sizeof(output_bih);i<temp_len;i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02X ",temp[i]);
130 // if( mp_msg_test(MSGT_WIN32,MSGL_V) ) {
131 printf("Starting compression:\n");
132 printf(" Input format:\n");
133 printf(" biSize %d\n", input_bih->biSize);
134 printf(" biWidth %d\n", input_bih->biWidth);
135 printf(" biHeight %d\n", input_bih->biHeight);
136 printf(" biPlanes %d\n", input_bih->biPlanes);
137 printf(" biBitCount %d\n", input_bih->biBitCount);
138 printf(" biCompression 0x%x ('%.4s')\n", input_bih->biCompression, (char *)&input_bih->biCompression);
139 printf(" biSizeImage %d\n", input_bih->biSizeImage);
140 printf(" Output format:\n");
141 printf(" biSize %d\n", output_bih->biSize);
142 printf(" biWidth %d\n", output_bih->biWidth);
143 printf(" biHeight %d\n", output_bih->biHeight);
144 printf(" biPlanes %d\n", output_bih->biPlanes);
145 printf(" biBitCount %d\n", output_bih->biBitCount);
146 printf(" biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
147 printf(" biSizeImage %d\n", output_bih->biSizeImage);
148 // }
150 output_bih->biWidth=input_bih->biWidth;
151 output_bih->biHeight=input_bih->biHeight;
153 ret = ICCompressQuery(encoder_hic, input_bih, output_bih);
154 if(ret){
155 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressQuery failed: Error %d\n", (int)ret);
156 return 0;
157 } else
158 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressQuery OK\n");
160 ret = ICCompressBegin(encoder_hic, input_bih, output_bih);
161 if(ret){
162 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressBegin failed: Error %d\n", (int)ret);
163 // return 0;
164 } else
165 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressBegin OK\n");
166 mp_msg(MSGT_WIN32,MSGL_INFO," Output format after query/begin:\n");
167 mp_msg(MSGT_WIN32,MSGL_INFO," biSize %d\n", output_bih->biSize);
168 mp_msg(MSGT_WIN32,MSGL_INFO," biWidth %d\n", output_bih->biWidth);
169 mp_msg(MSGT_WIN32,MSGL_INFO," biHeight %d\n", output_bih->biHeight);
170 mp_msg(MSGT_WIN32,MSGL_INFO," biPlanes %d\n", output_bih->biPlanes);
171 mp_msg(MSGT_WIN32,MSGL_INFO," biBitCount %d\n", output_bih->biBitCount);
172 mp_msg(MSGT_WIN32,MSGL_INFO," biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
173 mp_msg(MSGT_WIN32,MSGL_INFO," biSizeImage %d\n", output_bih->biSizeImage);
175 encoder_buf_size=input_bih->biSizeImage;
176 encoder_buf=malloc(encoder_buf_size);
177 encoder_frameno=0;
179 mp_msg(MSGT_WIN32,MSGL_V,"VIDEO CODEC Init OK!!! ;-)\n");
180 return 1;
183 static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf,
184 BITMAPINFOHEADER* biInput,void* Image,
185 long* keyframe, int quality){
186 HRESULT ret;
188 //long VFWAPIV ICCompress(
189 // HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpOutputBuf,
190 // LPBITMAPINFOHEADER lpbiInput,void* lpImage,long* lpckid,
191 // long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
192 // LPBITMAPINFOHEADER lpbiInputPrev,void* lpImagePrev
193 //);
195 // printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);
197 ret=ICCompress(encoder_hic, 0,
198 biOutput, OutBuf,
199 biInput, Image,
200 NULL, keyframe, encoder_frameno, 0, quality,
201 biInput, encoder_buf);
203 // printf("ok. size=%d\n",biOutput->biSizeImage);
205 memcpy(encoder_buf,Image,encoder_buf_size);
206 ++encoder_frameno;
208 return (int)ret;
210 #define mux_v (vf->priv->mux)
211 #define vfw_bih (vf->priv->bih)
213 static int config(struct vf_instance_s* vf,
214 int width, int height, int d_width, int d_height,
215 unsigned int flags, unsigned int outfmt){
217 vfw_bih->biWidth=width;
218 vfw_bih->biHeight=height;
219 vfw_bih->biSizeImage=width*height*((vfw_bih->biBitCount+7)/8);
220 mux_v->aspect = (float)d_width/d_height;
222 if(!vfw_start_encoder(vfw_bih, mux_v->bih)) return 0;
224 // mux_v->bih->biWidth=width;
225 // mux_v->bih->biHeight=height;
226 // mux_v->bih->biSizeImage=width*height*((mux_v->bih->biBitCount+7)/8);
228 return 1;
231 static int control(struct vf_instance_s* vf, int request, void* data){
233 return CONTROL_UNKNOWN;
236 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
237 if(fmt==IMGFMT_BGR24) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_FLIPPED;
238 return 0;
241 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
242 long flags=0;
243 int ret;
244 // flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack
245 ret=vfw_encode_frame(mux_v->bih, mux_v->buffer, vfw_bih, mpi->planes[0], &flags, 10000);
246 muxer_write_chunk(mux_v,mux_v->bih->biSizeImage,flags, pts, pts);
247 return 1;
250 //===========================================================================//
252 static int vf_open(vf_instance_t *vf, char* args){
253 vf->config=config;
254 vf->default_caps=VFCAP_CONSTANT;
255 vf->control=control;
256 vf->query_format=query_format;
257 vf->put_image=put_image;
258 vf->priv=malloc(sizeof(struct vf_priv_s));
259 memset(vf->priv,0,sizeof(struct vf_priv_s));
260 vf->priv->mux=(muxer_stream_t*)args;
262 vfw_bih=calloc(1, sizeof(BITMAPINFOHEADER));
263 vfw_bih->biSize=sizeof(BITMAPINFOHEADER);
264 vfw_bih->biWidth=0; // FIXME ?
265 vfw_bih->biHeight=0;
266 vfw_bih->biPlanes=1;
267 vfw_bih->biBitCount=24;
268 vfw_bih->biCompression=0;
269 // vfw_bih->biSizeImage=vo_w*vo_h*((vfw_bih->biBitCount+7)/8);
271 if (!vfw_param_codec)
273 mp_msg(MSGT_WIN32,MSGL_WARN, MSGTR_MPCODECS_NoVfwCodecSpecified);
274 return 0;
276 // mux_v->bih=vfw_open_encoder("divxc32.dll",vfw_bih,mmioFOURCC('D', 'I', 'V', '3'));
277 // mux_v->bih=vfw_open_encoder("AvidAVICodec.dll",vfw_bih, 0);
278 mux_v->bih = vfw_open_encoder(vfw_param_codec, vfw_bih, 0);
279 if(!mux_v->bih) return 0;
281 return 1;
284 vf_info_t ve_info_vfw = {
285 "Win32/VfW encoders",
286 "vfw",
287 "A'rpi",
288 "for internal use by mencoder",
289 vf_open
292 //===========================================================================//
293 #endif