不过这是windows的,android平台不知道函数是不是不同,但是至少可以做个参考
http://blog.csdn.net/xxq123321/article/details/10002475
直接代码:
- 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;
- }