ffmpeg解碼jpg並編碼成h264

直接代碼:

int getFileSize(const char* sFile)
{
	FILE* f = fopen(sFile, "rb");
	fseek(f,0,SEEK_END);
	int s = ftell(f);
	fclose(f);
	return s;
}
class CJpgQueue
{
public:
	CJpgQueue()
	{

	}
	~CJpgQueue()
	{

	}

	
	void AppendPicFromFile(string szFile)
	{
		int s = getFileSize(szFile.c_str());
	    FILE* f = fopen(szFile.c_str(), "rb");
		char* buffer = new char[s];
		fread(buffer,1,s,f);
		string data ;
		data.append(buffer,s);
		m_lstJpg.push_back(data);
		delete[] buffer;
	}

	string* GetData(int i)
	{
		if (m_lstJpg.empty())
		{
			return NULL;
		}
		int index = i%m_lstJpg.size();
		list<string>::iterator it;
		int j = 0;
		for (it=m_lstJpg.begin();it!=m_lstJpg.end();it++,j++)
		{
			if (index == j)
			{
				return &*it;
			}
		}
		return NULL;
	}


private:
	list<string> m_lstJpg;

};

int read_src_frame(int i,CJpgQueue* q, AVPacket* packet)
{
	string* s = q->GetData(i);
	packet->data = (uint8_t *)s->data();
	packet->size = s->size();
	
	return 0;
}

#define  CHECKPOINT(p) {  if(!p) throw "NULL"; }
#define  THROWERROR { char err[256]; sprintf(err,"error line:%d \r\n",__LINE__);throw err;  }
int _tmain(int argc, _TCHAR* argv[])
{

	//FileConvert* fc = new FileConvert();
	//fc->DecodeVideo("d:\\wildlife.wmv","d:\\wildlife.mp4");
	FILE* out = fopen("d:\\pgm\\out.h264","wb");
	FILE* outyuv = fopen("d:\\pgm\\out.yuv420p","wb"); //just testing

	try{
		CJpgQueue picQueue;
		for (int i=0;i<8;i++)
		{
			char name[20]={0};
			sprintf(name,"d:\\pgm\\image\\%d.jpg",i);
			picQueue.AppendPicFromFile(string(name));
		}

		av_register_all();

		AVCodec* dec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
		CHECKPOINT(dec)
			AVCodecContext* dec_ctx = avcodec_alloc_context3(dec);
		CHECKPOINT(dec_ctx)
		dec_ctx->width = 1024;
		dec_ctx->height = 768;
		dec_ctx->pix_fmt = AV_PIX_FMT_YUVJ444P;
		if(dec->capabilities&CODEC_CAP_TRUNCATED)
			dec_ctx->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */


		if(avcodec_open2(dec_ctx,dec,NULL)<0)
			THROWERROR

		AVCodec* enc = avcodec_find_encoder(AV_CODEC_ID_H264);
		CHECKPOINT(enc);
		AVCodecContext* enc_ctx = avcodec_alloc_context3(enc);
		CHECKPOINT(enc)
		enc_ctx->width = 640;
		enc_ctx->height = 480;
		enc_ctx->bit_rate = 500000;
		enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
		enc_ctx->time_base.den = 25;
		enc_ctx->time_base.num = 1;
		enc_ctx->gop_size = 12;
		enc_ctx->max_b_frames = 3;

		av_opt_set(enc_ctx->priv_data, "preset", "slow", 0);

		if (avcodec_open2(enc_ctx,enc,NULL)<0)
			THROWERROR

		SwsContext* sws_cxt = sws_getContext(dec_ctx->width,dec_ctx->height,dec_ctx->pix_fmt,
			enc_ctx->width,enc_ctx->height,enc_ctx->pix_fmt,SWS_BILINEAR,NULL,NULL,NULL);
		CHECKPOINT(sws_cxt);



		CHECKPOINT(out);
		AVFrame* src_frame = avcodec_alloc_frame();
		CHECKPOINT(src_frame);
		AVPacket src_packet;
		av_init_packet(&src_packet);
		src_packet.data = NULL;
		src_packet.size = 0;

		AVFrame* dst_frame = avcodec_alloc_frame();
		CHECKPOINT(dst_frame)
		int dst_size = av_image_alloc(dst_frame->data,dst_frame->linesize,
			enc_ctx->width,enc_ctx->height, enc_ctx->pix_fmt,32); 
		dst_frame->width = enc_ctx->width;
		dst_frame->height = enc_ctx->height;
		dst_frame->format = (int)enc_ctx->pix_fmt;
		dst_frame->pts = 0;
		AVPacket dst_packet;
		av_init_packet(&dst_packet);
		dst_packet.data = NULL;
		dst_packet.size = 0;

		int count = 0;
		int j = 0;
		while(read_src_frame(j,&picQueue,&src_packet) >=0)
		{
			if (count>=200)
			{
				break;
			}
			int got_frame = 0;	   
			if(avcodec_decode_video2(dec_ctx, src_frame,&got_frame,&src_packet )<0)
				THROWERROR
				if(got_frame)
				{
					sws_scale(sws_cxt, src_frame->data,src_frame->linesize,0,src_frame->height,
						dst_frame->data,dst_frame->linesize);
					//寫yuv420到文件測試
					//for(int h=0;h<enc_ctx->height;h++)
					//{
					//	fwrite(dst_frame->data[0] + h * dst_frame->linesize[0],1,enc_ctx->width,outyuv);
					//}
					//for(int h=0;h<enc_ctx->height/2;h++)
					//{
					//	fwrite(dst_frame->data[1] + h * dst_frame->linesize[1],1,enc_ctx->width/2,outyuv);
					//}for(int h=0;h<enc_ctx->height/2;h++)
					//{
					//	fwrite(dst_frame->data[2] + h * dst_frame->linesize[2],1,enc_ctx->width/2,outyuv);
					//}fflush(outyuv);
					
					int got_packet = 0;
					dst_packet.pts = dst_packet.dts = dst_frame->pts;
					if(avcodec_encode_video2(enc_ctx,&dst_packet,dst_frame,&got_packet)<0)
						THROWERROR;
					if (got_packet)
					{
						int ret = fwrite(dst_packet.data,1,dst_packet.size, out);
						fflush(out);
						dst_packet.data = NULL;
						dst_packet.size = 0;
						count++;
						j++;
						dst_frame->pts = count*1000;
					}

				}			

		}
	}
	catch(exception e)
	{
		std::cout<<e.what()<<endl;
	}
	fclose(out);

	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章