zoukankan      html  css  js  c++  java
  • 视频解码图片

    extern "C"
    {
    	#include <libavdevice/avdevice.h>
    	#include <libavcodec/avcodec.h>
    	#include <libavformat/avformat.h>
    	#include <libswscale/swscale.h>
    	#include <libavutil/avutil.h>
    }
    
    #pragma comment( lib, "avcodec.lib" )
    #pragma comment( lib, "avdevice.lib" )
    #pragma comment( lib, "avformat.lib" )
    #pragma comment( lib, "avutil.lib" )
    #pragma comment( lib, "swscale.lib" )
    
    #include <windows.h>
    
    static int av_create_bmp(char* filename,uint8_t *pRGBBuffer,int width,int height,int bpp)
    {
    	BITMAPFILEHEADER bmpheader;
    	BITMAPINFO bmpinfo;
    	FILE *fp;
    
    	fp = fopen(filename,"wb");
    	if(!fp)return -1;
    
    	bmpheader.bfType = ('M'<<8)|'B';
    	bmpheader.bfReserved1 = 0;
    	bmpheader.bfReserved2 = 0;
    	bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    	bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;
    
    	bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	bmpinfo.bmiHeader.biWidth = width;
    	bmpinfo.bmiHeader.biHeight = height;
    	bmpinfo.bmiHeader.biPlanes = 1;
    	bmpinfo.bmiHeader.biBitCount = bpp;
    	bmpinfo.bmiHeader.biCompression = BI_RGB;
    	bmpinfo.bmiHeader.biSizeImage = 0;
    	bmpinfo.bmiHeader.biXPelsPerMeter = 100;
    	bmpinfo.bmiHeader.biYPelsPerMeter = 100;
    	bmpinfo.bmiHeader.biClrUsed = 0;
    	bmpinfo.bmiHeader.biClrImportant = 0;
    
    	uint8_t* pBuffer = new uint8_t[width * bpp / 8];
    	int byteWidth = width * bpp / 8;
    	for( int h = 0; h < height / 2; ++h )
    	{
    		memcpy( pBuffer, pRGBBuffer + h * byteWidth, byteWidth );
    		memcpy( pRGBBuffer + h * byteWidth, pRGBBuffer + (height - h - 1) * byteWidth, byteWidth );
    		memcpy( pRGBBuffer + (height - h - 1) * byteWidth, pBuffer, byteWidth );
    	}
    	delete[] pBuffer;
    
    	fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
    	fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
    	fwrite(pRGBBuffer,width*height*bpp/8,1,fp);
    	
    	fclose(fp);
    
    	return 0;
    }
    
    int main()   
    {   
    	SwsContext *pSWSCtx;   
    	AVFormatContext *pFormatCtx;   
    	const char *filename="F:\ACG\缘之空\[SumiSora][Yosuga_no_Sora][BDRip][CM01][720P].mp4";   
    	int i,videoStream,y_size;   
    	AVCodecContext *pCodecCtx;   
    	AVFrame *pFrame;   
    	AVFrame *pFrameRGB;   
    	int     numBytes,frameFinished;   
    	uint8_t *buffer;   
    	static AVPacket packet;   
    
    
    	av_register_all();   
    
    	if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)   
    		printf("error!
    ");   
    
    	if(av_find_stream_info(pFormatCtx)<0)   
    		printf("error!
    ");   
    
    	dump_format(pFormatCtx, 0, filename, false);   
    
    
    	videoStream=-1;   
    
    	for(i=0; i<pFormatCtx->nb_streams; i++)   
    		if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)   
    		{   
    			videoStream=i;   
    			continue;   
    		}   
    		if(videoStream==-1)   
    			printf("error!
    ");// Didn't find a video stream   
    
    		pCodecCtx=pFormatCtx->streams[videoStream]->codec;   
    		AVCodec *pCodec;   
    
    		pCodec=avcodec_find_decoder(pCodecCtx->codec_id);   
    		if(pCodec==NULL)   
    			printf("error!
    ");
    
    
    		if(avcodec_open(pCodecCtx, pCodec)<0)   
    			printf("error!
    "); 
    		pFrame=avcodec_alloc_frame();   
    
    
    		pFrameRGB = avcodec_alloc_frame();   
    		numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);   
    		buffer=new uint8_t[numBytes];   
    		avpicture_fill((AVPicture *)pFrameRGB, buffer, 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_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);   
    				if(frameFinished)   
    				{   
    					if(pFrame->key_frame==1 || pFrame->pict_type == FF_P_TYPE)//这里取到关键帧数据   
    					{   
    						sws_scale(pSWSCtx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);   
    						i++;  
    						static char path[100] = {0};
    						sprintf( path, "E:/video/img_%d.bmp", i - 1);
    						av_create_bmp( path,pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,24);
    					}   
    				}   
    			}   
    			av_free_packet(&packet);   
    		}   
    
    		av_free(pFrameRGB);   
    
    		av_free(pFrame);   
    
    		sws_freeContext(pSWSCtx);   
    
    		avcodec_close(pCodecCtx);   
    
    		av_close_input_file(pFormatCtx);   
    
    		return 0;   
    
    }
  • 相关阅读:
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    剑指offer-栈的压入、弹出序列
    剑指offer-包含min函数的栈
    图-Dijkster最短路径
    剑指offer-顺时针打印矩阵
    二叉树的镜像
    剑指offer-树的子结构
  • 原文地址:https://www.cnblogs.com/LinuxHunter/p/4072575.html
Copyright © 2011-2022 走看看