不用 SDL 的QT+FFMPEG 播放器

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

代码片段(1)

[代码] cpp代码

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 
029extern "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 
055class QMasterClock //主时钟
056{
057public:
058    QMasterClock();
059    void adjusttime(int us);
060    qint64 getuscurtime();
061    void setstarttime(QTime t);
062protected:
063    QReadWriteLock m;
064    QTime starttime;
065 
066};
067 
068class QDecodecThread : public QThread
069{
070    Q_OBJECT
071public:
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 
090protected:
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 
108class QAudioThread : public QDecodecThread
109{
110    Q_OBJECT
111public:
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);
119public slots:
120  void notified();
121  void audiostate(QAudio::State state);
122protected:
123   int writeaudio(char *data ,const int size);
124 
125    QAudioOutput *audio;
126    QIODevice *audioIO;
127 
128 
129};
130 
131class QVideoThread : public QDecodecThread
132{
133   Q_OBJECT
134public:
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 
143protected:
144   SwsContext *m_img_convert_ctx;//图像转换设置
145 
146   char *framebuffer;
147   int framebuffersize;
148   qint64 pts;
149 
150   QWaitCondition videowait;
151 
152 
153private:
154   AVFrame *yuvframe;
155   AVFrame *rgbframe;
156};
157 
158class QSubtitleThread : public QDecodecThread
159{
160    Q_OBJECT
161public:
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 
168class QFfWidget : public QWidget
169{
170    Q_OBJECT
171 
172public:
173    explicit QFfWidget(QWidget *parent = 0);
174    ~QFfWidget();
175    void setframe(QImage *f);
176    void lockframe();
177    void unlockframe();
178private:
179    QImage *frame;
180    QMutex m;
181protected:
182    void paintEvent(QPaintEvent *);
183 
184};
185 
186class QFfplay : public QThread
187{
188    Q_OBJECT
189public:
190    QFfplay(QVideoThread *v,QMasterClock *c, QObject *parent);
191    ~QFfplay();
192    QWidget* getwidget();
193protected:
194    void run();
195    QVideoThread *video;
196    QMasterClock *masterclock;
197    QImage *frame;
198    char *framebuffer;
199    QFfWidget *widget;
200 
201 
202};
203 
204class QFfmpeg : public QThread
205{
206    Q_OBJECT
207public:
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 
225signals:
226 
227public slots:
228 
229protected:
230 
231    void run();
232private:
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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值