直接代码:
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::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 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;hheight;h++)
//{
// fwrite(dst_frame->data[0] + h * dst_frame->linesize[0],1,enc_ctx->width,outyuv);
//}
//for(int h=0;hheight/2;h++)
//{
// fwrite(dst_frame->data[1] + h * dst_frame->linesize[1],1,enc_ctx->width/2,outyuv);
//}for(int h=0;hheight/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<