ezMPEG is an easy-to-use and easy-to-understand MPEG1 video encoder API
- Introduction
- Features
- Missing Features / ToDo
- Known Bugs
- ezMPEG API
- Main data structure
- ezMPEGStream
- Generating a MPEG video stream
- ezMPEG_Init(...)
- ezMPEG_Start(...)
- ezMPEG_Add(...)
- ezMPEG_Finalize(...)
- Error handling
- ezMPEG_GetLastError(...)
- Tools
- ezMPEG_Resize(...)
- Main data structure
- Example
- How to compile
- Legal
ezMPEG is an easy-to-use and easy-to-understand MPEG1 video encoder API. I started this project because I wanted to know how MPEG works and the best way to learn it is to implement my own encoder. So I downloaded the ISO specs and began to read and code. My implementation doesn't have the goal to be better than all the others. The goal is to have a simple, portable and esay to understand code for all the people (and for me) who wants to know how a MPEG1 video encoder works.
- based on ISO-11172.2 Specs
- I frame encoding
- GOP size can be defined
- quality settings can be defined
- multiple parallel streams
- variable bitrate
- some more I forgot
- implement P and B frames
- constant bitrate
- better data structures (especially for images)
- some optimizations
- ...
Nothing found till now :)
This chapter explains how the API works and what is needed to make it work.
The structure ezMPEGStream contains all the needed information for the current MPEG stream.
typedef struct ezMPEGStream {
char *outfile; // name of the resulting MPEG file
FILE *out; // filehandler for the outfile
int hsize; // height in pixels
int vsize; // width in pixels
int picture_rate; // how many pictures per sec
int gop_size; // how many pictures per GOP
int dc_prev[3]; // storage for the dc-coefficients
double q_scale; // scaling factor (quality setting)
// settings for the output buffer
int picture_count;
int buffersize;
int buffercount;
char *buffer;
int buf;
int pos;
short error_code;
char error_msg[256];
} ezMPEGStream;
There is no need to change the entries of ezMPEGStream by hand. They've get all initialized
by ezMPEG_Init(...)
(see section 2.2.1)
This section will explain the function needed to encode a MPEG video. Please see the example in section 3 to see how to use the following function in your code.
This function initializes an instance of ezMPEGStream. It returns 0 (zero) if something went wrong.
int ezMPEG_Init(ezMPEGStream *ms, // ms is an instance of ezMPEGStream
const char *outfile, // name of the resulting MPEG file
int hsize, // height of the video in pixel
int vsize, // width of the video in pixel
int picture_rate, // how many pictures per sec (currently 25 is possible)
int gop_size, // how many pictures per GOP
int q_scale // quality setting, 1 (high quality) to 31 (low quality)
);
This function starts the MPEG stream, will say it opens the outfile and initilizes the buffer. It returns 0 (zero) if something went wrong.
int ezMPEG_Start(ezMPEGStream *ms);
This function adds a picture to the MPEG stream defined by the given instance of ezMPEGStream. It returns 0 (zero) if something went wrong.
int ezMPEG_Add(ezMPEGStream *ms,
unsigned char *picture
);
The pointer picture must point to an array of unsigned chars containing for every pixel three chars for red, green and blue. It looks like this:
picture[0] = R0, picture[1] = G0, picture[2] = B0, picture[3] = R1, .... where R0 is the red value of the first pixel, G0 is the green value of the first pixel and so on
This function closes the MPEG stream defined by the given instance of ezMPEGStream. It returns 0 (zero) if something went wrong.
int ezMPEG_Finalize(ezMPEGStream *ms);
After applying this function it is not possible to add any more pictures to this stream
This section explains how the error handling works
This function will return a string containing the last error message generated by a function of the API.
char *ezMPEG_GetLastError(ezMPEGStream *ms);
This section will give an overview of the current available tools for ezMPEG
This function resizes a picture to a given size.
void ezMPEG_Resize(ezMPEGStream *ms, // ms is an instance of ezMPEGStream
unsigned char *outbild, // pointer to an array containing the resized picture
unsigned char *inbild, // pointer to an array containing the picture to be reiszed
int x, // height of the original picture
int y, // width of the original picture
int u, // height of the resized picture
int v // widht of the resized picture
);
The resizing algorithm ist quite simple. So don't expect good results.
This chapter explains the example code how to use the ezMPEG API. It is based on the example you find in the 'example' directory in this release.
This example code will encode one picture to measure the duration of the encoding process.
// First we must include some header files
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Then include 'ezmpeg.h' to have access to the API
#include "../ezmpeg.h"
// Main
int main(int argc, char *argv[])
{
FILE *in;
int i, j, m;
// pointer to an array which holds the image
unsigned char *picture;
clock_t dur;
// create an instance of ezMPEGStream
ezMPEGStream ms;
// allocate memory for the picture
picture = (unsigned char *)malloc(3 * 320 * 240 * sizeof(char));
// here we initialize our instance of ezMPEGStream
// the output filename is 'ezmpeg_test.mpeg'
// height = 320
// width = 240
// picture rate = 25
// GOP size = 30
// quality = 2 (good quality)
// and we can see the usage of the error handling function
if(!ezMPEG_Init(&ms, "ezmpeg_test.mpeg", 320, 240, 25, 30, 2))
printf("%s\n", ezMPEG_GetLastError(&ms));
// here we start the MPEG stream
if(!ezMPEG_Start(&ms))
printf("%s\n", ezMPEG_GetLastError(&ms));
// in this loop we encode the same picture 75 times
for(m = 0; m < 75; m++) {
// read in the picture
if((in = fopen("ezmpeg_test.ppm", "rb")) == NULL)
exit(1);
fseek(in, 45, SEEK_SET);
j = 0;
do {
i = fgetc(in);
if(i != EOF)
picture[j++] = i;
else
break;
}while(i != EOF);
fclose(in);
// take the starting time
dur = clock();
// add the picture to the stream defind by 'ms'
if(!ezMPEG_Add(&ms, picture))
printf("%s\n", ezMPEG_GetLastError(&ms));
// take the time again
dur = clock() - dur;
// print out the encoding time
printf("Frame %4d: %f secs\n", m, (float)dur / (float)CLOCKS_PER_SEC);
}
// finally close the the MPEG stream
if(!ezMPEG_Finalize(&ms))
printf("%s\n", ezMPEG_GetLastError(&ms));
// return to the shell
return 0;
}
This section will explain how to compile your code.
To compile the example from chapter 3 which can be found in the 'example' directory in this release just chdir to the mentioned directory. Then type (if you use gcc)
gcc ezmpeg_example.c ../ezmpeg.c -o ezmpeg_example -lm
This should compile the code. After that you can execute 'ezmpeg_example' and it will create a MPEG video.
ezMPEG Copyright (c) 2002 Ingo Oppermann