static void parse_args(cl_info_t *cl, int argc, char **argv) { int c; cl->offset = 0; cl->framecount = 0; cl->aspect = y4m_sar_SQUARE; cl->interlace = Y4M_ILACE_NONE; cl->framerate = y4m_fps_NTSC; cl->interleave = 0; cl->repeatlast = 0; cl->ss_mode = DEFAULT_CHROMA_MODE; cl->verbosity = 1; cl->bgr = 0; cl->fdin = fileno(stdin); /* default to stdin */ while ((c = getopt(argc, argv, "BA:F:I:Lo:n:rS:v:h")) != -1) { switch (c) { case 'A': if (y4m_parse_ratio(&(cl->aspect), optarg) != Y4M_OK) { mjpeg_error("Could not parse ratio: '%s'", optarg); goto ERROR_EXIT; } break; case 'F': if (y4m_parse_ratio(&(cl->framerate), optarg) != Y4M_OK) { mjpeg_error("Could not parse ratio: '%s'", optarg); goto ERROR_EXIT; } break; case 'I': switch (optarg[0]) { case 'p': cl->interlace = Y4M_ILACE_NONE; break; case 't': cl->interlace = Y4M_ILACE_TOP_FIRST; break; case 'b': cl->interlace = Y4M_ILACE_BOTTOM_FIRST; break; default: mjpeg_error("Unknown value for interlace: '%c'", optarg[0]); goto ERROR_EXIT; break; } break; case 'L': cl->interleave = 1; break; case 'B': cl->bgr = 1; break; case 'o': if ((cl->offset = atoi(optarg)) < 0) mjpeg_error_exit1("Offset must be >= 0: '%s'", optarg); break; case 'n': if ((cl->framecount = atoi(optarg)) < 0) mjpeg_error_exit1("Frame count must be >= 0: '%s'", optarg); break; case 'r': cl->repeatlast = 1; break; case 'S': cl->ss_mode = y4m_chroma_parse_keyword(optarg); if (cl->ss_mode == Y4M_UNKNOWN) { mjpeg_error("Unknown subsampling mode option: %s", optarg); goto ERROR_EXIT; } else if (!chroma_sub_implemented(cl->ss_mode)) { mjpeg_error("Unsupported subsampling mode option: %s", optarg); goto ERROR_EXIT; } break; case 'v': cl->verbosity = atoi(optarg); if ((cl->verbosity < 0) || (cl->verbosity > 2)) mjpeg_error("Verbosity must be 0, 1, or 2: '%s'", optarg); break; case 'h': usage(argv[0]); exit(0); break; case '?': default: goto ERROR_EXIT; break; } } /* optional remaining argument is a filename */ if (optind == (argc - 1)) { if ((cl->fdin = open(argv[optind], O_RDONLY | O_BINARY)) == -1) mjpeg_error_exit1("Failed to open '%s': %s", argv[optind], strerror(errno)); } else if (optind != argc) goto ERROR_EXIT; mjpeg_default_handler_verbosity(cl->verbosity); mjpeg_info("Command-line Parameters:"); mjpeg_info(" framerate: %d:%d", cl->framerate.n, cl->framerate.d); mjpeg_info(" pixel aspect ratio: %d:%d", cl->aspect.n, cl->aspect.d); mjpeg_info(" pixel packing: %s", cl->bgr?"BGR":"RGB"); mjpeg_info(" interlace: %s%s", mpeg_interlace_code_definition(cl->interlace), (cl->interlace == Y4M_ILACE_NONE) ? "" : (cl->interleave) ? " (interleaved PPM input)" : " (field-sequential PPM input)"); mjpeg_info(" starting frame: %d", cl->offset); if (cl->framecount == 0) mjpeg_info(" # of frames: all%s", (cl->repeatlast) ? ", repeat last frame forever" : ", until input exhausted"); else mjpeg_info(" # of frames: %d%s", cl->framecount, (cl->repeatlast) ? ", repeat last frame until done" : ", or until input exhausted"); mjpeg_info(" chroma subsampling: %s", y4m_chroma_description(cl->ss_mode)); /* DONE! */ return; ERROR_EXIT: mjpeg_error("For usage hints, use option '-h'. Please take a hint."); exit(1); }
int y4m_parse_stream_tags(char *s, y4m_stream_info_t *i) { char *token, *value; char tag; int err; /* parse fields */ for (token = strtok(s, Y4M_DELIM); token != NULL; token = strtok(NULL, Y4M_DELIM)) { if (token[0] == '\0') continue; /* skip empty strings */ tag = token[0]; value = token + 1; switch (tag) { case 'W': /* width */ i->width = atoi(value); if (i->width <= 0) return Y4M_ERR_RANGE; break; case 'H': /* height */ i->height = atoi(value); if (i->height <= 0) return Y4M_ERR_RANGE; break; case 'F': /* frame rate (fps) */ if ((err = y4m_parse_ratio(&(i->framerate), value)) != Y4M_OK) return err; if (i->framerate.n < 0) return Y4M_ERR_RANGE; break; case 'I': /* interlacing */ switch (value[0]) { case 'p': i->interlace = Y4M_ILACE_NONE; break; case 't': i->interlace = Y4M_ILACE_TOP_FIRST; break; case 'b': i->interlace = Y4M_ILACE_BOTTOM_FIRST; break; case 'm': i->interlace = Y4M_ILACE_MIXED; break; case '?': default: i->interlace = Y4M_UNKNOWN; break; } break; case 'A': /* sample (pixel) aspect ratio */ if ((err = y4m_parse_ratio(&(i->sampleaspect), value)) != Y4M_OK) return err; if (i->sampleaspect.n < 0) return Y4M_ERR_RANGE; break; case 'C': i->chroma = y4m_chroma_parse_keyword(value); if (i->chroma == Y4M_UNKNOWN) return Y4M_ERR_HEADER; break; case 'X': /* 'X' meta-tag */ if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err; break; default: /* possible error on unknown options */ if (_y4mparam_allow_unknown_tags) { /* unknown tags ok: store in xtag list and warn... */ if ((err = y4m_xtag_add(&(i->x_tags), token)) != Y4M_OK) return err; mjpeg_warn("Unknown stream tag encountered: '%s'", token); } else { /* unknown tags are *not* ok */ return Y4M_ERR_BADTAG; } break; } } /* Without 'C' tag or any other chroma spec, default to 420jpeg */ if (i->chroma == Y4M_UNKNOWN) i->chroma = Y4M_CHROMA_420JPEG; /* Error checking... */ /* - Width and Height are required. */ if ((i->width == Y4M_UNKNOWN) || (i->height == Y4M_UNKNOWN)) return Y4M_ERR_HEADER; /* - Non-420 chroma and mixed interlace require level >= 1 */ if (_y4mparam_feature_level < 1) { if ((i->chroma != Y4M_CHROMA_420JPEG) && (i->chroma != Y4M_CHROMA_420MPEG2) && (i->chroma != Y4M_CHROMA_420PALDV)) return Y4M_ERR_FEATURE; if (i->interlace == Y4M_ILACE_MIXED) return Y4M_ERR_FEATURE; } /* ta da! done. */ return Y4M_OK; }
int main(int argc, char **argv) { int sts, c, width = 640, height = 480, noheader = 0; int Y = 16, U = 128, V = 128, chroma_mode = Y4M_CHROMA_420MPEG2; int numframes = 1, force = 0; y4m_ratio_t rate_ratio = y4m_fps_NTSC; y4m_ratio_t aspect_ratio = y4m_sar_SQUARE; int plane_length[3]; u_char *yuv[3]; y4m_stream_info_t ostream; y4m_frame_info_t oframe; char interlace = Y4M_ILACE_NONE; opterr = 0; y4m_accept_extensions(1); while ((c = getopt(argc, argv, "Hfx:w:h:r:i:a:Y:U:V:n:")) != EOF) { switch (c) { case 'H': noheader = 1; break; case 'a': sts = y4m_parse_ratio(&aspect_ratio, optarg); if (sts != Y4M_OK) mjpeg_error_exit1("Invalid aspect: %s", optarg); break; case 'w': width = atoi(optarg); break; case 'h': height = atoi(optarg); break; case 'r': sts = y4m_parse_ratio(&rate_ratio, optarg); if (sts != Y4M_OK) mjpeg_error_exit1("Invalid rate: %s", optarg); break; case 'Y': Y = atoi(optarg); break; case 'U': U = atoi(optarg); break; case 'V': V = atoi(optarg); break; case 'i': switch (optarg[0]) { case 'p': interlace = Y4M_ILACE_NONE; break; case 't': interlace = Y4M_ILACE_TOP_FIRST; break; case 'b': interlace = Y4M_ILACE_BOTTOM_FIRST; break; default: usage(); } break; case 'x': chroma_mode = y4m_chroma_parse_keyword(optarg); if (chroma_mode == Y4M_UNKNOWN) { if (strcmp(optarg, "help") != 0) mjpeg_error("Invalid -x arg '%s'", optarg); chroma_usage(); } break; case 'f': force = 1; break; case 'n': numframes = atoi(optarg); break; case '?': default: usage(); } } if (width <= 0) mjpeg_error_exit1("Invalid Width: %d", width); if (height <= 0) mjpeg_error_exit1("Invalid Height: %d", height); if (!force && (Y < 16 || Y > 235)) mjpeg_error_exit1("16 < Y < 235"); if (!force && (U < 16 || U > 240)) mjpeg_error_exit1("16 < U < 240"); if (!force && (V < 16 || V > 240)) mjpeg_error_exit1("16 < V < 240"); y4m_init_stream_info(&ostream); y4m_init_frame_info(&oframe); y4m_si_set_width(&ostream, width); y4m_si_set_height(&ostream, height); y4m_si_set_interlace(&ostream, interlace); y4m_si_set_framerate(&ostream, rate_ratio); y4m_si_set_sampleaspect(&ostream, aspect_ratio); y4m_si_set_chroma(&ostream, chroma_mode); if (y4m_si_get_plane_count(&ostream) != 3) mjpeg_error_exit1("Only the 3 plane formats supported"); plane_length[0] = y4m_si_get_plane_length(&ostream, 0); plane_length[1] = y4m_si_get_plane_length(&ostream, 1); plane_length[2] = y4m_si_get_plane_length(&ostream, 2); yuv[0] = malloc(plane_length[0]); yuv[1] = malloc(plane_length[1]); yuv[2] = malloc(plane_length[2]); /* * Now fill the array once with black but use the provided Y, U and V values */ memset(yuv[0], Y, plane_length[0]); memset(yuv[1], U, plane_length[1]); memset(yuv[2], V, plane_length[2]); if (noheader == 0) y4m_write_stream_header(fileno(stdout), &ostream); while (numframes--) y4m_write_frame(fileno(stdout), &ostream, &oframe, yuv); free(yuv[0]); free(yuv[1]); free(yuv[2]); y4m_fini_stream_info(&ostream); y4m_fini_frame_info(&oframe); exit(0); }
int main(int argc, char *argv[]) { AVFormatContext *pFormatCtx; AVInputFormat *avif = NULL; int i, videoStream; AVCodecContext *pCodecCtx; AVCodec *pCodec; AVFrame *pFrame; AVFrame *pFrame444; AVPacket packet; int frameFinished; int numBytes; uint8_t *buffer; int fdOut = 1 ; int yuv_interlacing = Y4M_UNKNOWN; int yuv_ss_mode = Y4M_UNKNOWN; y4m_ratio_t yuv_frame_rate; y4m_ratio_t yuv_aspect; // need something for chroma subsampling type. int write_error_code; int header_written = 0; int convert = 0; int stream = 0; enum PixelFormat convert_mode; const static char *legal_flags = "chI:F:A:S:o:s:f:"; int y; int frame_data_size ; uint8_t *yuv_data[3] ; y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; y4m_init_stream_info(&streaminfo); y4m_init_frame_info(&frameinfo); yuv_frame_rate.d = 0; yuv_aspect.d = 0; // Register all formats and codecs av_register_all(); while ((i = getopt (argc, argv, legal_flags)) != -1) { switch (i) { case 'I': switch (optarg[0]) { case 'p': yuv_interlacing = Y4M_ILACE_NONE; break; case 't': yuv_interlacing = Y4M_ILACE_TOP_FIRST; break; case 'b': yuv_interlacing = Y4M_ILACE_BOTTOM_FIRST; break; default: mjpeg_error("Unknown value for interlace: '%c'", optarg[0]); return -1; break; } break; case 'F': if( Y4M_OK != y4m_parse_ratio(&yuv_frame_rate, optarg) ) mjpeg_error_exit1 ("Syntax for frame rate should be Numerator:Denominator"); break; case 'A': if( Y4M_OK != y4m_parse_ratio(&yuv_aspect, optarg) ) { if (!strcmp(optarg,PAL)) { y4m_parse_ratio(&yuv_aspect, "128:117"); } else if (!strcmp(optarg,PAL_WIDE)) { y4m_parse_ratio(&yuv_aspect, "640:351"); } else if (!strcmp(optarg,NTSC)) { y4m_parse_ratio(&yuv_aspect, "4320:4739"); } else if (!strcmp(optarg,NTSC_WIDE)) { y4m_parse_ratio(&yuv_aspect, "5760:4739"); } else { mjpeg_error_exit1 ("Syntax for aspect ratio should be Numerator:Denominator"); } } break; case 'S': yuv_ss_mode = y4m_chroma_parse_keyword(optarg); if (yuv_ss_mode == Y4M_UNKNOWN) { mjpeg_error("Unknown subsampling mode option: %s", optarg); mjpeg_error("Try: 420mpeg2 444 422 411"); return -1; } break; case 'o': fdOut = open (optarg,O_CREAT|O_WRONLY,0644); if (fdOut == -1) { mjpeg_error_exit1 ("Cannot open file for writing"); } break; case 'c': convert = 1; break; case 's': stream = atoi(optarg); break; case 'f': avif = av_find_input_format (optarg); break; case 'h': case '?': print_usage (argv); return 0 ; break; } } //fprintf (stderr,"optind: %d\n",optind); optind--; argc -= optind; argv += optind; if (argc == 1) { print_usage (argv); return 0 ; } // Open video file if(av_open_input_file(&pFormatCtx, argv[1], avif, 0, NULL)!=0) return -1; // Couldn't open file // Retrieve stream information if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error dump_format(pFormatCtx, 0, argv[1], 0); // Find the first video stream videoStream=-1; for(i=0; i<pFormatCtx->nb_streams; i++) if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) { // mark debug //fprintf (stderr,"Video Codec ID: %d (%s)\n",pFormatCtx->streams[i]->codec->codec_id ,pFormatCtx->streams[i]->codec->codec_name); if (videoStream == -1 && stream == 0) { // May still be overridden by the -s option videoStream=i; } if (stream == i) { videoStream=i; break; } } if(videoStream==-1) return -1; // Didn't find a video stream // Get a pointer to the codec context for the video stream pCodecCtx=pFormatCtx->streams[videoStream]->codec; // Find the decoder for the video stream pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) return -1; // Codec not found // Open codec if(avcodec_open(pCodecCtx, pCodec)<0) return -1; // Could not open codec // Read framerate, aspect ratio and chroma subsampling from Codec if (yuv_frame_rate.d == 0) { yuv_frame_rate.n = pFormatCtx->streams[videoStream]->r_frame_rate.num; yuv_frame_rate.d = pFormatCtx->streams[videoStream]->r_frame_rate.den; } if (yuv_aspect.d == 0) { yuv_aspect.n = pCodecCtx-> sample_aspect_ratio.num; yuv_aspect.d = pCodecCtx-> sample_aspect_ratio.den; } // 0:0 is an invalid aspect ratio default to 1:1 if (yuv_aspect.d == 0 || yuv_aspect.n == 0 ) { yuv_aspect.n=1; yuv_aspect.d=1; } if (convert) { if (yuv_ss_mode == Y4M_UNKNOWN) { print_usage(); return 0; } else { y4m_accept_extensions(1); switch (yuv_ss_mode) { case Y4M_CHROMA_420MPEG2: convert_mode = PIX_FMT_YUV420P; break; case Y4M_CHROMA_422: convert_mode = PIX_FMT_YUV422P; break; case Y4M_CHROMA_444: convert_mode = PIX_FMT_YUV444P; break; case Y4M_CHROMA_411: convert_mode = PIX_FMT_YUV411P; break; case Y4M_CHROMA_420JPEG: convert_mode = PIX_FMT_YUVJ420P; break; default: mjpeg_error_exit1("Cannot convert to this chroma mode"); break; } } } else if (yuv_ss_mode == Y4M_UNKNOWN) { switch (pCodecCtx->pix_fmt) { case PIX_FMT_YUV420P: yuv_ss_mode=Y4M_CHROMA_420MPEG2; break; case PIX_FMT_YUV422P: yuv_ss_mode=Y4M_CHROMA_422; break; case PIX_FMT_YUV444P: yuv_ss_mode=Y4M_CHROMA_444; break; case PIX_FMT_YUV411P: yuv_ss_mode=Y4M_CHROMA_411; break; case PIX_FMT_YUVJ420P: yuv_ss_mode=Y4M_CHROMA_420JPEG; break; default: yuv_ss_mode=Y4M_CHROMA_444; convert_mode = PIX_FMT_YUV444P; // is there a warning function mjpeg_error("Unsupported Chroma mode. Upsampling to YUV444\n"); // enable advanced yuv stream y4m_accept_extensions(1); convert = 1; break; } } // Allocate video frame pFrame=avcodec_alloc_frame(); // Output YUV format details // is there some mjpeg_info functions? fprintf (stderr,"YUV Aspect Ratio: %d:%d\n",yuv_aspect.n,yuv_aspect.d); fprintf (stderr,"YUV frame rate: %d:%d\n",yuv_frame_rate.n,yuv_frame_rate.d); fprintf (stderr,"YUV Chroma Subsampling: %d\n",yuv_ss_mode); // Set the YUV stream details // Interlace is handled when the first frame is read. y4m_si_set_sampleaspect(&streaminfo, yuv_aspect); y4m_si_set_framerate(&streaminfo, yuv_frame_rate); y4m_si_set_chroma(&streaminfo, yuv_ss_mode); // Loop until nothing read while(av_read_frame(pFormatCtx, &packet)>=0) { // Is this a packet from the video stream? if(packet.stream_index==videoStream) { // Decode video frame avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); // Did we get a video frame? if(frameFinished) { // Save the frame to disk // As we don't know interlacing until the first frame // we wait until the first frame is read before setting the interlace flag // and outputting the YUV header // It also appears that some codecs don't set width or height until the first frame either if (!header_written) { if (yuv_interlacing == Y4M_UNKNOWN) { if (pFrame->interlaced_frame) { if (pFrame->top_field_first) { yuv_interlacing = Y4M_ILACE_TOP_FIRST; } else { yuv_interlacing = Y4M_ILACE_BOTTOM_FIRST; } } else { yuv_interlacing = Y4M_ILACE_NONE; } } if (convert) { // initialise conversion to different chroma subsampling pFrame444=avcodec_alloc_frame(); numBytes=avpicture_get_size(convert_mode, pCodecCtx->width, pCodecCtx->height); buffer=(uint8_t *)malloc(numBytes); avpicture_fill((AVPicture *)pFrame444, buffer, convert_mode, pCodecCtx->width, pCodecCtx->height); } y4m_si_set_interlace(&streaminfo, yuv_interlacing); y4m_si_set_width(&streaminfo, pCodecCtx->width); y4m_si_set_height(&streaminfo, pCodecCtx->height); chromalloc(yuv_data,&streaminfo); fprintf (stderr,"YUV interlace: %d\n",yuv_interlacing); fprintf (stderr,"YUV Output Resolution: %dx%d\n",pCodecCtx->width, pCodecCtx->height); if ((write_error_code = y4m_write_stream_header(fdOut, &streaminfo)) != Y4M_OK) { mjpeg_error("Write header failed: %s", y4m_strerr(write_error_code)); } header_written = 1; } if (convert) { // convert to 444 /* +#ifdef HAVE_LIBSWSCALE + struct SwsContext* img_convert_ctx = + sws_getContext(context->width, context->height, PIX_FMT_RGB24, + context->width, context->height, context->pix_fmt, + SWS_BICUBIC, NULL, NULL, NULL); + + sws_scale(img_convert_ctx, pict->data, pict->linesize, + 0, context->height, encodable->data, + encodable->linesize); + + sws_freeContext (img_convert_ctx); +#else img_convert((AVPicture *)encodable, context->pix_fmt, (AVPicture *)pict, PIX_FMT_RGB24, context->width, context->height); - + (AVPicture *)pict, PIX_FMT_RGB24, + context->width, context->height); +#endif */ struct SwsContext* img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrame444->data, pFrame444->linesize); sws_freeContext (img_convert_ctx); //img_convert((AVPicture *)pFrame444, convert_mode, (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height); chromacpy(yuv_data,pFrame444,&streaminfo); } else { chromacpy(yuv_data,pFrame,&streaminfo); } write_error_code = y4m_write_frame( fdOut, &streaminfo, &frameinfo, yuv_data); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); } y4m_fini_stream_info(&streaminfo); y4m_fini_frame_info(&frameinfo); free(yuv_data[0]); free(yuv_data[1]); free(yuv_data[2]); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); return 0; }
/** parse_commandline * Parses the commandline for the supplied parameters. * in: argc, argv: the classic commandline parameters */ static void parse_commandline(int argc, char ** argv, parameters_t *param) { int c; param->pngformatstr = NULL; param->begin = 0; param->numframes = -1; param->framerate = y4m_fps_UNKNOWN; param->interlace = Y4M_UNKNOWN; param->interleave = -1; param->verbose = 1; param->ss_mode = DEFAULT_CHROMA_MODE; //param->mza_filename = NULL; //param->make_z_alpha = 0; /* parse options */ for (;;) { if (-1 == (c = getopt(argc, argv, "I:hv:L:b:j:n:f:z:S:"))) break; switch (c) { case 'j': param->pngformatstr = strdup(optarg); break; #if 0 case 'z': param->mza_filename = strdup(optarg); param->make_z_alpha = 1; break; #else case 'z': mjpeg_error("Z encoding currently unsupported !\n"); exit(-1); break; #endif case 'S': param->ss_mode = y4m_chroma_parse_keyword(optarg); if (param->ss_mode == Y4M_UNKNOWN) { mjpeg_error_exit1("Unknown subsampling mode option: %s", optarg); } else if (!chroma_sub_implemented(param->ss_mode)) { mjpeg_error_exit1("Unsupported subsampling mode option: %s", optarg); } break; case 'b': param->begin = atol(optarg); break; case 'n': param->numframes = atol(optarg); break; case 'f': param->framerate = mpeg_conform_framerate(atof(optarg)); break; case 'I': switch (optarg[0]) { case 'p': param->interlace = Y4M_ILACE_NONE; break; case 't': param->interlace = Y4M_ILACE_TOP_FIRST; break; case 'b': param->interlace = Y4M_ILACE_BOTTOM_FIRST; break; default: mjpeg_error_exit1 ("-I option requires arg p, t, or b"); } break; case 'L': param->interleave = atoi(optarg); if ((param->interleave != 0) && (param->interleave != 1)) mjpeg_error_exit1 ("-L option requires arg 0 or 1"); break; case 'v': param->verbose = atoi(optarg); if (param->verbose < 0 || param->verbose > 2) mjpeg_error_exit1( "-v option requires arg 0, 1, or 2"); break; case 'h': default: usage(argv[0]); exit(1); } } if (param->pngformatstr == NULL) { mjpeg_error("%s: input format string not specified. (Use -j option.)", argv[0]); usage(argv[0]); exit(1); } if (Y4M_RATIO_EQL(param->framerate, y4m_fps_UNKNOWN)) { mjpeg_error("%s: framerate not specified. (Use -f option)", argv[0]); usage(argv[0]); exit(1); } }