Skip to content

Instantly share code, notes, and snippets.

@leandromoreira
Created October 29, 2017 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leandromoreira/131cfd8de665404b1cff6442d150ffe1 to your computer and use it in GitHub Desktop.
Save leandromoreira/131cfd8de665404b1cff6442d150ffe1 to your computer and use it in GitHub Desktop.
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <stdio.h>
#include <stdarg.h>
void logging(const char *fmt, ...);
int main(int argc, const char *argv[])
{
av_register_all();
AVFormatContext *pFormatContext = avformat_alloc_context();
if (!pFormatContext) {
logging("ERROR could not allocate memory for Format Context");
return -1;
}
if (avformat_open_input(&pFormatContext, argv[1], NULL, NULL) != 0)
{
logging("ERROR could not open the file");
return -1;
}
if (avformat_find_stream_info(pFormatContext, NULL) < 0)
{
logging("ERROR could not get the stream info");
return -1;
}
AVCodec *pCodec = NULL;
AVStream *pStream = NULL;
int video_stream_index = -1;
// find the first video stream
for (int i = 0; i < pFormatContext->nb_streams; i++)
{
video_stream_index = i;
pStream = pFormatContext->streams[i];
AVCodecParameters *pCodecParameters = pStream->codecpar;
// https://ffmpeg.org/doxygen/trunk/group__lavu__misc.html#gga9a84bba4713dfced21a1a56163be1f48ac1a46f59be5c6c2d3412ab172d6b8cf5
if (pCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) {
pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
if (pCodec==NULL)
{
logging("ERROR unsupported codec!");
return -1;
}
break;
}
}
// https://ffmpeg.org/doxygen/trunk/structAVCodecContext.html
AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec);
if (!pCodecContext) {
logging("failed to allocated memory for AVCodecContext");
return -1;
}
if (avcodec_open2(pCodecContext, pCodec, NULL) < 0) {
logging("failed to open codec through avcodec_open2");
return -1;
}
// https://ffmpeg.org/doxygen/trunk/structAVFrame.html
AVFrame *pFrame = av_frame_alloc(); // pict_type, )ts
if (!pFrame) {
logging("failed to allocated memory for AVFrame");
return -1;
}
// https://ffmpeg.org/doxygen/trunk/structAVPacket.html
AVPacket *pPacket = av_packet_alloc(); // pts, dts, duration
if (!pPacket) {
logging("failed to allocated memory for AVPacket");
return -1;
}
while (av_read_frame(pFormatContext, pPacket) >= 0) {
int response = avcodec_send_packet(pCodecContext, pPacket);
if (response < 0) {
logging("error sending packet");
return -1;
}
while (response >= 0) {
response = avcodec_receive_frame(pCodecContext, pFrame);
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
logging("error receiving frame");
return -1;
} else if (response < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
printf("saving frame %3d\n", pCodecContext->frame_number);
}
}
logging("releasing all the resources");
avformat_close_input(&pFormatContext);
avformat_free_context(pFormatContext);
av_packet_free(&pPacket);
av_frame_free(&pFrame);
avcodec_free_context(&pCodecContext);
return 0;
}
void logging(const char *fmt, ...)
{
va_list args;
fprintf( stderr, "LOG: " );
va_start( args, fmt );
vfprintf( stderr, fmt, args );
va_end( args );
fprintf( stderr, "\n" );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment