您的位置:首页 > 编程语言 > Qt开发

不用 SDL 的QT+FFMPEG 播放器

2011-12-09 10:44 253 查看
QT+ffmpeg

1、不用SDL的理由

SDL是为游戏开发的,大量的依赖硬件加速。不用sdl是为了能方便的将程序移植到其他的平台 。

本人受条件限制未向其他系统移植。但由于没采用QT(ffmpeg)之外的其他第三方代码,相信

移植是个很小的问题。本人曾经做过arm920+qt+linux(fambuffer)的开发。

本程序仅用了Qwideg来显示,就是为了移植方便。ffmpeg用C写的可以向多种平台移植。

2、如何实现音频视频同步

本范例采用系统时钟作为主时钟,用音频时钟校正主时钟。

3、如何实现多趋缓冲

本范例采用多线程处理机制。

1、QFfmpeg :主要负责读取数据包,存入QList列表.压缩前的数据占用空间小。缓冲大小可设,按视频帧数和声卡缓冲大小决定

2、QAudioThread:音频解码

3、QVideoThread:视频解码

4、QFfPlay :播放 (没有用定时器,定时器误差太大)

4、本范例实现QT+ffmpeg播放器的基本功能,仅出于爱好开发,未进行系统排错,用于大家参考交流。

在开发期间参考了ffplay 。

5、实现在QT4.6 QT4.7forwindows版编译运行,内存无重大泄露。

作者邮箱 lbwave@sina.com
标签:
ffmpeg
播放器
SDL
QT

代码片段(1)

[代码] cpp代码

view sourceprint?

001
#ifndef QFFMPEG_H
002
#define QFFMPEG_H
003
004
#include <QThreadPool>
005
#include <QRunnable>
006
#include <QWidget>
007
#include <QAudioDeviceInfo>
008
#include <QAudioOutput>
009
#include <QAudioFormat>
010
#include <QThread>
011
#include <QImage>
012
#include <QMutex>
013
#include <QTime>
014
#include <QPainter>
015
#include <QIODevice>
016
#include <QWaitCondition>
017
#include <QSemaphore>
018
#include <QReadWriteLock>
019
#include <QDebug>
020
021
022
#include <stdlib.h>
023
#include <stdio.h>
024
#include <memory.h>//注意要包含此头文件与qDebug函数相关
025
#include <stdint.h>
026
#include <QList>
027
028
029
extern
"C"
030
{
031
//ffmpeg相关的头文件
032
#include <libavcodec/avcodec.h>
033
#include <libavutil/common.h>
034
#include <libavutil/avstring.h>
035
#include <libavcodec/avcodec.h>
036
#include <libavformat/avformat.h>
037
#include <libswscale/swscale.h>
038
#include <libavcodec/opt.h>
039
#include <libavformat/avio.h>
040
041
042
043
//#include <libavdevice/avdevice.h>
044
045
}
046
//播放信息
047
048
#define DEFAULT_IMAGEFMT QImage::Format_RGB32
049
#define DEFAULT_FRAMEFMT PIX_FMT_RGB32
050
#define MAX_AUDIO_DIFFTIME 1000000//音频时间差,最大值
051
#define AUDIOBUFFERSIZE (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 //音频缓冲大小
052
#define MAX_BUFFER 50
053
054
055
class
QMasterClock
//主时钟
056
{
057
public
:
058
QMasterClock();
059
void

adjusttime(
int

us);
060
qint64 getuscurtime();
061
void

setstarttime(QTime t);
062
protected
:
063
QReadWriteLock m;
064
QTime starttime;
065
066
};
067
068
class
QDecodecThread :
public
QThread
069
{
070
Q_OBJECT
071
public
:
072
QDecodecThread(AVFormatContext *f,AVCodecContext *c,QMasterClock *cl,
int

index,QObject *parent=0);
073
~QDecodecThread();
074
void

run()=0;
075
076
void

setstreamindex(
const

int
index);
077
int

getstreamindex() ;
078
int

getusdtime() ;
079
void

setusdtime(
int

dt);
080
void

setisend(
const

bool
b);
081
void

lockdata();
082
void

unlockdata();
083
int

getcount() ;
084
void

putpacket(AVPacket *p);
085
void

free_packet(AVPacket *p);
086
AVPacket* getpacket();
087
qint64 getus(qint64 t);
088
QSemaphore sempfree;
089
090
protected
:
091
AVCodecContext *actx;
//解码器
092
AVFormatContext*formatctx;
093
int

stream_index;
094
095
QMasterClock *masterclock;
096
QSemaphore semp;
097
098
bool

isend;
099
100
QList <AVPacket*> pkts;
101
102
int

usdtime;
//时间差值,用于修正主时钟
103
QMutex mutex;
104
qint64 basetime;
105
};
106
107
108
class
QAudioThread :
public
QDecodecThread
109
{
110
Q_OBJECT
111
public
:
112
QAudioThread(AVFormatContext *f,AVCodecContext *c,QMasterClock *cl,
int

index,QObject *parent=0);
113
~QAudioThread();
114
QAudioOutput* getaudio();
115
void

run();
116
void

play();
117
int

ffsampleratetoint(
const

SampleFormat sf);
118
qint64 caltime(
const

uint64_t pts);
119
public
slots:
120
void

notified();
121
void

audiostate(QAudio::State state);
122
protected
:
123
 
int

writeaudio(
char

*data ,
const

int
size);
124
125
QAudioOutput *audio;
126
QIODevice *audioIO;
127
128
129
};
130
131
class
QVideoThread :
public
QDecodecThread
132
{
133
 
Q_OBJECT
134
public
:
135
 
QVideoThread(AVFormatContext *f, AVCodecContext *c,QMasterClock *cl,
int

index,QObject *parent=0);
136
 
~QVideoThread();
137
 
qint64 getframebuffer(
char

*data);
138
 
int

getwidth()
const
;
139
 
int

getheight()
const
;
140
 
int

getframesize();
141
 
void

run();
142
143
protected
:
144
 
SwsContext *m_img_convert_ctx;
//图像转换设置
145
146
 
char

*framebuffer;
147
 
int

framebuffersize;
148
 
qint64 pts;
149
150
 
QWaitCondition videowait;
151
152
153
private
:
154
 
AVFrame *yuvframe;
155
 
AVFrame *rgbframe;
156
};
157
158
class
QSubtitleThread :
public
QDecodecThread
159
{
160
Q_OBJECT
161
public
:
162
QSubtitleThread(AVFormatContext *f,AVCodecContext *c,QMasterClock *cl,
int

index,QObject *parent=0)
163
:QDecodecThread(f,c,cl,index,parent)
164
{}
165
void

run(){}
166
};
167
168
class
QFfWidget :
public
QWidget
169
{
170
Q_OBJECT
171
172
public
:
173
explicit

QFfWidget(QWidget *parent = 0);
174
~QFfWidget();
175
void

setframe(QImage *f);
176
void

lockframe();
177
void

unlockframe();
178
private
:
179
QImage *frame;
180
QMutex m;
181
protected
:
182
void

paintEvent(QPaintEvent *);
183
184
};
185
186
class
QFfplay :
public
QThread
187
{
188
Q_OBJECT
189
public
:
190
QFfplay(QVideoThread *v,QMasterClock *c, QObject *parent);
191
~QFfplay();
192
QWidget* getwidget();
193
protected
:
194
void

run();
195
QVideoThread *video;
196
QMasterClock *masterclock;
197
QImage *frame;
198
char

*framebuffer;
199
QFfWidget *widget;
200
201
202
};
203
204
class
QFfmpeg :
public
QThread
205
{
206
Q_OBJECT
207
public
:
208
explicit

QFfmpeg(QObject *parent);
209
//设置参数
210
void

seturl(QString url);
211
212
bool

open();
213
void

close();
214
215
bool

play();
216
void

stop();
217
218
//判断视频是否结束
219
bool

atEnd();
220
bool

IsOpen();
221
222
QWidget* getwidget();
223
224
225
signals:
226
227
public
slots:
228
229
protected
:
230
231
void

run();
232
private
:
233
/****解码相关******************/
234
char

m_url[255];
235
SwsContext *m_img_convert_ctx;
//图像转换设置
236
237
AVFormatContext *m_pFormatctx;
//视频流
238
QAudioThread *m_audiocodec;
//音频解码器
239
QVideoThread *m_videocodec;
//视频解码器
240
QSubtitleThread *m_subtitlecodec;
//字幕解码器
241
242
QMasterClock masterclock;
243
244
QImage *m_frame;
245
uint8_t* framebuffer;
//图象存储区 m_rgbframe m_frame 共享
246
247
QMutex m_mutex;
248
QFfplay *ffplay;
249
bool

m_isopen;
250
251
};
252
253
#endif // QFFMPEG_H
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: