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);
}