Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C++
Tip/Trick

FFmpeg Tutorial

Rate me:
Please Sign up or sign in to vote.
4.75/5 (18 votes)
21 Sep 2010CPOL3 min read 149.8K   31   15
Introduction



In this post, we will see how you can use FFmpeg libraries in your application and decode movie files. I am taking dranger's first tutorial as the source and I will build it using Visual C++ 6.0. You can find the source code here.


Background



If you do not have the ffmpeg libraries with you, you will need download the source code and build it. You will find a step by step tutorial for building the libraries here



Code



Opening the video file




First, we initialize ffmpeg by calling 'av_register_all()' at the starting of the program. This registers all supported formats and codecs.

Next we open the video file using av_open_input_file(). The first parameter is the pointer to the 'AVFormatContext' which we will use in our program to refer to the video file. The second parameter is the name of the file to be opened. The last three parameters are for file format, buffer size, and format options. By setting it to NULL and 0, libavformat detects and fills values on it own.

We dump information about the input file using 'dump_format()'

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 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);



Opening the decoder




We loop through the list of streams present in the input file to locate the 'video' stream present in it. The file can typically contain one or more audio/video streams in it. Once a video stream is located, we extract the codec type of the video stream. This codec type will be used to initialize the decode as shown below.

videoStream=-1;
for(i=0; inb_streams; i++)
  videoStream=i;
  break;
}
if(videoStream==-1)
return -1;
pCodecCtx=pFormatCtx->streams[videoStream]->codec;


avcodec_find_decoder accepts the codec id (obtained from the video file) as input and returns a pointer of type 'AVCodec'. The codec is then open by making a call to 'avcodec_open()'

pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1;
}

if(avcodec_open(pCodecCtx, pCodec)>0)
return -1;




Allocating buffers for decoding




This part of the code is fairly elementary. We calculate the size of the buffer required, allocate a temporary buffer using malloc

numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, 
pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,  
pCodecCtx->width, pCodecCtx->height); 

Decoding frames


Well, this is the part of the code that excites me the most, decoding the frames :) You read frames the file using av_read_frame. This function returns a non-zero positive value if the file has not reached its end. After receiving a packet, we first check if it is a video packet. We pass the CodecContext, Packet data and size as the input to the function. If decoding of the packet is successful, the 'pFrame' pointer points to decoded data. Success or failure of the decoding process is indicated by the 'frameFinished'. If it fails, the value will be '0'. We then convert the data from YUV to RBG format so that we can write to the file. I guess, by default, the decoded data is of type YUV.

i=0; 
while(av_read_frame(pFormatCtx, &packet)>=0) {
if(packet.stream_index==videoStream) {
  avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); 
  if(frameFinished) {
  img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
                (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
                pCodecCtx->height);

if(++i>=5)
  SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,i);
  }
}


Cleanup


This is the part of the code i normally hate. But any mistake in this part will result in memory leaks or run time exceptions. So we will release all the allocated buffers and frames using av_free(). We will also close the codecontext and file using avcodec_close() and av_close_input_file() respectively.

av_free(buffer); 
av_free(pFrameRGB);
av_free(pFrame);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);


Steps to add ffmpeg libraries to your code


1. Create a win32 console application using Visual C++ 6.0. Let us name it 'ffmpeg'.
2. Create a folder named 'Libraries' and copy the following library files (avcodec.lib, avformat.lib, avutil.lib) to that folder.
3. Add 'tutorial1.c' to the project.
4. Open the 'Project Settings' dialog box and in the C++ tab, choose the 'Preprocessor' option. In the 'Additional Include Directories', add the folder where the ffmpeg header files are present. (ex: C:\ffmpeg)
5. Navigate to the 'Link' tab in the project settings dialog and choose 'Input' as category. Add the following libraries to the 'Object/Library modules' text box : avformat.lib avcodec.lib avutil.lib. Add 'libraries' to the 'Additional Library path' text box.
6. Build the application and you should be able to build it without any problem.



















License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Benson Guandaru20-Sep-22 5:04
Benson Guandaru20-Sep-22 5:04 
QuestionHOW TO GET OUTPUT FRAME AS THE VIDEO CLIP Pin
Member 116676425-May-15 21:40
Member 116676425-May-15 21:40 
Question.h264 metadata Pin
Kirthivasan23-Sep-14 1:46
Kirthivasan23-Sep-14 1:46 
Questioni have some error in the source code... Pin
Stefan Mitev18-Jun-13 2:46
Stefan Mitev18-Jun-13 2:46 
AnswerRe: i have some error in the source code... Pin
RajaManikandan_R18-Jun-13 19:54
RajaManikandan_R18-Jun-13 19:54 
QuestionFFmpeg Tutorial Pin
Someshwar Sutar26-Apr-13 1:58
professionalSomeshwar Sutar26-Apr-13 1:58 
AnswerRe: FFmpeg Tutorial Pin
RajaManikandan_R28-Apr-13 23:50
RajaManikandan_R28-Apr-13 23:50 
GeneralRe: FFmpeg Tutorial Pin
boys2129-Jun-13 2:44
boys2129-Jun-13 2:44 
GeneralRe: FFmpeg Tutorial Pin
RajaManikandan_R30-Jun-13 1:27
RajaManikandan_R30-Jun-13 1:27 
GeneralRe: FFmpeg Tutorial Pin
boys2130-Jun-13 6:23
boys2130-Jun-13 6:23 
QuestionWhere can I find the source? Pin
hackamada25-Feb-13 12:20
hackamada25-Feb-13 12:20 
AnswerRe: Where can I find the source? Pin
RajaManikandan_R26-Feb-13 0:14
RajaManikandan_R26-Feb-13 0:14 
Questionffmpeg lib Pin
nguyenle.it6-Jun-12 18:54
nguyenle.it6-Jun-12 18:54 
AnswerRe: ffmpeg lib Pin
RajaManikandan_R7-Jun-12 18:52
RajaManikandan_R7-Jun-12 18:52 
GeneralReason for my vote of 5 nice one Pin
e35649221-Sep-10 20:46
e35649221-Sep-10 20:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.