使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

http://www.aerchi.com/csdn-all-sjin_1314-41145349.html

 ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件。

实现将视频文件yuv格式保存的图片格式的测试,图像格式png,jpg, gif等等测试均OK



   具体代码:

[cpp]  view plain  copy
 print ?
  1. #define _AFXDLL    
  2. #include   
  3. #ifdef  __cplusplus  
  4. extern "C" {  
  5. #endif  
  6.   
  7. #include   
  8. #include   
  9. #include   
  10.     void main()  
  11.     {  
  12.         CFile file[5];  
  13.         BYTE *szTxt[5];  
  14.   
  15.         int nWidth = 0;  
  16.         int nHeight= 0;  
  17.   
  18.         int nDataLen=0;  
  19.   
  20.         int nLen;  
  21.   
  22.         CString csFileName;  
  23.         for (int fileI = 1; fileI <= 5; fileI ++)  
  24.         {  
  25.             csFileName.Format("%d.bmp", fileI);  
  26.             file[fileI - 1].Open(csFileName,CFile::modeRead | CFile::typeBinary);  
  27.             nLen = file[fileI - 1].GetLength();  
  28.   
  29.             szTxt[fileI -1] = new BYTE[nLen];  
  30.             file[fileI - 1].Read(szTxt[fileI - 1], nLen);  
  31.             file[fileI - 1].Close();  
  32.   
  33.             //BMP bmi;//BITMAPINFO bmi;  
  34.             //int nHeadLen = sizeof(BMP);  
  35.             BITMAPFILEHEADER bmpFHeader;  
  36.             BITMAPINFOHEADER bmpIHeader;  
  37.             memcpy(&bmpFHeader,szTxt[fileI -1],sizeof(BITMAPFILEHEADER));  
  38.   
  39.             int nHeadLen = bmpFHeader.bfOffBits - sizeof(BITMAPFILEHEADER);  
  40.             memcpy(&bmpIHeader,szTxt[fileI - 1]+sizeof(BITMAPFILEHEADER),nHeadLen);  
  41.   
  42.             nWidth = bmpIHeader.biWidth;// 464;// bmi.bmpInfo.bmiHeader.biWidth;// ;  
  43.             nHeight = bmpIHeader.biHeight;//362;// bmi.bmpInfo.bmiHeader.biHeight;// ;  
  44.   
  45.             szTxt[fileI - 1] += bmpFHeader.bfOffBits;  
  46.             nDataLen = nLen-bmpFHeader.bfOffBits;  
  47.         }  
  48.         getchar();  
  49.         av_register_all();  
  50.         avcodec_register_all();  
  51.         AVFrame *m_pRGBFrame =  new AVFrame[1];  //RGB帧数据    
  52.         AVFrame *m_pYUVFrame = new AVFrame[1];;  //YUV帧数据  
  53.         AVCodecContext *c= NULL;  
  54.         AVCodecContext *in_c= NULL;  
  55.         AVCodec *pCodecH264; //编码器  
  56.         uint8_t * yuv_buff;//  
  57.   
  58.         //查找h264编码器  
  59.         pCodecH264 = avcodec_find_encoder(CODEC_ID_H264);  
  60.         if(!pCodecH264)  
  61.         {  
  62.             fprintf(stderr, "h264 codec not found\n");  
  63.             getchar();  
  64.             exit(1);  
  65.         }  
  66.   
  67.         c= avcodec_alloc_context3(pCodecH264);  
  68.         c->bit_rate = 3000000;// put sample parameters   
  69.         c->width =nWidth;//   
  70.         c->height = nHeight;//   
  71.   
  72.         // frames per second   
  73.         AVRational rate;  
  74.         rate.num = 1;  
  75.         rate.den = 25;  
  76.         c->time_base= rate;//(AVRational){1,25};  
  77.         c->gop_size = 10; // emit one intra frame every ten frames   
  78.         c->max_b_frames=1;  
  79.         c->thread_count = 1;  
  80.         c->pix_fmt = PIX_FMT_YUV420P;//PIX_FMT_RGB24;  
  81.   
  82.         //av_opt_set(c->priv_data, /*"preset"*/"libvpx-1080p.ffpreset", /*"slow"*/NULL, 0);  
  83.         //打开编码器  
  84.         if(avcodec_open2(c,pCodecH264,NULL)<0){  
  85.             printf("avcodec_open2 failed\n");  
  86.             TRACE("不能打开编码库");  
  87.             getchar();  
  88.         }  
  89.   
  90.         int size = c->width * c->height;  
  91.   
  92.         yuv_buff = (uint8_t *) malloc((size * 3) / 2); // size for YUV 420   
  93.   
  94.         //将rgb图像数据填充rgb帧  
  95.         uint8_t * rgb_buff = new uint8_t[nDataLen];  
  96.   
  97.         //图象编码 outbuf_size太小会报错,图像清晰度也会差  
  98.         int outbuf_size = 900000;  
  99.         uint8_t * outbuf= (uint8_t*)malloc(outbuf_size);   
  100.         int u_size = 0;  
  101.         FILE *f=NULL;   
  102.         char * filename = "myData.h264";  
  103.         f = fopen(filename, "wb");  
  104.         if (!f)  
  105.         {  
  106.             TRACE( "could not open %s\n", filename);  
  107.             getchar();  
  108.             exit(1);  
  109.         }  
  110.   
  111.         //初始化SwsContext  
  112.         SwsContext * scxt = sws_getContext(c->width,c->height,PIX_FMT_BGR24,c->width,c->height,PIX_FMT_YUV420P,SWS_POINT,NULL,NULL,NULL);  
  113.   
  114.         AVPacket avpkt;  
  115.   
  116.         //AVFrame *pTFrame=new AVFrame  
  117.         for (int i=0;i<250;++i)  
  118.         {  
  119.   
  120.             //AVFrame *m_pYUVFrame = new AVFrame[1];  
  121.   
  122.             int index = (i / 25) % 5;  
  123.             memcpy(rgb_buff,szTxt[index],nDataLen);  
  124.   
  125.             avpicture_fill((AVPicture*)m_pRGBFrame, (uint8_t*)rgb_buff, PIX_FMT_RGB24, nWidth, nHeight);  
  126.   
  127.             //将YUV buffer 填充YUV Frame  
  128.             avpicture_fill((AVPicture*)m_pYUVFrame, (uint8_t*)yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight);  
  129.   
  130.             // 翻转RGB图像  
  131.             m_pRGBFrame->data[0]  += m_pRGBFrame->linesize[0] * (nHeight - 1);  
  132.             m_pRGBFrame->linesize[0] *= -1;                     
  133.             m_pRGBFrame->data[1]  += m_pRGBFrame->linesize[1] * (nHeight / 2 - 1);  
  134.             m_pRGBFrame->linesize[1] *= -1;  
  135.             m_pRGBFrame->data[2]  += m_pRGBFrame->linesize[2] * (nHeight / 2 - 1);  
  136.             m_pRGBFrame->linesize[2] *= -1;  
  137.   
  138.   
  139.             //将RGB转化为YUV  
  140.             sws_scale(scxt,m_pRGBFrame->data,m_pRGBFrame->linesize,0,c->height,m_pYUVFrame->data,m_pYUVFrame->linesize);  
  141.   
  142.             static int got_packet_ptr = 0;  
  143.             av_init_packet(&avpkt);  
  144.             avpkt.data = outbuf;  
  145.             avpkt.size = outbuf_size;  
  146.             u_size = avcodec_encode_video2(c, &avpkt, m_pYUVFrame, &got_packet_ptr);  
  147.             m_pYUVFrame->pts++;  
  148.             if (u_size == 0)  
  149.             {  
  150.                 fwrite(avpkt.data, 1, avpkt.size, f);  
  151.             }  
  152.         }  
  153.   
  154.         fclose(f);   
  155.         delete []m_pRGBFrame;  
  156.         delete []m_pYUVFrame;  
  157.         delete []rgb_buff;  
  158.         free(outbuf);  
  159.         avcodec_close(c);  
  160.         av_free(c);  
  161.   
  162.     }  
  163.   
  164. #ifdef  __cplusplus  
  165. }  
  166. #endif  

 完全按照博客中的代码测试发现会报下面的信息,而且在播放过程中,画面都是模糊的。修改了outbuff_size的大小解决了这个问题。


使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码_第1张图片
 

疑问:为什么要循环250次?有知道麻烦解答下!
[cpp]  view plain  copy
 print ?
  1. for (int i=0;i<250;++i)  

将H264视频保存为BMP图片,具体代码如下:

[cpp]  view plain  copy
 print ?
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.   
  6. #ifdef  __cplusplus  
  7. extern "C" {  
  8. #endif  
  9.   
  10. #include   
  11. #include   
  12. #include   
  13.   
  14. void SaveAsBMP (AVFrame *pFrameRGB, int width, int height, int index, int bpp)  
  15. {  
  16.     char buf[5] = {0};  
  17.     BITMAPFILEHEADER bmpheader;  
  18.     BITMAPINFOHEADER bmpinfo;  
  19.     FILE *fp;  
  20.   
  21.     char filename[20] = "";  
  22.     _itoa (index, buf, 10);  
  23.     strcat (filename, buf);  
  24.     strcat (filename, ".bmp");  
  25.   
  26.     if ( (fp = fopen(filename,"wb+")) == NULL )  
  27.     {  
  28.         printf ("open file failed!\n");  
  29.         return;  
  30.     }  
  31.   
  32.     bmpheader.bfType = 0x4d42;  
  33.     bmpheader.bfReserved1 = 0;  
  34.     bmpheader.bfReserved2 = 0;  
  35.     bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  
  36.     bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;  
  37.   
  38.     bmpinfo.biSize = sizeof(BITMAPINFOHEADER);  
  39.     bmpinfo.biWidth = width;  
  40.     bmpinfo.biHeight = height;  
  41.     bmpinfo.biPlanes = 1;  
  42.     bmpinfo.biBitCount = bpp;  
  43.     bmpinfo.biCompression = BI_RGB;  
  44.     bmpinfo.biSizeImage = (width*bpp+31)/32*4*height;  
  45.     bmpinfo.biXPelsPerMeter = 100;  
  46.     bmpinfo.biYPelsPerMeter = 100;  
  47.     bmpinfo.biClrUsed = 0;  
  48.     bmpinfo.biClrImportant = 0;  
  49.   
  50.     fwrite (&bmpheader, sizeof(bmpheader), 1, fp);  
  51.     fwrite (&bmpinfo, sizeof(bmpinfo), 1, fp);  
  52.     fwrite (pFrameRGB->data[0], width*height*bpp/8, 1, fp);  
  53.   
  54.     fclose(fp);  
  55. }  
  56.   
  57.   
  58. int main (void)  
  59. {  
  60.     unsigned int i = 0, videoStream = -1;  
  61.     AVCodecContext *pCodecCtx;  
  62.     AVFormatContext *pFormatCtx = NULL;  
  63.     AVCodec *pCodec;  
  64.     AVFrame *pFrame, *pFrameRGB;  
  65.     struct SwsContext *pSwsCtx;  
  66.     const char *filename = "myData.h264";  
  67.     AVPacket packet;  
  68.     int frameFinished;  
  69.     int PictureSize;  
  70.     uint8_t *buf;  
  71.   
  72.     av_register_all();  
  73.   
  74.     if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0 ){  
  75.         printf ("av open input file failed!\n");  
  76.         exit (1);  
  77.     }  
  78.   
  79.     if ( avformat_find_stream_info(pFormatCtx,NULL) < 0 ){  
  80.         printf ("av find stream info failed!\n");  
  81.         exit (1);  
  82.     }  
  83.   
  84.     for ( i=0; inb_streams; i++ ){  
  85.         if ( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ){  
  86.             videoStream = i;  
  87.             break;  
  88.         }  
  89.     }  
  90.   
  91.     if (videoStream == -1){  
  92.         printf ("find video stream failed!\n");  
  93.         exit (1);  
  94.     }  
  95.   
  96.     pCodecCtx = pFormatCtx->streams[videoStream]->codec;  
  97.   
  98.     pCodec = avcodec_find_decoder (pCodecCtx->codec_id);  
  99.     if (pCodec == NULL){  
  100.         printf ("avcode find decoder failed!\n");  
  101.         exit (1);  
  102.     }  
  103.   
  104.   
  105.   
  106.   
  107.     if ( avcodec_open2(pCodecCtx, pCodec,NULL)<0 ){  
  108.         printf ("avcode open failed!\n");  
  109.         exit (1);  
  110.     }  
  111.   
  112.     pFrame = avcodec_alloc_frame();  
  113.     pFrameRGB = avcodec_alloc_frame();  
  114.   
  115.     if ( (pFrame == NULL)||(pFrameRGB == NULL) ){  
  116.         printf("avcodec alloc frame failed!\n");  
  117.         exit (1);  
  118.     }  
  119.   
  120.     PictureSize = avpicture_get_size (PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);  
  121.   
  122.     buf = (uint8_t *)av_malloc(PictureSize);  
  123.   
  124.     if ( buf == NULL ){  
  125.         printf( "av malloc failed!\n");  
  126.         exit(1);  
  127.     }  
  128.   
  129.     avpicture_fill ( (AVPicture *)pFrameRGB, buf, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);  
  130.   
  131.     pSwsCtx = sws_getContext (pCodecCtx->width,  
  132.             pCodecCtx->height,  
  133.             pCodecCtx->pix_fmt,  
  134.             pCodecCtx->width,  
  135.             pCodecCtx->height,  
  136.             PIX_FMT_BGR24,  
  137.             SWS_BICUBIC,  
  138.             NULL, NULL, NULL);  
  139.   
  140.         i = 0;  
  141.   
  142.     while(av_read_frame(pFormatCtx, &packet) >= 0){  
  143.         if(packet.stream_index == videoStream){  
  144.             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);  
  145.   
  146.             if(frameFinished){   
  147.                     //反转图像  
  148.                 pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);  
  149.                 pFrame->linesize[0] *= -1;  
  150.                 pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);  
  151.                 pFrame->linesize[1] *= -1;  
  152.                 pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);  
  153.                 pFrame->linesize[2] *= -1;  
  154.   
  155.                 sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);  
  156.   
  157.                 SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);  
  158.             }   
  159.         }  
  160.         av_free_packet(&packet);  
  161.     }  
  162.   
  163.     while(1){    
  164.         packet.data = NULL;    
  165.         packet.size = 0;    
  166.         avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);  
  167.   
  168.         if(frameFinished){   
  169.             //反转图像  
  170.             pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height - 1);  
  171.             pFrame->linesize[0] *= -1;  
  172.             pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height / 2 - 1);  
  173.             pFrame->linesize[1] *= -1;  
  174.             pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height / 2 - 1);  
  175.             pFrame->linesize[2] *= -1;  
  176.   
  177.             sws_scale (pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);  
  178.   
  179.             SaveAsBMP (pFrameRGB, pCodecCtx->width, pCodecCtx->height, i++, 24);  
  180.         }else{  
  181.             break;  
  182.         }  
  183.   
  184.         av_free_packet(&packet);    
  185.     }    
  186.   
  187.     sws_freeContext (pSwsCtx);  
  188.     av_free (pFrame);  
  189.     av_free (pFrameRGB);  
  190.     avcodec_close (pCodecCtx);  
  191.     avformat_close_input (&pFormatCtx);  
  192.   
  193.     return 0;  
  194. }  
  195.   
  196. #ifdef  __cplusplus  
  197. }  
  198. #endif  


视频文件保存图片的另外一个方法,看代码

[cpp]  view plain  copy
 print ?
  1. /*File : yuv2pic 
  2.  *Auth : sjin 
  3.  *Date : 20141123 
  4.  *Mail : [email protected] 
  5.  */  
  6.   
  7. /*  
  8.  * 参考博客http://blog.csdn.net/leixiaohua1020/article/details/25346147 
  9.  *本程序实现了YUV420P像素数据编码为JPEG图片。是最简单的FFmpeg编码方面的教程。 
  10.  *通过学习本例子可以了解FFmpeg的编码流程。 
  11.  */  
  12. #include   
  13. #include   
  14. #include   
  15.   
  16. #define INPUT_FILE_NAME  "yuv420p.yuv"  
  17. #define OUTPUT_FILE_NAME "encode.png"  
  18. #define INPUT_FILE_WDITH  176  
  19. #define INPUT_FILE_HEIGHT 144  
  20.   
  21. int main(int argc, char* argv[])  
  22. {  
  23.     AVFormatContext* pFormatCtx;  
  24.     AVOutputFormat* fmt;  
  25.     AVStream* video_st;  
  26.     AVCodecContext* pCodecCtx;  
  27.     AVCodec* pCodec;  
  28.   
  29.     uint8_t* picture_buf;  
  30.     AVFrame* picture;  
  31.     int size;  
  32.   
  33.     FILE *in_file = fopen(INPUT_FILE_NAME, "rb");   //视频YUV源文件   
  34.     int in_w = INPUT_FILE_WDITH;  
  35.     int in_h = INPUT_FILE_HEIGHT;                                   //宽高  
  36.     const char* out_file = OUTPUT_FILE_NAME;                    //输出文件路径  
  37.   
  38.     av_register_all();  
  39. #if 0  
  40.     //方法1.组合使用几个函数  
  41.     pFormatCtx = avformat_alloc_context();  
  42.     //猜格式。用MJPEG编码  
  43.     fmt = av_guess_format("mjpeg", NULL, NULL);  
  44.     pFormatCtx->oformat = fmt;  
  45.     //注意:输出路径  
  46.     if (avio_open(&pFormatCtx->pb,out_file, AVIO_FLAG_READ_WRITE) < 0){  
  47.         printf("输出文件打开失败");  
  48.         return -1;  
  49.     }  
  50. #else  
  51.     //方法2.更加自动化一些  
  52.     //分配一个输出(out_file)文件格式的AVFormatContext的上下文句柄  
  53.     avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);  
  54.     fmt = pFormatCtx->oformat;  
  55.   
  56.     video_st = avformat_new_stream(pFormatCtx,NULL);  
  57.     if (video_st==NULL){  
  58.         return -1;  
  59.     }  
  60. #endif  
  61.     pCodecCtx = video_st->codec;  
  62.     pCodecCtx->codec_id = fmt->video_codec;  
  63.     pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;  
  64.     pCodecCtx->pix_fmt = PIX_FMT_YUVJ420P;  
  65.   
  66.     pCodecCtx->width = in_w;    
  67.     pCodecCtx->height = in_h;  
  68.   
  69.     pCodecCtx->time_base.num = 1;    
  70.     pCodecCtx->time_base.den = 25;     
  71.     //输出格式信息  
  72.     av_dump_format(pFormatCtx, 0, out_file, 1);  
  73.   
  74.     pCodec = avcodec_find_encoder(pCodecCtx->codec_id);  
  75.     if (!pCodec){  
  76.         printf("没有找到合适的编码器!");  
  77.         return -1;  
  78.     }  
  79.     if (avcodec_open2(pCodecCtx, pCodec,NULL) < 0){  
  80.         printf("编码器打开失败!");  
  81.         return -1;  
  82.     }  
  83.       
  84.     //申请解码后保存视频帧的空间,AVFrame结构体  
  85.     picture = avcodec_alloc_frame();  
  86.     //即使我们申请的一帧的内存,当转换的时候,我们仍需要内存去保存原始的数据  
  87.     //利用下面的函数来获得原始数据帧的大小,手动分配内存  
  88.     size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);  
  89.     picture_buf = (uint8_t *)av_malloc(size);  
  90.     if (!picture_buf){  
  91.         return -1;  
  92.     }  
  93.     //设置指定图像的参数,并指着图像数据缓冲区  
  94.     avpicture_fill((AVPicture *)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);  
  95.   
  96.     //写文件头  
  97.     avformat_write_header(pFormatCtx,NULL);  
  98.   
  99.     AVPacket pkt;  
  100.     int y_size = pCodecCtx->width * pCodecCtx->height;  
  101.     av_new_packet(&pkt,y_size*3);  
  102.     //读入YUV  
  103.     if (fread(picture_buf, 1, y_size*3/2, in_file) < 0){  
  104.         printf("文件读取错误");  
  105.         return -1;  
  106.     }  
  107.   
  108.     //翻转图像  
  109.     picture->data[0] = picture_buf;  // 亮度Y  
  110.     picture->data[1] = picture_buf+ y_size;  // U   
  111.     picture->data[2] = picture_buf+ y_size*5/4; // V  
  112.     int got_picture=0;  
  113.     //编码  
  114.     int ret = avcodec_encode_video2(pCodecCtx, &pkt,picture, &got_picture);  
  115.     if(ret < 0){  
  116.         printf("编码错误!\n");  
  117.         return -1;  
  118.     }  
  119.     if (got_picture==1){  
  120.         pkt.stream_index = video_st->index;  
  121.         ret = av_write_frame(pFormatCtx, &pkt);  
  122.     }  
  123.   
  124.     av_free_packet(&pkt);  
  125.     //写文件尾  
  126.     av_write_trailer(pFormatCtx);  
  127.   
  128.     printf("编码成功!\n");  
  129.   
  130.     if (video_st){  
  131.         avcodec_close(video_st->codec);  
  132.         av_free(picture);  
  133.         av_free(picture_buf);  
  134.     }  
  135.       
  136.     avio_close(pFormatCtx->pb);  
  137.     avformat_free_context(pFormatCtx);  
  138.   
  139.     fclose(in_file);  
  140.   
  141.     return 0;  
  142. }  

下面是编译的时候,比较好用的Makefile文件
[cpp]  view plain  copy
 print ?
  1. # use pkg-config for getting CFLAGS and LDLIBS  
  2. FFMPEG_LIBS=    libavdevice                        \  
  3.                 libavformat                        \  
  4.                 libavfilter                        \  
  5.                 libavcodec                         \  
  6.                 libswresample                      \  
  7.                 libswscale                         \  
  8.                 libavutil                          \  
  9.   
  10. CFLAGS += -Wall -O2 -g  
  11. CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)  
  12. LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)  
  13.   
  14. EXAMPLES=  yuv2pic  
  15.                                           
  16. OBJS=$(addsuffix .o,$(EXAMPLES))  
  17.   
  18. # the following examples make explicit use of the math library  
  19. LDLIBS += -lx264 -m32 -pthread -lm -ldl  
  20.   
  21. .phony:all clean  
  22.   
  23. all: $(OBJS) $(EXAMPLES)  
  24.   
  25. clean:  
  26.     rm $(EXAMPLES) $(OBJS)  

你可能感兴趣的:(Cpp)