5550
|
1 #include <stdio.h>
|
|
2 #include <stdlib.h>
|
|
3 #include <string.h>
|
7238
|
4 #include <unistd.h>
|
8585
|
5 #include <inttypes.h>
|
5550
|
6
|
|
7 #include "../config.h"
|
|
8 #ifdef USE_WIN32DLL
|
|
9
|
|
10 #include "../mp_msg.h"
|
|
11
|
|
12 #include "codec-cfg.h"
|
7231
|
13 //#include "stream.h"
|
|
14 //#include "demuxer.h"
|
|
15 //#include "stheader.h"
|
|
16
|
|
17 #include "loader.h"
|
|
18 //#include "wine/mmreg.h"
|
|
19 #include "wine/vfw.h"
|
|
20 #include "wine/avifmt.h"
|
5550
|
21
|
5607
|
22 #include "img_format.h"
|
|
23 #include "mp_image.h"
|
5550
|
24 #include "vf.h"
|
|
25
|
8585
|
26 #include "muxer.h"
|
|
27
|
5550
|
28 //===========================================================================//
|
|
29
|
6083
|
30 static char *vfw_param_codec = NULL;
|
|
31
|
|
32 #include "cfgparser.h"
|
|
33
|
|
34 struct config vfwopts_conf[]={
|
|
35 {"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
|
36 {NULL, NULL, 0, 0, 0, 0, NULL}
|
|
37 };
|
|
38
|
5550
|
39 struct vf_priv_s {
|
8585
|
40 muxer_stream_t* mux;
|
5550
|
41 BITMAPINFOHEADER* bih;
|
|
42 };
|
|
43
|
7557
|
44 static HIC encoder_hic;
|
7231
|
45 static void* encoder_buf=NULL;
|
|
46 static int encoder_buf_size=0;
|
|
47 static int encoder_frameno=0;
|
|
48
|
|
49 //int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih)
|
|
50 static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc)
|
|
51 {
|
|
52 HRESULT ret;
|
|
53 BITMAPINFOHEADER* output_bih=NULL;
|
|
54 int temp_len;
|
|
55
|
|
56 //sh_video = malloc(sizeof(sh_video_t));
|
|
57
|
|
58 mp_msg(MSGT_WIN32,MSGL_V,"======= Win32 (VFW) VIDEO Encoder init =======\n");
|
|
59
|
|
60 // memset(&sh_video->o_bih, 0, sizeof(BITMAPINFOHEADER));
|
|
61 // output_bih->biSize = sizeof(BITMAPINFOHEADER);
|
|
62
|
7390
|
63 // encoder_hic = ICOpen( 0x63646976, out_fourcc, ICMODE_COMPRESS);
|
7557
|
64 encoder_hic = ICOpen( (long) dll_name, out_fourcc, ICMODE_COMPRESS);
|
7231
|
65 if(!encoder_hic){
|
|
66 mp_msg(MSGT_WIN32,MSGL_ERR,"ICOpen failed! unknown codec / wrong parameters?\n");
|
|
67 return NULL;
|
|
68 }
|
|
69 printf("HIC: %x\n", encoder_hic);
|
|
70
|
|
71 #if 1
|
|
72 {
|
|
73 ICINFO icinfo;
|
|
74
|
|
75 ret = ICGetInfo(encoder_hic, &icinfo, sizeof(ICINFO));
|
8123
|
76 printf("%ld - %ld - %d\n", ret, icinfo.dwSize, sizeof(ICINFO));
|
|
77 printf("Compressor type: %.4lx\n", icinfo.fccType);
|
|
78 printf("Compressor subtype: %.4lx\n", icinfo.fccHandler);
|
7231
|
79 printf("Compressor flags: %lu, version %lu, ICM version: %lu\n",
|
|
80 icinfo.dwFlags, icinfo.dwVersion, icinfo.dwVersionICM);
|
|
81 //printf("Compressor name: %s\n", icinfo.szName);
|
|
82 //printf("Compressor description: %s\n", icinfo.szDescription);
|
|
83
|
|
84 printf("Flags:");
|
|
85 if (icinfo.dwFlags & VIDCF_QUALITY)
|
|
86 printf(" quality");
|
|
87 if (icinfo.dwFlags & VIDCF_FASTTEMPORALD)
|
|
88 printf(" fast-decompr");
|
|
89 if (icinfo.dwFlags & VIDCF_QUALITYTIME)
|
|
90 printf(" temp-quality");
|
|
91 printf("\n");
|
|
92 }
|
|
93 #endif
|
|
94
|
|
95 temp_len = ICCompressGetFormatSize(encoder_hic, input_bih);
|
|
96 printf("ICCompressGetFormatSize ret: %d\n", temp_len);
|
|
97
|
|
98 if (temp_len < sizeof(BITMAPINFOHEADER)) temp_len=sizeof(BITMAPINFOHEADER);
|
|
99
|
|
100 output_bih = malloc(temp_len+4);
|
|
101 memset(output_bih,0,temp_len);
|
|
102 output_bih->biSize = temp_len; //sizeof(BITMAPINFOHEADER);
|
|
103
|
|
104 return output_bih;
|
|
105 }
|
|
106
|
|
107 static int vfw_start_encoder(BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih){
|
|
108 HRESULT ret;
|
|
109 int temp_len=output_bih->biSize;
|
|
110 int i;
|
|
111
|
|
112 ret = ICCompressGetFormat(encoder_hic, input_bih, output_bih);
|
|
113 if(ret < 0){
|
|
114 unsigned char* temp=(unsigned char*)output_bih;
|
|
115 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressGetFormat failed: Error %d (0x%X)\n", (int)ret, (int)ret);
|
|
116 for (i=0; i < temp_len; i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02x ", temp[i]);
|
|
117 return 0;
|
|
118 }
|
|
119 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressGetFormat OK\n");
|
|
120
|
|
121 if (temp_len > sizeof(BITMAPINFOHEADER))
|
|
122 {
|
|
123 unsigned char* temp=(unsigned char*)output_bih;
|
|
124 mp_msg(MSGT_WIN32, MSGL_V, "Extra info in o_bih (%d bytes)!\n",
|
|
125 temp_len-sizeof(BITMAPINFOHEADER));
|
|
126 for(i=sizeof(output_bih);i<temp_len;i++) mp_msg(MSGT_WIN32, MSGL_DBG2, "%02X ",temp[i]);
|
|
127 }
|
|
128
|
|
129 // if(verbose) {
|
|
130 printf("Starting compression:\n");
|
|
131 printf(" Input format:\n");
|
8123
|
132 printf(" biSize %d\n", input_bih->biSize);
|
|
133 printf(" biWidth %d\n", input_bih->biWidth);
|
|
134 printf(" biHeight %d\n", input_bih->biHeight);
|
7231
|
135 printf(" biPlanes %d\n", input_bih->biPlanes);
|
|
136 printf(" biBitCount %d\n", input_bih->biBitCount);
|
8123
|
137 printf(" biCompression 0x%x ('%.4s')\n", input_bih->biCompression, (char *)&input_bih->biCompression);
|
|
138 printf(" biSizeImage %d\n", input_bih->biSizeImage);
|
7231
|
139 printf(" Output format:\n");
|
8123
|
140 printf(" biSize %d\n", output_bih->biSize);
|
|
141 printf(" biWidth %d\n", output_bih->biWidth);
|
|
142 printf(" biHeight %d\n", output_bih->biHeight);
|
7231
|
143 printf(" biPlanes %d\n", output_bih->biPlanes);
|
|
144 printf(" biBitCount %d\n", output_bih->biBitCount);
|
8123
|
145 printf(" biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
|
|
146 printf(" biSizeImage %d\n", output_bih->biSizeImage);
|
7231
|
147 // }
|
|
148
|
|
149 output_bih->biWidth=input_bih->biWidth;
|
|
150 output_bih->biHeight=input_bih->biHeight;
|
|
151
|
|
152 ret = ICCompressQuery(encoder_hic, input_bih, output_bih);
|
|
153 if(ret){
|
|
154 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressQuery failed: Error %d\n", (int)ret);
|
|
155 return 0;
|
|
156 } else
|
|
157 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressQuery OK\n");
|
|
158
|
|
159 ret = ICCompressBegin(encoder_hic, input_bih, output_bih);
|
|
160 if(ret){
|
|
161 mp_msg(MSGT_WIN32,MSGL_ERR,"ICCompressBegin failed: Error %d\n", (int)ret);
|
|
162 // return 0;
|
|
163 } else
|
|
164 mp_msg(MSGT_WIN32,MSGL_V,"ICCompressBegin OK\n");
|
|
165
|
|
166 printf(" Output format after query/begin:\n");
|
8123
|
167 printf(" biSize %d\n", output_bih->biSize);
|
|
168 printf(" biWidth %d\n", output_bih->biWidth);
|
|
169 printf(" biHeight %d\n", output_bih->biHeight);
|
7231
|
170 printf(" biPlanes %d\n", output_bih->biPlanes);
|
|
171 printf(" biBitCount %d\n", output_bih->biBitCount);
|
8123
|
172 printf(" biCompression 0x%x ('%.4s')\n", output_bih->biCompression, (char *)&output_bih->biCompression);
|
|
173 printf(" biSizeImage %d\n", output_bih->biSizeImage);
|
7231
|
174
|
|
175 encoder_buf_size=input_bih->biSizeImage;
|
|
176 encoder_buf=malloc(encoder_buf_size);
|
|
177 encoder_frameno=0;
|
|
178
|
|
179 mp_msg(MSGT_WIN32,MSGL_V,"VIDEO CODEC Init OK!!! ;-)\n");
|
|
180 return 1;
|
|
181 }
|
|
182
|
|
183 static int vfw_encode_frame(BITMAPINFOHEADER* biOutput,void* OutBuf,
|
|
184 BITMAPINFOHEADER* biInput,void* Image,
|
|
185 long* keyframe, int quality){
|
|
186 HRESULT ret;
|
|
187
|
|
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 //);
|
|
194
|
|
195 // printf("vfw_encode_frame(%p,%p, %p,%p, %p,%d)\n",biOutput,OutBuf,biInput,Image,keyframe,quality);
|
|
196
|
|
197 ret=ICCompress(encoder_hic, 0,
|
|
198 biOutput, OutBuf,
|
|
199 biInput, Image,
|
|
200 NULL, keyframe, encoder_frameno, 0, quality,
|
|
201 biInput, encoder_buf);
|
|
202
|
|
203 // printf("ok. size=%d\n",biOutput->biSizeImage);
|
|
204
|
|
205 memcpy(encoder_buf,Image,encoder_buf_size);
|
|
206 ++encoder_frameno;
|
|
207
|
|
208 return (int)ret;
|
|
209 }
|
5550
|
210 #define mux_v (vf->priv->mux)
|
|
211 #define vfw_bih (vf->priv->bih)
|
|
212
|
|
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){
|
|
216
|
|
217 vfw_bih->biWidth=width;
|
|
218 vfw_bih->biHeight=height;
|
|
219 vfw_bih->biSizeImage=width*height*((vfw_bih->biBitCount+7)/8);
|
5551
|
220
|
|
221 if(!vfw_start_encoder(vfw_bih, mux_v->bih)) return 0;
|
|
222
|
|
223 // mux_v->bih->biWidth=width;
|
|
224 // mux_v->bih->biHeight=height;
|
|
225 // mux_v->bih->biSizeImage=width*height*((mux_v->bih->biBitCount+7)/8);
|
5550
|
226
|
|
227 return 1;
|
|
228 }
|
|
229
|
|
230 static int control(struct vf_instance_s* vf, int request, void* data){
|
|
231
|
|
232 return CONTROL_UNKNOWN;
|
|
233 }
|
|
234
|
|
235 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
|
5565
|
236 if(fmt==IMGFMT_BGR24) return 3 | VFCAP_FLIPPED;
|
5550
|
237 return 0;
|
|
238 }
|
|
239
|
7368
|
240 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
|
5550
|
241 long flags=0;
|
|
242 int ret;
|
|
243 // flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack
|
|
244 ret=vfw_encode_frame(mux_v->bih, mux_v->buffer, vfw_bih, mpi->planes[0], &flags, 10000);
|
9014
|
245 muxer_write_chunk(mux_v,mux_v->bih->biSizeImage,flags);
|
7368
|
246 return 1;
|
5550
|
247 }
|
|
248
|
|
249 //===========================================================================//
|
|
250
|
|
251 static int vf_open(vf_instance_t *vf, char* args){
|
|
252 vf->config=config;
|
|
253 vf->control=control;
|
|
254 vf->query_format=query_format;
|
|
255 vf->put_image=put_image;
|
|
256 vf->priv=malloc(sizeof(struct vf_priv_s));
|
|
257 memset(vf->priv,0,sizeof(struct vf_priv_s));
|
8585
|
258 vf->priv->mux=(muxer_stream_t*)args;
|
5550
|
259
|
|
260 vfw_bih=malloc(sizeof(BITMAPINFOHEADER));
|
|
261 vfw_bih->biSize=sizeof(BITMAPINFOHEADER);
|
|
262 vfw_bih->biWidth=0; // FIXME ?
|
|
263 vfw_bih->biHeight=0;
|
|
264 vfw_bih->biPlanes=1;
|
|
265 vfw_bih->biBitCount=24;
|
|
266 vfw_bih->biCompression=0;
|
|
267 // vfw_bih->biSizeImage=vo_w*vo_h*((vfw_bih->biBitCount+7)/8);
|
6083
|
268
|
|
269 if (!vfw_param_codec)
|
|
270 {
|
|
271 printf("No VfW codec specified! It's required!\n");
|
|
272 return 0;
|
|
273 }
|
5550
|
274 // mux_v->bih=vfw_open_encoder("divxc32.dll",vfw_bih,mmioFOURCC('D', 'I', 'V', '3'));
|
6083
|
275 // mux_v->bih=vfw_open_encoder("AvidAVICodec.dll",vfw_bih, 0);
|
|
276 mux_v->bih = vfw_open_encoder(vfw_param_codec, vfw_bih, 0);
|
5550
|
277 if(!mux_v->bih) return 0;
|
|
278
|
|
279 return 1;
|
|
280 }
|
|
281
|
|
282 vf_info_t ve_info_vfw = {
|
|
283 "Win32/VfW encoders",
|
|
284 "vfw",
|
|
285 "A'rpi",
|
|
286 "for internal use by mencoder",
|
|
287 vf_open
|
|
288 };
|
|
289
|
|
290 //===========================================================================//
|
|
291 #endif
|