ffmpeg解码jpg并编码成h264

来源:互联网 发布:刘义军 知乎 编辑:程序博客网 时间:2024/05/01 11:47

直接代码:

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 testingtry{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)THROWERRORAVCodec* 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)THROWERRORSwsContext* 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)THROWERRORif(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;}