Use ffmpeg to encode the BMP image as a x264 video file and save the H264 video as a BMP image,
The ffmpeg open-source library encodes bmp images into x264 files and decodes and saves the encoded H264 files as BMP files. Based on the blog code, you can build a test environment in vs2010. Resource download code:
# Define _ AFXDLL # include <afxwin. h> # ifdef _ cplusplusextern "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: modeR Ead | 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 bmp fheader; bitmapinfoheader bmp iheader; memcpy (& BMP fheader, szTxt [fileI-1], sizeof (BITMAPFILEHEADER); int nHeadLen = BMP fheader. bfOffBits-sizeof (BITMAPFILEHEADER); me Mcpy (& BMP iheader, szTxt [fileI-1] + sizeof (BITMAPFILEHEADER), nHeadLen); nWidth = BMP iheader. biWidth; /// 464; // bmi.bmp Info. bmiHeader. biWidth; //; nHeight = BMP header. biHeight; // 362; // bmi.bmp Info. bmiHeader. biHeight; //; szTxt [fileI-1] + = BMP fheader. bfOffBits; nDataLen = nLen-bmpFHeader.bfOffBits;} getchar (); av_register_all (); avcodec_register_all (); AVFrame * m_pRGBFrame = new AVFrame [1]; // AVFrame data AVFrame * M_pYUVFrame = new AVFrame [1]; // AVCodecContext * c = NULL; AVCodecContext * in_c = NULL; AVCodec * pCodecH264; // encoder uint8_t * yuv_buff; /// find the h264 encoder 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) {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); // enable the encoder if (avcodec_open2 (c, pCodecH264, NULL) <0) {printf ("avcodec_open2 failed \ n "); TRACE ("the encoding library cannot be opened"); getchar () ;}int size = c-> width * c-> height; yuv_buff = (uint8_t *) malloc (size * 3)/2); // size for YUV 420 // fill rgb image data with rgb frame uint8_t * rgb_buff = new uint8_t [nDataLen]; // Image Encoding If the value of outbuf_size is too small, an error is reported, and the image definition is less than int outbuf_size = 900000. uint8_t * outbuf = (uint8_t *) malloc (outbuf_size); int u_size = 0; FILE * f =; char * filename = "myData. h264 "; f = fopen (filename," wb "); if (! F) {TRACE ("cocould not open % s \ n", filename); getchar (); exit (1 );} // initialize SwsContextSwsContext * 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 AVFramefor (int I = 0; I <250; ++ I) {// AVFrame * m_pYUVFrame = new AVFrame [1]; int index = (I/25) % 5; memcpy (rgb_buff, szTxt [index], nDataLen ); fill (AVPicture *) m_pRGBFrame, (uint8_t *) rgb_buff, blocks, nWidth, nHeight); // fill YUV buffer with YUV fill (AVPicture *) m_pYUVFrame, (uint8_t *) yuv_buff, PIX_FMT_YUV420P, nWidth, nHeight); // flip the RGB image 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; // Convert RGB to YUVsws_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
The following information is reported when you test the code in the blog, and the picture is blurred during playback. The size of outbuff_size is modified to solve this problem.
Q: Why do we need to loop for 250 times? You have any questions!
for (int i=0;i<250;++i)
Save the H264 video as a BMP image. The Code is as follows:
# Include <stdio. h> # include <stdlib. h> # include <string. h> # include <windows. h> # ifdef _ cplusplusextern "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 bmp Info; 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; BMP info. biSize = sizeof (BITMAPINFOHEADER); BMP info. biWidth = width; BMP info. biHeight = height; BMP info. biPlanes = 1; BMP info. biBitCount = bpp; BMP info. biCompression = BI_RGB; BMP info. BiSizeImage = (width * bpp + 31)/32*4 * height; BMP info. biXPelsPerMeter = 100; BMP info. biYPelsPerMeter = 100; BMP info. biClrUsed = 0; BMP info. biClrImportant = 0; fwrite (& bmpheader, sizeof (bmpheader), 1, fp); fwrite (& BMP info, sizeof (BMP info), 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 (bytes, 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, distance, SWS_BICUBIC, NULL ); I = 0; while (av_read_frame (pFormatCtx, & packet)> = 0) {if (packet. stream_index = videoStream) {avcodec_decode_video2 (pCodecCtx, pFrame, & frameFinished, & packet); if (frameFinished) {// reverse image 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) {// reverse image 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); convert (& pFormatCtx); return 0 ;}# ifdef _ cplusplus} # endif
References: http://blog.csdn.net/eightdegree/article/details/7425635#reply