读取png照片内容到AVFrame中



#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;
}

 

posted @ 2022-05-23 09:36  微风中带有暖意  阅读(160)  评论(0)    收藏  举报