ffmpeg解码jpg并编码成h264

不过这是windows的,android平台不知道函数是不是不同,但是至少可以做个参考

http://blog.csdn.net/xxq123321/article/details/10002475

直接代码:

[cpp]  view plain  copy
  1. int getFileSize(const char* sFile)  
  2. {  
  3.     FILE* f = fopen(sFile, "rb");  
  4.     fseek(f,0,SEEK_END);  
  5.     int s = ftell(f);  
  6.     fclose(f);  
  7.     return s;  
  8. }  
  9. class CJpgQueue  
  10. {  
  11. public:  
  12.     CJpgQueue()  
  13.     {  
  14.   
  15.     }  
  16.     ~CJpgQueue()  
  17.     {  
  18.   
  19.     }  
  20.   
  21.       
  22.     void AppendPicFromFile(string szFile)  
  23.     {  
  24.         int s = getFileSize(szFile.c_str());  
  25.         FILE* f = fopen(szFile.c_str(), "rb");  
  26.         char* buffer = new char[s];  
  27.         fread(buffer,1,s,f);  
  28.         string data ;  
  29.         data.append(buffer,s);  
  30.         m_lstJpg.push_back(data);  
  31.         delete[] buffer;  
  32.     }  
  33.   
  34.     string* GetData(int i)  
  35.     {  
  36.         if (m_lstJpg.empty())  
  37.         {  
  38.             return NULL;  
  39.         }  
  40.         int index = i%m_lstJpg.size();  
  41.         list<string>::iterator it;  
  42.         int j = 0;  
  43.         for (it=m_lstJpg.begin();it!=m_lstJpg.end();it++,j++)  
  44.         {  
  45.             if (index == j)  
  46.             {  
  47.                 return &*it;  
  48.             }  
  49.         }  
  50.         return NULL;  
  51.     }  
  52.   
  53.   
  54. private:  
  55.     list<string> m_lstJpg;  
  56.   
  57. };  
  58.   
  59. int read_src_frame(int i,CJpgQueue* q, AVPacket* packet)  
  60. {  
  61.     string* s = q->GetData(i);  
  62.     packet->data = (uint8_t *)s->data();  
  63.     packet->size = s->size();  
  64.       
  65.     return 0;  
  66. }  
  67.   
  68. #define  CHECKPOINT(p) {  if(!p) throw "NULL"; }  
  69. #define  THROWERROR { char err[256]; sprintf(err,"error line:%d \r\n",__LINE__);throw err;  }  
  70. int _tmain(int argc, _TCHAR* argv[])  
  71. {  
  72.   
  73.     //FileConvert* fc = new FileConvert();  
  74.     //fc->DecodeVideo("d:\\wildlife.wmv","d:\\wildlife.mp4");  
  75.     FILE* out = fopen("d:\\pgm\\out.h264","wb");  
  76.     FILE* outyuv = fopen("d:\\pgm\\out.yuv420p","wb"); //just testing  
  77.   
  78.     try{  
  79.         CJpgQueue picQueue;  
  80.         for (int i=0;i<8;i++)  
  81.         {  
  82.             char name[20]={0};  
  83.             sprintf(name,"d:\\pgm\\image\\%d.jpg",i);  
  84.             picQueue.AppendPicFromFile(string(name));  
  85.         }  
  86.   
  87.         av_register_all();  
  88.   
  89.         AVCodec* dec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);  
  90.         CHECKPOINT(dec)  
  91.             AVCodecContext* dec_ctx = avcodec_alloc_context3(dec);  
  92.         CHECKPOINT(dec_ctx)  
  93.         dec_ctx->width = 1024;  
  94.         dec_ctx->height = 768;  
  95.         dec_ctx->pix_fmt = AV_PIX_FMT_YUVJ444P;  
  96.         if(dec->capabilities&CODEC_CAP_TRUNCATED)  
  97.             dec_ctx->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */  
  98.   
  99.   
  100.         if(avcodec_open2(dec_ctx,dec,NULL)<0)  
  101.             THROWERROR  
  102.   
  103.         AVCodec* enc = avcodec_find_encoder(AV_CODEC_ID_H264);  
  104.         CHECKPOINT(enc);  
  105.         AVCodecContext* enc_ctx = avcodec_alloc_context3(enc);  
  106.         CHECKPOINT(enc)  
  107.         enc_ctx->width = 640;  
  108.         enc_ctx->height = 480;  
  109.         enc_ctx->bit_rate = 500000;  
  110.         enc_ctx->pix_fmt = AV_PIX_FMT_YUV420P;  
  111.         enc_ctx->time_base.den = 25;  
  112.         enc_ctx->time_base.num = 1;  
  113.         enc_ctx->gop_size = 12;  
  114.         enc_ctx->max_b_frames = 3;  
  115.   
  116.         av_opt_set(enc_ctx->priv_data, "preset""slow", 0);  
  117.   
  118.         if (avcodec_open2(enc_ctx,enc,NULL)<0)  
  119.             THROWERROR  
  120.   
  121.         SwsContext* sws_cxt = sws_getContext(dec_ctx->width,dec_ctx->height,dec_ctx->pix_fmt,  
  122.             enc_ctx->width,enc_ctx->height,enc_ctx->pix_fmt,SWS_BILINEAR,NULL,NULL,NULL);  
  123.         CHECKPOINT(sws_cxt);  
  124.   
  125.   
  126.   
  127.         CHECKPOINT(out);  
  128.         AVFrame* src_frame = avcodec_alloc_frame();  
  129.         CHECKPOINT(src_frame);  
  130.         AVPacket src_packet;  
  131.         av_init_packet(&src_packet);  
  132.         src_packet.data = NULL;  
  133.         src_packet.size = 0;  
  134.   
  135.         AVFrame* dst_frame = avcodec_alloc_frame();  
  136.         CHECKPOINT(dst_frame)  
  137.         int dst_size = av_image_alloc(dst_frame->data,dst_frame->linesize,  
  138.             enc_ctx->width,enc_ctx->height, enc_ctx->pix_fmt,32);   
  139.         dst_frame->width = enc_ctx->width;  
  140.         dst_frame->height = enc_ctx->height;  
  141.         dst_frame->format = (int)enc_ctx->pix_fmt;  
  142.         dst_frame->pts = 0;  
  143.         AVPacket dst_packet;  
  144.         av_init_packet(&dst_packet);  
  145.         dst_packet.data = NULL;  
  146.         dst_packet.size = 0;  
  147.   
  148.         int count = 0;  
  149.         int j = 0;  
  150.         while(read_src_frame(j,&picQueue,&src_packet) >=0)  
  151.         {  
  152.             if (count>=200)  
  153.             {  
  154.                 break;  
  155.             }  
  156.             int got_frame = 0;       
  157.             if(avcodec_decode_video2(dec_ctx, src_frame,&got_frame,&src_packet )<0)  
  158.                 THROWERROR  
  159.                 if(got_frame)  
  160.                 {  
  161.                     sws_scale(sws_cxt, src_frame->data,src_frame->linesize,0,src_frame->height,  
  162.                         dst_frame->data,dst_frame->linesize);  
  163.                     //写yuv420到文件测试  
  164.                     //for(int h=0;h<enc_ctx->height;h++)  
  165.                     //{  
  166.                     //  fwrite(dst_frame->data[0] + h * dst_frame->linesize[0],1,enc_ctx->width,outyuv);  
  167.                     //}  
  168.                     //for(int h=0;h<enc_ctx->height/2;h++)  
  169.                     //{  
  170.                     //  fwrite(dst_frame->data[1] + h * dst_frame->linesize[1],1,enc_ctx->width/2,outyuv);  
  171.                     //}for(int h=0;h<enc_ctx->height/2;h++)  
  172.                     //{  
  173.                     //  fwrite(dst_frame->data[2] + h * dst_frame->linesize[2],1,enc_ctx->width/2,outyuv);  
  174.                     //}fflush(outyuv);  
  175.                       
  176.                     int got_packet = 0;  
  177.                     dst_packet.pts = dst_packet.dts = dst_frame->pts;  
  178.                     if(avcodec_encode_video2(enc_ctx,&dst_packet,dst_frame,&got_packet)<0)  
  179.                         THROWERROR;  
  180.                     if (got_packet)  
  181.                     {  
  182.                         int ret = fwrite(dst_packet.data,1,dst_packet.size, out);  
  183.                         fflush(out);  
  184.                         dst_packet.data = NULL;  
  185.                         dst_packet.size = 0;  
  186.                         count++;  
  187.                         j++;  
  188.                         dst_frame->pts = count*1000;  
  189.                     }  
  190.   
  191.                 }             
  192.   
  193.         }  
  194.     }  
  195.     catch(exception e)  
  196.     {  
  197.         std::cout<<e.what()<<endl;  
  198.     }  
  199.     fclose(out);  
  200.   
  201.     return 0;  
  202. }  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值