学习分享
main函数 decodetorgb32.h 文件 decodetorgb32 .cpp文件
main函数
# include <QApplication>
# include "decodetorgb32.h"
int main ( int argc, char * argv[ ] )
{
QApplication a ( argc, argv) ;
DecodeToRGB32 toRGB32;
int res= toRGB32. openVideo ( "../fileIn/Warcraft3_End.avi" ) ;
if ( res == 0 )
{
if ( toRGB32. findStream ( ) == 0 )
{
if ( toRGB32. openDecoder ( ) == 0 )
{
toRGB32. decodeRGB ( ) ;
}
}
}
return a. exec ( ) ;
}
decodetorgb32.h 文件
# ifndef DECODETORGB32_H
# define DECODETORGB32_H
# include <QString>
# include <QDebug>
# include <QImage>
# include <stdio.h>
extern "C"
{
# include "libavcodec/avcodec.h"
# include "libavdevice/avdevice.h"
# include "libavfilter/avfilter.h"
# include "libavformat/avformat.h"
# include "libavutil/avutil.h"
# include "libswresample/swresample.h"
# include "libswscale/swscale.h"
}
class DecodeToRGB32
{
public :
DecodeToRGB32 ( ) ;
int openVideo ( QString filename) ;
int findStream ( ) ;
int openDecoder ( ) ;
void decodeRGB ( ) ;
private :
AVFormatContext* pFormatContext;
int video_index;
AVCodecContext * pCodecContext;
AVCodec* deocder;
AVPacket * pkt;
AVFrame * picture, * pictureRGB, * pictureYUV;
} ;
# endif
decodetorgb32 .cpp文件
# include "decodetorgb32.h"
DecodeToRGB32 :: DecodeToRGB32 ( )
{
}
int DecodeToRGB32 :: openVideo ( QString filename)
{
av_register_all ( ) ;
this -> pFormatContext= avformat_alloc_context ( ) ;
int res= avformat_open_input ( & this -> pFormatContext, filename. toUtf8 ( ) , nullptr , nullptr ) ;
if ( res!= 0 )
{
qDebug ( ) << "open_input fail" << res;
}
return res;
}
int DecodeToRGB32 :: findStream ( )
{
int res= avformat_find_stream_info ( this -> pFormatContext, nullptr ) ;
if ( res< 0 )
{
qDebug ( ) << "find_stream_info fail" << res;
return res;
}
for ( int i= 0 ; i< this -> pFormatContext-> nb_streams; i++ )
{
if ( AVMEDIA_TYPE_VIDEO== this -> pFormatContext-> streams [ i] -> codec-> codec_type)
{
this -> video_index= i;
return 0 ;
}
}
return res;
}
int DecodeToRGB32 :: openDecoder ( )
{
int res= - 1 ;
this -> pCodecContext= this -> pFormatContext-> streams[ this -> video_index] -> codec;
this -> deocder= avcodec_find_decoder ( this -> pCodecContext-> codec_id) ;
if ( nullptr == this -> deocder)
{
qDebug ( ) << "find_decoder fail" << res;
return 1 ;
}
res= avcodec_open2 ( this -> pCodecContext, this -> deocder, nullptr ) ;
if ( res!= 0 )
{
qDebug ( ) << "find_decoder fail" << res;
}
return res;
}
void DecodeToRGB32 :: decodeRGB ( )
{
this -> pkt = ( AVPacket* ) malloc ( sizeof ( AVPacket) ) ;
int size = this -> pCodecContext-> width* this -> pCodecContext-> height;
av_new_packet ( this -> pkt, size) ;
this -> picture = av_frame_alloc ( ) ;
this -> picture-> width= this -> pCodecContext-> width;
this -> picture-> height= this -> pCodecContext-> height;
this -> picture-> format= this -> pCodecContext-> pix_fmt;
this -> pictureRGB= av_frame_alloc ( ) ;
this -> pictureRGB-> width= this -> pCodecContext-> width;
this -> pictureRGB-> height= this -> pCodecContext-> height;
this -> pictureRGB-> format= this -> pCodecContext-> pix_fmt;
this -> pictureYUV= av_frame_alloc ( ) ;
this -> pictureYUV-> width= this -> pCodecContext-> width;
this -> pictureYUV-> height= this -> pCodecContext-> height;
this -> pictureYUV-> format= this -> pCodecContext-> pix_fmt;
int imgByte= avpicture_get_size ( AV_PIX_FMT_RGB32, this -> pCodecContext-> width, this -> pCodecContext-> height) ;
uint8_t * buffer= ( uint8_t * ) malloc ( imgByte* sizeof ( uint8_t ) ) ;
avpicture_fill ( ( AVPicture* ) this -> pictureRGB, buffer, AV_PIX_FMT_RGB32,
this -> pCodecContext-> width, this -> pCodecContext-> height) ;
SwsContext* swContext= sws_getContext ( this -> pCodecContext-> width, this -> pCodecContext-> height, this -> pCodecContext-> pix_fmt,
this -> pCodecContext-> width, this -> pCodecContext-> height, AV_PIX_FMT_RGB32,
SWS_BICUBIC, nullptr , nullptr , nullptr ) ;
int imgByteYUV= avpicture_get_size ( AV_PIX_FMT_YUV420P, this -> pCodecContext-> width, this -> pCodecContext-> height) ;
uint8_t * bufferYUV= ( uint8_t * ) malloc ( imgByte* sizeof ( uint8_t ) ) ;
avpicture_fill ( ( AVPicture* ) this -> pictureYUV, bufferYUV, AV_PIX_FMT_YUV420P,
this -> pCodecContext-> width, this -> pCodecContext-> height) ;
SwsContext* swContextYUV= sws_getContext ( this -> pCodecContext-> width, this -> pCodecContext-> height, this -> pCodecContext-> pix_fmt,
this -> pCodecContext-> width, this -> pCodecContext-> height, AV_PIX_FMT_YUV420P,
SWS_BICUBIC, nullptr , nullptr , nullptr ) ;
int num= 0 ;
FILE * pyuv= fopen ( "../fileOut/save.yuv" , "wb+" ) ;
char path[ 256 ] = { 0 } ;
while ( av_read_frame ( this -> pFormatContext, this -> pkt) == 0 )
{
if ( pkt-> stream_index== this -> video_index)
{
int got_num = - 1 ;
avcodec_decode_video2 ( this -> pCodecContext, this -> picture, & got_num, this -> pkt) ;
if ( got_num != 0 )
{
qDebug ( ) << "解码成功:" << num;
sws_scale ( swContext, picture-> data, picture-> linesize, 0 , this -> picture-> height,
this -> pictureRGB-> data, this -> pictureRGB-> linesize) ;
sws_scale ( swContextYUV, picture-> data, picture-> linesize, 0 , this -> picture-> height,
this -> pictureYUV-> data, this -> pictureYUV-> linesize) ;
fwrite ( this -> pictureYUV-> data[ 0 ] , this -> pCodecContext-> width* this -> pCodecContext-> height, 1 , pyuv) ;
fwrite ( this -> pictureYUV-> data[ 1 ] , this -> pCodecContext-> width* this -> pCodecContext-> height/ 4 , 1 , pyuv) ;
fwrite ( this -> pictureYUV-> data[ 2 ] , this -> pCodecContext-> width* this -> pCodecContext-> height/ 4 , 1 , pyuv) ;
QImage img ( ( uchar* ) buffer, this -> pictureRGB-> width, this -> pictureRGB-> height,
QImage:: Format_RGB32) ;
sprintf ( path, "../fileOut/image%d.png" , num) ;
img. save ( path) ;
num++ ;
if ( num> 5 ) break ;
}
}
}
qDebug ( ) << num;
fclose ( pyuv) ;
}