-
-
Save leandromoreira/131cfd8de665404b1cff6442d150ffe1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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