Reputation: 1
This is the code in the main thread.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
Ffplay f;
QObject::connect(&f,&Ffplay::send,&w,&MainWindow::paint);
w.show();
f.start();
return a.exec();
}
MainWindow is the form that displays images.Ffplay is a thread used for decoding.Ffplay::send() is a function that sends the decoded image to the main thread,MainWindow::paint() is a function that puts the decoded image on qlabel.
The complete code of Ffplay thread:
class Ffplay : public QThread
{
Q_OBJECT
public:
Ffplay();
signals:
void send(QImage* image);
protected:
void run() override;
public:
AVFormatContext* format;
AVCodecContext* codec;
const AVCodec* c;
AVPacket* packet;
AVFrame* frame;
SwsContext* s;
};
Ffplay::Ffplay() {}
void Ffplay::run(){
format=avformat_alloc_context();
avformat_open_input(&format,"c:/Qt/project/player/movie.mp4",NULL,NULL);
avformat_find_stream_info(format,NULL);
int index=-1;
for(unsigned int i=0;i<format->nb_streams;i++){
if(format->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO){
index=i;
break;
}
}
c=avcodec_find_decoder(format->streams[index]->codecpar->codec_id);
codec=avcodec_alloc_context3(c);
avcodec_parameters_to_context(codec,format->streams[index]->codecpar);
avcodec_open2(codec,c,NULL);
packet=av_packet_alloc();
frame=av_frame_alloc();
s=sws_getContext(codec->width,codec->height,codec->pix_fmt,655,378,AV_PIX_FMT_RGB32,SWS_FAST_BILINEAR,NULL,NULL,NULL);
QImage* image=new QImage(655,378,QImage::Format_RGB32);
uint8_t* dst[]={image->bits()};
int dstStride[4];
av_image_fill_linesizes(dstStride,AV_PIX_FMT_RGB32,655);
while(av_read_frame(format,packet)==0){
if(packet->stream_index==0){
avcodec_send_packet(codec,packet);
while(avcodec_receive_frame(codec,frame)>=0){
sws_scale(s,frame->data,frame->linesize,0,frame->height,dst,dstStride);
emit send(image);
}
}
}
}
The complete code of MainWindow class:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void paint(QImage* image);
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::paint(QImage* image){
QPixmap m=QPixmap::fromImage(*image);
ui->label->setPixmap(m);
ui->label->setScaledContents(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
Theoretically, this shouldn't happen, how can I fix this?
Upvotes: 0
Views: 36