Hi, I am writing a program to convert video files into MPEG-1 format. You see, there are a set of parameters to define the converting process, like frame rate, bit rate, etc. For MPEG-1 format, only 23.976, 24, 25, 29.97, 30, 59.94, 60 fps(frame per second) are available.
To test the converted MPEG-1 file, I first use Windows Media Player (9.0) to play the converted file. I found that the MPEG-1 files with frame rate other than 60fps are played well. But when playing the MPEG-1 files with frame rate of 60fps, mosaic effect appears apparently. Then I played these converted files by other decoders which are Moonlight-Elecard MPEG2 Video Decoder, Nero Video Decoder, Libavcodec, and Libmpeg2. With these decoders, the MPEG-1 files with frame rate of 60fps play well with no mosaic effect at all.
I have also tried other encoder software (Panasonic MPEG-1 Encoder) to generate MPEG-1 files. Results are the same: by Windows Media Player, mosaic effect happens only if playing 60 fps MPEG-1 files; other frame rates are OK. And by other video decoders listed above, all frame rates (include 60fps) are OK with no mosaic effect at all.
I use DirectShow to find the decoder used by Windows Media Player, that is Microsoft MPEG1 Video Decoder 2.0. And I found that decoder depends on quartz.dll.
In addition, I convert the file format into MPEG-1 by ffmpeg, the source code is listed below.
int PPMtoMPEG1(const char *input_file,
const char *output_file,
unsigned int width /* = 0 */,
unsigned int height /* = 0 */,
unsigned int bit_rate /* = 12000 */,
int overwrite /* = 1 */,
void *para /* = NULL */)
{
const int max_int_oct_bits = 20;
int argc = 14;
if (width > 0 && height > 0) { // '-s size' option is needed
argc += 2;
}
if (overwrite) { // '-y' option is needed
++ argc;
}
// We need an additional argument, see below.
char **argv = new char *[argc + 1];
// see whether output file exists.
FILE *fp = fopen(output_file, "rb");
if (NULL != fp) {
if (!overwrite) { // file exists but we are not allowed to overwrite it
sprintf(error_message, "Output file '%s' already exists\n", output_file);
return 1;
}
fclose(fp);
}
int opt_index = 0;
// dumb argument
argv[opt_index ++] = "ffmpeg";
// '-r fps' set frame rate (default = 25)
argv[opt_index ++] = "-r";
char opt_fps[11];
sprintf(opt_fps, "%d/%d", frame_rate_tab[frame_rate_index], MPEG1_FRAME_RATE_BASE);
argv[opt_index ++] = opt_fps;
// '-i filename' input file name
argv[opt_index ++] = "-i";
char *input = new char[strlen(input_file) + 1];
strcpy(input, input_file);
argv[opt_index ++] = input;
// '-s size' set frame size (WxH)
if (width > 0 && height > 0) {
argv[opt_index ++] = "-s";
char opt_size[max_int_oct_bits * 2 + 1];
sprintf(opt_size, "%dx%d", width, height);
argv[opt_index ++] = opt_size;
}
// '-b bitrate' set video bitrate (in kbit/s)
argv[opt_index ++] = "-b";
char opt_bitrate[max_int_oct_bits + 1];
sprintf(opt_bitrate, "%d", bit_rate);
argv[opt_index ++] = opt_bitrate;
// '-y' overwrite output file
if (overwrite) {
argv[opt_index ++] = "-y";
}
// '-qscale q' use fixed video quantiser scale (VBR), always 1 to indicate the excellent quality
argv[opt_index ++] = "-qscale";
argv[opt_index ++] = "1";
// '-vcodec codec' force video codec to mpeg1video.
argv[opt_index ++] = "-vcodec";
argv[opt_index ++] = "mpeg1video";
// '-r fps' set frame rate (default = 25)
argv[opt_index ++] = "-r";
argv[opt_index ++] = opt_fps;
// output file name
char *output = new char[strlen(output_file) + 1];
strcpy(output, output_file);
argv[opt_index ++] = output;
// the standard requires that argv[argc] be a null pointer - from K&R. Section.5.10.
argv[opt_index] = NULL;
FFMPEG_PROGRESS_CALLBACK cb = NULL;
if (progress_callback) {
cb = ToMPEG1CallBack;
}
int ret = ffmpegmain(argc, argv, error_message, cb, para);
delete []output;
delete []input;
delete []argv;
return ret;
}
Because the users of my program will play the converted MPEG-1 files by Windows Media Player, I have to make sure why mosaic effect happens: is it because Windows Media Player could not play 60fps MPEG-1 files? Or is it because of codes errors? Could you help me? Thanks a lot.