mpenkov / ffmpeg-tutorial Goto Github PK
View Code? Open in Web Editor NEWA set of tutorials that demonstrates how to write a video player based on FFmpeg
Home Page: http://www.ffmpeg.org/documentation.html
A set of tutorials that demonstrates how to write a video player based on FFmpeg
Home Page: http://www.ffmpeg.org/documentation.html
I'm trying to use my gpu for my frame decoding in C++, but I am unable to activate gpu hardware acceleration.
I tried stuff mentionned in this thread :
https://stackoverflow.com/questions/25791722/using-hardware-acceleration-with-libavcodec#25952193
Regarding frameFinished in https://github.com/mpenkov/ffmpeg-tutorial/blob/master/tutorial01.c#L150
It is worth noting here that frameFinished might result in missed frames. Consider the following frame format:
F1 F2 F3 F4
II BB BB PP
01 02 03 04 PTS (Presentation Time Stamp)
01 04 02 03 DTS (Decode Time Stamp)
In the above example, avcodec_decode_video2 would return got_frame with nonzero for the first frame, but what happens with the Bi-Predictive frame for frame 02? A Bi-Predictive frame requires both the previous frame and a frame somewhere after it. In this case, the frame it needs is in frame 04. So avcodec_decode_video2 will return got_frame with zero for frame 02 and 03, buffering the frames until it can properly decode them. At the point that it hits frame 04, it is now able to decode frame 02 and 03, and will return got_picture with a non-zero value.
01 02 03 04 05 06 Calls to avcodec_decode_video2
++ -- -- ++ ?? ?? got_picture_ptr returns zero on -- frames
01 -- -- 02 03 04 Order of returned frames
What does all this mean? By the time we reach the end of the file, although we have presented every frame we can decode in correct order, we will have ended up skipping a given number of frames for every B frame. The presentation will stop after decoding every frame, but not after processing every frame by our application!
As discussed, those frames are buffered internally. This means that at the end of the primary loop, every frame has been processed, and all of the information needed to process every B frame is now complete. For every time that got_picture returned zero, our buffer still grew by a frame, but avcodec_decode_video2 couldn't return it as it would be out of Presentation Time Stamp order. So where are those frames by the time we reach the end of this primary loop?
They are simply sitting buffered. To display all of the frames in the file, we must continue to call avcodec_decode_video2 after the primary loop until got_frame returns zero. This should be the number of times that got_picture returned zero.
[root@dev ffmpeg-tutorial-master]# make
Package libavformat was not found in the pkg-config search path.
Perhaps you should add the directory containing libavformat.pc' to the PKG_CONFIG_PATH environment variable No package 'libavformat' found Package libavcodec was not found in the pkg-config search path. Perhaps you should add the directory containing
libavcodec.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavcodec' found
Package libswscale was not found in the pkg-config search path.
Perhaps you should add the directory containing libswscale.pc' to the PKG_CONFIG_PATH environment variable No package 'libswscale' found Package libavutil was not found in the pkg-config search path. Perhaps you should add the directory containing
libavutil.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavutil' found
Package sdl was not found in the pkg-config search path.
Perhaps you should add the directory containing sdl.pc' to the PKG_CONFIG_PATH environment variable No package 'sdl' found Package libavformat was not found in the pkg-config search path. Perhaps you should add the directory containing
libavformat.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavformat' found
Package libavcodec was not found in the pkg-config search path.
Perhaps you should add the directory containing libavcodec.pc' to the PKG_CONFIG_PATH environment variable No package 'libavcodec' found Package libswscale was not found in the pkg-config search path. Perhaps you should add the directory containing
libswscale.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libswscale' found
Package libavutil was not found in the pkg-config search path.
Perhaps you should add the directory containing libavutil.pc' to the PKG_CONFIG_PATH environment variable No package 'libavutil' found Package sdl was not found in the pkg-config search path. Perhaps you should add the directory containing
sdl.pc'
to the PKG_CONFIG_PATH environment variable
No package 'sdl' found
mkdir -p obj
mkdir -p bin
gcc -Wall -ggdb obj/tutorial01.o -lm -o bin/tutorial01.out
obj/tutorial01.o: In function main': /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:70: undefined reference to
av_register_all'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:73: undefined reference to avformat_open_input' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:77: undefined reference to
avformat_find_stream_info'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:81: undefined reference to av_dump_format' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:97: undefined reference to
avcodec_find_decoder'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:103: undefined reference to avcodec_open2' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:107: undefined reference to
avcodec_alloc_frame'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:110: undefined reference to avcodec_alloc_frame' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:115: undefined reference to
avpicture_get_size'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:117: undefined reference to av_malloc' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:120: undefined reference to
sws_getContext'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:137: undefined reference to avpicture_fill' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:146: undefined reference to
avcodec_decode_video2'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:152: undefined reference to sws_scale' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:171: undefined reference to
av_free_packet'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:142: undefined reference to av_read_frame' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:175: undefined reference to
av_free'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:176: undefined reference to av_free' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:179: undefined reference to
av_free'
/home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:182: undefined reference to avcodec_close' /home/sangeeta/ffmpeg/ffmpeg-tutorial-master/tutorial01.c:185: undefined reference to
avformat_close_input'
collect2: ld returned 1 exit status
make: *** [bin/tutorial01.out] Error 1
Tutorial07 plays the video without sound.
I use ffmpeg version 3.0 , and when I complie the codes I get some trouble.
AVCodecContext has no member named release_buffer
.
I'm following the tutorial (updating things bc some of the methods/properties where deprecated )
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <stdlib.h>
// #include <ffmpeg/swscale.h>
// How to compile it: gcc -o stream stream.c -lavutil -lavformat -lavcodec -lz -lavutil -lm
// How to run it ./stream <video>
int main (int argc, char * argv []) {
av_register_all();
AVFormatContext * pFormatCtx = NULL;
// Open a video file
if (avformat_open_input(&pFormatCtx, argv[1], NULL, 0) != 0)
return -1; // Couldn't open the file
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
return -1; // Counldn't find the stream
int i;
int videoStream;
AVCodecContext * pCodecCtxOrig = NULL;
AVCodecParameters * pCodecCtx = NULL;
AVCodecContext * pCodecRealCtx = NULL;
videoStream = -1;
// pFormatCtx->streams is an array of pointers
// of size pFormatCtx->nb_strams
for (i = 0; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
if (videoStream == -1)
return -1;
// get the pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codecpar;
AVCodec *pCodec = NULL;
// Find the decoder for the video stream
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
fprintf(stderr, "Unsupported Codec \n");
return -1; // Codec not found
}
// Open Codec
avcodec_parameters_to_context(pCodecRealCtx, pCodecCtx);
if (avcodec_open2(pCodecRealCtx, pCodec, NULL) < 0)
return -1;
AVFrame *pFrame = NULL;
AVFrame *pFrameRGB = NULL;
// Allocate video frame
pFrame = av_frame_alloc();
pFrameRGB = av_frame_alloc();
if (pFrameRGB == NULL)
return -1;
uint8_t *buffer = NULL;
int numBytes;
// numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 0);
return 0;
}
this is my code for now but for numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height, 0);
I get:
stream.c:65:14: warning: implicit declaration of function 'av_image_get_buffer_size' is invalid in C99 [-Wimplicit-function-declaration]
but it should be defined on the imports right? based on this
Line 113 and Line 135 in Tutorial 1:
PIX_FMT_RGB24 should be AV_PIX_FMT_RGB24.
Thanks :-)
The included Makefile fails if OpenCV is not installed despite the fact that none of the .c files reference OpenCV headers.
Hi
The image and the audio are not synchronized anymore, once seeked backwards. The image seems to be in the correct position unlike the audio. However, the video becomes synchronized subsequently being seeked forwards once.
Do you have any idea how to resolve this problem?
AVCODEC_MAX_AUDIO_FRAME_SIZE macro seems to be taken off from the latest ffmpeg build. I replaced it with a constant 192000 (suggestions seen elsewhere). Is there any other way this can be handled?
http://ffmpeg.org/doxygen/0.6/avcodec_8h.html#d18c27288ee5928bfb77fb2aead28c7e
Used your latest. Video works fine but Audio is scratchy and high pitched. Can you provide any guidance on this ?
Thanks
Sean
I have an error while compiling the Tutorial07.c
release_buffer is not a member of AVCodecContext. The version of ffmpeg that I used is 4.1. I could not found the alternative of release_buffer. It is obsolute in 4.1.
Change to AVFormatContext *pFormatCtx = NULL; otherwise it will crash!
This:
for(y=0; y<height; y++){
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
can be done with this:
fwrite(pFrame->data[0], 1, width*height*3, pFile);
which is easier to understand, at least for me, since I'm not acknowledged with ffmpeg.
The tutorials are compiling fine but I am getting segmentation fault error when running tutorial4 it or any other tutorials after that.
gdb backtrace
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x1813 of process 84136]
0x00007fff955d4432 in stack_not_16_byte_aligned_error ()
from /usr/lib/system/libdyld.dylib
(gdb) backtrace
#0 0x00007fff955d4432 in stack_not_16_byte_aligned_error ()
from /usr/lib/system/libdyld.dylib
#1 0x000000010a2f1ee0 in ?? ()
#2 0x0000000101341008 in ?? () from /usr/local/lib/libSDL-1.2.0.dylib
#3 0x00000000000005d0 in ?? ()
#4 0x00000001013362e9 in RunThread () from /usr/local/lib/libSDL-1.2.0.dylib
#5 0x00000001013362e2 in RunThread () from /usr/local/lib/libSDL-1.2.0.dylib
#6 0x00007fff8d1d4268 in ?? () from /usr/lib/system/libsystem_pthread.dylib
#7 0x0000000000006f23 in ?? ()
#8 0x000000010a2f2000 in ?? ()
#9 0x000000010a2f1f50 in ?? ()
#10 0x00007fff8d1d41e5 in ?? () from /usr/lib/system/libsystem_pthread.dylib
#11 0x0000000000000000 in ?? ()
(gdb)
Is seems like it is related to the sdl library. How do i resolve it.
here is the link to the valgring output(was just playing around with it) (http://pastebin.com/1HFrwP5W) maybe this can help find the problem.
when compile the code i found many attributes have been deprecated,like avcodec_default_get_buffer,avcodec_default_release_buffer,etc. so which version should i use for compiling this code?
br@breach ~/ffmpeg-tutorial $ make
mkdir -p obj
mkdir -p bin
gcc -Wall -ggdb `pkg-config --cflags libavcodec libavformat libavutil libswscale sdl` -Wno-write-strings -Wno-unused -c tutorial01.c -o obj/tutorial01.o
gcc -Wall -ggdb `pkg-config --cflags libavcodec libavformat libavutil libswscale sdl` -Wno-write-strings -Wno-unused `pkg-config --cflags libavcodec libavformat libavutil libswscale sdl` `pkg-config --libs libavcodec libavformat libavutil libswscale sdl` -lm obj/tutorial01.o -o bin/tutorial01.out
obj/tutorial01.o: In function `main':
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:69: undefined reference to `av_register_all'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:72: undefined reference to `avformat_open_input'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:76: undefined reference to `avformat_find_stream_info'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:80: undefined reference to `av_dump_format'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:96: undefined reference to `avcodec_find_decoder'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:102: undefined reference to `avcodec_open2'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:106: undefined reference to `avcodec_alloc_frame'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:109: undefined reference to `avcodec_alloc_frame'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:114: undefined reference to `avpicture_get_size'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:116: undefined reference to `av_malloc'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:118: undefined reference to `sws_getContext'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:136: undefined reference to `avpicture_fill'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:145: undefined reference to `avcodec_decode_video2'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:152: undefined reference to `sws_scale'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:170: undefined reference to `av_free_packet'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:141: undefined reference to `av_read_frame'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:174: undefined reference to `av_free'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:175: undefined reference to `av_free'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:178: undefined reference to `av_free'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:181: undefined reference to `avcodec_close'
/home/br/dev/cocktail/build/ffmpeg-tutorial/tutorial01.c:184: undefined reference to `avformat_close_input'
collect2: ld returned 1 exit status
make: *** [bin/tutorial01.out] Error 1
where
br@breach ~/ffmpeg-tutorial $ echo `pkg-config --cflags libavcodec libavformat libavutil libswscale sdl` && echo `pkg-config --libs libavcodec libavformat libavutil libswscale sdl`
-D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL
-lavcodec -lavformat -lavutil -lswscale -lSDL
I disabled if(++i<=5)
check in tutorial01.c
and ran it on my mp4 video. The count of ppm files I got is 137.
But when I tried to extract frames with ffmpeg
tool I got 305 frames, instead of 137.
ffmpeg -i video.mp4 /tmp/fr/%4d.bmp
I also checked it with keyframe extraction and also got 274 frames instead of 137.
ffmpeg -i video.mp4 -vf select='eq(pict_type\,I)' /tmp/fr/%4d.bmp
So, why tutorial01 produce less frames than ffmpeg tool?
Attempting to seek prints this to standard error:
/home/misha/nobackup/big_buck_bunny_1080p_surround.avi: error while seeking
Would you happen to know about any tutorials that contain code for reading an encoded frame from memory and then streaming it to the network?
I noticed 2 problems about the function "synchronize_audio".
I tried to resample the result with "swr_convert", without success.
Thanks for your repository anyway.
A lot of noise/clicking/garbage can be heard in addition to something that vaguely resembles what should be heard.
I've tried tutorial 3 and 7 but neither play audio correctly. I've tried this on both Windows 7 and Arch Linux with the latest versions of g++/VC++, FFMpeg and SDL to the same avail. FFPlay works fine on both machines.
$ make
mkdir -p obj
mkdir -p bin
gcc -Wall -ggdb tutorial01.c -c -o obj/tutorial01.o
tutorial01.c:20:32: fatal error: libavcodec/avcodec.h: No such file or directory
#include <libavcodec/avcodec.h>
^
compilation terminated.
Makefile:34: recipe for target 'obj/tutorial01.o' failed
make: *** [obj/tutorial01.o] Error 1
I get this "libavcodec/avcodec.h not found" when following the original tutorial and when trying to make this tutorial.
Had you looked into migrating the tutorials to avconv
what to do with PKG_CONFIG_PATH environment variable?
cannot find SDL is there more info?
using wheezy
some error messages removed with:
$ ldd /usr/bin/ffmpeg
..
libavutil.so.51 => /usr/lib/x86_64-linux-gnu/libavutil.so.51 (0x00007f0873a04000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0873782000)
..
hence
$ export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/
$ export LD_LIBRARY_PATH=/lib/x86_64-linux-gnu/
but
$ cd ffmpeg-tutorial-master
$ make
Package libavformat was not found in the pkg-config search path.
Perhaps you should add the directory containing libavformat.pc' to the PKG_CONFIG_PATH environment variable No package 'libavformat' found Package libavcodec was not found in the pkg-config search path. Perhaps you should add the directory containing
libavcodec.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavcodec' found
Package libswscale was not found in the pkg-config search path.
Perhaps you should add the directory containing libswscale.pc' to the PKG_CONFIG_PATH environment variable No package 'libswscale' found Package libavutil was not found in the pkg-config search path. Perhaps you should add the directory containing
libavutil.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavutil' found
Package sdl was not found in the pkg-config search path.
Perhaps you should add the directory containing sdl.pc' to the PKG_CONFIG_PATH environment variable No package 'sdl' found Package libavformat was not found in the pkg-config search path. Perhaps you should add the directory containing
libavformat.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavformat' found
Package libavcodec was not found in the pkg-config search path.
Perhaps you should add the directory containing libavcodec.pc' to the PKG_CONFIG_PATH environment variable No package 'libavcodec' found Package libswscale was not found in the pkg-config search path. Perhaps you should add the directory containing
libswscale.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libswscale' found
Package libavutil was not found in the pkg-config search path.
Perhaps you should add the directory containing libavutil.pc' to the PKG_CONFIG_PATH environment variable No package 'libavutil' found Package sdl was not found in the pkg-config search path. Perhaps you should add the directory containing
sdl.pc'
to the PKG_CONFIG_PATH environment variable
No package 'sdl' found
If the video window is closed while the video is still playing, then the application exits. However, if the video has finished playing back, then closing the video window does not achieve anything.
This only applies to tutorials 4 and above.
Hi!
I took the player (tutorial07.c), changed the main into: playVideoFile(char *filename); by simply exchanging argv to filename. Everything works, but when exiting the player function, the memory isn't freed.
In order to get audio to play the second time you want to play a movie within your program, you need to call SDL_CloseAudio(); in the SDL_QUIT event, like so:
case SDL_QUIT:
SDL_CloseAudio();
is->quit = 1;
otherwise the audio won't play the 2nd time you start a video.
I'm trying to find what memory to free, but I'm new to thread programming (just started learning them by writing a web server in C for a Lab at the university), so I haven't found what to free yet.
When playing a video, it allocates the memory it needs, then stays there. And when closing down the
video, the memory is still allocated, in my case around 72Mb
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.