http://www.aerchi.com/csdn-all-sjin_1314-41145349.html
ffmpeg開源庫,實現將bmp格式的圖片編碼成x264文件,並將編碼好的H264文件解碼保存爲BMP文件。
實現將視頻文件yuv格式保存的圖片格式的測試,圖像格式png,jpg, gif等等測試均OK
具體代碼:
-
#define _AFXDLL
-
#include<afxwin.h>
-
#ifdef __cplusplus
-
extern "C" {
-
#endif
-
-
#include <libavcodec/avcodec.h>
-
#include <libavformat/avformat.h>
-
#include <libswscale/swscale.h>
-
void main()
-
{
-
CFile file[5];
-
BYTE *szTxt[5];
-
-
int nWidth = 0;
-
int nHeight= 0;
-
-
int nDataLen=0;
-
-
int nLen;
-
-
CString csFileName;
-
for (int fileI = 1; fileI <= 5; fileI ++)
-
{
-
csFileName.Format("%d.bmp", fileI);
-
file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);
-
nLen = file[fileI - 1].GetLength();
-
-
szTxt[fileI -1] = new BYTE[nLen];
-
file[fileI - 1].Read(szTxt[fileI - 1], nLen);
-
file[fileI - 1].Close();
-
-
//BMP bmi;//BITMAPINFO bmi;
-
//int nHeadLen = sizeof(BMP);
-
BITMAPFILEHEADER bmpFHeader;
-
BITMAPINFOHEADER bmpIHeader;
-
memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));
-
-
int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
-
memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);
-
-
nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
-
nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;
-
-
szTxt[fileI - 1] += bmpFHeader.bfOffBits;
-
nDataLen = nLen-bmpFHeader.bfOffBits;
-
}
-
getchar();
-
av_register_all();
-
avcodec_register_all();
-
AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB幀數據
-
AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV幀數據
-
AVCodecContext *c= NULL;
-
AVCodecContext *in_c= NULL;
-
AVCodec *pCodecH264; //編碼器
-
uint8_t * yuv_buff;//
-
-
//查找h264編碼器
-
pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
-
if(!pCodecH264)
-
{
-
fprintf(stderr, "h264 codec not found\n");
-
getchar();
-
exit(1);
-
}
-
-
c= avcodec_alloc_context3(pCodecH264);
-
c->bit_rate = 3000000;// put sample parameters
-
c->width =nWidth;//
-
c->height = nHeight;//
-
-
// frames per second
-
AVRational rate;
-
rate.num = 1;
-
rate.den = 25;
-
c->time_base= rate;//(AVRational){1,25};
-
c->gop_size = 10; // emit one intra frame every ten frames
-
c->max_b_frames=1;
-
c->thread_count = 1;
-
c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;
-
-
//av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
-
//打開編碼器
-
if(avcodec_open2(c,pCodecH264,NULL)<0){
-
printf("avcodec_open2 failed\n");
-
TRACE("不能打開編碼庫");
-
getchar();
-
}
-
-
int size = c->width * c->height;
-
-
yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420
-
-
//將rgb圖像數據填充rgb幀
-
uint8_t * rgb_buff = new uint8_t[nDataLen];
-
-
//圖象編碼 outbuf_size太小會報錯,圖像清晰度也會差
-
int outbuf_size = 900000;
-
uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);
-
int u_size = 0;
-
FILE *f=NULL;
-
char * filename = "myData.h264";
-
f = fopen(filename, "wb");
-
if (!f)
-
{
-
TRACE( "could not open %s\n", filename);
-
getchar();
-
exit(1);
-
}
-
-
//初始化SwsContext
-
SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);
-
-
AVPacket avpkt;
-
-
//AVFrame *pTFrame=new AVFrame
-
for (int i=0;i<250;++i)
-
{
-
-
//AVFrame *m_pYUVFrame = new AVFrame[1];
-
-
int index = (i / 25) % 5;
-
memcpy(rgb_buff,szTxt[index],nDataLen);
-
-
avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);
-
-
//將YUV buffer 填充YUV Frame
-
avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);
-
-
// 翻轉RGB圖像
-
m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
-
m_pRGBFrame->linesize[0] *= -1;
-
m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
-
m_pRGBFrame->linesize[1] *= -1;
-
m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
-
m_pRGBFrame->linesize[2] *= -1;
-
-
-
//將RGB轉化爲YUV
-
sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);
-
-
static int got_packet_ptr = 0;
-
av_init_packet(&avpkt);
-
avpkt.data = outbuf;
-
avpkt.size = outbuf_size;
-
u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
-
m_pYUVFrame->pts++;
-
if (u_size == 0)
-
{
-
fwrite(avpkt.data, 1, avpkt.size, f);
-
}
-
}
-
-
fclose(f);
-
delete []m_pRGBFrame;
-
delete []m_pYUVFrame;
-
delete []rgb_buff;
-
free(outbuf);
-
avcodec_close(c);
-
av_free(c);
-
-
}
-
-
#ifdef __cplusplus
-
}
-
#endif
完全按照博客中的代碼測試發現會報下面的信息,而且在播放過程中,畫面都是模糊的。修改了outbuff_size的大小解決了這個問題。
- #define _AFXDLL
- #include<afxwin.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- void main()
- {
- CFile file[5];
- BYTE *szTxt[5];
- int nWidth = 0;
- int nHeight= 0;
- int nDataLen=0;
- int nLen;
- CString csFileName;
- for (int fileI = 1; fileI <= 5; fileI ++)
- {
- csFileName.Format("%d.bmp", fileI);
- file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);
- nLen = file[fileI - 1].GetLength();
- szTxt[fileI -1] = new BYTE[nLen];
- file[fileI - 1].Read(szTxt[fileI - 1], nLen);
- file[fileI - 1].Close();
- //BMP bmi;//BITMAPINFO bmi;
- //int nHeadLen = sizeof(BMP);
- BITMAPFILEHEADER bmpFHeader;
- BITMAPINFOHEADER bmpIHeader;
- memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));
- int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);
- memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);
- nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;
- nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;
- szTxt[fileI - 1] += bmpFHeader.bfOffBits;
- nDataLen = nLen-bmpFHeader.bfOffBits;
- }
- getchar();
- av_register_all();
- avcodec_register_all();
- AVFrame *m_pRGBFrame = new AVFrame[1]; //RGB幀數據
- AVFrame *m_pYUVFrame = new AVFrame[1];; //YUV幀數據
- AVCodecContext *c= NULL;
- AVCodecContext *in_c= NULL;
- AVCodec *pCodecH264; //編碼器
- uint8_t * yuv_buff;//
- //查找h264編碼器
- pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);
- if(!pCodecH264)
- {
- fprintf(stderr, "h264 codec not found\n");
- getchar();
- exit(1);
- }
- c= avcodec_alloc_context3(pCodecH264);
- c->bit_rate = 3000000;// put sample parameters
- c->width =nWidth;//
- c->height = nHeight;//
- // frames per second
- AVRational rate;
- rate.num = 1;
- rate.den = 25;
- c->time_base= rate;//(AVRational){1,25};
- c->gop_size = 10; // emit one intra frame every ten frames
- c->max_b_frames=1;
- c->thread_count = 1;
- c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;
- //av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);
- //打開編碼器
- if(avcodec_open2(c,pCodecH264,NULL)<0){
- printf("avcodec_open2 failed\n");
- TRACE("不能打開編碼庫");
- getchar();
- }
- int size = c->width * c->height;
- yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420
- //將rgb圖像數據填充rgb幀
- uint8_t * rgb_buff = new uint8_t[nDataLen];
- //圖象編碼 outbuf_size太小會報錯,圖像清晰度也會差
- int outbuf_size = 900000;
- uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);
- int u_size = 0;
- FILE *f=NULL;
- char * filename = "myData.h264";
- f = fopen(filename, "wb");
- if (!f)
- {
- TRACE( "could not open %s\n", filename);
- getchar();
- exit(1);
- }
- //初始化SwsContext
- SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);
- AVPacket avpkt;
- //AVFrame *pTFrame=new AVFrame
- for (int i=0;i<250;++i)
- {
- //AVFrame *m_pYUVFrame = new AVFrame[1];
- int index = (i / 25) % 5;
- memcpy(rgb_buff,szTxt[index],nDataLen);
- avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);
- //將YUV buffer 填充YUV Frame
- avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);
- // 翻轉RGB圖像
- m_pRGBFrame->data[0] += m_pRGBFrame->linesize[0] * (nHeight - 1);
- m_pRGBFrame->linesize[0] *= -1;
- m_pRGBFrame->data[1] += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);
- m_pRGBFrame->linesize[1] *= -1;
- m_pRGBFrame->data[2] += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);
- m_pRGBFrame->linesize[2] *= -1;
- //將RGB轉化爲YUV
- sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);
- static int got_packet_ptr = 0;
- av_init_packet(&avpkt);
- avpkt.data = outbuf;
- avpkt.size = outbuf_size;
- u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);
- m_pYUVFrame->pts++;
- if (u_size == 0)
- {
- fwrite(avpkt.data, 1, avpkt.size, f);
- }
- }
- fclose(f);
- delete []m_pRGBFrame;
- delete []m_pYUVFrame;
- delete []rgb_buff;
- free(outbuf);
- avcodec_close(c);
- av_free(c);
- }
- #ifdef __cplusplus
- }
- #endif
疑問:爲什麼要循環250次?有知道麻煩解答下!
-
for (int i=0;i<250;++i)
- for (int i=0;i<250;++i)
將H264視頻保存爲BMP圖片,具體代碼如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <windows.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- void SaveAsBMP (AVFrame *pFrameRGB, int width, int height, int index, int bpp)
- {
- char buf[5] = {0};
- BITMAPFILEHEADER bmpheader;
- BITMAPINFOHEADER bmpinfo;
- FILE *fp;
- char filename[20] = "";
- _itoa (index, buf, 10);
- strcat (filename, buf);
- strcat (filename, ".bmp");
- if ( (fp = fopen(filename,"wb+")) == NULL )
- {
- printf ("open file failed!\n");
- return;
- }
- bmpheader.bfType = 0x4d42;
- bmpheader.bfReserved1 = 0;
- bmpheader.bfReserved2 = 0;
- bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;
- bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
- bmpinfo.biWidth = width;
- bmpinfo.biHeight = height;
- bmpinfo.biPlanes = 1;
- bmpinfo.biBitCount = bpp;
- bmpinfo.biCompression = BI_RGB;
- bmpinfo.biSizeImage = (width*bpp+31)/32*4*height;
- bmpinfo.biXPelsPerMeter = 100;
- bmpinfo.biYPelsPerMeter = 100;
- bmpinfo.biClrUsed = 0;
- bmpinfo.biClrImportant = 0;
- fwrite (&bmpheader, sizeof(bmpheader), 1, fp);
- fwrite (&bmpinfo, sizeof(bmpinfo), 1, fp);
- fwrite (pFrameRGB->data[0], width*height*bpp/8, 1, fp);
- fclose(fp);
- }
- int main (void)
- {
- unsigned int i = 0, videoStream = -1;
- AVCodecContext *pCodecCtx;
- AVFormatContext *pFormatCtx = NULL;
- AVCodec *pCodec;
- AVFrame *pFrame, *pFrameRGB;
- struct SwsContext *pSwsCtx;
- const char *filename = "myData.h264";
- AVPacket packet;
- int frameFinished;
- int PictureSize;
- uint8_t *buf;
- av_register_all();
- if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0 ){
- printf ("av open input file failed!\n");
- exit (1);
- }
- if ( avformat_find_stream_info(pFormatCtx,NULL) < 0 ){
- printf ("av find stream info failed!\n");
- exit (1);
- }
- for ( i=0; i<pFormatCtx->nb_streams; i++ ){
- if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ){
- videoStream = i;
- break;
- }
- }
- if (videoStream == -1){
- printf ("find video stream failed!\n");
- exit (1);
- }
- pCodecCtx = pFormatCtx->streams[videoStream]->codec;
- pCodec = avcodec_find_decoder (pCodecCtx->codec_id);
- if (pCodec == NULL){
- printf ("avcode find decoder failed!\n");
- exit (1);
- }
- if ( avcodec_open2(pCodecCtx, pCodec,NULL)<0 ){
- printf ("avcode open failed!\n");
- exit (1);
- }
- pFrame = avcodec_alloc_frame();
- pFrameRGB = avcodec_alloc_frame();
- if ( (pFrame == NULL)||(pFrameRGB == NULL) ){
- printf("avcodec alloc frame failed!\n");
- exit (1);
- }
- PictureSize = avpicture_get_size (PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
- buf = (uint8_t *)av_malloc(PictureSize);
- if ( buf == NULL ){
- printf( "av malloc failed!\n");
- exit(1);
- }
- avpicture_fill ( (AVPicture *)pFrameRGB, buf, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
- pSwsCtx = sws_getContext (pCodecCtx->width,
- pCodecCtx->height,
- pCodecCtx->pix_fmt,
- pCodecCtx->width,
- pCodecCtx->height,
- PIX_FMT_BGR24,
- SWS_BICUBIC,
- NULL, NULL, NULL);
- i = 0;
- while(av_read_frame(pFormatCtx, &packet) >= 0){
- if(packet.stream_index == videoStream){
- avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
- if(frameFinished){
- //反轉圖像
- pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
- pFrame->linesize[0] *= -1;
- pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
- pFrame->linesize[1] *= -1;
- pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
- pFrame->linesize[2] *= -1;
- sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
- SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);
- }
- }
- av_free_packet(&packet);
- }
- while(1){
- packet.data = NULL;
- packet.size = 0;
- avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
- if(frameFinished){
- //反轉圖像
- pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);
- pFrame->linesize[0] *= -1;
- pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);
- pFrame->linesize[1] *= -1;
- pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);
- pFrame->linesize[2] *= -1;
- sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
- SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);
- }else{
- break;
- }
- av_free_packet(&packet);
- }
- sws_freeContext (pSwsCtx);
- av_free (pFrame);
- av_free (pFrameRGB);
- avcodec_close (pCodecCtx);
- avformat_close_input (&pFormatCtx);
- return 0;
- }
- #ifdef __cplusplus
- }
- #endif
視頻文件保存圖片的另外一個方法,看代碼
- /*File : yuv2pic
- *Auth : sjin
- *Date : 20141123
- *Mail : [email protected]
- */
- /*
- * 參考博客http://blog.csdn.net/leixiaohua1020/article/details/25346147
- *本程序實現了YUV420P像素數據編碼爲JPEG圖片。是最簡單的FFmpeg編碼方面的教程。
- *通過學習本例子可以瞭解FFmpeg的編碼流程。
- */
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- #define INPUT_FILE_NAME "yuv420p.yuv"
- #define OUTPUT_FILE_NAME "encode.png"
- #define INPUT_FILE_WDITH 176
- #define INPUT_FILE_HEIGHT 144
- int main(int argc, char* argv[])
- {
- AVFormatContext* pFormatCtx;
- AVOutputFormat* fmt;
- AVStream* video_st;
- AVCodecContext* pCodecCtx;
- AVCodec* pCodec;
- uint8_t* picture_buf;
- AVFrame* picture;
- int size;
- FILE *in_file = fopen(INPUT_FILE_NAME, "rb"); //視頻YUV源文件
- int in_w = INPUT_FILE_WDITH;
- int in_h = INPUT_FILE_HEIGHT; //寬高
- const char* out_file = OUTPUT_FILE_NAME; //輸出文件路徑
- av_register_all();
- #if 0
- //方法1.組合使用幾個函數
- pFormatCtx = avformat_alloc_context();
- //猜格式。用MJPEG編碼
- fmt = av_guess_format("mjpeg", NULL, NULL);
- pFormatCtx->oformat = fmt;
- //注意:輸出路徑
- if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){
- printf("輸出文件打開失敗");
- return -1;
- }
- #else
- //方法2.更加自動化一些
- //分配一個輸出(out_file)文件格式的AVFormatContext的上下文句柄
- avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);
- fmt = pFormatCtx->oformat;
- video_st = avformat_new_stream(pFormatCtx,NULL);
- if (video_st==NULL){
- return -1;
- }
- #endif
- pCodecCtx = video_st->codec;
- pCodecCtx->codec_id = fmt->video_codec;
- pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
- pCodecCtx->pix_fmt = PIX_FMT_YUVJ420P;
- pCodecCtx->width = in_w;
- pCodecCtx->height = in_h;
- pCodecCtx->time_base.num = 1;
- pCodecCtx->time_base.den = 25;
- //輸出格式信息
- av_dump_format(pFormatCtx, 0, out_file, 1);
- pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
- if (!pCodec){
- printf("沒有找到合適的編碼器!");
- return -1;
- }
- if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){
- printf("編碼器打開失敗!");
- return -1;
- }
- //申請解碼後保存視頻幀的空間,AVFrame結構體
- picture = avcodec_alloc_frame();
- //即使我們申請的一幀的內存,當轉換的時候,我們仍需要內存去保存原始的數據
- //利用下面的函數來獲得原始數據幀的大小,手動分配內存
- size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
- picture_buf = (uint8_t *)av_malloc(size);
- if (!picture_buf){
- return -1;
- }
- //設置指定圖像的參數,並指着圖像數據緩衝區
- avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
- //寫文件頭
- avformat_write_header(pFormatCtx,NULL);
- AVPacket pkt;
- int y_size = pCodecCtx->width * pCodecCtx->height;
- av_new_packet(&pkt,y_size*3);
- //讀入YUV
- if (fread(picture_buf, 1, y_size*3/2, in_file) < 0){
- printf("文件讀取錯誤");
- return -1;
- }
- //翻轉圖像
- picture->data[0] = picture_buf; // 亮度Y
- picture->data[1] = picture_buf+ y_size; // U
- picture->data[2] = picture_buf+ y_size*5/4; // V
- int got_picture=0;
- //編碼
- int ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);
- if(ret < 0){
- printf("編碼錯誤!\n");
- return -1;
- }
- if (got_picture==1){
- pkt.stream_index = video_st->index;
- ret = av_write_frame(pFormatCtx, &pkt);
- }
- av_free_packet(&pkt);
- //寫文件尾
- av_write_trailer(pFormatCtx);
- printf("編碼成功!\n");
- if (video_st){
- avcodec_close(video_st->codec);
- av_free(picture);
- av_free(picture_buf);
- }
- avio_close(pFormatCtx->pb);
- avformat_free_context(pFormatCtx);
- fclose(in_file);
- return 0;
- }
下面是編譯的時候,比較好用的Makefile文件
- # use pkg-config for getting CFLAGS and LDLIBS
- FFMPEG_LIBS= libavdevice \
- libavformat \
- libavfilter \
- libavcodec \
- libswresample \
- libswscale \
- libavutil \
- CFLAGS += -Wall -O2 -g
- CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
- LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
- EXAMPLES= yuv2pic
- OBJS=$(addsuffix .o,$(EXAMPLES))
- # the following examples make explicit use of the math library
- LDLIBS += -lx264 -m32 -pthread -lm -ldl
- .phony:all clean
- all: $(OBJS) $(EXAMPLES)
- clean:
- rm $(EXAMPLES) $(OBJS)