#include "libavformat/avformat.h"
#include "libavutil/timestamp.h"
#define NUMS 33
void saveframe(AVFrame *frame, const char *filename) {
FILE *file;
file = fopen(filename, "wb+");
int width = 320;
int height = 480;
unsigned char *buf = (unsigned char*)malloc(width * height * 3 / 2);
/*
memcpy(data, frame->data[0], 320 * 480);
memcpy(data+width*height, frame->data[1], 320 * 480/4);
memcpy(data + width * height*5/4, frame->data[2], 320 * 480/4);
*/
int i;
int a = 0;
for (i = 0; i < height; i++)
{
memcpy(buf + a, frame->data[0] + i * frame->linesize[0], width);
a += width;
}
for (i = 0; i < height / 2; i++)
{
memcpy(buf + a, frame->data[1] + i * frame->linesize[1], width / 2);
a += width / 2;
}
for (i = 0; i < height / 2; i++)
{
memcpy(buf + a, frame->data[2] + i * frame->linesize[2], width / 2);
a += width / 2;
}
fwrite(buf, 1, width*height * 3 / 2, file);
fclose(file);
}
int main()
{
char input_filename[20];
const char *output_filename = "out.mp4";
const char *output_filename111 = "1.yuv";
AVCodec* pDecodec;
AVCodecContext* pDecodecCtx;
AVFrame* pDeFrame;
AVPacket pDePacket;
int deCFflag;
AVCodec* pEncodec;
AVCodecContext* pEncodecCtx;
AVFrame* pEnFrame;
AVPacket pEnPacket;
AVFormatContext* pOutPutFormatCtx;
AVStream* pVideoStream;
//解码器初始化。。。。。。。。。。。。。。。
//读取jpg用的解码器mjpeg
pDecodec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
//获取解码器上下文
pDecodecCtx = avcodec_alloc_context3(pDecodec);
pDecodecCtx->width = 320;
pDecodecCtx->height = 480;
pDecodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
//打开解码器
avcodec_open2(pDecodecCtx, pDecodec, NULL);
//编码器初始化。。。。。。。。。。。。。。。。。
avformat_alloc_output_context2(&pOutPutFormatCtx, NULL, NULL, output_filename);
pVideoStream = avformat_new_stream(pOutPutFormatCtx, NULL);
avio_open(&pOutPutFormatCtx->pb, output_filename, AVIO_FLAG_READ_WRITE);
av_dump_format(pOutPutFormatCtx, 0, output_filename, 1);
pEncodecCtx = pVideoStream->codec;
pEncodecCtx->codec_id = pOutPutFormatCtx->oformat->video_codec;
pEncodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pEncodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
pEncodecCtx->width = 320;
pEncodecCtx->height = 480;
//pEncodecCtx->bit_rate = 400000; 码流 适用于网络传输
pEncodecCtx->gop_size = 1;
pEncodecCtx->time_base.num = 1;
pEncodecCtx->time_base.den = 10;
pEncodecCtx->qmin = 10;
pEncodecCtx->qmax = 51;
pEncodecCtx->max_b_frames = 0;
//质量 文件
pEncodecCtx->bit_rate = 0;
av_opt_set_int(pEncodecCtx->priv_data, "crf", 0, 0);
pEncodecCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
//找一个视频编码器
pEncodec = avcodec_find_encoder(pEncodecCtx->codec_id);
//打开编码器
avcodec_open2(pEncodecCtx, pEncodec, NULL);
//将编码器的信息与输出的信息属性关联起来
avcodec_parameters_from_context(pVideoStream->codecpar, pEncodecCtx);
av_codec_get_tag2(pOutPutFormatCtx->oformat->codec_tag, pEncodecCtx->codec_id, &pVideoStream->codecpar->codec_tag);
//写输出的文件的头
avformat_write_header(pOutPutFormatCtx, NULL);
AVRational rational;
rational.den = 10;
rational.num = 1;
for (int i = 0; i < NUMS; i++) {
FILE *file;
sprintf(input_filename, "%d.jpg", i + 1);
//char *input_filename = "10.jpg";
file = fopen(input_filename, "rb+");
printf("%s\n", input_filename);
fseek(file, 0, SEEK_END);
int frame_size = ftell(file);
fseek(file, 0, SEEK_SET);
unsigned char *jpgdata = (unsigned char *)malloc(frame_size);
int readlen = fread(jpgdata, 1, frame_size, file);
// 用一个avstream来接收解码的数据帧
pDeFrame = av_frame_alloc();
//pDeFrame->width = 320;
//pDeFrame->height = 480;
//初始化一个avpacket数据包
av_init_packet(&pDePacket);
pDePacket.data = jpgdata;
pDePacket.size = frame_size;
//调用解码器解码,解码成功
avcodec_decode_video2(pDecodecCtx, pDeFrame, &deCFflag, &pDePacket);
if (deCFflag == 0) {
printf("decode false!!!!!!!\n");
goto end;
}
//saveframe(pDeFrame, output_filename111);
//初始话编码的包
av_init_packet(&pEnPacket);
av_new_packet(&pEnPacket, 90 * 1024);
int gotpicture = 0;
//pEnFrame->pts = i;
//编码
avcodec_encode_video2(pEncodecCtx, &pEnPacket, pDeFrame, &gotpicture);
if (gotpicture != 1)
goto end1;
printf("----encodecresult %d \n",gotpicture);
pEnPacket.pts = av_rescale_q(pEnPacket.pts, rational, pVideoStream->time_base);
pEnPacket.stream_index = pVideoStream->index;
//将编码得到的包写入输出文件
av_write_frame(pOutPutFormatCtx, &pEnPacket);
end1:
av_free_packet(&pEnPacket);
end:
av_frame_free(&pDeFrame);
//av_free_packet(&pDePacket);
fclose(file);
}
//写文件尾
av_write_trailer(pOutPutFormatCtx);
printf("hello,world!!!!\n");
system("pause");
return 0;
}