diff --git a/TOOLS/vfw2menc.c b/TOOLS/vfw2menc.c new file mode 100644 index 0000000000..fc746120da --- /dev/null +++ b/TOOLS/vfw2menc.c @@ -0,0 +1,257 @@ +/* + * VFW Compressor Settings Tool + * + * Copyright (c) 2006 Gianluigi Tiesi + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this software; if not, write to the + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* On mingw compile with: gcc getopt.c vfw2menc.c -o vfw2menc.exe -lwinmm */ +/* Using wine: winegcc getopt.c vfw2menc.c -o vfw2menc -lwinmm */ + +#ifdef _MSC_VER +#define _CRT_SECURE_NO_DEPRECATE +#pragma warning(disable: 4996) +#endif + +#include +#include +#include +#include +#include +#include + +#define BAIL(msg) { printf("%s: %s\n", argv[0], msg); ret = -1; goto cleanup; } + +enum +{ + MODE_NONE = 0, + MODE_CHECK, + MODE_SAVE, + MODE_VIEW +}; + +int save_settings(HDRVR hDriver, const char *filename) +{ + FILE *fd = NULL; + DWORD cb = (DWORD) SendDriverMessage(hDriver, ICM_GETSTATE, 0, 0); + char *pv = NULL; + + if (!cb) + { + printf("ICM_GETSTATE returned 0 size\n"); + return -1; + } + + pv = (char *) malloc(cb); + if (SendDriverMessage(hDriver, ICM_GETSTATE, (LPARAM) pv, (LPARAM) &cb) != ICERR_OK) + { + printf("ICM_GETSTATE failed\n"); + free(pv); + return -1; + } + + fd = fopen(filename, "wb"); + if (!fd) + { + printf("Cannot open file %s for writing\n", filename); + free(pv); + return -1; + } + + if (fwrite(pv, cb, 1, fd) != 1) + { + printf("fwrite() failed on %s\n", filename); + free(pv); + fclose(fd); + return -1; + } + fclose(fd); + free(pv); + return 0; +} + +int load_settings(HDRVR hDriver, const char *filename) +{ + struct stat info; + FILE *fd = NULL; + char *pv; + + if (stat(filename, &info) < 0) + { + printf("stat() on %s failed\n", filename); + return -1; + } + + pv = (char *) malloc(info.st_size); + fd = fopen(filename, "rb"); + + if (!fd) + { + printf("Cannot open file %s for reading\n", filename); + free(pv); + return -1; + } + + if (fread(pv, info.st_size, 1, fd) != 1) + { + printf("fread() failed on %s\n", filename); + free(pv); + fclose(fd); + return -1; + } + fclose(fd); + if (!SendDriverMessage(hDriver, ICM_SETSTATE, (LPARAM) pv, (LPARAM) info.st_size)) + { + printf("ICM_SETSTATE failed\n"); + free(pv); + return -1; + } + free(pv); + return 0; +} + +static struct option long_options[] = +{ + { "help", no_argument, NULL, 'h' }, + { "driver", required_argument, NULL, 'd' }, + { "fourcc", required_argument, NULL, 'f' }, + { "save", required_argument, NULL, 's' }, + { "check", required_argument, NULL, 'c' }, + { "view", no_argument, NULL, 'v' }, + { 0, 0, 0, 0 } +}; + +void help(const char *progname) +{ + printf("VFW to mencoder - Copyright 2006 - Gianluigi Tiesi \n"); + printf("This program is Free Software\n\n"); + printf("Usage: %s\n", progname); + printf(" -h|--help - displays this help\n"); + printf(" -d|--driver filename - dll or drv to load\n"); + printf(" -f|--fourcc fourcc - fourcc of selected driver (look at codecs.conf)\n"); + printf(" -s|--save filename - save settings to file\n"); + printf(" -c|--check filename - load and show setting in filename\n"); + printf(" -v|--view - displays the config dialog and do nothing\n"); + printf("\nExamples:\n"); + printf(" %s -f VP62 -d vp6vfw.dll -s firstpass.mcf\n", progname); + printf(" %s -f VP62 -d vp6vfw.dll -c firstpass.mcf\n", progname); + printf(" %s -f VP62 -d vp6vfw.dll -v\n", progname); + printf("\nIf the driver dialog doesn't work, you can try without specifing a fourcc,\n"); + printf("but the compdata file will not work with mencoder.\n"); + printf("Driver option is required and you must specify at least -s, -c -o -v\n"); + printf("Usage with mencoder -ovc vfw -xvfwopts codec=vp6vfw.dll:compdata=settings.mcf\n"); +} + + +int main(int argc, char *argv[]) +{ + char *driver = NULL; + char *fourcc = NULL; + char *filename = NULL; + unsigned char mode = 0; + + wchar_t drvfile[MAX_PATH]; + HDRVR hDriver = NULL; + int ret = 0; + int c = -1, long_options_index = -1; + + if (argc < 2) + { + help(argv[0]); + ret = -1; + goto cleanup; + } + + while ((c = getopt_long(argc, argv, "hd:f:s:c:v", long_options, &long_options_index)) != -1) + { + switch (c) + { + case 'h': + help(argv[0]); + ret = 0; + goto cleanup; + case 'd': + driver = strdup(optarg); + break; + case 'f': + fourcc = strdup(optarg); + if (strlen(optarg) != 4) BAIL("Fourcc must be exactly 4 chars"); + break; + case 's': + if (mode != MODE_NONE) BAIL("Incompatible arguments"); + filename = strdup(optarg); + mode = MODE_SAVE; + break; + case 'c': + if (mode != MODE_NONE) BAIL("Incompatible arguments"); + filename = strdup(optarg); + mode = MODE_CHECK; + break; + case 'v': + if (mode != MODE_NONE) BAIL("Incompatible arguments"); + mode = MODE_VIEW; + break; + default: + printf("Wrong arguments!\n"); + } + } + + + if (!(argc == optind) && (mode != MODE_NONE) && + driver && (filename || (mode == MODE_VIEW))) + { + help(argv[0]); + goto cleanup; + } + + if (!MultiByteToWideChar(CP_ACP, 0, driver, -1, drvfile, MAX_PATH)) + BAIL("MultiByteToWideChar() failed\n"); + + if (!(hDriver = OpenDriver(drvfile, 0, (fourcc) ? ((LPARAM) fourcc) : 0))) + BAIL("OpenDriver() failed\n"); + + if (SendDriverMessage(hDriver, ICM_CONFIGURE, -1, 0) != ICERR_OK) + BAIL("The driver doesn't provide a configure dialog"); + + switch(mode) + { + case MODE_CHECK: + if (load_settings(hDriver, filename)) + BAIL("Cannot load settings from file"); + if (SendDriverMessage(hDriver, ICM_CONFIGURE, 0, 0) != ICERR_OK) + BAIL("ICM_CONFIGURE failed"); + break; + case MODE_SAVE: + if (SendDriverMessage(hDriver, ICM_CONFIGURE, 0, 0) != ICERR_OK) + BAIL("ICM_CONFIGURE failed"); + if (save_settings(hDriver, filename)) + BAIL("Cannot save settings to file"); + break; + case MODE_VIEW: + if (SendDriverMessage(hDriver, ICM_CONFIGURE, 0, 0) != ICERR_OK) + BAIL("ICM_CONFIGURE failed"); + break; + default: + BAIL("This should not happen :)"); + } + +cleanup: + if (driver) free(driver); + if (fourcc) free(fourcc); + if (filename) free(filename); + if (hDriver) CloseDriver(hDriver, 0, 0); + return ret; +} diff --git a/libmpcodecs/ve_vfw.c b/libmpcodecs/ve_vfw.c index 965bca3487..428cbc0e2d 100644 --- a/libmpcodecs/ve_vfw.c +++ b/libmpcodecs/ve_vfw.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "config.h" @@ -29,11 +30,13 @@ //===========================================================================// static char *vfw_param_codec = NULL; +static char *vfw_param_compdata = NULL; #include "m_option.h" m_option_t vfwopts_conf[]={ {"codec", &vfw_param_codec, CONF_TYPE_STRING, 0, 0, 0, NULL}, + {"compdata", &vfw_param_compdata, CONF_TYPE_STRING, 0, 0, 0, NULL}, {NULL, NULL, 0, 0, 0, 0, NULL} }; @@ -48,11 +51,14 @@ static int encoder_buf_size=0; static int encoder_frameno=0; //int init_vfw_encoder(char *dll_name, BITMAPINFOHEADER *input_bih, BITMAPINFOHEADER *output_bih) -static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc) +static BITMAPINFOHEADER* vfw_open_encoder(char *dll_name, char *compdatafile, BITMAPINFOHEADER *input_bih,unsigned int out_fourcc) { HRESULT ret; BITMAPINFOHEADER* output_bih=NULL; int temp_len; + FILE *fd=NULL; + char *drvdata=NULL; + struct stat st; //sh_video = malloc(sizeof(sh_video_t)); @@ -93,6 +99,47 @@ mp_msg(MSGT_WIN32,MSGL_INFO,"\n"); } #endif + if(compdatafile){ + if (!strncmp(compdatafile, "dialog", 6)){ + if (ICSendMessage(encoder_hic, ICM_CONFIGURE, -1, 0) != ICERR_OK){ + mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor doesn't have a configure dialog!\n"); + return NULL; + } + if (ICSendMessage(encoder_hic, ICM_CONFIGURE, 0, 0) != ICERR_OK){ + mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor configure dialog failed!\n"); + return NULL; + } + } + else { + if (stat(compdatafile, &st) < 0){ + mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data file not found!\n"); + return NULL; + } + fd = fopen(compdatafile, "rb"); + if (!fd){ + mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot open Compressor data file!\n"); + return NULL; + } + drvdata = (char *) malloc(st.st_size); + if (fread(drvdata, st.st_size, 1, fd) != 1) { + mp_msg(MSGT_WIN32,MSGL_ERR,"Cannot read Compressor data file!\n"); + fclose(fd); + free(drvdata); + return NULL; + } + fclose(fd); + mp_msg(MSGT_WIN32,MSGL_ERR,"Compressor data %d bytes\n", st.st_size); + if (!(temp_len = (unsigned int) ICSendMessage(encoder_hic, ICM_SETSTATE, (LPARAM) drvdata, (int) st.st_size))){ + mp_msg(MSGT_WIN32,MSGL_ERR,"ICSetState failed!\n"); + fclose(fd); + free(drvdata); + return NULL; + } + free(drvdata); + mp_msg(MSGT_WIN32,MSGL_INFO,"ICSetState ret: %d\n", temp_len); + } + } + temp_len = ICCompressGetFormatSize(encoder_hic, input_bih); mp_msg(MSGT_WIN32,MSGL_INFO,"ICCompressGetFormatSize ret: %d\n", temp_len); @@ -243,6 +290,8 @@ static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ int ret; // flip_upside_down(vo_image_ptr,vo_image_ptr,3*vo_w,vo_h); // dirty hack ret=vfw_encode_frame(mux_v->bih, mux_v->buffer, vfw_bih, mpi->planes[0], &flags, 10000); +// if (ret != ICERR_OK) +// return 0; muxer_write_chunk(mux_v,mux_v->bih->biSizeImage,flags, pts, pts); return 1; } @@ -275,7 +324,7 @@ static int vf_open(vf_instance_t *vf, char* args){ } // mux_v->bih=vfw_open_encoder("divxc32.dll",vfw_bih,mmioFOURCC('D', 'I', 'V', '3')); // mux_v->bih=vfw_open_encoder("AvidAVICodec.dll",vfw_bih, 0); - mux_v->bih = vfw_open_encoder(vfw_param_codec, vfw_bih, 0); + mux_v->bih = vfw_open_encoder(vfw_param_codec, vfw_param_compdata, vfw_bih, 0); if(!mux_v->bih) return 0; return 1;