Changeset 7263 in vbox for trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
- Timestamp:
- Mar 4, 2008 9:11:57 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxHeadless/VBoxHeadless.cpp
r6285 r7263 37 37 #include <iprt/stream.h> 38 38 #include <iprt/ldr.h> 39 #include <iprt/getopt.h> 39 40 40 41 #ifdef VBOX_FFMPEG … … 54 55 55 56 #define LogError(m,rc) \ 56 if (1){ \57 do { \ 57 58 Log (("VBoxHeadless: ERROR: " m " [rc=0x%08X]\n", rc)); \ 58 59 RTPrintf (m " (rc = 0x%08X)\n", rc); \ 59 } 60 } while (0) 60 61 61 62 //////////////////////////////////////////////////////////////////////////////// … … 267 268 { 268 269 RTPrintf("Usage:\n" 269 " -s tartvm <name|uuid>Start given VM (required argument)\n"270 " -s, -startvm, --startvm <name|uuid> Start given VM (required argument)\n" 270 271 #ifdef VBOX_WITH_VRDP 271 " -vrdpport <port> Port number the VRDP server will bind to\n" 272 " -vrdpaddress <ip> Interface IP the VRDP will bind to \n" 273 #endif 274 #ifdef VBOX_FFMPEG 275 " -capture Record the VM screen output to a file\n" 276 "\n" 277 "When recording, the following optional environment variables are also\n" 278 "recognized:\n" 279 "\n" 280 " VBOX_CAPTUREWIDTH Frame width\n" 281 " VBOX_CAPTUREHEIGHT Frame height\n" 282 " VBOX_CAPTUREBITRATE Recording bit rate\n" 283 " VBOX_CAPTUREBITRATE Recording bit rate\n" 284 " VBOX_CAPTUREFILE Specify a file name\n" 272 " -p, -vrdpport, --vrdpport <port> Port number the VRDP server will bind\n" 273 " to\n" 274 " -a, -vrdpaddress, --vrdpaddress <ip> Interface IP the VRDP will bind to \n" 275 #endif 276 #ifdef VBOX_FFMPEG 277 " -c, -capture, --capture Record the VM screen output to a file\n" 278 " -w, --width Frame width when recording\n" 279 " -h, --height Frame height when recording\n" 280 " -r, --bitrate Recording bit rate when recording\n" 281 " -f, --filename File name when recording. The codec\n" 282 " used will be chosen based on the\n" 283 " file extension\n" 285 284 #endif 286 285 "\n"); 287 286 } 287 288 #ifdef VBOX_FFMPEG 289 /** 290 * Parse the environment for variables which can influence the FFMPEG settings. 291 * purely for backwards compatibility. 292 * @param pulFrameWidth may be updated with a desired frame width 293 * @param pulFrameHeight may be updated with a desired frame height 294 * @param pulBitRate may be updated with a desired bit rate 295 * @param ppszFileName may be updated with a desired file name 296 */ 297 static void parse_environ(unsigned long *pulFrameWidth, unsigned long *pulFrameHeight, 298 unsigned long *pulBitRate, const char **ppszFileName) 299 { 300 const char *pszEnvTemp; 301 302 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREWIDTH")) != 0) 303 { 304 errno = 0; 305 unsigned long ulFrameWidth = strtoul(pszEnvTemp, 0, 10); 306 if (errno != 0) 307 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREWIDTH environment variable", 0); 308 else 309 *pulFrameWidth = ulFrameWidth; 310 } 311 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREHEIGHT")) != 0) 312 { 313 errno = 0; 314 unsigned long ulFrameHeight = strtoul(pszEnvTemp, 0, 10); 315 if (errno != 0) 316 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREHEIGHT environment variable", 0); 317 else 318 *pulFrameHeight = ulFrameHeight; 319 } 320 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREBITRATE")) != 0) 321 { 322 errno = 0; 323 unsigned long ulBitRate = strtoul(pszEnvTemp, 0, 10); 324 if (errno != 0) 325 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREBITRATE environment variable", 0); 326 else 327 *pulBitRate = ulBitRate; 328 } 329 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREFILE")) != 0) 330 *ppszFileName = pszEnvTemp; 331 } 332 #endif /* VBOX_FFMPEG defined */ 288 333 289 334 /** … … 302 347 #ifdef VBOX_FFMPEG 303 348 unsigned fFFMPEG = 0; 304 unsigned ulFrameWidth = 800;305 unsigned ulFrameHeight = 600;306 unsigned ulBitRate = 300000;349 unsigned long ulFrameWidth = 800; 350 unsigned long ulFrameHeight = 600; 351 unsigned long ulBitRate = 300000; 307 352 char pszMPEGFile[RTPATH_MAX]; 353 const char *pszFileNameParam = "VBox-%d.vob"; 308 354 #endif /* VBOX_FFMPEG */ 309 355 … … 321 367 const char *name = NULL; 322 368 369 #ifdef VBOX_FFMPEG 370 /* Parse the environment */ 371 parse_environ(&ulFrameWidth, &ulFrameHeight, &ulBitRate, &pszFileNameParam); 372 #endif 373 374 enum eHeadlessOptions 375 { 376 OPT_RAW_R0 = 0x100, 377 OPT_NO_RAW_R0, 378 OPT_RAW_R3, 379 OPT_NO_RAW_R3, 380 OPT_PATM, 381 OPT_NO_PATM, 382 OPT_CSAM, 383 OPT_NO_CSAM, 384 OPT_COMMENT 385 }; 386 387 static const RTOPTIONDEF g_aOptions[] = 388 { 389 { "-startvm", 's', RTGETOPT_REQ_STRING }, 390 { "--startvm", 's', RTGETOPT_REQ_STRING }, 391 #ifdef VBOX_WITH_VRDP 392 { "-vrdpport", 'p', RTGETOPT_REQ_UINT32 }, 393 { "--vrdpport", 'p', RTGETOPT_REQ_UINT32 }, 394 { "-vrdaddress", 'a', RTGETOPT_REQ_STRING }, 395 { "--vrdaddress", 'a', RTGETOPT_REQ_STRING }, 396 #endif /* VBOX_WITH_VRDP defined */ 397 { "-rawr0", OPT_RAW_R0, 0 }, 398 { "--rawr0", OPT_RAW_R0, 0 }, 399 { "-norawr0", OPT_NO_RAW_R0, 0 }, 400 { "--norawr0", OPT_NO_RAW_R0, 0 }, 401 { "-rawr3", OPT_RAW_R3, 0 }, 402 { "--rawr3", OPT_RAW_R3, 0 }, 403 { "-norawr3", OPT_NO_RAW_R3, 0 }, 404 { "--norawr3", OPT_NO_RAW_R3, 0 }, 405 { "-patm", OPT_PATM, 0 }, 406 { "--patm", OPT_PATM, 0 }, 407 { "-nopatm", OPT_NO_PATM, 0 }, 408 { "--nopatm", OPT_NO_PATM, 0 }, 409 { "-csam", OPT_CSAM, 0 }, 410 { "--csam", OPT_CSAM, 0 }, 411 { "-nocsam", OPT_NO_CSAM, 0 }, 412 { "--nocsam", OPT_NO_CSAM, 0 }, 413 #ifdef VBOX_FFMPEG 414 { "-capture", 'c', 0 }, 415 { "--capture", 'c', 0 }, 416 { "--width", 'w', RTGETOPT_REQ_UINT32 }, 417 { "--height", 'h', RTGETOPT_REQ_UINT32 }, 418 { "--bitrate", 'r', RTGETOPT_REQ_UINT32 }, 419 { "--filename", 'f', RTGETOPT_REQ_STRING }, 420 #endif /* VBOX_FFMPEG defined */ 421 { "-comment", OPT_COMMENT, RTGETOPT_REQ_STRING }, 422 { "--comment", OPT_COMMENT, RTGETOPT_REQ_STRING } 423 }; 424 323 425 // parse the command line 324 for (int curArg = 1; curArg < argc; curArg++) 325 { 326 if (strcmp(argv[curArg], "-startvm") == 0) 327 { 328 if (++curArg >= argc) 329 { 330 LogError("VBoxHeadless: ERROR: missing VM identifier!", 0); 331 return -1; 332 } 333 id = argv[curArg]; 334 /* If the argument was not a UUID, then it must be a name. */ 335 if (!id) 336 { 337 name = argv[curArg]; 338 } 339 } 426 int ch; 427 int i = 1; 428 RTOPTIONUNION ValueUnion; 429 while ((ch = RTGetOpt(argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), &i, &ValueUnion))) 430 { 431 if (ch < 0) 432 { 433 show_usage(); 434 exit(-1); 435 } 436 switch(ch) 437 { 438 case 's': 439 id = ValueUnion.psz; 440 /* If the argument was not a UUID, then it must be a name. */ 441 if (!id) 442 name = ValueUnion.psz; 443 break; 340 444 #ifdef VBOX_WITH_VRDP 341 else if (strcmp(argv[curArg], "-vrdpport") == 0) 342 { 343 if (++curArg >= argc) 344 { 345 LogError("VBoxHeadless: ERROR: missing VRDP port value!", 0); 346 return -1; 347 } 348 vrdpPort = atoi(argv[curArg]); 349 } 350 else if (strcmp(argv[curArg], "-vrdpaddress") == 0) 351 { 352 if (++curArg >= argc) 353 { 354 LogError("VBoxHeadless: ERROR: missing VRDP address value!", 0); 355 return -1; 356 } 357 vrdpAddress = argv[curArg]; 358 } 359 #endif 360 else if (strcmp(argv[curArg], "-rawr0") == 0) 361 { 362 fRawR0 = true; 363 } 364 else if (strcmp(argv[curArg], "-norawr0") == 0) 365 { 366 fRawR0 = false; 367 } 368 else if (strcmp(argv[curArg], "-rawr3") == 0) 369 { 370 fRawR3 = true; 371 } 372 else if (strcmp(argv[curArg], "-norawr3") == 0) 373 { 374 fRawR3 = false; 375 } 376 else if (strcmp(argv[curArg], "-patm") == 0) 377 { 378 fPATM = true; 379 } 380 else if (strcmp(argv[curArg], "-nopatm") == 0) 381 { 382 fPATM = false; 383 } 384 else if (strcmp(argv[curArg], "-csam") == 0) 385 { 386 fCSAM = true; 387 } 388 else if (strcmp(argv[curArg], "-nocsam") == 0) 389 { 390 fCSAM = false; 391 } 392 #ifdef VBOX_FFMPEG 393 else if (strcmp(argv[curArg], "-capture") == 0) 394 { 395 fFFMPEG = true; 396 } 397 #endif 398 else if (strcmp(argv[curArg], "-comment") == 0) 399 { 400 /* We could just ignore this, but check the syntax for consistency... */ 401 if (++curArg >= argc) 402 { 403 LogError("VBoxHeadless: ERROR: missing comment!", 0); 404 return -1; 405 } 406 } 407 else 408 { 409 LogError("VBoxHeadless: ERROR: unknown option '%s'", argv[curArg]); 410 show_usage(); 411 return -1; 412 } 413 } 414 415 #ifdef VBOX_FFMPEG 416 const char *pszEnvTemp; 417 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREWIDTH")) != 0) 418 { 419 errno = 0; 420 ulFrameWidth = strtoul(pszEnvTemp, 0, 10); 421 if (errno != 0) 422 { 423 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREWIDTH environment variable", 0); 424 return -1; 425 } 426 if (ulFrameWidth < 512 || ulFrameWidth > 2048 || ulFrameWidth % 2) 427 { 428 LogError("VBoxHeadless: ERROR: please specify an even VBOX_CAPTUREWIDTH variable between 512 and 2048", 0); 429 return -1; 430 } 431 } 432 433 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREHEIGHT")) != 0) 434 { 435 errno = 0; 436 ulFrameHeight = strtoul(pszEnvTemp, 0, 10); 437 if (errno != 0) 438 { 439 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREHEIGHT environment variable", 0); 440 return -1; 441 } 442 if (ulFrameHeight < 384 || ulFrameHeight > 1536 || ulFrameHeight % 2) 443 { 444 LogError("VBoxHeadless: ERROR: please specify an even VBOX_CAPTUREHEIGHT variable between 384 and 1536", 0); 445 return -1; 446 } 447 } 448 449 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREBITRATE")) != 0) 450 { 451 errno = 0; 452 ulBitRate = strtoul(pszEnvTemp, 0, 10); 453 if (errno != 0) 454 { 455 LogError("VBoxHeadless: ERROR: invalid VBOX_CAPTUREBITRATE environment variable", 0); 456 return -1; 457 } 458 if (ulBitRate < 300000 || ulBitRate > 1000000) 459 { 460 LogError("VBoxHeadless: ERROR: please specify an even VBOX_CAPTUREHEIGHT variable between 300000 and 1000000", 0); 461 return -1; 462 } 463 } 464 465 if ((pszEnvTemp = RTEnvGet("VBOX_CAPTUREFILE")) == 0) 466 /* Standard base name */ 467 pszEnvTemp = "VBox-%d.vob"; 468 469 /* Make sure we only have %d or %u (or none) */ 470 char *pcPercent = (char*)strchr(pszEnvTemp, '%'); 445 case 'p': 446 vrdpPort = ValueUnion.u32; 447 break; 448 case 'a': 449 vrdpAddress = ValueUnion.psz; 450 break; 451 #endif /* VBOX_WITH_VRDP defined */ 452 case OPT_RAW_R0: 453 fRawR0 = true; 454 break; 455 case OPT_NO_RAW_R0: 456 fRawR0 = false; 457 break; 458 case OPT_RAW_R3: 459 fRawR3 = true; 460 break; 461 case OPT_NO_RAW_R3: 462 fRawR3 = false; 463 break; 464 case OPT_PATM: 465 fPATM = true; 466 break; 467 case OPT_NO_PATM: 468 fPATM = false; 469 break; 470 case OPT_CSAM: 471 fCSAM = true; 472 break; 473 case OPT_NO_CSAM: 474 fCSAM = false; 475 break; 476 #ifdef VBOX_FFMPEG 477 case 'c': 478 fFFMPEG = true; 479 break; 480 case 'w': 481 ulFrameWidth = ValueUnion.u32; 482 break; 483 case 'h': 484 ulFrameHeight = ValueUnion.u32; 485 break; 486 case 'r': 487 ulBitRate = ValueUnion.u32; 488 break; 489 case 'f': 490 pszFileNameParam = ValueUnion.psz; 491 break; 492 #endif /* VBOX_FFMPEG defined */ 493 default: /* comment */ 494 break; 495 } 496 } 497 498 #ifdef VBOX_FFMPEG 499 if (ulFrameWidth < 512 || ulFrameWidth > 2048 || ulFrameWidth % 2) 500 { 501 LogError("VBoxHeadless: ERROR: please specify an even frame width between 512 and 2048", 0); 502 return -1; 503 } 504 if (ulFrameHeight < 384 || ulFrameHeight > 1536 || ulFrameHeight % 2) 505 { 506 LogError("VBoxHeadless: ERROR: please specify an even frame height between 384 and 1536", 0); 507 return -1; 508 } 509 if (ulBitRate < 300000 || ulBitRate > 1000000) 510 { 511 LogError("VBoxHeadless: ERROR: please specify an even bitrate between 300000 and 1000000", 0); 512 return -1; 513 } 514 /* Make sure we only have %d or %u (or none) in the file name specified */ 515 char *pcPercent = (char*)strchr(pszFileNameParam, '%'); 471 516 if (pcPercent != 0 && *(pcPercent + 1) != 'd' && *(pcPercent + 1) != 'u') 472 517 { 473 LogError("VBoxHeadless: ERROR: Only %%d and %%u are allowed in the VBOX_CAPTUREFILE parameter.", -1);518 LogError("VBoxHeadless: ERROR: Only %%d and %%u are allowed in the capture file name.", -1); 474 519 return -1; 475 520 } 476 477 521 /* And no more than one % in the name */ 478 522 if (pcPercent != 0 && strchr(pcPercent + 1, '%') != 0) 479 523 { 480 LogError("VBoxHeadless: ERROR: Only one format modifier is allowed in the VBOX_CAPTUREFILE parameter.", -1);524 LogError("VBoxHeadless: ERROR: Only one format modifier is allowed in the capture file name.", -1); 481 525 return -1; 482 526 } 483 RTStrPrintf(&pszMPEGFile[0], RTPATH_MAX, psz EnvTemp, RTProcSelf());527 RTStrPrintf(&pszMPEGFile[0], RTPATH_MAX, pszFileNameParam, RTProcSelf()); 484 528 #endif /* defined VBOX_FFMPEG */ 485 529
Note:
See TracChangeset
for help on using the changeset viewer.