ffmpeg 从yuv文件剪切一帧图片

#include "stdafx.h"
#ifdef _WIN32
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h"
#include "libavutil/avutil.h"
};
#else
//Linux...
#ifdef __cplusplus
extern "C"
{
#endif
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/parseutils.h>
#include <libavutil/avutil.h>
#ifdef __cplusplus
};
#endif
#endif

void encoder()
{
	const char *pOutFile = "cuc_view_encode.jpg";
	FILE*pFile = fopen("cuc_view_480x272.yuv", "rb");
	if (!pFile){
		return;
	}

	av_register_all();
	AVFormatContext *pFormatContext = avformat_alloc_context();
	AVOutputFormat *pOutputFormat = av_guess_format("mjpeg", pOutFile, NULL);
	pFormatContext->oformat = pOutputFormat;

	avio_open(&pFormatContext->pb, pOutFile, AVIO_FLAG_READ_WRITE);
	AVStream *pStream = avformat_new_stream(pFormatContext, 0);
	if (!pStream){
		return;
	}

	AVCodecContext*pCodecContext = NULL;
	pCodecContext = pStream->codec;
	pCodecContext->codec_id = pOutputFormat->video_codec;
	pCodecContext->codec_type = AVMEDIA_TYPE_VIDEO;
	pCodecContext->pix_fmt = PIX_FMT_YUVJ420P;

	pCodecContext->width = 480;
	pCodecContext->height = 272;

	pCodecContext->time_base.num = 1;
	pCodecContext->time_base.den = 25;


	AVCodec *pCodec = avcodec_find_encoder(pCodecContext->codec_id);//查找编码器
	if (!pCodec){
		return;
	}
	
	avcodec_open2(pCodecContext, pCodec, NULL);

	AVFrame *pFrame = av_frame_alloc();
	int nPicSize = avpicture_get_size(pCodecContext->pix_fmt, pCodecContext->width, pCodecContext->height);
	uint8_t *buf = (uint8_t*)av_malloc(nPicSize);
	avpicture_fill((AVPicture*)pFrame, buf, pCodecContext->pix_fmt, pCodecContext->width, pCodecContext->height);


	avformat_write_header(pFormatContext, NULL);

	AVPacket pkt;
	av_new_packet(&pkt, pCodecContext->width * pCodecContext->height * 3);
	if (fread(buf, 1, pCodecContext->width * pCodecContext->height*3/2, pFile) <=0){
		printf("Could not read input file.");
		return;
	}
	pFrame->data[0] = buf;  // 亮度Y
	pFrame->data[1] = buf+ pCodecContext->width * pCodecContext->height;  // U 
	pFrame->data[2] = buf+ pCodecContext->width * pCodecContext->height*5/4; // V

	//Encode
	int got_picture = 0;
	int ret = avcodec_encode_video2(pCodecContext, &pkt, pFrame, &got_picture);
	if(ret < 0){
		printf("Encode Error.\n");
		return ;
	}
	if (got_picture == 1){
		pkt.stream_index = pStream->index;
		ret = av_write_frame(pFormatContext, &pkt);
	}

	av_free_packet(&pkt);
	//Write Trailer
	av_write_trailer(pFormatContext);

	printf("Encode Successful.\n");

	if (pStream){
		avcodec_close(pStream->codec);
	}
	av_free(pFrame);
	av_free(buf);
	avio_close(pFormatContext->pb);
	avformat_free_context(pFormatContext);

	fclose(pFile);
	return ;
}

int _tmain(int argc, _TCHAR* argv[])
{
	encoder();
	return 0;
}
从雷神的代码里面拷贝的,整理了下。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值