Fix fps output with -identify when frame rate extension is used for MPEG-2
[mplayer.git] / TOOLS / vfw2menc.c
blobb15b773a054981ada24ee144bad8323b2bd42b27
1 /*
2 * VFW Compressor Settings Tool
4 * Copyright (c) 2006 Gianluigi Tiesi <sherpya@netfarm.it>
6 * Official Website : http://oss.netfarm.it/mplayer-win32.php
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, write to the the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 /* On MinGW compile with: gcc vfw2menc.c -o vfw2menc.exe -lwinmm -lole32 */
24 /* Using Wine: winegcc vfw2menc.c -o vfw2menc -lwinmm -lole32 */
25 /* MSVC requires getopt.c and getopt.h available at the original website */
27 #ifdef _MSC_VER
28 #define _CRT_SECURE_NO_DEPRECATE
29 #pragma warning(disable: 4996)
30 #endif
32 #define VERSION "0.1"
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/stat.h>
38 #include <getopt.h>
39 #include <windows.h>
40 #include <vfw.h>
42 #define BAIL(msg) { printf("%s: %s\n", argv[0], msg); ret = -1; goto cleanup; }
44 typedef struct {
45 UINT uDriverSignature;
46 HINSTANCE hDriverModule;
47 DRIVERPROC DriverProc;
48 DWORD dwDriverID;
49 } DRVR;
51 typedef DRVR *PDRVR;
52 typedef DRVR *NPDRVR;
53 typedef DRVR *LPDRVR;
55 enum
57 MODE_NONE = 0,
58 MODE_CHECK,
59 MODE_SAVE,
60 MODE_VIEW
63 static int save_settings(HDRVR hDriver, const char *filename)
65 FILE *fd = NULL;
66 DWORD cb = (DWORD) SendDriverMessage(hDriver, ICM_GETSTATE, 0, 0);
67 char *pv = NULL;
69 if (!cb)
71 printf("ICM_GETSTATE returned 0 size\n");
72 return -1;
75 pv = (char *) malloc(cb);
76 if (SendDriverMessage(hDriver, ICM_GETSTATE, (LPARAM) pv, (LPARAM) &cb) != ICERR_OK)
78 printf("ICM_GETSTATE failed\n");
79 free(pv);
80 return -1;
83 fd = fopen(filename, "wb");
84 if (!fd)
86 printf("Cannot open file %s for writing\n", filename);
87 free(pv);
88 return -1;
91 if (fwrite(pv, cb, 1, fd) != 1)
93 printf("fwrite() failed on %s\n", filename);
94 free(pv);
95 fclose(fd);
96 return -1;
98 fclose(fd);
99 free(pv);
100 return 0;
103 static int load_settings(HDRVR hDriver, const char *filename)
105 struct stat info;
106 FILE *fd = NULL;
107 char *pv;
109 if (stat(filename, &info) < 0)
111 printf("stat() on %s failed\n", filename);
112 return -1;
115 pv = (char *) malloc(info.st_size);
116 fd = fopen(filename, "rb");
118 if (!fd)
120 printf("Cannot open file %s for reading\n", filename);
121 free(pv);
122 return -1;
125 if (fread(pv, info.st_size, 1, fd) != 1)
127 printf("fread() failed on %s\n", filename);
128 free(pv);
129 fclose(fd);
130 return -1;
132 fclose(fd);
133 if (!SendDriverMessage(hDriver, ICM_SETSTATE, (LPARAM) pv, (LPARAM) info.st_size))
135 printf("ICM_SETSTATE failed\n");
136 free(pv);
137 return -1;
139 free(pv);
140 return 0;
143 static struct option long_options[] =
145 { "help", no_argument, NULL, 'h' },
146 { "driver", required_argument, NULL, 'd' },
147 { "fourcc", required_argument, NULL, 'f' },
148 { "save", required_argument, NULL, 's' },
149 { "check", required_argument, NULL, 'c' },
150 { "view", no_argument, NULL, 'v' },
151 { 0, 0, 0, 0 }
154 static void help(const char *progname)
156 printf("VFW to mencoder v"VERSION" - Copyright 2007 - Gianluigi Tiesi <sherpya@netfarm.it>\n");
157 printf("This program is Free Software\n\n");
158 printf("Usage: %s\n", progname);
159 printf(" -h|--help - displays this help\n");
160 printf(" -d|--driver filename - dll or drv to load\n");
161 printf(" -f|--fourcc fourcc - fourcc of selected driver (look at codecs.conf)\n");
162 printf(" -s|--save filename - save settings to file\n");
163 printf(" -c|--check filename - load and show setting in filename\n");
164 printf(" -v|--view - displays the config dialog and do nothing\n");
165 printf("\nExamples:\n");
166 printf(" %s -f VP62 -d vp6vfw.dll -s firstpass.mcf\n", progname);
167 printf(" %s -f VP62 -d vp6vfw.dll -c firstpass.mcf\n", progname);
168 printf(" %s -f VP62 -d vp6vfw.dll -v\n", progname);
169 printf("\nIf the driver dialog doesn't work, you can try without specifing a fourcc,\n");
170 printf("but the compdata file will not work with mencoder.\n");
171 printf("Driver option is required and you must specify at least -s, -c -o -v\n");
172 printf("Usage with mencoder -ovc vfw -xvfwopts codec=vp6vfw.dll:compdata=settings.mcf\n");
175 int main(int argc, char *argv[])
177 char *driver = NULL;
178 char *fourcc = NULL;
179 char *filename = NULL;
180 unsigned char mode = 0;
181 DWORD dwFCC = 0;
182 ICOPEN icopen;
183 HRESULT coinit = -1;
184 /* ICINFO icinfo; */
186 wchar_t drvfile[MAX_PATH];
187 HDRVR hDriver = NULL;
188 int ret = 0;
189 int c = -1, long_options_index = -1;
191 if (argc < 2)
193 help(argv[0]);
194 ret = -1;
195 goto cleanup;
198 while ((c = getopt_long(argc, argv, "hd:f:s:c:v", long_options, &long_options_index)) != -1)
200 switch (c)
202 case 'h':
203 help(argv[0]);
204 ret = 0;
205 goto cleanup;
206 case 'd':
207 driver = strdup(optarg);
208 break;
209 case 'f':
210 fourcc = strdup(optarg);
211 if (strlen(optarg) != 4) BAIL("Fourcc must be exactly 4 chars");
212 break;
213 case 's':
214 if (mode != MODE_NONE) BAIL("Incompatible arguments");
215 filename = strdup(optarg);
216 mode = MODE_SAVE;
217 break;
218 case 'c':
219 if (mode != MODE_NONE) BAIL("Incompatible arguments");
220 filename = strdup(optarg);
221 mode = MODE_CHECK;
222 break;
223 case 'v':
224 if (mode != MODE_NONE) BAIL("Incompatible arguments");
225 mode = MODE_VIEW;
226 break;
227 default:
228 printf("Wrong arguments!\n");
229 help(argv[0]);
230 goto cleanup;
234 if (!(argc == optind) && (mode != MODE_NONE) &&
235 driver && (filename || (mode == MODE_VIEW)))
237 help(argv[0]);
238 goto cleanup;
241 if (!MultiByteToWideChar(CP_ACP, 0, driver, -1, drvfile, MAX_PATH))
242 BAIL("MultiByteToWideChar() failed\n");
244 if (fourcc) memcpy(&dwFCC, fourcc, 4);
245 memset(&icopen, 0, sizeof(icopen));
247 icopen.dwSize = sizeof(icopen);
248 icopen.fccType = ICTYPE_VIDEO; /* VIDC */
249 icopen.fccHandler = dwFCC;
250 icopen.dwVersion = 0x00001000; /* FIXME */
251 icopen.dwFlags = ICMODE_COMPRESS;
252 icopen.dwError = 0;
253 icopen.pV1Reserved = NULL;
254 icopen.pV2Reserved = NULL;
255 icopen.dnDevNode = -1; /* FIXME */
257 coinit = CoInitialize(NULL);
259 if (!(hDriver = OpenDriver(drvfile, NULL, (LPARAM) &icopen)))
260 BAIL("OpenDriver() failed\n");
263 memset(&icinfo, 0, sizeof(ICINFO));
264 icinfo.dwSize = sizeof(ICINFO);
265 SendDriverMessage(hDriver, ICM_GETINFO, (LPARAM) &icinfo, sizeof(ICINFO));
268 if (SendDriverMessage(hDriver, ICM_CONFIGURE, -1, 0) != ICERR_OK)
269 BAIL("The driver doesn't provide a configure dialog");
272 switch(mode)
274 case MODE_CHECK:
275 if (load_settings(hDriver, filename))
276 BAIL("Cannot load settings from file");
277 if (SendDriverMessage(hDriver, ICM_CONFIGURE, 0, 0) != ICERR_OK)
278 BAIL("ICM_CONFIGURE failed");
279 break;
280 case MODE_SAVE:
281 if (SendDriverMessage(hDriver, ICM_CONFIGURE, 0, 0) != ICERR_OK)
282 BAIL("ICM_CONFIGURE failed");
283 if (save_settings(hDriver, filename))
284 BAIL("Cannot save settings to file");
285 break;
286 case MODE_VIEW:
288 HWND hwnd = GetDesktopWindow();
289 if (SendDriverMessage(hDriver, ICM_CONFIGURE, (LPARAM) hwnd, 0) != ICERR_OK)
290 BAIL("ICM_CONFIGURE failed");
292 break;
293 default:
294 BAIL("This should not happen :)");
297 cleanup:
298 if (driver) free(driver);
299 if (fourcc) free(fourcc);
300 if (filename) free(filename);
301 if (hDriver) CloseDriver(hDriver, 0, 0);
302 if ((coinit == S_OK) || coinit == S_FALSE) CoUninitialize();
303 return ret;