关闭

[置顶] ffmpeg中将每帧视频图像保存为图片的方法

标签: c++ffmpegvideo
1149人阅读 评论(0) 收藏 举报
分类:
bool  FrameDump::saveBMP(const char* filename){
<span style="white-space:pre">	</span>bool ret = save_pic(in_frm, AV_PIX_FMT_BGR24, AV_CODEC_ID_BMP, filename, dst_width, dst_height);
<span style="white-space:pre">	</span>return ret;
}
bool  FrameDump::saveJPG(const char* filename){
<span style="white-space:pre">	</span>bool ret = save_pic(in_frm, AV_PIX_FMT_YUVJ420P, AV_CODEC_ID_MJPEG, filename, dst_width, dst_height);
<span style="white-space:pre">	</span>return ret;
}
bool  FrameDump::savePNG(const char* filename){
<span style="white-space:pre">	</span>bool ret = save_pic(in_frm, AV_PIX_FMT_RGBA, AV_CODEC_ID_PNG, filename, dst_width, dst_height) ;
<span style="white-space:pre">	</span>return ret;
}
bool  FrameDump::save_pic(AVFrame *frm, AVPixelFormat pfmt, AVCodecID cid, const char* filename, int width, int height){
	AVFrame* m_frm = change_frm_fmt(in_frm, (AVPixelFormat)in_frm->format, pfmt, width, height);
	if (m_frm == NULL)
		return false;
	int outbuf_size = 900000;
	uint8_t * outbuf = (uint8_t*)malloc(outbuf_size);
	int got_pkt = 0;


	/*uint8_t *Pbuffer;
	int numBytes;
	AVFrame *pFrameRGB;
	pFrameRGB = av_frame_alloc();
	numBytes = avpicture_get_size(pfmt, dst_width, dst_height);
	Pbuffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));


	avpicture_fill((AVPicture*)pFrameRGB, Pbuffer, AV_PIX_FMT_RGBA, dst_width, dst_height);
	struct SwsContext* img_convert_ctx;
	img_convert_ctx = sws_getContext(in_frm->width, in_frm->height, (AVPixelFormat)in_frm->format,
		dst_width, dst_height, AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);
	sws_scale(img_convert_ctx, in_frm->data, in_frm->linesize, 0, in_frm->height,
		pFrameRGB->data, pFrameRGB->linesize);*/




	FILE* pf;
	pf = fopen(filename, "wb");
	if (pf == NULL)
		return false;
	AVPacket pkt;
	AVCodec *pCodecRGB24;
	AVCodecContext *ctx = NULL;
	pCodecRGB24 = avcodec_find_encoder(cid);
	if (!pCodecRGB24)
		return false;
	ctx = avcodec_alloc_context3(pCodecRGB24);
	ctx->bit_rate = 3000000;
	ctx->width = dst_width;
	ctx->height = dst_height;
	AVRational rate;
	rate.num = 1;
	rate.den = 25;
	ctx->time_base = rate;
	ctx->gop_size = 10;
	ctx->max_b_frames = 0;
	ctx->thread_count = 1;
	ctx->pix_fmt = pfmt;


	int ret = avcodec_open2(ctx, pCodecRGB24, NULL);
	if (ret < 0)
		return false;


	int size = ctx->width * ctx->height;
	av_init_packet(&pkt);
	static int got_packet_ptr = 0;
	pkt.size = outbuf_size;
	pkt.data = outbuf;
	got_pkt = avcodec_encode_video2(ctx, &pkt, m_frm, &got_packet_ptr);
	m_frm->pts++;
	if (got_pkt == 0)
	{
		fwrite(pkt.data, 1, pkt.size, pf);
	}
	else{
		return false;
	}
	fclose(pf);
	return true;
}

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:3856次
    • 积分:106
    • 等级:
    • 排名:千里之外
    • 原创:6篇
    • 转载:3篇
    • 译文:0篇
    • 评论:0条
    文章分类