使用ffmpeg將BMP圖片編碼為x264視訊檔案,將H264視訊儲存為BMP圖片,yuv視訊檔案儲存為圖片的程式碼
阿新 • • 發佈:2019-02-14
#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