#ifdef __cplusplus
extern "C" {
#endif
#include <libavcodec\avcodec.h>
#include <libavformat\avformat.h>
#include <libswscale\swscale.h>
#include <libavutil\pixfmt.h>
#include <libavutil\imgutils.h>
#ifdef __cplusplus
}
#endif
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"swscale.lib")
AVFrame* readImageToFrame(const char* imageFileName)
{
AVFormatContext* pFormatCtx = NULL;
if (avformat_open_input(&(pFormatCtx), imageFileName, NULL, NULL) != 0)
{
printf("Can't open image file '%s'\n", imageFileName);
return NULL;
}
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
{
printf("Can't find stream\n");
return NULL;
}
av_dump_format(pFormatCtx, 0, imageFileName, false);
AVCodecContext* pCodecCtx;
int index = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
const AVCodec* dec = avcodec_find_decoder(pFormatCtx->streams[index]->codecpar->codec_id);
pCodecCtx = avcodec_alloc_context3(dec);
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[index]->codecpar);
// Find the decoder for the video stream
const AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (!pCodec)
{
printf("Codec not found\n");
return NULL;
}
// Open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
{
printf("Could not open codec\n");
return NULL;
}
//
AVFrame* pFrame;
pFrame = av_frame_alloc();
if (!pFrame)
{
printf("Can't allocate memory for AVFrame\n");
return NULL;
}
AVPacket packet;
packet.data = NULL;
packet.size = 0;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
if (packet.stream_index != index)
{
continue;
}
int ret = avcodec_send_packet(pCodecCtx, &packet);
if (ret >= 0)
{
ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
break;
}
}
else
{
break;
}
}
AVFrame* dst = av_frame_alloc();
int width = pFrame->width;
int height = pFrame->height;
// 设置转帧格式
enum AVPixelFormat dst_pixfmt = AV_PIX_FMT_YUV420P;//AV_PIX_FMT_RGBA
// 计算转帧需要的buff大小
int numBytes = av_image_get_buffer_size(dst_pixfmt, width, height, 1);
uint8_t* buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
av_image_fill_arrays(dst->data, dst->linesize, buffer, dst_pixfmt, width, height, 1);
struct SwsContext* convert_ctx = NULL;
convert_ctx = sws_getContext(pFrame->width, pFrame->height, pCodecCtx->pix_fmt, width, height, dst_pixfmt,SWS_POINT, NULL, NULL, NULL);
sws_scale(convert_ctx, pFrame->data, pFrame->linesize, 0, pFrame->height,dst->data, dst->linesize);
sws_freeContext(convert_ctx);
av_frame_free(&pFrame);
avformat_close_input(&(pFormatCtx));
avcodec_free_context(&pCodecCtx);
dst->format = (int)dst_pixfmt;
dst->width = width;
dst->height = height;
dst->pts = 0;
dst->pkt_dts = 0;
return dst;
}