diff --git a/QQtExample.pro b/QQtExample.pro
index 505c3bc1..9c7b40c3 100644
--- a/QQtExample.pro
+++ b/QQtExample.pro
@@ -80,10 +80,11 @@ SUBDIRS += test/qqtdicttest2
#SUBDIRS += test/giftest
#必开 这个例子是关于LibQQt MultiMedia的最好展示
-#
-greaterThan(QT_VERSION, 4.6.0):SUBDIRS += test/voicetest
-#
-mac:lessThan(QT_MAJOR_VERSION , 5):SUBDIRS -= test/voicetest
+SUBDIRS += test/voicetest
+SUBDIRS += test/voicetest2
+SUBDIRS += test/videotest
+SUBDIRS += test/videotest2
+SUBDIRS += test/videotest3
#这边是个组合项,客户端和服务器一起的。必看
#SUBDIRS += examples/qqtclientexample
diff --git a/QQtExample_App.pro b/QQtExample_App.pro
index a3b4e23e..31477471 100644
--- a/QQtExample_App.pro
+++ b/QQtExample_App.pro
@@ -109,10 +109,11 @@ SUBDIRS += test/qqtdicttest2
SUBDIRS += test/giftest
#必开 这个例子是关于LibQQt MultiMedia的最好展示
-#
-greaterThan(QT_VERSION, 4.6.0):SUBDIRS += test/voicetest
-#
-mac:lessThan(QT_MAJOR_VERSION , 5):SUBDIRS -= test/voicetest
+SUBDIRS += test/voicetest
+SUBDIRS += test/voicetest2
+SUBDIRS += test/videotest
+SUBDIRS += test/videotest2
+SUBDIRS += test/videotest3
#
SUBDIRS += examples/qqtclientexample
#
diff --git a/README.md b/README.md
index 3ccfd734..af4985d3 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,7 @@ github link: https://github.com/AbelTian/LibQQt
- *全在frame文件夹*
8. 支持多页表格 [QQtMultiPageTableWidget](src/widgets/qqtmultipagetablewidget.h)
9. 添加 [QQtApplication](src/frame/qqtapplication.h),支持入门级、通用级、专用级嵌入式App所必须的初始化内容
-5. 支持Qt5.9.2
+5. 支持Qt5.8,Qt5.9.2
- 建议桌面使用这个版本,对三大桌面,和IOS Android e-linux支持都很好。
0. 跨平台支持macOS、iOS、Android、Windows、Linux、MIPS、ARM等。
1. 添加矢量图形widgets
@@ -108,9 +108,13 @@ github link: https://github.com/AbelTian/LibQQt
- 添加内存服务器(一套Input(Reader),Output(Writer)),处理内存和设备之间的数据交互。(这部分的功能完全按照为内存服务的思路设计研发。)
- [QQtAudioManager](src/multimedia/qqtaudiomanager.h)、
- 将 AudioInputDevice 和 AudioOutputDevice 当做一个设备进行读写,App处理获取到的声音。
+ - 增加QQtWavAudioManager、QQtWavSoundEffect、QQtWavSound,
+ - 像操作一个设备一样读、写wav文件。
+ - 增加QQtVideoManager、QQtLogicVideoManager,
+ - 支持桌面摄像头采集画面,支持模拟摄像头采集画面。
6. 添加Http功能支持工具
- QQtWebAccessManager,支持管理Session、Cookies。
- - 添加GumboQuery爬虫工具。
+ - 添加GumboQuery爬虫工具,爬取网页信息。
- 支持webservice (QtSoap)
8. 添加Qt没有的组件QQtTitleBar
- 可以组完全自定义的Form。
@@ -194,7 +198,7 @@ LibQQt R3支持Qt5,由于使用Multi-link 2,不支持Qt4。
邮箱: tianduanrui@163.com
QQ: 2657635903
-
+LibQQt技术分享和交流群: 560584206
========================================================================
# 用户使用协议
diff --git a/demo/QQtRoseMonitor/qqtosdform.cpp b/demo/QQtRoseMonitor/qqtosdform.cpp
index 3ec917af..71dfda85 100644
--- a/demo/QQtRoseMonitor/qqtosdform.cpp
+++ b/demo/QQtRoseMonitor/qqtosdform.cpp
@@ -38,7 +38,7 @@ QQtOsdForm::QQtOsdForm ( QWidget* parent ) :
//setWindowFlag ( Qt::WindowSystemMenuHint, true );
//setAttribute ( Qt::WA_DeleteOnClose, true );
- setPixmap ( qrc ( "rose.png" ) );
+ setPixmap ( conf_qrc ( "rose.png" ) );
}
QQtOsdForm::~QQtOsdForm()
diff --git a/examples/qqtaudioexample/AppRoot/res/9763.wav b/examples/qqtaudioexample/AppRoot/res/9763.wav
new file mode 100644
index 00000000..91b8faad
Binary files /dev/null and b/examples/qqtaudioexample/AppRoot/res/9763.wav differ
diff --git a/examples/qqtaudioexample/android/AndroidManifest.xml b/examples/qqtaudioexample/android/AndroidManifest.xml
new file mode 100644
index 00000000..75006f8d
--- /dev/null
+++ b/examples/qqtaudioexample/android/AndroidManifest.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/qqtaudioexample/android/res/drawable-hdpi/icon.png b/examples/qqtaudioexample/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..c214b280
Binary files /dev/null and b/examples/qqtaudioexample/android/res/drawable-hdpi/icon.png differ
diff --git a/examples/qqtaudioexample/android/res/drawable-ldpi/icon.png b/examples/qqtaudioexample/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..e21e1c98
Binary files /dev/null and b/examples/qqtaudioexample/android/res/drawable-ldpi/icon.png differ
diff --git a/examples/qqtaudioexample/android/res/drawable-mdpi/icon.png b/examples/qqtaudioexample/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..24680bc7
Binary files /dev/null and b/examples/qqtaudioexample/android/res/drawable-mdpi/icon.png differ
diff --git a/examples/qqtaudioexample/android/res/values/libs.xml b/examples/qqtaudioexample/android/res/values/libs.xml
new file mode 100644
index 00000000..4009a778
--- /dev/null
+++ b/examples/qqtaudioexample/android/res/values/libs.xml
@@ -0,0 +1,25 @@
+
+
+
+ - https://download.qt.io/ministro/android/qt5/qt-5.9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/qqtaudioexample/main.cpp b/examples/qqtaudioexample/main.cpp
new file mode 100644
index 00000000..30c9ad7b
--- /dev/null
+++ b/examples/qqtaudioexample/main.cpp
@@ -0,0 +1,12 @@
+#include "mainwindow.h"
+#include
+
+int main ( int argc, char* argv[] )
+{
+ QQtApplication a ( argc, argv );
+
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/examples/qqtaudioexample/mainwindow.cpp b/examples/qqtaudioexample/mainwindow.cpp
new file mode 100644
index 00000000..3e2b32c6
--- /dev/null
+++ b/examples/qqtaudioexample/mainwindow.cpp
@@ -0,0 +1,45 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include
+
+MainWindow::MainWindow ( QWidget* parent ) :
+ QMainWindow ( parent ),
+ ui ( new Ui::MainWindow )
+{
+ ui->setupUi ( this );
+
+ //wavManager设置待播放的文件,inputFormat起效
+ wavManager.setInputSourceFile ( conf_res ( "9763.wav" ) );
+ //audManager设置输出设备,也就是设置输出喇叭,并且,这里的并且很重要,设置输出格式,等于wav里的音频的格式。
+ audManager.outputDeviceInfo() = QQtAudioManager::defaultOutputDevice();
+ audManager.outputAudioFormat() = wavManager.inputAudioFormat();
+
+ //连接wavManager的音频帧接收槽,这里其实是个接收器,在接收器里播放。
+ connect ( &wavManager, SIGNAL ( readyRead() ), this, SLOT ( on_play_frame() ) );
+ ;
+
+ //这个是专门为使用机械硬盘设置的,减慢读取timer,要不有滋滋的噪音。
+ wavManager.inputManager()->setTimerInterval ( 100 );
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::on_pushButton_clicked()
+{
+ wavManager.stopInput();
+ audManager.stopOutput();
+
+ audManager.startDefaultOutput();
+ wavManager.startInput();
+}
+
+void MainWindow::on_play_frame()
+{
+ //这里readAll就是读一帧,(wavManger内部对音频进行了切帧)。
+ QByteArray bytes = wavManager.readAll();
+ //播放
+ audManager.write ( bytes );
+}
diff --git a/examples/qqtaudioexample/mainwindow.h b/examples/qqtaudioexample/mainwindow.h
new file mode 100644
index 00000000..fc399e91
--- /dev/null
+++ b/examples/qqtaudioexample/mainwindow.h
@@ -0,0 +1,34 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+
+#include "qqtwavaudiomanager.h"
+#include "qqtaudiomanager.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow ( QWidget* parent = 0 );
+ ~MainWindow();
+
+public slots:
+ void on_play_frame();
+
+private slots:
+ void on_pushButton_clicked();
+
+private:
+ Ui::MainWindow* ui;
+
+ QQtWavAudioManager wavManager;
+ QQtAudioManager audManager;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/qqtaudioexample/mainwindow.ui b/examples/qqtaudioexample/mainwindow.ui
new file mode 100644
index 00000000..b6328544
--- /dev/null
+++ b/examples/qqtaudioexample/mainwindow.ui
@@ -0,0 +1,35 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 229
+ 351
+
+
+
+ MainWindow
+
+
+
+
+
+ 50
+ 50
+ 111
+ 31
+
+
+
+ Play
+
+
+
+
+
+
+
+
diff --git a/examples/qqtaudioexample/qqtaudioexample.pro b/examples/qqtaudioexample/qqtaudioexample.pro
new file mode 100644
index 00000000..fcba30ab
--- /dev/null
+++ b/examples/qqtaudioexample/qqtaudioexample.pro
@@ -0,0 +1,69 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-04-19T07:52:51
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = qqtaudioexample
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui
+
+CONFIG += mobility
+MOBILITY =
+
+system(touch main.cpp)
+
+include(../../multi-link/multi-link/add_base_manager.pri)
+
+
+
+contains(QSYS_PRIVATE, Android|AndroidX86) {
+ CONFIG += mobility
+ MOBILITY =
+ DISTFILES += \
+ android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $${PWD}/android
+}
+
+RESOURCES += \
+ qqtaudioexample.qrc
+
+#这个的设置有特点,要先设置
+add_version (1,0,0,0)
+
+#先发布App
+#app从build到deploy
+add_deploy()
+
+#后发布依赖
+#libQQt从sdk到build和deploy
+add_dependent_manager(QQt)
+
+#发布配置文件 把AppRoot里的配置项目拷贝到运行目录和发布目录
+add_deploy_config($${PWD}/AppRoot)
diff --git a/examples/qqtaudioexample/qqtaudioexample.qrc b/examples/qqtaudioexample/qqtaudioexample.qrc
new file mode 100644
index 00000000..9062d140
--- /dev/null
+++ b/examples/qqtaudioexample/qqtaudioexample.qrc
@@ -0,0 +1,5 @@
+
+
+ AppRoot/res/9763.wav
+
+
diff --git a/multi-environ/README.md b/multi-environ/README.md
new file mode 100644
index 00000000..a2c58ac4
--- /dev/null
+++ b/multi-environ/README.md
@@ -0,0 +1,118 @@
+# Multi-environ Technology
+
+为了方便用户在命令行里工作,我开发了多环境管理器Multi-environ Manager(即PyMake),
+在此为LibQQt提供多环境编译支持,具备方便的同时编译能力。
+
+# 安装PyMake
+
+如果电脑上没有PyMake,需要先安装,
+PyMake可以帮助用户在命令行里做各种工作,不仅仅限于此处编译,所以,请自行事先安装。
+
+#### 下载PyMake安装包
+######国内
+PyMake Gitee Clone:[https://gitee.com/drabel/PyMake.git](https://gitee.com/drabel/PyMake.git)
+PyMake V7.8.2 Zip包:[https://gitee.com/drabel/PyMake/repository/archive/v7.8.2](https://gitee.com/drabel/PyMake/repository/archive/v7.8.2)
+######国外
+PyMake Github Clone:[https://github.com/AbelTian/PyMake.git](https://github.com/AbelTian/PyMake.git)
+
+#### 安装PyMake
+1. 需要管理员权限,切换到PyMake目录,install.bat %*。Unix系统install.sh。
+
+#### 配置PyMake
+```bash
+
+# 更改多环境根目录到自己定义的目录。
+pymake source root
+
+# 更改环境文件到自己私有的环境配置文件,一般一台电脑用一个环境文件。
+pymake source config
+
+# 使用我在Windows上的环境配置文件,初始化自己的环境文件。
+pymake port file /example/pymake7-win-tai5.json /
+
+# 修改/环境文件里的几个命名路径。
+pymake source config --edit
+
+# 查看一次所有设置
+pymake get all settings -a -r
+
+# 修改以下字段,不限于这些字段,建议用户一次配置好长期使用。
+# path-assemblage:
+ # root路径,一系列根路径
+ # cc路径,这个路径下有PyMake
+ # wincc路径,这个路径下有cmake和很多品种语言的解释器
+ # qt路径
+ # android路径
+ # java路径
+ # 人工检查配置其他路径
+
+# 修改/custom.path+.ini
+ # ${cmake.bin} 添加一行,用于支持cmake编译。如果需要,还可以增加很多其他路径。
+
+# 修改完路径后,查看一下环境,你需要编译几个环境的,就查看几个环境
+pymake env mingw32
+pymake env mingw64
+pymake env android.mobile
+pymake env android.x86
+pymake env msvc2015
+pymake env msvc2015.x64
+pymake env mscos
+pymake env ios
+pymake env gcc
+pymake env armhf32
+pymake env mips32
+
+# 查看一遍以后,检查一下环境配置的是否正确,如果不正确及时修改,你需要编译几个环境的,就检查几个环境,还可以检查path、cmd配置是否正确
+pymake chk -slc
+pymake chk path -a
+pymake chk cmd -a
+pymake chk mingw32
+pymake chk mingw64
+pymake chk android.mobile
+pymake chk android.x86
+pymake chk msvc2015
+pymake chk msvc2015.x64
+pymake chk mscos
+pymake chk ios
+pymake chk gcc
+pymake chk armhf32
+pymake chk mips32
+
+```
+
+# 使用PyMake开始编译
+
+PyMake只需要配置一次,以后,直接开始编译即可。
+
+```bash
+
+# 环境检查无误,修改/里的qqt.build.all命令
+set MODULEARRAY=QQt ...还有其他的库才会需要添加其他的库名,用空格分隔
+set ENVARRAY=mingw32 ...需要编译几个环境的就添加几个环境,用空格分隔
+
+# 切换到LibQQt的上一层目录,开始编译
+# 导出qqt.build.all这一个命令
+pymake type here qqt.build.all to qqt.build.all
+# 开始
+qqt.build.all.bat
+# 如果一切正常,会开启多个编译命令行。实现同时多环境编译。 这个脚本可以多次使用。我测试的开启52个编译环境命令行,正常编译。这取决于你的电脑的能力。
+
+# 如果不希望导出这个命令,那么执行以下命令,
+pymake system ccvp here qqt.build.all
+# 如果一切正常,现象同上。
+
+# 如果仅仅编译一个环境的目标,那么执行以下命令,
+# 切换到LibQQt源代码目录,编译mingw32环境的目标
+pymake use mingw32 ccvp here build.qmake QQt
+
+# 如果需要其他功能支持,在/里command组下,添加自己的命令即可。PyMake提供多种模式的ccvp直接执行。
+```
+
+# 编译截图
+
+![](a0.png)
+![](a1.png)
+![](b0.png)
+![](b1.png)
+![](b2.png)
+![](c0.png)
\ No newline at end of file
diff --git a/multi-environ/a0.png b/multi-environ/a0.png
new file mode 100644
index 00000000..752dda82
Binary files /dev/null and b/multi-environ/a0.png differ
diff --git a/multi-environ/a1.png b/multi-environ/a1.png
new file mode 100644
index 00000000..7f0714dd
Binary files /dev/null and b/multi-environ/a1.png differ
diff --git a/multi-environ/b0.png b/multi-environ/b0.png
new file mode 100644
index 00000000..d6fa0a0f
Binary files /dev/null and b/multi-environ/b0.png differ
diff --git a/multi-environ/b1.png b/multi-environ/b1.png
new file mode 100644
index 00000000..782b9796
Binary files /dev/null and b/multi-environ/b1.png differ
diff --git a/multi-environ/b2.png b/multi-environ/b2.png
new file mode 100644
index 00000000..534ad887
Binary files /dev/null and b/multi-environ/b2.png differ
diff --git a/multi-environ/c0.png b/multi-environ/c0.png
new file mode 100644
index 00000000..f62d91e1
Binary files /dev/null and b/multi-environ/c0.png differ
diff --git a/multi-link b/multi-link
index dbb43fa3..131c27f3 160000
--- a/multi-link
+++ b/multi-link
@@ -1 +1 @@
-Subproject commit dbb43fa39b64a4c1a713edcc8c05dee2a5209e27
+Subproject commit 131c27f39bbffe61498ca33c54e836430122307c
diff --git a/project.md b/project.md
index 7bcceab4..cde2c88c 100644
--- a/project.md
+++ b/project.md
@@ -5,11 +5,11 @@
|LibQQt(主库)| [工程链接](https://gitee.com/drabel/LibQQt) |Commercial,GPL Series|
|QQtExquisite|[工程链接](https://gitee.com/drabel/QQtExquisite)|Commercial,GPL Series|
|QQtHighGrade|[工程链接](https://gitee.com/drabel/QQtHighGrade)|Commercial,GPL Series|
-|QQtInput|[工程链接](https://gitee.com/drabel/QQtInput)|Commercial,GPL Series|
|QQtRuntimeExtention|[工程链接](https://gitee.com/drabel/QQtRuntimeExtention)|Commercial,GPL Series|
|QQtInstallFramework|[工程链接](https://gitee.com/drabel/QQtInstallFramework)|Commercial,GPL Series|
|QQtTool|[工程链接](https://gitee.com/drabel/QQtTool)|Commercial,GPL Series|
|QQtMediaExtention|[工程链接](https://gitee.com/drabel/QQtMediaExtention)|Commercial|
+|QQtInput|[工程链接](https://gitee.com/drabel/QQtInput)|Commercial|
|QQtSupport|[工程链接](https://gitee.com/drabel/QQtSupport)|Commercial|
|QQtExquisitePlugin|[工程链接](https://gitee.com/drabel/QQtExquisitePlugin)|Commercial|
|QQtIndustrialControl|[工程链接](https://gitee.com/drabel/QQtIndustrialControl)|Commercial|
diff --git a/src/QQt.pro b/src/QQt.pro
index 8d0542e1..943726c3 100644
--- a/src/QQt.pro
+++ b/src/QQt.pro
@@ -18,7 +18,7 @@
#################################################################
##Usage
#################################################################
-#Suggest Qt 5.9.2/4.8.6/4.8.7
+#Suggest Qt 5.8/5.9.2/4.8.6/4.8.7
#please dont use Qt 5.9.1, it is broken with android and ios.
#please dont modify this pro
#use LibQQt you need change Qt Creator default build directory: your-pc-build-station/%{CurrentProject:Name}/%{CurrentKit:FileSystemName}/%{Qt:Version}/%{CurrentBuild:Name} (Only Once)
diff --git a/src/core/qqtdictionary.cpp b/src/core/qqtdictionary.cpp
index d77a6458..295b7028 100644
--- a/src/core/qqtdictionary.cpp
+++ b/src/core/qqtdictionary.cpp
@@ -533,13 +533,28 @@ void QQtDictionary::parseDictionaryToJsonValue ( const QQtDictionary& node, QJso
QList& l = node.getList();
QJsonValue value;
parseDictionaryToJsonValue ( l[i], value );
- array.append ( value );
+ //array.append ( value );
+ array.push_back ( value );
}
result = array;
break;
}
case DictMap:
+ {
+ //"name": {"a":"b", "a2":"b2", "a3":["b31", "b32"], "a4":{"a41":"b41", "a42":"b42"}, ...}
+ QJsonObject object;
+ for ( QMap::Iterator itor = node.getMap().begin(); itor != node.getMap().end(); itor++ )
+ {
+ //QMap& m = node.getMap();
+ const QString& key = itor.key();
+ const QQtDictionary& srcvalue = itor.value();
+ QJsonValue value;
+ parseDictionaryToJsonValue ( srcvalue, value );
+ object.insert ( key, value );
+ }
+ result = object;
break;
+ }
case DictMax:
default:
break;
diff --git a/src/core/qqtdictionary.h b/src/core/qqtdictionary.h
index 4e34d0e5..d748af37 100644
--- a/src/core/qqtdictionary.h
+++ b/src/core/qqtdictionary.h
@@ -3,7 +3,7 @@
#include
#include
-#include
+#include
#include
#include
@@ -14,11 +14,11 @@
class QQtDictionary;
typedef QMap QQtDictionaryMap;
typedef QMapIterator QQtDictionaryMapIterator;
-typedef QMutableMapIterator QQtDictionaryMutableMapIterator;
+typedef QMutableMapIterator QQtDictionaryMapConstIterator;
typedef QList QQtDictionaryList;
typedef QListIterator QQtDictionaryListIterator;
-typedef QMutableListIterator QQtDictionaryMutableListIterator;
+typedef QMutableListIterator QQtDictionaryListConstIterator;
/**
* @brief The QQtDictionary class
@@ -30,8 +30,8 @@ typedef QMutableListIterator QQtDictionaryMutableListIterator;
* 接受嵌套访问 操作方式 dict["cccc"][0]["eeeee"]
* 通过重载函数来实现类型的变化,不建议使用中更改类型。
* 比json和xml的数据结构要庞大。toJson toXML fromJson fromXML
- * QVariant 不能直接获取到真实数据,改变必须使用临时变量。
- * 而且,接口设计也不够灵活,存入和取出都不太方便。
+ * QVariant 不能直接获取到真实数据,改变必须使用临时变量,而且,接口设计也不够灵活,存入和取出都不太方便。
+ * QQtDictionary封装了QVariant,实现直接操作真实数据。提供大量操作符。存取数据方便快捷,类型多样。
*/
class QQTSHARED_EXPORT QQtDictionary
{
diff --git a/src/core/qqtorderedmap.cpp b/src/core/qqtorderedmap.cpp
new file mode 100644
index 00000000..85d6bacb
--- /dev/null
+++ b/src/core/qqtorderedmap.cpp
@@ -0,0 +1 @@
+#include
diff --git a/src/core/qqtorderedmap.h b/src/core/qqtorderedmap.h
new file mode 100644
index 00000000..30ee6b4d
--- /dev/null
+++ b/src/core/qqtorderedmap.h
@@ -0,0 +1,6 @@
+#ifndef QQTORDEREDMAP_H
+#define QQTORDEREDMAP_H
+
+#include
+
+#endif // QQTORDEREDMAP_H
diff --git a/src/exquisite/qqtpicturetabbar.cpp b/src/exquisite/qqtpicturetabbar.cpp
index ad72cd51..5e318aa4 100644
--- a/src/exquisite/qqtpicturetabbar.cpp
+++ b/src/exquisite/qqtpicturetabbar.cpp
@@ -58,11 +58,11 @@ void QQtPictureTabBar::setSelectedTextColor ( QColor selectedTextColor )
void QQtPictureTabBar::tabPixmap ( int index, QImage& img, QImage& imgSel )
{
- if ( index < 0 || index + 1 > count() || index + 1 > imgList.size() )
+ if ( index < 0 || index + 1 > count() || index + 1 > dict1["image"].size() )
return;
- img = QImage ( imgList[index][BTN_NORMAL] );
- imgSel = QImage ( imgList[index][BTN_PRESS] );
+ img = QImage ( dict1["image"][index][BTN_NORMAL].getValue().toString() );
+ imgSel = QImage ( dict1["image"][index][BTN_PRESS].getValue().toString() );
return ;
}
@@ -72,20 +72,20 @@ void QQtPictureTabBar::setTabPixmap ( int index, const QString& img, const QStri
if ( index < 0 || index + 1 > count() )
return;
- TBtnIconTable table;
- table[BTN_NORMAL] = img;
- table[BTN_PRESS] = imgSel;
- imgList.insert ( index, table );
+ dict1["image"][index][BTN_NORMAL] = img;
+ dict1["image"][index][BTN_PRESS] = imgSel;
}
void QQtPictureTabBar::tabIcon ( int index, QImage& icon, QImage& iconSel )
{
- if ( index < 0 || index + 1 > count() || index + 1 > imgList.size() )
+ if ( index < 0 || index + 1 > count() || index + 1 > dict1["icon"].size() )
return;
- icon = QImage ( iconList[index][BTN_NORMAL] );
- iconSel = QImage ( iconList[index][BTN_PRESS] );
+ icon = QImage ( dict1["icon"][index][BTN_NORMAL].getValue().toString() );
+ iconSel = QImage ( dict1["icon"][index][BTN_PRESS].getValue().toString() );
+ //pline() << icon;
+ //pline() << iconSel;
return ;
}
@@ -95,11 +95,13 @@ void QQtPictureTabBar::setTabIcon ( int index, const QString& icon, const QStrin
if ( index < 0 || index + 1 > count() )
return;
- TBtnIconTable table;
- table[BTN_NORMAL] = icon;
- table[BTN_PRESS] = iconSel;
- iconList.insert ( index, table );
+ dict1["icon"][index][BTN_NORMAL] = icon;
+ dict1["icon"][index][BTN_PRESS] = iconSel;
+
+ //pline() << dict1["icon"][index][BTN_NORMAL];
+ //pline() << dict1["icon"][index][BTN_PRESS];
+
}
void QQtPictureTabBar::setBackgroundColor ( QColor backgroundColor )
@@ -154,20 +156,20 @@ void QQtPictureTabBar::drawPicture ( QPainter* p )
{
QRect tRect0 = tabRect ( index );
- if ( imgList.size() > index )
+ if ( dict1["image"].size() > index )
{
p->save();
int sel = currentIndex() == index ? BTN_PRESS : BTN_NORMAL;
#if 1
//tabRect = rect()?
- p->drawPixmap ( tRect0, QIcon ( imgList[index][sel] ).pixmap ( tRect0.size(), QIcon::Normal, QIcon::On ) );
+ p->drawPixmap ( tRect0, QIcon ( dict1["image"][index][sel].getValue().toString() ).pixmap ( tRect0.size(), QIcon::Normal, QIcon::On ) );
#endif
/*
* 失真不明显,使用以下方法
*/
#if 0
- QImage image ( iconList[index][sel] );
+ QImage image ( dict1["image"][index][sel].getValue().toString() );
p.drawItemPixmap ( tabRectValue, Qt::AlignLeft | Qt::AlignTop, QPixmap::fromImage ( image.scaled ( tabRectValue.size(),
Qt::KeepAspectRatio ) ) );
#endif
@@ -176,7 +178,7 @@ void QQtPictureTabBar::drawPicture ( QPainter* p )
//为什么不用这个呢?因为上边那个QIcon直接缩放到了完整的符合Icon大小的图.直接居中.
//这个不需要,多次一举.
#if 0
- p->drawItemPixmap ( tRect0, Qt::AlignCenter, QIcon ( imgList[index][sel] ).pixmap ( tRect0.size(), QIcon::Normal,
+ p->drawItemPixmap ( tRect0, Qt::AlignCenter, QIcon ( dict1["image"][index][sel].getValue().toString() ).pixmap ( tRect0.size(), QIcon::Normal,
QIcon::On ) );
#endif
p->restore();
@@ -252,17 +254,17 @@ void QQtPictureTabBar::drawIcon ( QPainter* p )
int sel = BTN_NORMAL;
sel = currentIndex() == index ? BTN_PRESS : BTN_NORMAL;
- //pline() << iconList.size() << index << iconList[index][sel];
+ //pline() << dict1["icon"].size() << index << dict1["icon"][index][sel].getValue().toString();
- if ( iconList.size() > index )
+ if ( dict1["icon"].size() > index )
{
p->save();
//tabRect = rect()?
- p->drawPixmap ( tRect0, QIcon ( iconList[index][sel] ).pixmap ( tRect0.size(), mode, QIcon::On ) );
+ p->drawPixmap ( tRect0, QIcon ( dict1["icon"][index][sel].getValue().toString() ).pixmap ( tRect0.size(), mode, QIcon::On ) );
/*
* 失真不明显,使用以下方法
*/
- //QImage image(iconList[index][sel]);
+ //QImage image(dict1["icon"][index][sel].getValue().toString());
//p.drawItemPixmap(tabRectValue, Qt::AlignLeft |Qt::AlignTop, QPixmap::fromImage(image.scaled(tabRectValue.size(), Qt::KeepAspectRatio)));
p->restore();
}
diff --git a/src/exquisite/qqtpicturetabbar.h b/src/exquisite/qqtpicturetabbar.h
index 9ae6bb72..bf0a6ec7 100644
--- a/src/exquisite/qqtpicturetabbar.h
+++ b/src/exquisite/qqtpicturetabbar.h
@@ -8,6 +8,7 @@
#include "qqtwidgets.h"
#include "qqttabbar.h"
#include "qqt-local.h"
+#include "qqtdictionary.h"
class QQTSHARED_EXPORT QQtPictureTabBar : public QQtTabBar
{
@@ -27,6 +28,7 @@ public:
/*
* 依赖iconSize,layoutSpacing设置图片位置
*/
+ //default
IconStyle_Left_And_RightText,
IconStyle_Right_And_LeftText,
IconStyle_MiddleText,
@@ -85,8 +87,7 @@ protected:
public slots:
private:
- QList imgList;
- QList iconList;
+ QQtDictionary dict1;
IconStyle iconStyle;
QFont textFont;
QColor textColor;
diff --git a/src/frame/qqtapplication.cpp b/src/frame/qqtapplication.cpp
index ccd4461d..3f84c53f 100644
--- a/src/frame/qqtapplication.cpp
+++ b/src/frame/qqtapplication.cpp
@@ -52,7 +52,7 @@ QQtApplication::QQtApplication ( int& argc, char** argv ) :
#endif
qDebug() << tr ( "QQt Application Framework Software [LibQQt]" );
- qDebug() << tr ( "Copyright © 2017 Tianduanrui. All rights reserved." );
+ qDebug() << tr ( "Copyright (C) 2017 Tianduanrui. All rights reserved." );
qDebug() << tr ( "Assigned by Dezhou." );
pline() << "Qt version:" << QT_VERSION_STR;
@@ -165,7 +165,7 @@ void QQtApplication::setHighDpiScaling ( bool open )
{
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
setAttribute ( Qt::AA_EnableHighDpiScaling, open );
- //setAttribute ( Qt::AA_UseHighDpiPixmaps, open );
+ setAttribute ( Qt::AA_UseHighDpiPixmaps, open );
#endif
}
@@ -214,7 +214,7 @@ bool QQtApplication::setTextFont ( QString fontfile, int fontsize )
/*这个函数没有任何问题,检测完毕。过去的报错是工作目录不对,无法加载其他数据库*/
/*此处,改为使用QFontDatabase的经典静态方法调用方式*/
//ignored
- QFontDatabase db;
+ QFontDatabase fontdb0;
int fontID = QFontDatabase::addApplicationFont ( fontfile );
pline() << "font file:" << fontfile;
@@ -229,8 +229,8 @@ bool QQtApplication::setTextFont ( QString fontfile, int fontsize )
QString ziti = QFontDatabase::applicationFontFamilies ( fontID ).at ( 0 );
pline() << "font name:" << ziti;
- QFont font ( ziti, fontsize );
- QApplication::setFont ( font );
+ QFont font1 ( ziti, fontsize );
+ QApplication::setFont ( font1 );
return true;
}
diff --git a/src/frame/qqtframe.h b/src/frame/qqtframe.h
index 95ac1c4f..9e1a90d9 100644
--- a/src/frame/qqtframe.h
+++ b/src/frame/qqtframe.h
@@ -22,43 +22,6 @@
extern "C" {
#endif /* __cplusplus */
-enum
-{
- Lib_Id = 0,
- Lib_Name,
- Lib_Creater,
- Lib_CreateTime,
- Lib_Comment,
-};
-
-enum
-{
- Method_Id = 0,
- Method_Name,
- Method_Type,
- Method_Vessel,
-};
-
-enum
-{
- Stage_Id = 0,
- Stage_Index,
- Stage_Vessel,
- Stage_Timeramp,
- Stage_Presspsi,
- Stage_Tempture,
- Stage_Hold,
- Stage_MethodId,
-};
-
-enum
-{
- Type_Standard = 0,
- Type_Temprature,
- Type_Stressure,
- Type_Extract,
-};
-
enum
{
Login_Request,
@@ -73,19 +36,6 @@ enum
};
-typedef enum tagSampleEnum
-{
- ESampleId,
- ESampleMingcheng,
- ESampleBianhao,
- ESampleYangpinliang,
- ESampleYangpindanwei,
- ESampleJieguo,
- ESampleJieguodanwei,
- ESampleCeshiren,
- ESampleCeshishijian,
-} ESampleColomn;
-
enum
{
Language_English,
@@ -114,37 +64,42 @@ enum
};
-#define CONFIG_ROOT "."
-#define CONFIG_PATH "./conf"
-#define LOG_PATH "./log"
-#define AV_PATH "./res"
-#define SKIN_PATH "./skin"
+#define CONFIG_ROOT QString(".")
+#define CONFIG_PATH QString(CONFIG_ROOT + "/conf")
+#define LOG_PATH QString(CONFIG_ROOT + "/log")
+#define AV_PATH QString(CONFIG_ROOT + "/res")
+#define SKIN_PATH QString(CONFIG_ROOT + "/skin")
+#define FONT_PATH QString(CONFIG_ROOT + "/font")
+#define DB_PATH QString(CONFIG_ROOT + "/db")
+#define LANG_PATH QString(CONFIG_ROOT + "/lang")
#if defined (__ANDROIDX86__)
-#define qrc(file) QString("%1/%2").arg("assets:/").arg(file)
-#define res(file) QString("%1/%2").arg("assets:/res").arg(file)
-#define skin(file) QString("%1/%2").arg("assets:/skin").arg(file)
+#define conf_qrc(file) QString("%1/%2").arg("assets:/").arg(file)
+#define conf_res(file) QString("%1/%2").arg("assets:/res").arg(file)
+#define conf_skin(file) QString("%1/%2").arg("assets:/skin").arg(file)
+#define conf_font(file) QString("%1/%2").arg("assets:/font").arg(file)
+#define conf_db(file) QString("%1/%2").arg("assets:/db").arg(file)
+#define conf_lang(file) QString("%1/%2").arg("assets:/lang").arg(file)
#elif defined (__ANDROID__)
-#define qrc(file) QString("%1/%2").arg("://").arg(file)
-#define res(file) QString("%1/%2").arg("://res").arg(file)
-#define skin(file) QString("%1/%2").arg("://skin").arg(file)
+#define conf_qrc(file) QString("%1/%2").arg("://").arg(file)
+#define conf_res(file) QString("%1/%2").arg("://res").arg(file)
+#define conf_skin(file) QString("%1/%2").arg("://skin").arg(file)
+#define conf_font(file) QString("%1/%2").arg("://font").arg(file)
+#define conf_db(file) QString("%1/%2").arg("://db").arg(file)
+#define conf_lang(file) QString("%1/%2").arg("://lang").arg(file)
#else
-#define qrc(file) QDir(qApp->applicationDirPath()).relativeFilePath(QString("%1/%2").arg(CONFIG_ROOT).arg(file))
-#define res(file) QDir(qApp->applicationDirPath()).relativeFilePath(QString("%1/%2").arg(AV_PATH).arg(file))
-#define skin(file) QDir(qApp->applicationDirPath()).relativeFilePath(QString("%1/%2").arg(SKIN_PATH).arg(file))
+#define conf_qrc(file) QDir().absoluteFilePath(QString("%1/%2").arg(CONFIG_ROOT).arg(file))
+#define conf_res(file) QDir().absoluteFilePath(QString("%1/%2").arg(AV_PATH).arg(file))
+#define conf_skin(file) QDir().absoluteFilePath(QString("%1/%2").arg(SKIN_PATH).arg(file))
+#define conf_font(file) QDir().absoluteFilePath(QString("%1/%2").arg(FONT_PATH).arg(file))
+#define conf_db(file) QDir().absoluteFilePath(QString("%1/%2").arg(DB_PATH).arg(file))
+#define conf_lang(file) QDir().absoluteFilePath(QString("%1/%2").arg(LANG_PATH).arg(file))
#endif
-
-#define TABLE_LIBRARY "Library"
-#define TABLE_METHOD "Method"
-#define TABLE_STAGE "Stage"
-#define TABLE_EVTYPE "Type"
-
extern QString gUserName;
extern QString gPassword;
extern int gAuthority;
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/frame/qqtqssmanager.cpp b/src/frame/qqtqssmanager.cpp
index 44127b04..02019c81 100644
--- a/src/frame/qqtqssmanager.cpp
+++ b/src/frame/qqtqssmanager.cpp
@@ -1,6 +1,9 @@
#include "qqtqssmanager.h"
+#include "qqtcore.h"
+#include
+#include
-QQtQSSManager::QQtQSSManager ( QObject* parent )
+QQtQSSManager::QQtQSSManager ( QObject* parent ) : QObject ( parent )
{
}
@@ -14,7 +17,7 @@ QList QQtQSSManager::styleList()
{
while ( mStyleList.count() > 0 )
mStyleList.removeAt ( 0 );
- QDir d ( SKIN_PATH );
+ QDir d ( conf_skin ( "." ) );
foreach ( QFileInfo mfi, d.entryInfoList() )
{
if ( mfi.isFile() )
@@ -24,41 +27,52 @@ QList QQtQSSManager::styleList()
//不包括default.qss
if ( mfi.baseName() == "default" )
continue;
+ if ( mfi.baseName() == "current" )
+ continue;
QString styleName = mfi.completeBaseName();
mStyleList.push_back ( styleName );
}
}
+ //pline() << d.absolutePath();
+ //pline() << mStyleList;
return mStyleList;
}
void QQtQSSManager::setCurrentStyle ( QString styleName )
{
- if ( !QDir ( skin ( "default.qss" ) ).exists() )
- return;
- if ( !QDir ( skin ( QString ( "%1.qss" ).arg ( styleName ) ) ).exists() )
- return;
+ //pline() << "set style";
+ //pline() << conf_skin ( "default.qss" );
+ //pline() << QFile ( conf_skin ( "default.qss" ) ).exists() << QDir ( conf_skin ( "default.qss" ) ).exists();
+ //pline() << conf_skin ( QString ( "%1.qss" ).arg ( styleName ) );
+ //pline() << QFile ( conf_skin ( QString ( "%1.qss" ).arg ( styleName ) ) ).exists() << QDir ( conf_skin ( QString ( "%1.qss" ).arg ( styleName ) ) ).exists();
+ if ( !QFile ( conf_skin ( "default.qss" ) ).exists() )
+ return;
+ if ( !QFile ( conf_skin ( QString ( "%1.qss" ).arg ( styleName ) ) ).exists() )
+ return;
+ //pline() << "set style 2" << styleName;
#ifdef __EMBEDDED_LINUX__
- QString cmd = QString ( "touch %1" ).arg ( skin ( "current.qss" ) );
+ QString cmd = QString ( "touch %1" ).arg ( conf_skin ( "current.qss" ) );
system ( cmd.toLocal8Bit().constData() );
#endif
QByteArray bytes;
- QFile f1 ( skin ( "default.qss" ) );
+ QFile f1 ( conf_skin ( "default.qss" ) );
f1.open ( QFile::ReadOnly );
bytes = f1.readAll();
f1.close();
- QFile f2 ( skin ( QString ( "%1.qss" ).arg ( styleName ) ) );
+ QFile f2 ( conf_skin ( QString ( "%1.qss" ).arg ( styleName ) ) );
f2.open ( QFile::ReadOnly );
bytes += f2.readAll();
f2.close();
- QFile file ( skin ( "current.qss" ) );
+ QFile file ( conf_skin ( "current.qss" ) );
file.open ( QFile::Truncate | QFile::WriteOnly );
file.write ( bytes );
file.close();
- qqtApp->setQSSStyle ( skin ( "current.qss" ) );
+ //pline() << conf_skin ( "current.qss" );
+ qqtApp->setQSSStyle ( conf_skin ( "current.qss" ) );
}
diff --git a/src/multimedia/libqwav/libqwav.cpp b/src/multimedia/libqwav/libqwav.cpp
new file mode 100644
index 00000000..875597d2
--- /dev/null
+++ b/src/multimedia/libqwav/libqwav.cpp
@@ -0,0 +1,202 @@
+#include "libqwav.h"
+
+#include
+#include
+
+//header data tail
+bool addWavHeader ( QIODevice& outputDevice, const QAudioFormat& format )
+{
+ // 开始设置WAV的文件头
+ // 这里具体的数据代表什么含义请看上一篇文章(Qt之WAV文件解析)中对wav文件头的介绍
+ WAVFILEHEADER WavFileHeader;
+ qstrcpy ( WavFileHeader.RiffName, "RIFF" );
+ qstrcpy ( WavFileHeader.WavName, "WAVE" );
+ qstrcpy ( WavFileHeader.FmtName, "fmt " );
+ qstrcpy ( WavFileHeader.DATANAME, "data" );
+
+ // 表示 FMT块 的长度
+ WavFileHeader.nFmtLength = 16;
+
+ // 表示 按照PCM 编码;
+ WavFileHeader.nAudioFormat = 1;
+ // 声道数目;
+ WavFileHeader.nChannleNumber = format.channelCount();
+ // 采样频率;
+ WavFileHeader.nSampleRate = format.sampleRate();
+ //这个地方,int到unsinged int数据没有丢失。
+ //pline() << WavFileHeader.nSampleRate << mFormat.sampleRate();
+ // 每次采样得到的样本数据位数;
+ WavFileHeader.nBitsPerSample = format.sampleSize();
+
+ // nBytesPerSample 和 nBytesPerSecond这两个值通过设置的参数计算得到;
+ // 数据块对齐单位(每个采样需要的字节数 = 通道数 × 每次采样得到的样本数据位数 / 8 )
+ WavFileHeader.nBlockAlign = WavFileHeader.nChannleNumber * WavFileHeader.nBitsPerSample / 8;
+ // 波形数据传输速率
+ // (每秒平均字节数 = 采样频率 × 通道数 × 每次采样得到的样本数据位数 / 8 = 采样频率 × 每个采样需要的字节数 )
+ WavFileHeader.nBytesPerSecond = WavFileHeader.nSampleRate * WavFileHeader.nChannleNumber *
+ WavFileHeader.nBitsPerSample / 8;
+
+ outputDevice.seek ( 0 );
+ //riff 8 + 4
+ WavFileHeader.nRiffLength = outputDevice.size() - 8;
+ outputDevice.write ( WavFileHeader.RiffName, sizeof ( WavFileHeader.RiffName ) - 1 );
+ outputDevice.write ( ( char* ) &WavFileHeader.nRiffLength, sizeof ( WavFileHeader.nRiffLength ) );
+ outputDevice.write ( WavFileHeader.WavName, sizeof ( WavFileHeader.WavName ) - 1 );
+
+ //fmt 8 + 16
+ outputDevice.write ( WavFileHeader.FmtName, 4 );
+ outputDevice.write ( ( char* ) &WavFileHeader.nFmtLength, 4 );
+
+ outputDevice.write ( ( char* ) &WavFileHeader.nAudioFormat, sizeof ( WavFileHeader.nAudioFormat ) );
+ outputDevice.write ( ( char* ) &WavFileHeader.nChannleNumber, sizeof ( WavFileHeader.nChannleNumber ) );
+ outputDevice.write ( ( char* ) &WavFileHeader.nSampleRate, sizeof ( WavFileHeader.nSampleRate ) );
+ outputDevice.write ( ( char* ) &WavFileHeader.nBytesPerSecond, sizeof ( WavFileHeader.nBytesPerSecond ) );
+ outputDevice.write ( ( char* ) &WavFileHeader.nBlockAlign, sizeof ( WavFileHeader.nBlockAlign ) );
+ outputDevice.write ( ( char* ) &WavFileHeader.nBitsPerSample, sizeof ( WavFileHeader.nBitsPerSample ) );
+
+ //data 8
+ outputDevice.write ( WavFileHeader.DATANAME, 4 );
+ outputDevice.write ( ( char* ) &WavFileHeader.nDataLength, 4 );
+
+ WavFileHeader.fileHeaderSize = outputDevice.pos();
+
+ //44
+ //int headerSize = WavFileHeader.fileHeaderSize;
+ //qDebug() << headerSize;
+ return true;
+}
+
+bool addWavTail ( QIODevice& outputDevice )
+{
+ QByteArray tailBytes;
+ tailBytes += "q\xFCq\xFC";
+ tailBytes += "a\xFB";
+ tailBytes += "a\xFB";
+ //8
+ //pline() << tailBytes << tailBytes.size();
+ outputDevice.write ( tailBytes );
+ return true;
+}
+
+
+bool addWavDataBytes ( QIODevice& outputDevice, const QByteArray& bytes )
+{
+ outputDevice.write ( bytes );
+ return true;
+}
+
+bool wavParse ( QString fileName, WAVFILEHEADER& WavFileHeader )
+{
+ QFile fileInfo ( fileName );
+
+ if ( !fileInfo.open ( QIODevice::ReadOnly ) )
+ {
+ return false;
+ }
+
+ // 警告:每一次读,都不seek的!用户调用了seek不会引发pos变化,read会。
+
+ // 读取 资源交换文件标志 "RIFF";
+ fileInfo.read ( WavFileHeader.RiffName, sizeof ( WavFileHeader.RiffName ) - 1 );
+
+ // 读取 RIFF 头后字节数;
+ fileInfo.read ( ( char* ) &WavFileHeader.nRiffLength, sizeof ( WavFileHeader.nRiffLength ) );
+ // 读取 波形文件标识符 "WAVE";
+ fileInfo.read ( WavFileHeader.WavName, sizeof ( WavFileHeader.WavName ) - 1 );
+
+ // 警告:每一次读,都不seek的!用户调用了seek不会引发pos变化,read会。
+ while ( 1 )
+ {
+ char tempName[5] = {0};
+ unsigned int tempSize = 0;
+
+ fileInfo.read ( tempName, 4 );
+ fileInfo.read ( ( char* ) &tempSize, 4 );
+
+ QString strTempName ( tempName );
+
+ if ( 0 == strTempName.compare ( "fmt ", Qt::CaseInsensitive ) )
+ {
+ strcpy ( WavFileHeader.FmtName, tempName );
+ WavFileHeader.nFmtLength = tempSize;
+ // 读取 格式种类;
+ fileInfo.read ( ( char* ) &WavFileHeader.nAudioFormat, sizeof ( WavFileHeader.nAudioFormat ) );
+ // 读取 音频通道数目;
+ fileInfo.read ( ( char* ) &WavFileHeader.nChannleNumber, sizeof ( WavFileHeader.nChannleNumber ) );
+ // 读取 采样频率;
+ fileInfo.read ( ( char* ) &WavFileHeader.nSampleRate, sizeof ( WavFileHeader.nSampleRate ) );
+ // 读取 波形数据传输速率;
+ fileInfo.read ( ( char* ) &WavFileHeader.nBytesPerSecond, sizeof ( WavFileHeader.nBytesPerSecond ) );
+ // 读取 数据块对齐单位;
+ fileInfo.read ( ( char* ) &WavFileHeader.nBlockAlign, sizeof ( WavFileHeader.nBlockAlign ) );
+ // 读取 每次采样得到的样本数据位数值;
+ fileInfo.read ( ( char* ) &WavFileHeader.nBitsPerSample, sizeof ( WavFileHeader.nBitsPerSample ) );
+ // 如果有扩展字节
+ fileInfo.read ( tempSize - 16 );
+ }
+ else if ( 0 == strTempName.compare ( "fact", Qt::CaseInsensitive ) )
+ {
+ // 存在fact块,读取数据;
+ strcpy ( WavFileHeader.FactName, tempName );
+ // fact块长度;
+ WavFileHeader.nFactLength = tempSize;
+ // 读取fact块数据;但是不处理
+ fileInfo.read ( tempSize );
+ qDebug() << "fact data" << tempName << tempSize;
+ }
+ else if ( 0 == strTempName.compare ( "data", Qt::CaseInsensitive ) )
+ {
+ strcpy ( WavFileHeader.DATANAME, tempName );
+ WavFileHeader.nDataLength = tempSize;
+
+ // 读取 音频数据大小;
+ WavFileHeader.fileDataSize = tempSize;
+ //文件头大小;
+ WavFileHeader.fileHeaderSize = fileInfo.pos();
+
+ // 注意:这里的总大小,包括结尾8个字节,wav文件有8个结尾字节。"q\xFCq\xFC""a\xFB""a\xFB"
+ // 文件总大小;
+ WavFileHeader.fileTotalSize = WavFileHeader.nRiffLength + 8;
+
+ break;
+ }
+ else
+ {
+ qDebug() << "unhandled chunk" << tempName << tempSize;
+ fileInfo.read ( tempSize );
+ break;
+ }
+ }
+
+ //测试OK
+ // pline() << "filesize" << WavFileHeader.fileTotalSize;
+ // pline() << "fileheadersize" << WavFileHeader.fileHeaderSize;
+ // pline() << "filedatasize" << WavFileHeader.fileDataSize;
+ // pline() << "filetailsize" << WavFileHeader.fileTailSize;
+ // pline() << WavFileHeader.nChannleNumber << WavFileHeader.nSampleRate << WavFileHeader.nBitsPerSample;
+
+ fileInfo.close();
+}
+
+
+/*
+ * 解析方法2 支援Qt 资源文件
+ */
+bool anlysisWavFileHeader ( QString fileName, QAudioFormat& format, TWavFileInfo& fileinfo )
+{
+ WAVFILEHEADER WavFileHeader;
+ bool ret = wavParse ( fileName, WavFileHeader );
+
+ format.setChannelCount ( WavFileHeader.nChannleNumber );
+ format.setSampleRate ( WavFileHeader.nSampleRate );
+ format.setSampleSize ( WavFileHeader.nBitsPerSample );
+ format.setByteOrder ( QAudioFormat::LittleEndian );
+ format.setCodec ( "audio/pcm" );
+ format.setSampleType ( QAudioFormat::SignedInt );
+
+ fileinfo.fileTotalSize = WavFileHeader.fileTotalSize;
+ fileinfo.fileHeaderSize = WavFileHeader.fileHeaderSize;
+ fileinfo.fileDataSize = WavFileHeader.fileDataSize;
+ fileinfo.fileTailSize = WavFileHeader.fileTailSize;
+ return true;
+}
diff --git a/src/multimedia/libqwav/libqwav.h b/src/multimedia/libqwav/libqwav.h
new file mode 100644
index 00000000..7df66d44
--- /dev/null
+++ b/src/multimedia/libqwav/libqwav.h
@@ -0,0 +1,98 @@
+#ifndef LIBQWAV_H
+#define LIBQWAV_H
+
+#include "libqwav_global.h"
+
+#include "string.h"
+#include
+#include
+
+//dll __imp_ lib no __imp_
+//跟这个extern没关系。
+//动态导出、导入时就是有__imp_
+//静态导出、导入时就是没有__imp_,导出的是函数原型。
+
+//这个extern的作用是在导出库源文件是.c文件时,使用者必须使用extern "C"包含对应的头文件。
+//就这么一个作用。
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+
+/*
+ * 解析方法2 使用QtFile接口,支持Qt资源文件
+ */
+// wav文件头信息结构
+struct WAVFILEHEADER
+{
+ // RIFF 头;
+ char RiffName[5];//RIFF
+ int nRiffLength;//fileLen-8
+ // 数据类型标识符;
+ char WavName[5];//WAVE
+
+ // 格式块中的块头;
+ char FmtName[5];//fmt
+ int nFmtLength;
+ // 格式块中的块数据;
+ short nAudioFormat;
+ short nChannleNumber;
+ int nSampleRate;
+ int nBytesPerSecond;
+ short nBlockAlign;
+ short nBitsPerSample;
+
+ // 附加信息(可选),根据 nFmtLength 来判断;
+ // 扩展域大小;
+ short nAppendMessage;
+
+ //Fact块,可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk;
+ char FactName[5];
+ int nFactLength;
+
+ // DATA块,数据块中的块头;
+ char DATANAME[5];
+ int nDataLength;//fileDataSize
+
+ // 以下是附加的一些计算信息;
+ int fileDataSize; // 文件音频数据大小;
+ int fileHeaderSize; // 文件头大小;
+ int fileTailSize; // 文件尾大小; 一般忽略。
+ int fileTotalSize; // 文件总大小;
+
+
+ // 理论上应该将所有数据初始化,这里只初始化可选的数据;
+ WAVFILEHEADER() {
+ fileTailSize = 8;
+ memset ( RiffName, 0, 5 );
+ memset ( WavName, 0, 5 );
+ memset ( FmtName, 0, 5 );
+ memset ( FactName, 0, 5 );
+ }
+
+};
+
+//44 固定的
+LIBQWAVSHARED_EXPORT bool addWavHeader ( QIODevice& outputDevice, const QAudioFormat& format );
+//8 固定的
+LIBQWAVSHARED_EXPORT bool addWavTail ( QIODevice& outputDevice );
+LIBQWAVSHARED_EXPORT bool addWavDataBytes ( QIODevice& outputDevice, const QByteArray& bytes );
+
+
+typedef struct _TWavFileInfo
+{
+ int fileDataSize; // 文件音频数据大小;
+ int fileHeaderSize; // 文件头大小;
+ int fileTailSize; // 文件尾大小; 一般忽略。
+ int fileTotalSize; // 文件总大小;
+} TWavFileInfo;
+
+
+LIBQWAVSHARED_EXPORT bool wavParse ( QString fileName, WAVFILEHEADER& WavFileHeader );
+LIBQWAVSHARED_EXPORT bool anlysisWavFileHeader ( QString fileName, QAudioFormat& format, TWavFileInfo& fileinfo );
+
+//#ifdef __cplusplus
+//}
+//#endif
+
+#endif // LIBQWAV_H
diff --git a/src/multimedia/libqwav/libqwav_global.h b/src/multimedia/libqwav/libqwav_global.h
new file mode 100644
index 00000000..94c8837c
--- /dev/null
+++ b/src/multimedia/libqwav/libqwav_global.h
@@ -0,0 +1,18 @@
+#ifndef LIBQWAV_GLOBAL_H
+#define LIBQWAV_GLOBAL_H
+
+#include
+
+#ifdef Q_OS_WIN
+#if defined(LIBQWAV_LIBRARY)
+# define LIBQWAVSHARED_EXPORT Q_DECL_EXPORT
+#elif defined(LIBQWAV_STATIC_LIBRARY)
+# define LIBQWAVSHARED_EXPORT
+#else
+# define LIBQWAVSHARED_EXPORT Q_DECL_IMPORT
+#endif
+#else
+# define LIBQWAVSHARED_EXPORT
+#endif
+
+#endif // LIBQWAV_GLOBAL_H
diff --git a/src/multimedia/qqtcamera.cpp b/src/multimedia/qqtcamera.cpp
new file mode 100644
index 00000000..fe1c8ab1
--- /dev/null
+++ b/src/multimedia/qqtcamera.cpp
@@ -0,0 +1,646 @@
+#include
+
+QQtCameraExposure::QQtCameraExposure ( QObject* parent ) : QObject ( parent )
+{
+ mExposure = 0;
+}
+
+QQtCameraExposure::~QQtCameraExposure() {}
+
+void QQtCameraExposure::setCameraExposure ( QCameraExposure* object )
+{
+ Q_ASSERT ( object );
+
+ if ( mExposure )
+ {
+ disconnect ( mExposure, SIGNAL ( flashReady ( bool ) ), this, SIGNAL ( flashReady ( bool ) ) );
+ disconnect ( mExposure, SIGNAL ( apertureChanged ( qreal ) ), this, SIGNAL ( apertureChanged ( qreal ) ) );
+ disconnect ( mExposure, SIGNAL ( apertureRangeChanged() ), this, SIGNAL ( apertureRangeChanged() ) );
+ disconnect ( mExposure, SIGNAL ( shutterSpeedChanged ( qreal ) ), this, SIGNAL ( shutterSpeedChanged ( qreal ) ) );
+ disconnect ( mExposure, SIGNAL ( shutterSpeedRangeChanged() ), this, SIGNAL ( shutterSpeedRangeChanged() ) );
+ disconnect ( mExposure, SIGNAL ( isoSensitivityChanged ( int ) ), this, SIGNAL ( isoSensitivityChanged ( int ) ) );
+ disconnect ( mExposure, SIGNAL ( exposureCompensationChanged ( qreal ) ), this, SIGNAL ( exposureCompensationChanged ( qreal ) ) );
+
+ mExposure->deleteLater();
+ }
+
+ mExposure = object;
+
+ connect ( mExposure, SIGNAL ( flashReady ( bool ) ), this, SIGNAL ( flashReady ( bool ) ) );
+ connect ( mExposure, SIGNAL ( apertureChanged ( qreal ) ), this, SIGNAL ( apertureChanged ( qreal ) ) );
+ connect ( mExposure, SIGNAL ( apertureRangeChanged() ), this, SIGNAL ( apertureRangeChanged() ) );
+ connect ( mExposure, SIGNAL ( shutterSpeedChanged ( qreal ) ), this, SIGNAL ( shutterSpeedChanged ( qreal ) ) );
+ connect ( mExposure, SIGNAL ( shutterSpeedRangeChanged() ), this, SIGNAL ( shutterSpeedRangeChanged() ) );
+ connect ( mExposure, SIGNAL ( isoSensitivityChanged ( int ) ), this, SIGNAL ( isoSensitivityChanged ( int ) ) );
+ connect ( mExposure, SIGNAL ( exposureCompensationChanged ( qreal ) ), this, SIGNAL ( exposureCompensationChanged ( qreal ) ) );
+
+}
+
+QCameraExposure* QQtCameraExposure::exposure()
+{
+ return mExposure;
+}
+
+bool QQtCameraExposure::isAvailable() const
+{
+ return mExposure->isAvailable();
+}
+
+QCameraExposure::FlashModes QQtCameraExposure::flashMode() const
+{
+ return mExposure->flashMode();
+}
+
+bool QQtCameraExposure::isFlashModeSupported ( QCameraExposure::FlashModes mode ) const
+{
+ return mExposure->isFlashModeSupported ( mode );
+}
+
+bool QQtCameraExposure::isFlashReady() const
+{
+ return mExposure->isFlashReady();
+}
+
+QCameraExposure::ExposureMode QQtCameraExposure::exposureMode() const
+{
+ return mExposure->exposureMode();
+}
+
+bool QQtCameraExposure::isExposureModeSupported ( QCameraExposure::ExposureMode mode ) const
+{
+ return mExposure->isExposureModeSupported ( mode );
+}
+
+qreal QQtCameraExposure::exposureCompensation() const
+{
+ return mExposure->exposureCompensation();
+}
+
+QCameraExposure::MeteringMode QQtCameraExposure::meteringMode() const
+{
+ return mExposure->meteringMode();
+}
+
+bool QQtCameraExposure::isMeteringModeSupported ( QCameraExposure::MeteringMode mode ) const
+{
+ return mExposure->isMeteringModeSupported ( mode );
+}
+
+QPointF QQtCameraExposure::spotMeteringPoint() const
+{
+ return mExposure->spotMeteringPoint();
+}
+
+void QQtCameraExposure::setSpotMeteringPoint ( const QPointF& point )
+{
+ return mExposure->setSpotMeteringPoint ( point );
+}
+
+int QQtCameraExposure::isoSensitivity() const
+{
+ return mExposure->isoSensitivity();
+}
+
+qreal QQtCameraExposure::aperture() const
+{
+ return mExposure->aperture();
+}
+
+qreal QQtCameraExposure::shutterSpeed() const
+{
+ return mExposure->shutterSpeed();
+}
+
+int QQtCameraExposure::requestedIsoSensitivity() const
+{
+ return mExposure->requestedIsoSensitivity();
+}
+
+qreal QQtCameraExposure::requestedAperture() const
+{
+ return mExposure->requestedAperture();
+}
+
+qreal QQtCameraExposure::requestedShutterSpeed() const
+{
+ return mExposure->requestedShutterSpeed();
+}
+
+QList QQtCameraExposure::supportedIsoSensitivities ( bool* continuous ) const
+{
+ return mExposure->supportedIsoSensitivities ( continuous );
+}
+
+QList QQtCameraExposure::supportedApertures ( bool* continuous ) const
+{
+ return mExposure->supportedApertures ( continuous );
+}
+
+QList QQtCameraExposure::supportedShutterSpeeds ( bool* continuous ) const
+{
+ return mExposure->supportedShutterSpeeds ( continuous );
+}
+
+void QQtCameraExposure::setFlashMode ( QCameraExposure::FlashModes mode )
+{
+ return mExposure->setFlashMode ( mode );
+}
+
+void QQtCameraExposure::setExposureMode ( QCameraExposure::ExposureMode mode )
+{
+ return mExposure->setExposureMode ( mode );
+}
+
+void QQtCameraExposure::setMeteringMode ( QCameraExposure::MeteringMode mode )
+{
+ return mExposure->setMeteringMode ( mode );
+}
+
+void QQtCameraExposure::setExposureCompensation ( qreal ev )
+{
+ return mExposure->setExposureCompensation ( ev );
+}
+
+void QQtCameraExposure::setManualIsoSensitivity ( int iso )
+{
+ return mExposure->setManualIsoSensitivity ( iso );
+}
+
+void QQtCameraExposure::setAutoIsoSensitivity()
+{
+ return mExposure->setAutoIsoSensitivity ( );
+}
+
+void QQtCameraExposure::setManualAperture ( qreal aperture )
+{
+ return mExposure->setManualAperture ( aperture );
+}
+
+void QQtCameraExposure::setAutoAperture()
+{
+ return mExposure->setAutoAperture ( );
+}
+
+void QQtCameraExposure::setManualShutterSpeed ( qreal seconds )
+{
+ return mExposure->setManualShutterSpeed ( seconds );
+}
+
+void QQtCameraExposure::setAutoShutterSpeed()
+{
+ return mExposure->setAutoShutterSpeed ( );
+}
+
+
+QQtCameraFocus::QQtCameraFocus ( QObject* parent ) : QObject ( parent )
+{
+ mFocus = 0;
+}
+
+QQtCameraFocus::~QQtCameraFocus() {}
+
+void QQtCameraFocus::setCameraFocus ( QCameraFocus* object )
+{
+ Q_ASSERT ( object );
+
+ if ( mFocus )
+ {
+ disconnect ( mFocus, SIGNAL ( opticalZoomChanged ( qreal ) ), this, SIGNAL ( opticalZoomChanged ( qreal ) ) );
+ disconnect ( mFocus, SIGNAL ( digitalZoomChanged ( qreal ) ), this, SIGNAL ( digitalZoomChanged ( qreal ) ) );
+ disconnect ( mFocus, SIGNAL ( focusZonesChanged ( ) ), this, SIGNAL ( focusZonesChanged ( ) ) );
+ disconnect ( mFocus, SIGNAL ( maximumOpticalZoomChanged ( qreal ) ), this, SIGNAL ( maximumOpticalZoomChanged ( qreal ) ) );
+ disconnect ( mFocus, SIGNAL ( maximumDigitalZoomChanged ( qreal ) ), this, SIGNAL ( maximumDigitalZoomChanged ( qreal ) ) );
+ mFocus->deleteLater();
+ }
+
+ mFocus = object;
+
+ connect ( mFocus, SIGNAL ( opticalZoomChanged ( qreal ) ), this, SIGNAL ( opticalZoomChanged ( qreal ) ) );
+ connect ( mFocus, SIGNAL ( digitalZoomChanged ( qreal ) ), this, SIGNAL ( digitalZoomChanged ( qreal ) ) );
+ connect ( mFocus, SIGNAL ( focusZonesChanged ( ) ), this, SIGNAL ( focusZonesChanged ( ) ) );
+ connect ( mFocus, SIGNAL ( maximumOpticalZoomChanged ( qreal ) ), this, SIGNAL ( maximumOpticalZoomChanged ( qreal ) ) );
+ connect ( mFocus, SIGNAL ( maximumDigitalZoomChanged ( qreal ) ), this, SIGNAL ( maximumDigitalZoomChanged ( qreal ) ) );
+
+}
+
+QCameraFocus* QQtCameraFocus::focus()
+{
+ return mFocus;
+}
+
+bool QQtCameraFocus::isAvailable() const
+{
+ return mFocus->isAvailable();
+}
+
+QCameraFocus::FocusModes QQtCameraFocus::focusMode() const
+{
+ return mFocus->focusMode();
+}
+
+void QQtCameraFocus::setFocusMode ( QCameraFocus::FocusModes mode )
+{
+ return mFocus->setFocusMode ( mode );
+}
+
+bool QQtCameraFocus::isFocusModeSupported ( QCameraFocus::FocusModes mode ) const
+{
+ return mFocus->isFocusModeSupported ( mode );
+}
+
+QCameraFocus::FocusPointMode QQtCameraFocus::focusPointMode() const
+{
+ return mFocus->focusPointMode ( );
+}
+
+void QQtCameraFocus::setFocusPointMode ( QCameraFocus::FocusPointMode mode )
+{
+ return mFocus->setFocusPointMode ( mode );
+}
+
+bool QQtCameraFocus::isFocusPointModeSupported ( QCameraFocus::FocusPointMode mode ) const
+{
+ return mFocus->isFocusPointModeSupported ( mode );
+}
+
+QPointF QQtCameraFocus::customFocusPoint() const
+{
+ return mFocus->customFocusPoint ( );
+}
+
+void QQtCameraFocus::setCustomFocusPoint ( const QPointF& point )
+{
+ return mFocus->setCustomFocusPoint ( point );
+}
+
+QCameraFocusZoneList QQtCameraFocus::focusZones() const
+{
+ return mFocus->focusZones ( );
+}
+
+qreal QQtCameraFocus::maximumOpticalZoom() const
+{
+ return mFocus->maximumOpticalZoom ( );
+}
+
+qreal QQtCameraFocus::maximumDigitalZoom() const
+{
+ return mFocus->maximumDigitalZoom ( );
+}
+
+qreal QQtCameraFocus::opticalZoom() const
+{
+ return mFocus->opticalZoom ( );
+}
+
+qreal QQtCameraFocus::digitalZoom() const
+{
+ return mFocus->digitalZoom ( );
+}
+
+void QQtCameraFocus::zoomTo ( qreal opticalZoom, qreal digitalZoom )
+{
+ return mFocus->zoomTo ( opticalZoom, digitalZoom );
+}
+
+
+QQtCameraImageProcessing::QQtCameraImageProcessing ( QObject* parent ) : QObject ( parent )
+{
+ mImageProcessing = 0;
+}
+
+QQtCameraImageProcessing::~QQtCameraImageProcessing() {}
+
+void QQtCameraImageProcessing::setCameraImageProcessing ( QCameraImageProcessing* object )
+{
+ Q_ASSERT ( object );
+
+ if ( mImageProcessing )
+ {
+ mImageProcessing->deleteLater();
+ }
+
+ mImageProcessing = object;
+}
+
+bool QQtCameraImageProcessing::isAvailable() const
+{
+ return mImageProcessing->isAvailable();
+}
+
+QCameraImageProcessing::WhiteBalanceMode QQtCameraImageProcessing::whiteBalanceMode() const
+{
+ return mImageProcessing->whiteBalanceMode();
+}
+
+void QQtCameraImageProcessing::setWhiteBalanceMode ( QCameraImageProcessing::WhiteBalanceMode mode )
+{
+ return mImageProcessing->setWhiteBalanceMode ( mode );
+}
+
+bool QQtCameraImageProcessing::isWhiteBalanceModeSupported ( QCameraImageProcessing::WhiteBalanceMode mode ) const
+{
+ return mImageProcessing->isWhiteBalanceModeSupported ( mode );
+}
+
+qreal QQtCameraImageProcessing::manualWhiteBalance() const
+{
+ return mImageProcessing->manualWhiteBalance();
+}
+
+void QQtCameraImageProcessing::setManualWhiteBalance ( qreal colorTemperature )
+{
+ return mImageProcessing->setManualWhiteBalance ( colorTemperature );
+}
+
+qreal QQtCameraImageProcessing::brightness() const
+{
+ return mImageProcessing->brightness();
+}
+
+void QQtCameraImageProcessing::setBrightness ( qreal value )
+{
+ return mImageProcessing->setManualWhiteBalance ( value );
+}
+
+qreal QQtCameraImageProcessing::contrast() const
+{
+ return mImageProcessing->contrast();
+}
+
+void QQtCameraImageProcessing::setContrast ( qreal value )
+{
+ return mImageProcessing->setContrast ( value );
+}
+
+qreal QQtCameraImageProcessing::saturation() const
+{
+ return mImageProcessing->saturation();
+}
+
+void QQtCameraImageProcessing::setSaturation ( qreal value )
+{
+ return mImageProcessing->setSaturation ( value );
+}
+
+qreal QQtCameraImageProcessing::sharpeningLevel() const
+{
+ return mImageProcessing->sharpeningLevel();
+}
+
+void QQtCameraImageProcessing::setSharpeningLevel ( qreal value )
+{
+ return mImageProcessing->setSharpeningLevel ( value );
+}
+
+qreal QQtCameraImageProcessing::denoisingLevel() const
+{
+ return mImageProcessing->denoisingLevel();
+}
+
+void QQtCameraImageProcessing::setDenoisingLevel ( qreal value )
+{
+ return mImageProcessing->setDenoisingLevel ( value );
+}
+
+QCameraImageProcessing::ColorFilter QQtCameraImageProcessing::colorFilter() const
+{
+ return mImageProcessing->colorFilter();
+}
+
+void QQtCameraImageProcessing::setColorFilter ( QCameraImageProcessing::ColorFilter filter )
+{
+ return mImageProcessing->setColorFilter ( filter );
+}
+
+bool QQtCameraImageProcessing::isColorFilterSupported ( QCameraImageProcessing::ColorFilter filter ) const
+{
+ return mImageProcessing->isColorFilterSupported ( filter );
+}
+
+QQtCamera::QQtCamera ( QObject* parent ) : QObject ( parent )
+{
+ //初始化Camera。
+ mCamera = 0;
+ //初始化CameraInfo。
+ mCameraInfo = QCameraInfo::defaultCamera();
+
+ //mCamera 句柄持续为真。
+ setCameraInfo ( QCameraInfo::defaultCamera() );
+}
+
+QQtCamera::~QQtCamera() {}
+
+void QQtCamera::setCameraInfo ( const QCameraInfo& camInfo )
+{
+ //更新mCamera
+ if ( mCamera )
+ {
+ disconnect ( mCamera, SIGNAL ( stateChanged ( QCamera::State ) ), this, SIGNAL ( stateChanged ( QCamera::State ) ) );
+ disconnect ( mCamera, SIGNAL ( captureModeChanged ( QCamera::CaptureModes ) ), this, SIGNAL ( captureModeChanged ( QCamera::CaptureModes ) ) );
+ disconnect ( mCamera, SIGNAL ( statusChanged ( QCamera::Status ) ), this, SIGNAL ( statusChanged ( QCamera::Status ) ) );
+ disconnect ( mCamera, SIGNAL ( locked() ), this, SIGNAL ( locked() ) );
+ disconnect ( mCamera, SIGNAL ( lockFailed() ), this, SIGNAL ( lockFailed() ) );
+ disconnect ( mCamera, SIGNAL ( lockStatusChanged ( QCamera::LockStatus, QCamera::LockChangeReason ) ), this, SIGNAL ( lockStatusChanged ( QCamera::LockStatus, QCamera::LockChangeReason ) ) );
+ disconnect ( mCamera, SIGNAL ( lockStatusChanged ( QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason ) ), this, SIGNAL ( lockStatusChanged ( QCamera::LockType, QCamera::LockStatus,
+ QCamera::LockChangeReason ) ) );
+ disconnect ( mCamera, SIGNAL ( error ( QCamera::Error ) ), this, SIGNAL ( error ( QCamera::Error ) ) );
+ mCamera->stop();
+ mCamera->deleteLater();
+ }
+
+ mCameraInfo = camInfo;
+ mCamera = new QCamera ( mCameraInfo, this );
+
+#if 0
+ //更新 Viewfinder
+ setViewfinder ( m_vw_viewfinder );
+ setViewfinder ( m_gv_viewfinder );
+ setViewfinder ( m_avs_viewfinder );
+
+ //更新 ViewfinderSettings
+ setViewfinderSettings ( mVfSettings );
+#endif
+
+ //更新信号、槽的连接
+ connect ( mCamera, SIGNAL ( stateChanged ( QCamera::State ) ), this, SIGNAL ( stateChanged ( QCamera::State ) ) );
+ connect ( mCamera, SIGNAL ( captureModeChanged ( QCamera::CaptureModes ) ), this, SIGNAL ( captureModeChanged ( QCamera::CaptureModes ) ) );
+ connect ( mCamera, SIGNAL ( statusChanged ( QCamera::Status ) ), this, SIGNAL ( statusChanged ( QCamera::Status ) ) );
+ connect ( mCamera, SIGNAL ( locked() ), this, SIGNAL ( locked() ) );
+ connect ( mCamera, SIGNAL ( lockFailed() ), this, SIGNAL ( lockFailed() ) );
+ connect ( mCamera, SIGNAL ( lockStatusChanged ( QCamera::LockStatus, QCamera::LockChangeReason ) ), this, SIGNAL ( lockStatusChanged ( QCamera::LockStatus, QCamera::LockChangeReason ) ) );
+ connect ( mCamera, SIGNAL ( lockStatusChanged ( QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason ) ), this, SIGNAL ( lockStatusChanged ( QCamera::LockType, QCamera::LockStatus,
+ QCamera::LockChangeReason ) ) );
+ connect ( mCamera, SIGNAL ( error ( QCamera::Error ) ), this, SIGNAL ( error ( QCamera::Error ) ) );
+
+}
+
+QCameraInfo QQtCamera::cameraInfo() const
+{
+ return mCameraInfo;
+}
+
+QCamera* QQtCamera::camera() const
+{
+ return mCamera;
+}
+
+QMultimedia::AvailabilityStatus QQtCamera::availability() const
+{
+ return mCamera->availability();
+}
+
+QCamera::State QQtCamera::state() const
+{
+ return mCamera->state();
+}
+
+QCamera::Status QQtCamera::status() const
+{
+ return mCamera->status();
+}
+
+QCamera::CaptureModes QQtCamera::captureMode() const
+{
+ return mCamera->captureMode();
+}
+
+bool QQtCamera::isCaptureModeSupported ( QCamera::CaptureModes mode ) const
+{
+ return mCamera->isCaptureModeSupported ( mode );
+}
+
+QCameraExposure* QQtCamera::exposure() const
+{
+ return mCamera->exposure();
+}
+
+QCameraFocus* QQtCamera::focus() const
+{
+ return mCamera->focus();
+}
+
+QCameraImageProcessing* QQtCamera::imageProcessing() const
+{
+ return mCamera->imageProcessing();
+}
+
+void QQtCamera::setViewfinder ( QVideoWidget* viewfinder )
+{
+ mCamera->setViewfinder ( viewfinder );
+}
+
+void QQtCamera::setViewfinder ( QGraphicsVideoItem* viewfinder )
+{
+ mCamera->setViewfinder ( viewfinder );
+}
+
+void QQtCamera::setViewfinder ( QAbstractVideoSurface* surface )
+{
+ mCamera->setViewfinder ( surface );
+}
+
+QCameraViewfinderSettings QQtCamera::viewfinderSettings() const
+{
+ return mCamera->viewfinderSettings();
+}
+
+void QQtCamera::setViewfinderSettings ( const QCameraViewfinderSettings& settings )
+{
+ return mCamera->setViewfinderSettings ( settings );
+}
+
+QList QQtCamera::supportedViewfinderSettings ( const QCameraViewfinderSettings& settings ) const
+{
+ return mCamera->supportedViewfinderSettings ( settings );
+}
+
+QList QQtCamera::supportedViewfinderResolutions ( const QCameraViewfinderSettings& settings ) const
+{
+ return mCamera->supportedViewfinderResolutions ( settings );
+}
+
+QList QQtCamera::supportedViewfinderFrameRateRanges ( const QCameraViewfinderSettings& settings ) const
+{
+ return mCamera->supportedViewfinderFrameRateRanges ( settings );
+}
+
+QList QQtCamera::supportedViewfinderPixelFormats ( const QCameraViewfinderSettings& settings ) const
+{
+ return mCamera->supportedViewfinderPixelFormats ( settings );
+}
+
+QCamera::Error QQtCamera::error() const
+{
+ return mCamera->error ( );
+}
+
+QString QQtCamera::errorString() const
+{
+ return mCamera->errorString ( );
+}
+
+QCamera::LockTypes QQtCamera::supportedLocks() const
+{
+ return mCamera->supportedLocks ( );
+}
+
+QCamera::LockTypes QQtCamera::requestedLocks() const
+{
+ return mCamera->requestedLocks ( );
+}
+
+QCamera::LockStatus QQtCamera::lockStatus() const
+{
+ return mCamera->lockStatus ( );
+}
+
+QCamera::LockStatus QQtCamera::lockStatus ( QCamera::LockType lock ) const
+{
+ return mCamera->lockStatus ( lock );
+}
+
+void QQtCamera::setCaptureMode ( QCamera::CaptureModes mode )
+{
+ return mCamera->setCaptureMode ( mode );
+}
+
+void QQtCamera::load()
+{
+ return mCamera->load();
+}
+
+void QQtCamera::unload()
+{
+ return mCamera->unload();
+}
+
+void QQtCamera::start()
+{
+ return mCamera->start();
+}
+
+void QQtCamera::stop()
+{
+ return mCamera->stop();
+}
+
+void QQtCamera::searchAndLock()
+{
+ return mCamera->searchAndLock();
+}
+
+void QQtCamera::unlock()
+{
+ return mCamera->unlock();
+}
+
+void QQtCamera::searchAndLock ( QCamera::LockTypes locks )
+{
+ return mCamera->searchAndLock ( locks );
+}
+
+void QQtCamera::unlock ( QCamera::LockTypes locks )
+{
+ return mCamera->unlock ( locks );
+}
diff --git a/src/multimedia/qqtcamera.h b/src/multimedia/qqtcamera.h
new file mode 100644
index 00000000..2cd39728
--- /dev/null
+++ b/src/multimedia/qqtcamera.h
@@ -0,0 +1,283 @@
+#ifndef QQTCAMERA_H
+#define QQTCAMERA_H
+
+/**
+ * 包装类
+ * 为QQtVideoManager提供包装类,促使句柄、信号、槽,外部在使用时,不变。
+ * 用户感兴趣可以使用。
+ */
+
+#include
+#include
+
+#include
+
+/**
+ * @brief The QQtCameraExposure class
+ * 为QCameraExposure提供能够保持的句柄。
+ * 不应该管理句柄的删除。
+ */
+class QQTSHARED_EXPORT QQtCameraExposure : public QObject
+{
+ Q_OBJECT
+public:
+ QQtCameraExposure ( QObject* parent = 0 );
+ virtual ~QQtCameraExposure();
+
+ //决定exposure句柄
+ void setCameraExposure ( QCameraExposure* object );
+ QCameraExposure* exposure();
+
+ bool isAvailable() const;
+
+ QCameraExposure::FlashModes flashMode() const;
+ bool isFlashModeSupported ( QCameraExposure::FlashModes mode ) const;
+ bool isFlashReady() const;
+
+ QCameraExposure::ExposureMode exposureMode() const;
+ bool isExposureModeSupported ( QCameraExposure::ExposureMode mode ) const;
+
+ qreal exposureCompensation() const;
+
+ QCameraExposure::MeteringMode meteringMode() const;
+ bool isMeteringModeSupported ( QCameraExposure::MeteringMode mode ) const;
+
+ QPointF spotMeteringPoint() const;
+ void setSpotMeteringPoint ( const QPointF& point );
+
+ int isoSensitivity() const;
+ qreal aperture() const;
+ qreal shutterSpeed() const;
+
+ int requestedIsoSensitivity() const;
+ qreal requestedAperture() const;
+ qreal requestedShutterSpeed() const;
+
+ QList supportedIsoSensitivities ( bool* continuous = Q_NULLPTR ) const;
+ QList supportedApertures ( bool* continuous = Q_NULLPTR ) const;
+ QList supportedShutterSpeeds ( bool* continuous = Q_NULLPTR ) const;
+
+public slots:
+ void setFlashMode ( QCameraExposure::FlashModes mode );
+ void setExposureMode ( QCameraExposure::ExposureMode mode );
+ void setMeteringMode ( QCameraExposure::MeteringMode mode );
+
+ void setExposureCompensation ( qreal ev );
+
+ void setManualIsoSensitivity ( int iso );
+ void setAutoIsoSensitivity();
+
+ void setManualAperture ( qreal aperture );
+ void setAutoAperture();
+
+ void setManualShutterSpeed ( qreal seconds );
+ void setAutoShutterSpeed();
+
+signals:
+ void flashReady ( bool );
+
+ void apertureChanged ( qreal );
+ void apertureRangeChanged();
+ void shutterSpeedChanged ( qreal );
+ void shutterSpeedRangeChanged();
+ void isoSensitivityChanged ( int );
+ void exposureCompensationChanged ( qreal );
+
+private:
+ QCameraExposure* mExposure;
+};
+
+/**
+ * @brief The QQtCameraFocus class
+ * QCameraFocus的包装,保持句柄。
+ */
+class QQTSHARED_EXPORT QQtCameraFocus : public QObject
+{
+ Q_OBJECT
+public:
+ QQtCameraFocus ( QObject* parent = 0 );
+ virtual ~QQtCameraFocus();
+
+ void setCameraFocus ( QCameraFocus* object );
+ QCameraFocus* focus();
+
+ bool isAvailable() const;
+
+ QCameraFocus::FocusModes focusMode() const;
+ void setFocusMode ( QCameraFocus::FocusModes mode );
+ bool isFocusModeSupported ( QCameraFocus::FocusModes mode ) const;
+
+ QCameraFocus::FocusPointMode focusPointMode() const;
+ void setFocusPointMode ( QCameraFocus::FocusPointMode mode );
+ bool isFocusPointModeSupported ( QCameraFocus::FocusPointMode mode ) const;
+ QPointF customFocusPoint() const;
+ void setCustomFocusPoint ( const QPointF& point );
+
+ QCameraFocusZoneList focusZones() const;
+
+ qreal maximumOpticalZoom() const;
+ qreal maximumDigitalZoom() const;
+ qreal opticalZoom() const;
+ qreal digitalZoom() const;
+
+ void zoomTo ( qreal opticalZoom, qreal digitalZoom );
+
+signals:
+ void opticalZoomChanged ( qreal );
+ void digitalZoomChanged ( qreal );
+
+ void focusZonesChanged();
+
+ void maximumOpticalZoomChanged ( qreal );
+ void maximumDigitalZoomChanged ( qreal );
+
+private:
+ QCameraFocus* mFocus;
+};
+
+/**
+ * @brief The QQtCameraImageProcessing class
+ * QCameraImageProcessing的包装类,保持句柄。
+ */
+class QQTSHARED_EXPORT QQtCameraImageProcessing : public QObject
+{
+ Q_OBJECT
+public:
+ QQtCameraImageProcessing ( QObject* parent = 0 );
+ virtual ~QQtCameraImageProcessing();
+
+ void setCameraImageProcessing ( QCameraImageProcessing* object );
+
+ bool isAvailable() const;
+
+ QCameraImageProcessing::WhiteBalanceMode whiteBalanceMode() const;
+ void setWhiteBalanceMode ( QCameraImageProcessing::WhiteBalanceMode mode );
+ bool isWhiteBalanceModeSupported ( QCameraImageProcessing::WhiteBalanceMode mode ) const;
+
+ qreal manualWhiteBalance() const;
+ void setManualWhiteBalance ( qreal colorTemperature );
+
+ qreal brightness() const;
+ void setBrightness ( qreal value );
+
+ qreal contrast() const;
+ void setContrast ( qreal value );
+
+ qreal saturation() const;
+ void setSaturation ( qreal value );
+
+ qreal sharpeningLevel() const;
+ void setSharpeningLevel ( qreal value );
+
+ qreal denoisingLevel() const;
+ void setDenoisingLevel ( qreal value );
+
+ QCameraImageProcessing::ColorFilter colorFilter() const;
+ void setColorFilter ( QCameraImageProcessing::ColorFilter filter );
+ bool isColorFilterSupported ( QCameraImageProcessing::ColorFilter filter ) const;
+
+private:
+ QCameraImageProcessing* mImageProcessing;
+};
+
+/**
+ * @brief The QQtCamera class
+ * 封装QCamera
+ * 已预置defaultCamera,
+ * 句柄保持不变。
+ * 包装类的句柄不变,信号和槽就可以持续使用了。
+ * 内部句柄在变化,但是从外部看,无所谓,外部使用的句柄、信号、槽都是稳定的。
+ * 功能丰富、齐全。
+ * 多线程不安全。
+ */
+class QQTSHARED_EXPORT QQtCamera : public QObject
+{
+ Q_OBJECT
+public:
+ QQtCamera ( QObject* parent = 0 );
+ virtual ~QQtCamera();
+
+ //QQt setCameraInfo 决定以下所有关系照相机的操作。
+ //更改 CameraInfo,QQtCamera 会切换到新Camera的默认输出设置,用户需要重新设置 ViewfinderSettings 达到输出设置目的。
+ //更改 CameraInfo,QQtCamera 会舍弃过去的Viewfinder,用户需要重新设置 Viewfinder。
+ void setCameraInfo ( const QCameraInfo& camInfo );
+ QCameraInfo cameraInfo() const;
+
+ //optional
+ //以下函数可选使用,句柄处于持续变动之中。
+ QCamera* camera() const;
+
+ QMultimedia::AvailabilityStatus availability() const;
+
+ QCamera::State state() const;
+ QCamera::Status status() const;
+
+ QCamera::CaptureModes captureMode() const;
+ bool isCaptureModeSupported ( QCamera::CaptureModes mode ) const;
+
+ QCameraExposure* exposure() const;
+ QCameraFocus* focus() const;
+ QCameraImageProcessing* imageProcessing() const;
+
+ void setViewfinder ( QVideoWidget* viewfinder );
+ void setViewfinder ( QGraphicsVideoItem* viewfinder );
+ void setViewfinder ( QAbstractVideoSurface* surface );
+
+ QCameraViewfinderSettings viewfinderSettings() const;
+ void setViewfinderSettings ( const QCameraViewfinderSettings& settings );
+
+ QList supportedViewfinderSettings (
+ const QCameraViewfinderSettings& settings = QCameraViewfinderSettings() ) const;
+
+ QList supportedViewfinderResolutions (
+ const QCameraViewfinderSettings& settings = QCameraViewfinderSettings() ) const;
+
+ QList supportedViewfinderFrameRateRanges (
+ const QCameraViewfinderSettings& settings = QCameraViewfinderSettings() ) const;
+
+ QList supportedViewfinderPixelFormats (
+ const QCameraViewfinderSettings& settings = QCameraViewfinderSettings() ) const;
+
+ QCamera::Error error() const;
+ QString errorString() const;
+
+ QCamera::LockTypes supportedLocks() const;
+ QCamera::LockTypes requestedLocks() const;
+
+ QCamera::LockStatus lockStatus() const;
+ QCamera::LockStatus lockStatus ( QCamera::LockType lock ) const;
+
+public slots:
+ void setCaptureMode ( QCamera::CaptureModes mode );
+
+ void load();
+ void unload();
+
+ void start();
+ void stop();
+
+ void searchAndLock();
+ void unlock();
+
+ void searchAndLock ( QCamera::LockTypes locks );
+ void unlock ( QCamera::LockTypes locks );
+
+signals:
+ void stateChanged ( QCamera::State );
+ void captureModeChanged ( QCamera::CaptureModes );
+ void statusChanged ( QCamera::Status );
+
+ void locked();
+ void lockFailed();
+
+ void lockStatusChanged ( QCamera::LockStatus, QCamera::LockChangeReason );
+ void lockStatusChanged ( QCamera::LockType, QCamera::LockStatus, QCamera::LockChangeReason );
+
+ void error ( QCamera::Error );
+
+private:
+ QCamera* mCamera;
+ QCameraInfo mCameraInfo;
+};
+
+#endif // QQTCAMERA_H
diff --git a/src/multimedia/qqtlogicvideomanager.cpp b/src/multimedia/qqtlogicvideomanager.cpp
new file mode 100644
index 00000000..6bea5414
--- /dev/null
+++ b/src/multimedia/qqtlogicvideomanager.cpp
@@ -0,0 +1,342 @@
+#include "qqtlogicvideomanager.h"
+
+QQtLogicVideoManager::QQtLogicVideoManager ( QWidget* parent ) :
+ QWidget ( parent ),
+ ui ( new Ui::QQtLogicVideoManager )
+{
+ ui->setupUi ( this );
+
+ memset ( &sinfo, 0, sizeof ( struct sensor_info ) );
+ pre_bpp = 16;
+ rate = 15; /* default to 15fps */
+ addr = 0;
+ phys = 0;
+
+ pre_size.w = 720;
+ pre_size.h = 480;
+
+ fd = 0;
+
+ memset ( & pre_memory, 0, sizeof ( struct camera_memory ) );
+ memset ( & pre_buf, 0, sizeof ( struct camera_buffer ) );
+ memset ( & pre_size, 0, sizeof ( struct frm_size ) );
+
+ tlb_base_phys = 0;
+ format = HAL_PIXEL_FORMAT_YCbCr_422_I;
+
+ bFullScreen = false;
+ m_parent = parent;
+
+ timer = new QTimer ( this );
+ timer->setSingleShot ( false );
+ connect ( timer, SIGNAL ( timeout() ), this, SLOT ( update() ) );
+}
+
+QQtLogicVideoManager::~QQtLogicVideoManager()
+{
+ delete ui;
+}
+
+int QQtLogicVideoManager::play()
+{
+ /*
+ * 这块代码放在哪里
+ */
+ dmmu_init();
+ dmmu_get_page_table_base_phys ( &tlb_base_phys );
+
+ fd = ::open ( "/dev/cim", O_RDWR ); //av
+
+ if ( fd < 0 )
+ {
+ qDebug() << "Open device fail\n";
+ }
+
+ ioctl ( fd, CIMIO_SELECT_SENSOR, sinfo.sensor_id );
+
+ ioctl ( fd, CIMIO_GET_SENSORINFO, &sinfo );
+
+ ioctl ( fd, CIMIO_SET_TLB_BASE, tlb_base_phys ); //?????????
+
+ int i = 0;
+
+ if ( pre_buf.common && pre_buf.common->data )
+ {
+ dmmu_unmap_user_memory ( & ( pre_buf.dmmu_info ) );
+ free ( pre_buf.common->data );
+ }
+
+ pre_buf.fd = fd;
+ pre_buf.nr = 5;
+ pre_buf.size = pre_size.w * pre_size.h * 3;
+ pre_buf.common = &pre_memory;
+ pre_buf.common->size = pre_buf.size * pre_buf.nr;
+ pre_buf.common->data = memalign ( 4096, pre_buf.size * pre_buf.nr );
+ memset ( pre_buf.common->data, 0xa5, ( pre_buf.size * pre_buf.nr ) );
+
+ if ( pre_buf.common->data == NULL )
+ {
+ printf ( "==<%s L%d: null pointer!\n", __func__, __LINE__ );
+ return false;
+ }
+
+ pre_buf.paddr = 0;
+ pre_buf.dmmu_info.vaddr = pre_buf.common->data;
+ pre_buf.dmmu_info.size = pre_buf.common->size;
+
+ for ( i = 0; i < ( int ) ( pre_buf.common->size ); i += 0x1000 )
+ {
+ ( ( uint8_t* ) ( pre_buf.common->data ) ) [i] = 0xff;
+ }
+
+ ( ( uint8_t* ) ( pre_buf.common->data ) ) [pre_buf.common->size - 1] = 0xff;
+ dmmu_map_user_memory ( & ( pre_buf.dmmu_info ) );
+
+ for ( i = 0; i < pre_buf.nr; ++i )
+ {
+ pre_buf.yuvMeta[i].index = i;
+ pre_buf.yuvMeta[i].width = pre_size.w;
+ pre_buf.yuvMeta[i].height = pre_size.h;
+ pre_buf.yuvMeta[i].format = format;
+ pre_buf.yuvMeta[i].count = pre_buf.nr;
+#ifdef __LINUX64__
+ pre_buf.yuvMeta[i].yAddr = ( int64_t ) pre_buf.common->data + ( pre_buf.size ) * i;
+#else
+ pre_buf.yuvMeta[i].yAddr = ( int32_t ) pre_buf.common->data + ( pre_buf.size ) * i;
+#endif
+ pre_buf.yuvMeta[i].yPhy = pre_buf.paddr + i * ( pre_buf.size );
+
+ if ( pre_buf.yuvMeta[i].format == HAL_PIXEL_FORMAT_YCbCr_422_I ) //yuv422 packed
+ {
+ pre_buf.yuvMeta[i].uAddr = pre_buf.yuvMeta[i].yAddr;
+ pre_buf.yuvMeta[i].vAddr = pre_buf.yuvMeta[i].uAddr;
+ pre_buf.yuvMeta[i].uPhy = pre_buf.yuvMeta[i].yPhy;
+ pre_buf.yuvMeta[i].vPhy = pre_buf.yuvMeta[i].uPhy;
+ pre_buf.yuvMeta[i].yStride = pre_buf.yuvMeta[i].width << 1;
+ pre_buf.yuvMeta[i].uStride = pre_buf.yuvMeta[i].yStride;
+ pre_buf.yuvMeta[i].vStride = pre_buf.yuvMeta[i].yStride;
+ }
+ else if ( pre_buf.yuvMeta[i].format == HAL_PIXEL_FORMAT_JZ_YUV_420_P ) //yuv420 planar
+ {
+ pre_buf.yuvMeta[i].uAddr = pre_buf.yuvMeta[i].yAddr + pre_size.w * pre_size.h;
+ pre_buf.yuvMeta[i].vAddr = pre_buf.yuvMeta[i].uAddr + pre_size.w * pre_size.h / 4;
+ pre_buf.yuvMeta[i].uPhy = pre_buf.yuvMeta[i].yPhy + pre_size.w * pre_size.h;
+ pre_buf.yuvMeta[i].vPhy = pre_buf.yuvMeta[i].uPhy + pre_size.w * pre_size.h / 4;
+ pre_buf.yuvMeta[i].yStride = pre_buf.yuvMeta[i].width << 1;
+ pre_buf.yuvMeta[i].uStride = pre_buf.yuvMeta[i].width / 2;
+ pre_buf.yuvMeta[i].vStride = pre_buf.yuvMeta[i].width / 2;
+ }
+ else if ( pre_buf.yuvMeta[i].format == HAL_PIXEL_FORMAT_RAW_SENSOR ) //raw bayer
+ {
+ pre_buf.yuvMeta[i].uAddr = pre_buf.yuvMeta[i].yAddr + pre_size.w * pre_size.h;
+ pre_buf.yuvMeta[i].vAddr = pre_buf.yuvMeta[i].uAddr;
+ pre_buf.yuvMeta[i].uPhy = pre_buf.yuvMeta[i].yPhy;
+ pre_buf.yuvMeta[i].vPhy = pre_buf.yuvMeta[i].uPhy;
+ pre_buf.yuvMeta[i].yStride = pre_buf.yuvMeta[i].width;
+ pre_buf.yuvMeta[i].uStride = pre_buf.yuvMeta[i].yStride;
+ pre_buf.yuvMeta[i].vStride = pre_buf.yuvMeta[i].yStride;
+ }
+ }
+
+ ioctl ( fd, CIMIO_SET_PREVIEW_FMT, format );
+ ioctl ( fd, CIMIO_SET_PREVIEW_SIZE, &pre_size );
+
+ ioctl ( fd, CIMIO_SET_PREVIEW_MEM, ( unsigned long ) ( pre_buf.yuvMeta ) );
+
+ ioctl ( fd, CIMIO_START_PREVIEW );
+
+ pp = ( unsigned char* ) malloc ( pre_size.w * pre_size.h * 3 * sizeof ( char ) );
+ frame = new QImage ( pp, pre_size.w, pre_size.h, QImage::Format_RGB888 );
+ timer->start ( 100 );
+
+ return fd;
+}
+
+int QQtLogicVideoManager::close()
+{
+ bool ret = false;
+
+ if ( fd <= 0 )
+ printf ( "fd < 0\n" );
+
+ ret = ioctl ( fd, CIMIO_SHUTDOWN );
+
+ ::close ( fd );
+ fd = 0;
+
+ dmmu_unmap_user_memory ( & ( pre_buf.dmmu_info ) );
+ dmmu_deinit();
+
+ memset ( pre_buf.yuvMeta, 0, pre_buf.nr * sizeof ( CameraYUVMeta ) );
+ pre_buf.size = 0;
+ pre_buf.nr = 0;
+ pre_buf.paddr = 0;
+ pre_buf.fd = -1;
+
+ if ( ( pre_buf.common != NULL ) && ( pre_buf.common->data != NULL ) )
+ {
+ free ( pre_buf.common->data );
+ pre_buf.common->data = NULL;
+ }
+
+ phys = 0;
+
+ timer->stop();
+ free ( pp );
+ delete frame;
+
+ return ret;
+}
+
+
+int QQtLogicVideoManager::convert_yuv_to_rgb_pixel ( int y, int u, int v )
+{
+ unsigned int pixel32 = 0;
+ unsigned char* pixel = ( unsigned char* ) &pixel32;
+ int r, g, b;
+ b = y + ( ( 443 * ( u - 128 ) ) >> 8 );
+ b = ( b < 0 ) ? 0 : ( ( b > 255 ) ? 255 : b );
+ g = y - ( ( 179 * ( v - 128 ) + 86 * ( u - 128 ) ) >> 8 );
+ g = ( g < 0 ) ? 0 : ( ( g > 255 ) ? 255 : g );
+ r = y + ( ( 351 * ( v - 128 ) ) >> 8 );
+ r = ( r < 0 ) ? 0 : ( ( r > 255 ) ? 255 : r );
+ pixel[0] = r;
+ pixel[1] = g;
+ pixel[2] = b;
+ return pixel32;
+}
+
+int QQtLogicVideoManager::convert_yuv_to_rgb_buffer ( unsigned char* yuv, unsigned char* rgb, unsigned int width,
+ unsigned int height )
+{
+ unsigned int in, out = 0;
+ unsigned int pixel_16;
+ unsigned char pixel_24[3];
+ unsigned int pixel32;
+ int y0, u, y1, v;
+
+ for ( in = 0; in < width * height * 2; in += 4 )
+ {
+ pixel_16 =
+ yuv[in + 3] << 24 |
+ yuv[in + 2] << 16 |
+ yuv[in + 1] << 8 |
+ yuv[in + 0];
+ y0 = ( pixel_16 & 0x000000ff );
+ u = ( pixel_16 & 0x0000ff00 ) >> 8;
+ y1 = ( pixel_16 & 0x00ff0000 ) >> 16;
+ v = ( pixel_16 & 0xff000000 ) >> 24;
+ pixel32 = convert_yuv_to_rgb_pixel ( y0, u, v );
+ pixel_24[0] = ( pixel32 & 0x000000ff );
+ pixel_24[1] = ( pixel32 & 0x0000ff00 ) >> 8;
+ pixel_24[2] = ( pixel32 & 0x00ff0000 ) >> 16;
+ rgb[out++] = pixel_24[0];
+ rgb[out++] = pixel_24[1];
+ rgb[out++] = pixel_24[2];
+ pixel32 = convert_yuv_to_rgb_pixel ( y1, u, v );
+ pixel_24[0] = ( pixel32 & 0x000000ff );
+ pixel_24[1] = ( pixel32 & 0x0000ff00 ) >> 8;
+ pixel_24[2] = ( pixel32 & 0x00ff0000 ) >> 16;
+ rgb[out++] = pixel_24[0];
+ rgb[out++] = pixel_24[1];
+ rgb[out++] = pixel_24[2];
+ }
+
+ return 0;
+}
+
+
+void QQtLogicVideoManager::paintEvent ( QPaintEvent* )
+{
+ if ( fd <= 0 )
+ return;
+
+ QStylePainter painter ( this );
+
+ /*
+ * 此处采集视频为多线程采集 上边的log证明 数据已经被修改
+ */
+ addr = ioctl ( fd, CIMIO_GET_FRAME );
+ p = ( uchar* ) addr;
+
+ /*
+ * 不具备优化能力,yuv缺少alpha。
+ */
+ convert_yuv_to_rgb_buffer ( p, pp, pre_size.w, pre_size.h );
+ //frame->loadFromData((uchar *)pp, w * h * 3 * sizeof(char));
+ /*
+ * 采集的图像左边上边有黑边 更换摄像头或许回有所改善 待调试
+ */
+ QRect srcRect ( 2, 6, pre_size.w, pre_size.h );
+ QRect dstRect = rect();
+ painter.scale ( 1.01, 1.02 );
+ /*
+ * 缩放OK
+ */
+ painter.drawImage ( dstRect, *frame, srcRect );
+ //painter.drawPixmap(dstRect,QPixmap::fromImage(*frame,Qt::AutoColor),srcRect);;
+ /*
+ * 裁切OK
+ */
+ //painter.drawItemPixmap(srcRect, Qt::AlignCenter, QPixmap::fromImage(*frame,Qt::AutoColor));
+ /*
+ * 30ms 屏幕有闪烁
+ */
+ //update();
+}
+
+
+void QQtLogicVideoManager::mousePressEvent ( QMouseEvent* e )
+{
+ static bool bGInit = false;
+
+ if ( !bGInit && !bFullScreen )
+ {
+ flags = windowFlags();
+ flags |= Qt::FramelessWindowHint;
+ geome = geometry();
+ bGInit = true;
+ }
+
+#ifdef __EMBEDDED_LINUX__
+
+ //pline() << e->pos() << e->globalPos();
+ if ( e->pos().x() < 0 || e->pos().y() < 0 ||
+ e->pos().x() > geome.width() || e->pos().y() > geome.height() )
+ {
+ //在mips板上,全屏返回的时候,点击其他位置,会多响应一次,在此处过滤。
+ pline() << "warning!";
+ Q_UNUSED ( e );
+ return;
+ }
+
+#endif
+
+ setAttribute ( Qt::WA_TranslucentBackground, true );
+ setAttribute ( Qt::WA_NoMousePropagation, true );
+ setAttribute ( Qt::WA_OpaquePaintEvent, true );
+
+ if ( bFullScreen )
+ {
+ flags ^= Qt::Window;
+ flags |= Qt::Widget;
+ setParent ( m_parent, flags );
+ setGeometry ( geome );
+ show();
+ bFullScreen = false;
+ }
+ else
+ {
+ int QQT_SCRN_WIDTH = QApplication::desktop()->availableGeometry().width();
+ int QQT_SCRN_HEIGHT = QApplication::desktop()->availableGeometry().height();
+ flags ^= Qt::Widget;
+ flags |= Qt::Window;
+ setParent ( 0, flags );
+ setGeometry ( 0, 0, QQT_SCRN_WIDTH, QQT_SCRN_HEIGHT );
+ show();
+ bFullScreen = true;
+ }
+
+ pline() << flags;
+ QWidget::mousePressEvent ( e );
+}
diff --git a/src/multimedia/qqtlogicvideomanager.h b/src/multimedia/qqtlogicvideomanager.h
new file mode 100644
index 00000000..a05fddd5
--- /dev/null
+++ b/src/multimedia/qqtlogicvideomanager.h
@@ -0,0 +1,75 @@
+
+#ifndef QQTLOGICVIDEOMANAGER_H
+#define QQTLOGICVIDEOMANAGER_H
+
+#include "qqt-qt.h"
+#include "qqtlinux.h"
+#include "qqtcore.h"
+#include "qqt-local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include "graphics.h"
+#include "dmmu.h"
+#include "hal.h"
+#include "jz_cim.h"
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+/**
+ * @brief The QQtLogicVideoManager class
+ * QQt模拟摄像头预览控件
+ * 省略dmmu的Qt Wrapper类
+ */
+class QQTSHARED_EXPORT QQtLogicVideoManager : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QQtLogicVideoManager ( QWidget* parent = 0 );
+ ~QQtLogicVideoManager();
+ int play();
+ int close();
+
+private:
+ Ui::QQtLogicVideoManager* ui;
+
+ struct sensor_info sinfo;
+ int pre_bpp;
+ int rate; /* default to 15fps */
+ unsigned int addr;
+ unsigned int phys;
+
+ int fd;
+ int format;
+
+ struct camera_memory pre_memory;
+ struct camera_buffer pre_buf;
+ struct frm_size pre_size;
+ unsigned int tlb_base_phys;
+
+ uchar* pp;
+ uchar* p;
+ QImage* frame;
+ QTimer* timer;
+
+ bool bFullScreen;
+ QWidget* m_parent;
+ QRect geome;
+ Qt::WindowFlags flags;
+
+ int convert_yuv_to_rgb_pixel ( int y, int u, int v );
+ int convert_yuv_to_rgb_buffer ( unsigned char* yuv, unsigned char* rgb, unsigned int width, unsigned int height );
+
+ // QWidget interface
+protected:
+ void paintEvent ( QPaintEvent* );
+ void mousePressEvent ( QMouseEvent* e );
+};
+
+#endif // QQTLOGICVIDEOMANAGER_H
diff --git a/src/multimedia/qqtvideomanager.cpp b/src/multimedia/qqtvideomanager.cpp
new file mode 100644
index 00000000..2a63e697
--- /dev/null
+++ b/src/multimedia/qqtvideomanager.cpp
@@ -0,0 +1,497 @@
+#include
+#include
+
+QQtCameraVideoSurface::QQtCameraVideoSurface ( QObject* parent ) : QAbstractVideoSurface ( parent )
+{
+
+}
+
+QQtCameraVideoSurface::~QQtCameraVideoSurface()
+{
+
+}
+
+QList QQtCameraVideoSurface::supportedPixelFormats ( QAbstractVideoBuffer::HandleType handleType ) const
+{
+#ifdef Q_OS_ANDROID
+ //Android NV21
+ return QList()
+ << QVideoFrame::Format_NV21;
+#endif
+
+ //桌面
+ return QList()
+ << QVideoFrame::Format_RGB24
+ << QVideoFrame::Format_RGB32;
+}
+
+bool QQtCameraVideoSurface::present ( const QVideoFrame& frame )
+{
+ if ( !frame.isValid() )
+ return false;
+
+ QVideoFrame cloneFrame ( frame );
+ /**
+ * frame 可读
+ */
+ if ( !cloneFrame.map ( QAbstractVideoBuffer::ReadOnly ) )
+ return false;
+
+ /**
+ * 处理frame
+ */
+
+ //Android下的视频格式是怎么回事?需要转换吗?
+
+ const QImage _image ( cloneFrame.bits(),
+ cloneFrame.width(),
+ cloneFrame.height(),
+ QVideoFrame::imageFormatFromPixelFormat ( cloneFrame.pixelFormat() ) );
+
+ //需要对水平方向反转。
+ //Windows,现在的图像保存能成功,直接显示,程序会异常退出。使用QImage的mirrored函数进行了水平翻转,可以正常显示。
+ //水平翻转是为了不崩溃,正常显示图像。必选。
+ //垂直翻转是为了上下显示正常。
+ const QImage image = _image.mirrored ( true, true );
+
+ /**
+ * frame 不可读
+ */
+ cloneFrame.unmap();
+
+ emit readyRead ( image );
+ return true;
+}
+
+QQtVideoProbe::QQtVideoProbe ( QObject* parent ) : QQtCameraVideoSurface ( parent )
+{
+ m_mediaObject = 0;
+ m_AndroidProber = 0;
+}
+
+QQtVideoProbe::~QQtVideoProbe()
+{
+}
+
+void QQtVideoProbe::setMediaObject ( QMediaObject* mediaObject )
+{
+ Q_ASSERT ( mediaObject );
+#ifdef Q_OS_ANDROID
+ if ( m_AndroidProber )
+ {
+ //m_AndroidProber->setSource ( nullptr );
+ disconnect ( m_AndroidProber, SIGNAL ( videoFrameProbed ( const QVideoFrame& ) ),
+ this, SLOT ( slotVideoFrame ( const QVideoFrame& ) ) );
+ m_AndroidProber->deleteLater();
+ }
+
+ m_mediaObject = mediaObject;
+ m_AndroidProber = new QVideoProbe ( this );
+ connect ( m_AndroidProber, SIGNAL ( videoFrameProbed ( const QVideoFrame& ) ),
+ this, SLOT ( slotVideoFrame ( const QVideoFrame& ) ) );
+ m_AndroidProber->setSource ( m_mediaObject );
+#endif
+}
+
+QMediaObject* QQtVideoProbe::mediaObject() const
+{
+ return m_mediaObject;
+}
+
+void QQtVideoProbe::slotVideoFrame ( const QVideoFrame& frame )
+{
+ present ( frame );
+}
+
+QQtVideoInput::QQtVideoInput ( QObject* parent ) : QObject ( parent )
+{
+ /**
+ * 设置视频截图工具
+ */
+ mSurface = new QQtVideoProbe ( this );
+ connect ( mSurface, SIGNAL ( readyRead ( QImage ) ), this, SIGNAL ( readyRead ( QImage ) ) );
+ connect ( mSurface, SIGNAL ( readyRead ( QImage ) ), this, SLOT ( slotImageCaptured ( QImage ) ) );
+
+ /**
+ * 设置照相机
+ */
+ mCamera = new QQtCamera ( this );
+
+ //QQtCamera 默认就是使用默认照相机,所以,这里不必设置了。
+ mCamInfo = defaultCamera();
+ mCamera->setCameraInfo ( mCamInfo );
+
+#ifdef Q_OS_ANDROID
+ mSurface->setMediaObject ( mCamera->camera() );
+#else
+ mCamera->setViewfinder ( mSurface );
+#endif
+
+ //
+ mExposure = new QQtCameraExposure ( this );
+ mFocus = new QQtCameraFocus ( this );
+ mImageProcessing = new QQtCameraImageProcessing ( this );
+ mExposure->setCameraExposure ( mCamera->exposure() );
+ mFocus->setCameraFocus ( mCamera->focus() );
+ mImageProcessing->setCameraImageProcessing ( mCamera->imageProcessing() );
+
+ mAutoSearchMilliSeconds = 200;
+ mAutoSearchTimer = new QTimer ( this );
+ connect ( mAutoSearchTimer, SIGNAL ( timeout() ), this, SLOT ( slotTimeout() ) );
+ mAutoSearchTimer->setInterval ( mAutoSearchMilliSeconds );
+ mAutoSearchTimer->setSingleShot ( false );
+
+ //默认开启自动对焦
+ mAutoSearchFlag = true ;
+ //默认不截图
+ mCaptureFlag = false;
+}
+
+QQtVideoInput::~QQtVideoInput()
+{
+
+}
+
+QCameraInfo QQtVideoInput::defaultCamera()
+{
+ return QCameraInfo::defaultCamera();
+}
+
+QList QQtVideoInput::availableCameras ( QCamera::Position position )
+{
+ return QCameraInfo::availableCameras ( position );
+}
+
+QCameraInfo& QQtVideoInput::cameraInfo()
+{
+ return mCamInfo;
+}
+
+QCameraViewfinderSettings QQtVideoInput::viewFinderSettings()
+{
+ if ( !mCamera )
+ return QCameraViewfinderSettings();
+ return mCamera->viewfinderSettings();
+}
+
+void QQtVideoInput::setViewfinderSettings ( const QCameraViewfinderSettings& settings )
+{
+ if ( !mCamera )
+ return;
+ mCamera->setViewfinderSettings ( settings );
+}
+
+QList QQtVideoInput::supportedViewFinderSettings ( const QCameraInfo& camInfo )
+{
+ QCamera camera ( camInfo );
+ return camera.supportedViewfinderSettings();
+}
+
+QQtCamera* QQtVideoInput::camera() const
+{
+ return mCamera;
+}
+
+QQtCameraExposure* QQtVideoInput::expose() const
+{
+ return mExposure;
+}
+
+QQtCameraFocus* QQtVideoInput::focus() const
+{
+ return mFocus;
+}
+
+QQtCameraImageProcessing* QQtVideoInput::imageProcessing() const
+{
+ return mImageProcessing;
+}
+
+void QQtVideoInput::start()
+{
+ stop();
+
+ //初始化截图Flag
+ mCaptureFlag = false;
+
+ //初始化照相机句柄
+ mCamera->setCameraInfo ( mCamInfo );
+
+ //初始化照相机图像控制句柄
+ mExposure->setCameraExposure ( mCamera->exposure() );
+ mFocus->setCameraFocus ( mCamera->focus() );
+ mImageProcessing->setCameraImageProcessing ( mCamera->imageProcessing() );
+
+ /**
+ * 设置相机
+ * 程序内部持续使用Capture Video。
+ */
+ //Windows 打印不支持,但是其实支持。
+ if ( !mCamera->isCaptureModeSupported ( QCamera::CaptureVideo ) )
+ {
+ pline() << mCamInfo.deviceName();
+ //pline() << mCamera << "Camera cannot capture video";
+ }
+ //播放图像 = QCamera::CaptureStillImage
+ //播放图像 = QCamera::CaptureViewfinder
+ mCamera->setCaptureMode ( QCamera::CaptureVideo );
+
+ //设置输出
+#ifdef Q_OS_ANDROID
+ mSurface->setMediaObject ( mCamera->camera() );
+#else
+ mCamera->setViewfinder ( mSurface );
+#endif
+
+ //设置ViewfinderSettings
+ //启动后设置...
+
+ //启动
+ mCamera->start();
+ pline() << mCamInfo.deviceName();
+ pline() << mCamera << "Camera start to capture video";
+
+ //设置自动对焦
+ if ( mAutoSearchFlag )
+ mAutoSearchTimer->start();
+}
+
+void QQtVideoInput::stop()
+{
+ mAutoSearchTimer->stop();
+
+ if ( mCamera )
+ {
+ mCamera->stop();
+ //mCamera->deleteLater();
+ }
+
+ //mCamera = NULL;
+}
+
+void QQtVideoInput::load()
+{
+ mCamera->load();
+}
+
+void QQtVideoInput::unload()
+{
+ mCamera->unload();
+}
+
+void QQtVideoInput::startDefaultCamera()
+{
+ mCamInfo = defaultCamera();
+ start();
+}
+
+void QQtVideoInput::setPrepareInterval ( int milliSeconds )
+{
+ mAutoSearchMilliSeconds = milliSeconds;
+}
+
+int QQtVideoInput::prepareInterval() const
+{
+ return mAutoSearchMilliSeconds;
+}
+
+void QQtVideoInput::capture()
+{
+ //现在使用截图Flag,将来可能要使用ImageCapture类,可以调整Shutter速度。
+ //对外提供一个简化的截图功能。
+ QMutexLocker locker ( &mMutexCaptureFlag );
+ mCaptureFlag = true;
+}
+
+void QQtVideoInput::setAutoPrepare ( bool autosearch )
+{
+ mAutoSearchFlag = autosearch;
+
+ if ( autosearch )
+ mAutoSearchTimer->start();
+ else
+ mAutoSearchTimer->stop();
+}
+
+void QQtVideoInput::prepare ( QCamera::LockTypes locks )
+{
+ if ( !mCamera )
+ return;
+ mCamera->searchAndLock ( locks );
+}
+
+void QQtVideoInput::cancelPrepare ( QCamera::LockTypes locks )
+{
+ if ( !mCamera )
+ return;
+ mCamera->unlock();
+}
+
+void QQtVideoInput::slotTimeout()
+{
+ if ( !mCamera )
+ return;
+ mCamera->searchAndLock();
+}
+
+void QQtVideoInput::slotImageCaptured ( QImage image )
+{
+ QMutexLocker locker ( &mMutexCaptureFlag );
+
+ if ( !mCaptureFlag )
+ return;
+ mCaptureFlag = false;
+
+ emit readyReadCapture ( image );
+}
+
+QQtVideoOutput::QQtVideoOutput ( QObject* parent ) : QObject ( parent )
+{
+ mWidget = 0;
+ mStartFlag = false;
+}
+
+QQtVideoOutput::~QQtVideoOutput() {}
+
+QQtWidget*& QQtVideoOutput::viewFinder()
+{
+ return mWidget;
+}
+
+void QQtVideoOutput::start()
+{
+ QMutexLocker locker ( &mMutexStartFlag );
+ mStartFlag = true;
+}
+
+void QQtVideoOutput::stop()
+{
+ QMutexLocker locker ( &mMutexStartFlag );
+ mStartFlag = false;
+}
+
+void QQtVideoOutput::setPixmap ( QImage image )
+{
+ QMutexLocker locker ( &mMutexStartFlag );
+ if ( !mStartFlag )
+ return;
+ if ( !mWidget )
+ return;
+ mWidget->setPixmap ( image );
+}
+
+QQtVideoManager::QQtVideoManager ( QObject* parent ) : QObject ( parent )
+{
+ mInput = new QQtVideoInput ( this );
+ mOutput = new QQtVideoOutput ( this );
+
+ connect ( mInput, SIGNAL ( readyRead ( QImage ) ), this, SIGNAL ( readyRead ( QImage ) ) );
+ connect ( mInput, SIGNAL ( readyReadCapture ( QImage ) ), this, SIGNAL ( readyReadCapture ( QImage ) ) );
+}
+
+QQtVideoManager::~QQtVideoManager() {}
+
+QCameraInfo QQtVideoManager::defaultCamera()
+{
+ return QQtVideoInput::defaultCamera();
+}
+
+QList QQtVideoManager::availableCameras ( QCamera::Position position )
+{
+ return QQtVideoInput::availableCameras ( position );
+}
+
+QCameraInfo& QQtVideoManager::cameraInfo()
+{
+ return mInput->cameraInfo();
+}
+
+QQtWidget*& QQtVideoManager::viewFinder() const
+{
+ return mOutput->viewFinder();
+}
+
+QCameraViewfinderSettings QQtVideoManager::viewFinderSettings() const
+{
+ return mInput->viewFinderSettings();
+}
+
+void QQtVideoManager::setViewfinderSettings ( const QCameraViewfinderSettings& settings )
+{
+ return mInput->setViewfinderSettings ( settings );
+}
+
+QList QQtVideoManager::supportedViewFinderSettings()
+{
+ return mInput->supportedViewFinderSettings();
+}
+
+QQtCamera* QQtVideoManager::camera() const
+{
+ return mInput->camera();
+}
+
+QQtCameraExposure* QQtVideoManager::expose() const
+{
+ return mInput->expose();
+}
+
+QQtCameraFocus* QQtVideoManager::focus() const
+{
+ return mInput->focus();
+}
+
+QQtCameraImageProcessing* QQtVideoManager::imageProcessing() const
+{
+ return mInput->imageProcessing();
+}
+
+void QQtVideoManager::startInput()
+{
+ mInput->start();
+}
+
+void QQtVideoManager::stopInput()
+{
+ mInput->stop();
+}
+
+QQtVideoInput* QQtVideoManager::inputManager()
+{
+ return mInput;
+}
+
+void QQtVideoManager::startOutput()
+{
+ mOutput->start();
+}
+
+void QQtVideoManager::stopOutput()
+{
+ mOutput->stop();
+}
+
+QQtVideoOutput* QQtVideoManager::outputManager()
+{
+ return mOutput;
+}
+
+void QQtVideoManager::startDefaultInput()
+{
+ mInput->startDefaultCamera();
+}
+
+void QQtVideoManager::startDefaultOutput()
+{
+ mOutput->start();
+}
+
+void QQtVideoManager::capture()
+{
+ mInput->capture();
+}
+
+void QQtVideoManager::outputImage ( QImage image )
+{
+ mOutput->setPixmap ( image );
+}
diff --git a/src/multimedia/qqtvideomanager.h b/src/multimedia/qqtvideomanager.h
new file mode 100644
index 00000000..bde162ad
--- /dev/null
+++ b/src/multimedia/qqtvideomanager.h
@@ -0,0 +1,300 @@
+#ifndef QQTVIDEOMANAGER_H
+#define QQTVIDEOMANAGER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#include
+
+/**
+ * ---------------------------------------------------------------------------------------------------------------------
+ * | 使用方式 | Parent | Property Class | Childen | 备注
+ * ---------------------------------------------------------------------------------------------------------------------
+ * | setViewfinder | QAbstractVideoSurface | QQtCameraVideoSurface | | 视频,快,Buffer
+ * | | | | QQtVideoProbe | 视频,快,Buffer,+Android支持
+ * ---------------------------------------------------------------------------------------------------------------------
+ * | setViewfinder | QMediaBindableInterface | QGraphicsVideoItem | | QGraphicsItem 系统专用
+ * | | | QVideoWidget | QCameraViewfinder | 视频,快,属于输出位置上的
+ * ---------------------------------------------------------------------------------------------------------------------
+ * | setMetaObject | QMediaBindableInterface | QCameraImageCapture | | 截图,慢,默认保存文件
+ * | | | QMediaRecorder | QAudioRecorder | 录像,快,保存文件,音视频
+ * ---------------------------------------------------------------------------------------------------------------------
+ */
+
+/**
+ * 功能:
+ * 对视频设备进行管理。
+ * 输入:摄像头
+ * 输出:绘图设备(窗口)
+ */
+
+/**
+ * @brief The QQtVideoSurface class
+ * 从metaObject获取视频数据,帧。
+ * Buffer,快速。
+ */
+class QQTSHARED_EXPORT QQtCameraVideoSurface : public QAbstractVideoSurface
+{
+ Q_OBJECT
+public:
+ QQtCameraVideoSurface ( QObject* parent = 0 );
+ virtual ~QQtCameraVideoSurface();
+
+signals:
+ void readyRead ( QImage );
+
+ // QAbstractVideoSurface interface
+public:
+ virtual QList supportedPixelFormats ( QAbstractVideoBuffer::HandleType handleType ) const override;
+ virtual bool present ( const QVideoFrame& frame ) override;
+};
+
+/**
+ * @brief The QQtVideoProbe class
+ * 这是个数字摄像机管理器,这个类是为Android等需要Probe的数字录像设备准备的。
+ * 我在VideoManager内部使用这个类来兼容桌面和Android系统,
+ * 但是我发现,无论如何Probe在Android上都不能正常执行,所以现在暂时不支持Android。
+ * Qt5.9.2,何时支持,待定。
+ */
+class QQTSHARED_EXPORT QQtVideoProbe : public QQtCameraVideoSurface
+{
+ Q_OBJECT
+public:
+ QQtVideoProbe ( QObject* parent = 0 );
+ virtual ~QQtVideoProbe();
+
+ void setMediaObject ( QMediaObject* mediaObject );
+ QMediaObject* mediaObject() const;
+
+ /**
+ * 以下与用户无关。
+ */
+private slots:
+ void slotVideoFrame ( const QVideoFrame& frame );
+private:
+ QMediaObject* m_mediaObject;
+ QVideoProbe* m_AndroidProber;
+};
+
+/**
+ * @brief The QQtVideoInput class
+ * 图像输入
+ * 从照相机输入,输出QImage序。
+ * 从照相机输入,支持截图,输出QImage。
+ */
+class QQTSHARED_EXPORT QQtVideoInput : public QObject
+{
+ Q_OBJECT
+public:
+ QQtVideoInput ( QObject* parent = 0 );
+ virtual ~QQtVideoInput();
+
+ /**
+ * 选择输入设备
+ */
+ static QCameraInfo defaultCamera();
+ static QList availableCameras ( QCamera::Position position = QCamera::UnspecifiedPosition );
+ //决定使用哪个Camera
+ //QQtVideoInput不会立即生效,只有在开启后才会生效。
+ QCameraInfo& cameraInfo ( void );
+
+ /**
+ * 选择输入格式,启动后设置。
+ */
+ QCameraViewfinderSettings viewFinderSettings();
+ //设置采集的图像的PixFormat,帧率等信息。
+ void setViewfinderSettings ( const QCameraViewfinderSettings& settings = QCameraViewfinderSettings() );
+ //获取照相机支持的设置。默认查询defaultCamera的。
+ static QList supportedViewFinderSettings ( const QCameraInfo& camInfo = defaultCamera() );
+
+ /**
+ * 控制输入设备
+ */
+ QQtCamera* camera() const;
+ QQtCameraExposure* expose() const;
+ QQtCameraFocus* focus() const;
+ QQtCameraImageProcessing* imageProcessing() const;
+
+public slots:
+ void start();
+ void stop();
+ void load();
+ void unload();
+
+ void startDefaultCamera();
+
+ //自动对焦,手动对焦切换。默认,自动,200ms
+ void setAutoPrepare ( bool autosearch = true );
+ void setPrepareInterval ( int milliSeconds );
+ int prepareInterval() const;
+
+public slots:
+ //用这个函数手动对焦。
+ void prepare ( QCamera::LockTypes locks = QCamera::LockFocus );
+ //放弃对焦、对焦停止、对焦完成
+ void cancelPrepare ( QCamera::LockTypes locks = QCamera::LockFocus );
+
+ //截图
+ void capture();
+
+ /**
+ * 输出图像
+ */
+signals:
+ //输出QImage序
+ void readyRead ( QImage );
+ //输出QImage
+ void readyReadCapture ( QImage );
+
+ /**
+ * 以下与用户无关
+ */
+private slots:
+ void slotTimeout();
+ void slotImageCaptured ( QImage );
+private:
+ //经过调试,QCamera句柄,一个进程只能存在一个。
+ QQtCamera* mCamera;
+ QCameraInfo mCamInfo;
+ QQtVideoProbe* mSurface;
+ QQtCameraExposure* mExposure;
+ QQtCameraFocus* mFocus;
+ QQtCameraImageProcessing* mImageProcessing;
+
+ //自动对焦
+ bool mAutoSearchFlag;
+ QTimer* mAutoSearchTimer;
+ int mAutoSearchMilliSeconds;
+
+ //需要加锁吗?如果用户把这个类 moveToThread,并且不使用信号和槽模式调用 capture,那么需要加锁。
+ QMutex mMutexCaptureFlag;
+ bool mCaptureFlag;
+};
+
+/**
+ * @brief The QQtVideoOutput class
+ * 视频输出
+ * 把QImage输出到取景器。
+ * QWidget、QQtWidget都能完成。QVideoWidget QCameraViewfinder QGraphicsVideoItem这些需要QCamera。
+ * QCamera可以有多个吗?各自设置不同的?不可以。
+ */
+class QQTSHARED_EXPORT QQtVideoOutput : public QObject
+{
+ Q_OBJECT
+public:
+ QQtVideoOutput ( QObject* parent = 0 );
+ virtual ~QQtVideoOutput();
+
+ /**
+ * 设置输出设备
+ */
+ QQtWidget*& viewFinder();
+
+ /**
+ * 控制输出设备
+ */
+public slots:
+ //开启后才能使用。
+ void start();
+ //关闭后停止显示。
+ void stop();
+ //对窗口输出图像。
+ void setPixmap ( QImage image );
+
+private:
+ QQtWidget* mWidget;
+ //需要加锁吗?如果用户把这个类 moveToThread,并且不使用信号和槽模式调用 start stop,那么需要加锁。
+ QMutex mMutexStartFlag;
+ bool mStartFlag;
+};
+
+/**
+ * @brief The QQtVideoManager class
+ * 视频设备管理器
+ * 输入:照相机
+ * 输出:取景器。
+ *
+ * 功能:
+ * 获取录像机的每一帧,输出给用户处理,
+ * 提供输出设备的管理,辅助用户输出到确定的窗口。
+ */
+class QQTSHARED_EXPORT QQtVideoManager : public QObject
+{
+ Q_OBJECT
+public:
+ QQtVideoManager ( QObject* parent = 0 );
+ virtual ~QQtVideoManager();
+
+ /**
+ * 选择输入、输出设备
+ */
+ static QCameraInfo defaultCamera();
+ static QList availableCameras ( QCamera::Position position = QCamera::UnspecifiedPosition );
+ //输入设备信息
+ QCameraInfo& cameraInfo ( void );
+ //输出设备信息
+ QQtWidget*& viewFinder ( void ) const;
+
+ /**
+ * 设置输入、输出设备格式
+ */
+ //输入设备设置
+ QCameraViewfinderSettings viewFinderSettings() const;
+ void setViewfinderSettings ( const QCameraViewfinderSettings& settings );
+ QList supportedViewFinderSettings();
+ //输入设备的格式,决定输出设备的格式。
+
+ /**
+ * 控制输入、输出设备
+ */
+ QQtCamera* camera() const;
+ QQtCameraExposure* expose() const;
+ QQtCameraFocus* focus() const;
+ QQtCameraImageProcessing* imageProcessing() const;
+
+ QQtVideoInput* inputManager();
+ QQtVideoOutput* outputManager();
+
+public slots:
+ void startInput();
+ void stopInput();
+
+ void startOutput();
+ void stopOutput();
+
+ void startDefaultInput();
+ //等于start()。输出没有默认设备。
+ void startDefaultOutput();
+
+ void capture();
+
+ /**
+ * 输出图像
+ */
+signals:
+ //从输入设备获得图像。用户处理这些图像。
+ void readyRead ( QImage );
+ void readyReadCapture ( QImage );
+
+public slots:
+ //把图像输出到输出设备。
+ void outputImage ( QImage );
+
+private:
+ QQtVideoInput* mInput;
+ QQtVideoOutput* mOutput;
+};
+
+#endif // QQTVIDEOMANAGER_H
diff --git a/src/multimedia/qqtwavaudiomanager.cpp b/src/multimedia/qqtwavaudiomanager.cpp
new file mode 100644
index 00000000..3fb52026
--- /dev/null
+++ b/src/multimedia/qqtwavaudiomanager.cpp
@@ -0,0 +1,317 @@
+#include "qqtwavaudiomanager.h"
+#include "libqwav.h"
+
+QQtWavAudioInput::QQtWavAudioInput ( QObject* parent ) : QObject ( parent )
+{
+ mTimer = new QTimer ( this );
+ connect ( mTimer, SIGNAL ( timeout() ), SLOT ( slotTimeout() ) );
+
+ mFileBytes.clear();
+ mBytes.clear();
+ mBytesBuffer.setBuffer ( &mBytes );
+
+ mTimerInterval = 20;
+}
+
+QIODevice* QQtWavAudioInput::setSourceFile ( const QString& localFile )
+{
+ //如果开着,不管。
+ mSourceFile = localFile;
+
+#if QT_VERSION > QT_VERSION_CHECK(5,0,0)
+
+ //判断文件类型是否接受
+ QMimeDatabase mimedb;
+ QMimeType mimetype = mimedb.mimeTypeForFile ( mSourceFile );
+
+ if ( !QSoundEffect::supportedMimeTypes().contains ( mimetype.name(), Qt::CaseInsensitive ) )
+ {
+ pline() << "filename" << localFile << "mimetype" << mimetype.name()
+ << QSoundEffect::supportedMimeTypes().contains ( mimetype.name(), Qt::CaseInsensitive ) ;
+ pline() << "can't play file";
+ return NULL;
+ }
+#endif
+
+ //判断音频具体格式
+ //支持qrc文件
+ TWavFileInfo info;
+ bool ret = anlysisWavFileHeader ( mSourceFile, mFormat, info );
+ //仅仅支持本地文件
+ //bool ret = anlysisWavFileHeader_C ( localFile );
+
+ if ( !ret )
+ {
+ pline() << "wav format parse fail";
+ return NULL;
+ }
+
+ mFileTotalSize = info.fileTotalSize;
+ mFileHeaderSize = info.fileHeaderSize;
+ mFileDataSize = info.fileDataSize;
+ mFileTailSize = info.fileTailSize;
+
+ return &mBytesBuffer;
+}
+
+void QQtWavAudioInput::setTimerInterval ( int millSecond ) { mTimerInterval = millSecond; }
+
+
+void QQtWavAudioInput::start()
+{
+ stop();
+
+ mChannelCount = mFormat.channelCount();
+ mSampleSize = mFormat.sampleSize();
+ mSampleRate = mFormat.sampleRate();
+
+ //读取到数据
+ QFile f ( mSourceFile );
+ f.open ( QFile::ReadOnly );
+ QByteArray b = f.read ( mFileHeaderSize );
+ //这个地方测试完成:内部解析wav头,两个都很成功。C Qt 都OK.
+ //pline() << b;
+ mFileBytes = f.read ( mFileDataSize );
+ f.close();
+
+ mBytesBuffer.open ( QIODevice::ReadWrite );
+ mTimer->start ( mTimerInterval );
+ return;
+}
+
+void QQtWavAudioInput::stop()
+{
+ //如果正在播放,先关闭写入音频数据流。
+ mTimer->stop();
+ //如果存在,则清空。
+ //这两个变量Buffer是什么操作关系?QBuffer是QByteArray的QIODevice套。
+ //改变QByteArray,会直接影响QBuffer的读写。QBuffer也会影响QByteArray的内容。
+ mFileBytes.clear();
+ mBytes.clear();
+
+ if ( mBytesBuffer.isOpen() )
+ mBytesBuffer.close();
+}
+
+int QQtWavAudioInput::fileTotalSize() {return mFileTotalSize;}
+
+int QQtWavAudioInput::fileHeaderSize() { return mFileHeaderSize; }
+
+int QQtWavAudioInput::fileDataSize() {return mFileDataSize;}
+
+int QQtWavAudioInput::fileTailSize() {return mFileTailSize;}
+
+
+void QQtWavAudioInput::slotTimeout()
+{
+ //1s 字节数 = 采样率 * 采样深度(位宽)* 通道数 / 8
+ //mTimerInterval ms 字节数 = 1s 字节数 / (1000/mTimerInterval)
+ //每个音符 字节数 = 采样深度(位宽)* 通道数 / 8;
+ int frameSize = mSampleRate * mSampleSize * mChannelCount / 8 / ( 1000 / mTimerInterval );
+ QByteArray tempBytes;
+
+ if ( mFileBytes.size() > frameSize )
+ {
+ tempBytes.resize ( frameSize );
+ }
+ else
+ {
+ tempBytes.resize ( mFileBytes.size() );
+ }
+
+ //pline() << mFileBytes.size() << tempBytes.size() << frameSize;
+ //mFileBytes 逐渐减少
+ mFileBytes >> tempBytes;
+ //这是给用户的。
+ mBytes = tempBytes;
+ //回到初始位置
+ mBytesBuffer.seek ( 0 );
+ //激发readyRead信号
+ mBytesBuffer.write ( 0 );
+
+ if ( mFileBytes.isEmpty() )
+ {
+ //pline() << mFileBytes.size() << 0 << frameSize;
+ //这里不要关闭Buffer,客户一般还没用完。
+ mTimer->stop();
+ }
+
+ return;
+}
+
+QQtWavAudioOutput::QQtWavAudioOutput ( QObject* parent ) : QObject ( parent )
+{
+ mFileBytes.clear();
+ mBytesBuffer.setBuffer ( &mFileBytes );
+
+ mFormat.setByteOrder ( QAudioFormat::LittleEndian );
+ mFormat.setChannelCount ( 2 );
+ mFormat.setCodec ( "audio/pcm" );
+ mFormat.setSampleRate ( 44100 );
+ mFormat.setSampleSize ( 16 );
+ mFormat.setSampleType ( QAudioFormat::SignedInt );
+}
+
+QIODevice* QQtWavAudioOutput::setSourceFile ( const QString& localFile )
+{
+ mSourceFile = localFile;
+ return &mBytesBuffer;
+}
+
+QAudioFormat& QQtWavAudioOutput::format() { return mFormat; }
+
+void QQtWavAudioOutput::start()
+{
+ if ( mSourceFile.isEmpty() )
+ return;
+
+ //这里清空文件,不会发生保存?不会,这里清空Buffer。
+ mFileBytes.clear();
+
+ if ( mBytesBuffer.isOpen() )
+ mBytesBuffer.close();
+
+ mBytesBuffer.open ( QIODevice::WriteOnly );
+}
+
+void QQtWavAudioOutput::stop()
+{
+ //在stop的时候,才会把数据全部存储到wav文件
+ if ( mSourceFile.isEmpty() )
+ return;
+
+ //防止多次关闭导致音频文件被破坏。
+ if ( mFileBytes.isEmpty() )
+ return;
+
+ QFile file ( mSourceFile );
+ file.open ( QFile::Truncate | QFile::WriteOnly );
+
+ addWavHeader ( file, mFormat );
+ file.write ( mFileBytes );
+ addWavTail ( file );
+ //这个时候,Header里面RiffLength是错误的。改写
+ file.seek ( 0 );
+ addWavHeader ( file, mFormat );
+ //现在纠正好了。
+ file.close();
+
+ mFileBytes.clear();
+
+ if ( mBytesBuffer.isOpen() )
+ mBytesBuffer.close();
+}
+
+
+
+QQtWavAudioManager::QQtWavAudioManager ( QObject* parent ) : QObject ( parent )
+{
+ mInputManager = new QQtWavAudioInput ( this );
+ mOutputManager = new QQtWavAudioOutput ( this );
+
+ mInputDevice = mInputManager->device();
+ mOutputDevice = mOutputManager->device();
+
+ connect ( mInputDevice, SIGNAL ( readyRead() ),
+ this, SIGNAL ( readyRead() ) );
+
+}
+
+QQtWavAudioManager::~QQtWavAudioManager()
+{
+ stopInput();
+ stopOutput();
+}
+
+void QQtWavAudioManager::setInputSourceFile ( const QString& localFile )
+{
+ QIODevice* ioDev = mInputManager->setSourceFile ( localFile );
+
+ if ( !ioDev )
+ {
+ pline() << mInputManager->sourceFile()
+ << inputAudioFormat().sampleSize()
+ << inputAudioFormat().sampleRate()
+ << inputAudioFormat().channelCount()
+ << "open failed, errcode:"
+ << "-1";
+ return;
+ }
+}
+
+QString QQtWavAudioManager::inputSourceFile() { return mInputManager->sourceFile(); }
+
+void QQtWavAudioManager::setOutputSourceFile ( const QString& localFile )
+{
+ QIODevice* ioDev = mOutputManager->setSourceFile ( localFile );
+
+ if ( !ioDev )
+ {
+ pline() << mOutputManager->sourceFile()
+ << outputAudioFormat().sampleSize()
+ << outputAudioFormat().sampleRate()
+ << outputAudioFormat().channelCount()
+ << "open failed, errcode:"
+ << "-1";
+ return;
+ }
+}
+
+QString QQtWavAudioManager::outputSourceFile() { return mOutputManager->sourceFile(); }
+
+const QAudioFormat& QQtWavAudioManager::inputAudioFormat() { return mInputManager->format(); }
+
+QAudioFormat& QQtWavAudioManager::outputAudioFormat() { return mOutputManager->format(); }
+
+int QQtWavAudioManager::inputFileTotalSize() { return mInputManager->fileTotalSize(); }
+
+int QQtWavAudioManager::inputFileHeaderSize() { return mInputManager->fileHeaderSize(); }
+
+int QQtWavAudioManager::inputFileDataSize() { return mInputManager->fileDataSize(); }
+
+int QQtWavAudioManager::inputFileTailSize() { return mInputManager->fileTailSize(); }
+
+QQtWavAudioInput* QQtWavAudioManager::inputManager() { return mInputManager; }
+
+QIODevice* QQtWavAudioManager::inputDevice() { return mInputDevice; }
+
+QQtWavAudioOutput* QQtWavAudioManager::outputManager() { return mOutputManager; }
+
+QIODevice* QQtWavAudioManager::outputDevice() { return mOutputDevice; }
+
+void QQtWavAudioManager::startInput()
+{
+ stopInput();
+ mInputManager->start();
+}
+
+void QQtWavAudioManager::stopInput()
+{
+ mInputManager->stop();
+}
+
+void QQtWavAudioManager::startOutput()
+{
+ stopOutput();
+ mOutputManager->start();
+}
+
+void QQtWavAudioManager::stopOutput()
+{
+ mOutputManager->stop();
+}
+
+QByteArray QQtWavAudioManager::readAll()
+{
+ return mInputDevice->readAll();
+}
+
+QByteArray QQtWavAudioManager::read ( qint64 maxlen )
+{
+ return mInputDevice->read ( maxlen );
+}
+
+void QQtWavAudioManager::write ( const QByteArray& bytes )
+{
+ mOutputDevice->write ( bytes );
+}
diff --git a/src/multimedia/qqtwavaudiomanager.h b/src/multimedia/qqtwavaudiomanager.h
new file mode 100644
index 00000000..952fb36d
--- /dev/null
+++ b/src/multimedia/qqtwavaudiomanager.h
@@ -0,0 +1,220 @@
+#ifndef QQTWAVAUDIOMANAGER_H
+#define QQTWAVAUDIOMANAGER_H
+
+#include
+#include
+#include
+
+#if QT_VERSION > QT_VERSION_CHECK(5,0,0)
+#include
+#include
+#include
+
+#include
+#include
+#endif
+
+#include
+
+//设计思路:QQtWavAudioInput和QQtWavAudioOutput两边都是内存和wav文件,为内存服务。
+
+/**
+ * @brief The QQtWavAudioInput class
+ * QQtWavAudioInput具备QAudioInput的能力,可以把wav文件的音频帧,通过readyRead输出。
+ * 每次/10ms一帧,通过QIODevice readyRead发射给用户。
+ * 升级目标:QQtAudioInput里支持的设备比较广泛,文件类型比较多。
+ *
+ * 原理,设置Sourcefile,返回QIODevice,进行读取。一次加载,逐渐读取。
+ *
+ * 不要使用大文件。
+ * Qt 中有一个 QBuffer 类,可以将 QByteArray 包装成一个 QIODevice。QMemIODevice = QBuffer
+ * 如果来的是个QByteArray,那么,用QBuffer封装,
+ * 在 open 函数中调用 QIODevice::open(mode)
+ * 要解析wav,用自定义程序,还是用开源Library(libsndfile)?自定义程序
+ * 要播放wav,是用wav的音频格式来设定输出设备,还是用个输出设备支持的音频格式,wav里选取进行使用?使用wav的。
+ *
+ * 尝试用QAudioDecoder,解码器不支持x-wav,defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.audiodecode"
+ * 为什么QSoundEffect支持那么多wav格式?("audio/x-wav", "audio/wav", "audio/wave", "audio/x-pn-wav")
+ * LibQQt库
+ * QAudioDecoder保存了一个提交,#5643241
+ * QWavAudioEffect保存了一个提交,#5f43622
+ */
+class QQTSHARED_EXPORT QQtWavAudioInput : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QQtWavAudioInput ( QObject* parent = nullptr );
+ //自动解析格式,和文件大小
+ QIODevice* setSourceFile ( const QString& localFile );
+ QString sourceFile() { return mSourceFile; }
+
+ //读取用。这个是个内部公用的,并不是临时的。碰巧了。
+ QIODevice* device() { return &mBytesBuffer; }
+
+ //设置读文件的时钟快慢(硬盘快,时钟快,每次读的少;硬盘慢,时钟慢,每次读的多)
+ //采样间隔 10-100ms default: macOS SSD 20 ms
+ //windows 机械硬盘 100ms, windows 机械硬盘 is slower than macOS SSD.
+ int timerInterval() const { return mTimerInterval; }
+ void setTimerInterval ( int millSecond = 20 );
+ //可以频繁开启,tip:用完一定要关闭,系统会自动关闭。
+ //已经检查测试,没有文件设备漏开关问题。
+ void start();
+ void stop();
+
+ //每次修改SourceFile,这些都会改变。在不改变SourceFile的时候是内部使用的值。
+ const QAudioFormat& format() { return mFormat; }
+ int fileTotalSize();
+ int fileHeaderSize();
+ int fileDataSize();
+ int fileTailSize();
+
+signals:
+
+public slots:
+
+private slots:
+ void slotTimeout();
+
+private:
+ QString mSourceFile;
+ //用于保存文件全部Bytes
+ QByteArray mFileBytes;
+ //用于和Buffer联系,给用户提供每次读取的帧。
+ QByteArray mBytes;
+ QBuffer mBytesBuffer;
+
+ //每次设置新Source,会改变这些值。
+ QAudioFormat mFormat;
+ int mFileDataSize;
+ int mFileHeaderSize;
+ int mFileTailSize;
+ int mFileTotalSize;
+ //这三个不准公开出来啊。
+ int mSampleRate;
+ int mSampleSize;
+ int mChannelCount;
+
+ QTimer* mTimer;
+ int mTimerInterval;
+
+public:
+protected:
+
+public:
+protected:
+
+};
+
+class QQTSHARED_EXPORT QQtWavAudioOutput : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QQtWavAudioOutput ( QObject* parent = nullptr );
+
+ QIODevice* setSourceFile ( const QString& localFile );
+ QString sourceFile() { return mSourceFile; }
+
+ //写入用
+ QIODevice* device() { return &mBytesBuffer; }
+
+ //用户务必设置format,默认值为2 16 44100
+ QAudioFormat& format();
+
+ void start();
+
+ void stop();
+
+protected:
+
+private:
+ QString mSourceFile;
+ QAudioFormat mFormat;
+
+ QBuffer mBytesBuffer;
+ QByteArray mFileBytes;
+};
+
+/**
+ * @brief The QQtWavAudioManager class
+ * Wav媒体音频管理器
+ *
+ * 这个Wav音频管理器目标为用户提供Wav媒体的音频数据帧,附加音频数据帧输出到Wav媒体的功能。
+ */
+class QQTSHARED_EXPORT QQtWavAudioManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QQtWavAudioManager ( QObject* parent = nullptr );
+
+ ~QQtWavAudioManager();
+
+ /**
+ * 选择输入、输出Wav媒体
+ */
+ //设置输入或者输出wav文件
+ void setInputSourceFile ( const QString& localFile );
+ QString inputSourceFile();
+ void setOutputSourceFile ( const QString& localFile );
+ QString outputSourceFile();
+
+ /**
+ * 选择音频流的格式
+ */
+
+ //获取输入文件的音频流格式
+ const QAudioFormat& inputAudioFormat();
+ //设置输出音频流的音频格式,输出保存的时候使用。
+ QAudioFormat& outputAudioFormat();
+
+ //每次修改SourceFile,这些都会改变。
+ int inputFileTotalSize();
+ int inputFileHeaderSize();
+ int inputFileDataSize();
+ int inputFileTailSize();
+
+
+ /**
+ * 操作输入、输出Wav媒体
+ */
+
+ QQtWavAudioInput* inputManager();
+ //如果输入,从这里读取帧
+ QIODevice* inputDevice();
+
+ QQtWavAudioOutput* outputManager();
+ //如果输出,从这里写入帧,提前设置好格式哦...
+ QIODevice* outputDevice();
+
+ void startInput();
+ void stopInput();
+
+ void startOutput();
+ void stopOutput();
+
+ //这两个是方便函数,一般都用这几个进行读写,不使用上边的。
+ QByteArray readAll();
+ QByteArray read ( qint64 maxlen );
+ void write ( const QByteArray& bytes );
+
+signals:
+ /*音频数据准备就绪,readAll即可读取。*/
+ void readyRead();
+public slots:
+
+private:
+
+ QQtWavAudioInput* mInputManager;
+ QQtWavAudioOutput* mOutputManager;
+
+ QIODevice* mInputDevice;
+ QIODevice* mOutputDevice;
+
+ //这三个不准公开出来。
+ int mSampleRate;
+ int mSampleSize;
+ int mChannelCount;
+};
+
+#endif // QQTWAVAUDIOMANAGER_H
diff --git a/src/multimedia/qqtwavsoundeffect.cpp b/src/multimedia/qqtwavsoundeffect.cpp
new file mode 100644
index 00000000..5dd2ceda
--- /dev/null
+++ b/src/multimedia/qqtwavsoundeffect.cpp
@@ -0,0 +1,163 @@
+#include "qqtwavsoundeffect.h"
+
+
+QQtWavSoundEffect* QQtWavSoundEffect::msInstance = NULL;
+
+QQtWavSoundEffect* QQtWavSoundEffect::Instance ( QObject* parent )
+{
+ if ( !msInstance )
+ msInstance = new QQtWavSoundEffect ( parent );
+
+ return msInstance;
+}
+
+QQtWavSoundEffect::QQtWavSoundEffect ( QObject* parent ) : QObject ( parent )
+{
+ mVolume = 1;
+ mIOInput = NULL;
+ mLooping = 1;
+ mLoops = 1;
+}
+
+void QQtWavSoundEffect::setOutputDevice ( const QAudioDeviceInfo& output )
+{
+ if ( output.isNull() )
+ manager.outputDeviceInfo() = QQtAudioManager::defaultOutputDevice();
+ else
+ manager.outputDeviceInfo() = output;
+}
+
+void QQtWavSoundEffect::useDefaultOutputDevice()
+{
+ manager.outputDeviceInfo() = QQtAudioManager::defaultOutputDevice();
+}
+
+void QQtWavSoundEffect::useCustomOutputDevice ( const QAudioDeviceInfo& output )
+{
+ manager.outputDeviceInfo() = output;
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
+QDebug& operator << ( QDebug& dbg, const QAudioFormat& fmt )
+{
+ return dbg;
+}
+#endif
+
+void QQtWavSoundEffect::play ( QString localFile )
+{
+#if QT_VERSION > QT_VERSION_CHECK(5,0,0)
+
+ //判断文件类型是否接受
+ QMimeDatabase mimedb;
+ QMimeType mimetype = mimedb.mimeTypeForFile ( localFile );
+
+ if ( !QSoundEffect::supportedMimeTypes().contains ( mimetype.name(), Qt::CaseInsensitive ) )
+ {
+ pline() << "filename" << localFile << "mimetype" << mimetype.name()
+ << QSoundEffect::supportedMimeTypes().contains ( mimetype.name(), Qt::CaseInsensitive ) ;
+ pline() << "can't play file";
+ return;
+ }
+#endif
+
+ mSourceFile = localFile;
+
+ stop();
+
+ mIOInput = mWavInput.setSourceFile ( localFile );
+ connect ( mIOInput, SIGNAL ( readyRead() ),
+ this, SLOT ( readyRead() ) );
+
+ QAudioDeviceInfo& usingOutput = manager.outputDeviceInfo();
+
+ QAudioFormat fmt = mWavInput.format();
+
+ //输出设备是否支持格式是否支持
+ if ( !usingOutput.isFormatSupported ( fmt ) )
+ {
+ //当前使用设备是否支持
+ pline() << "output cant support" << fmt;
+ fmt = usingOutput.nearestFormat ( fmt ); //转换为最接近格式
+ pline() << "use format" << fmt;
+ }
+
+ manager.outputAudioFormat() = fmt;
+
+ manager.startOutput();
+#if QT_VERSION > QT_VERSION_CHECK(5,0,0)
+
+ //默认是静音的。
+ manager.outputManager()->setVolume ( mVolume );
+#endif
+
+ //不响,音频输出设备接受顺序的间隔的输出,不接受一股脑输出。
+ //manager.write ( bytes );
+ //OK, 达到QSound效果。
+ mWavInput.start();
+}
+
+void QQtWavSoundEffect::stop()
+{
+ //如果正在播放,先关闭
+ if ( mIOInput )
+ {
+ mWavInput.stop();
+ manager.stopOutput();
+ disconnect ( mIOInput, SIGNAL ( readyRead() ),
+ this, SLOT ( readyRead() ) );
+ mIOInput = NULL;
+ }
+
+ mLooping = 1;
+ mDataSize = 0;
+}
+
+void QQtWavSoundEffect::setVolume ( qreal volume )
+{
+ mVolume = volume;
+#if QT_VERSION > QT_VERSION_CHECK(5,0,0)
+
+ manager.outputManager()->setVolume ( mVolume );
+#endif
+}
+
+int QQtWavSoundEffect::loops() const { return mLoops; }
+
+int QQtWavSoundEffect::loopsRemaining() const
+{
+ return mLoops - mLooping;
+}
+
+void QQtWavSoundEffect::setLoops ( int loops )
+{
+ mLoops = loops;
+}
+
+void QQtWavSoundEffect::readyRead()
+{
+ QByteArray bytes = mIOInput->readAll();
+ //pline() << bytes.size();
+ manager.write ( bytes );
+
+ mDataSize += bytes.size();
+
+ if ( mDataSize == mWavInput.fileDataSize() )
+ {
+ int loop = mLooping;
+
+ if ( loop < loops() )
+ play ( mSourceFile );
+
+ mLooping = loop + 1;
+ }
+}
+
+QQtWavSoundEffect* QQtWavSound ( QString localFile )
+{
+ if ( !localFile.isEmpty() )
+ QQtWavSoundEffect::Instance ( )->play ( localFile );
+
+ return QQtWavSoundEffect::Instance();
+}
+
diff --git a/src/multimedia/qqtwavsoundeffect.h b/src/multimedia/qqtwavsoundeffect.h
new file mode 100644
index 00000000..b9501231
--- /dev/null
+++ b/src/multimedia/qqtwavsoundeffect.h
@@ -0,0 +1,80 @@
+#ifndef QQTAUDIOEFFECT_H
+#define QQTAUDIOEFFECT_H
+
+
+#include
+
+#include
+#include
+/*
+ * QQtWavSoundEffect = QSoundEffect + QSound +...
+ * QQtWavSoundEffect支持从wav获取声音并输出,弥补QSoundEffect(+他的高级点的封装QSound)不能支持选择设备的缺失。
+ * QQtWavSoundEffect默认使用默认输出设备。
+ */
+class QQTSHARED_EXPORT QQtWavSoundEffect : public QObject
+{
+ Q_OBJECT
+
+public:
+ //这样做的目的,在于使用一个实例去播放音效。
+ //如果是个临时变量,函数执行返回了,但是还没播放完,甚至还没来得及开始呢,这时,播放不出来的。
+ static QQtWavSoundEffect* Instance ( QObject* parent = nullptr );
+
+ explicit QQtWavSoundEffect ( QObject* parent = nullptr );
+ ~QQtWavSoundEffect() {
+ stop();
+ }
+
+ //设置设备以后,不需要每次都设置
+ //更换设备不会引发播放更改,只会更改内部设备记录。调用play才会导致播放更改。
+ void setOutputDevice ( const QAudioDeviceInfo& output = QAudioDeviceInfo() );
+
+ void useDefaultOutputDevice();
+
+ void useCustomOutputDevice ( const QAudioDeviceInfo& output );
+
+ void play ( QString localFile );
+
+ void stop();
+
+ //设置声音以后,不需要每次都要设置。
+ void setVolume ( qreal volume );
+
+ //设置loop会保存下来,不需要每次设置。
+ int loops() const;
+ int loopsRemaining() const;
+ void setLoops ( int loops );
+
+ //设置读文件的时钟快慢(硬盘快,时钟快,每次读的少;硬盘慢,时钟慢,每次读的多)
+ //默认使用 macOS SSD 20ms
+ //Windows上,机械硬盘,可能会延迟,可以设置100ms。
+ void setTimerInterval ( int millSecond = 20 ) {
+ mWavInput.setTimerInterval ( millSecond );
+ }
+
+private slots:
+ void readyRead();
+
+private:
+ //不需要额外初始化的地方
+ //mingw32 5.3 静态成员不准导出?作为静态类这块编译出现错误
+ //error: definition of static data member 'QQtWavSoundEffect::msInstance' of dllimport'd class
+ //这个已经查出来了,在qqt_header.pri有一个WIN64的宏缺失,导致QQT_STATIC_LIBRARY缺失,引发QQt在QQTSHAREDEXPORT=import下编译,所以引发这个变量重新定义的错误,而报错是在导入的类里面定义了静态成员,也就是说导入类不准许静态成员的定义初始化代码出现,引入类的静态成员在自己的实现文件里出现了定义。变量重定义了。
+ static QQtWavSoundEffect* msInstance;
+
+ QQtWavAudioInput mWavInput;
+ QIODevice* mIOInput;
+ QQtAudioManager manager;
+ QString mSourceFile;
+ int mDataSize;
+ //volume会被记住。
+ qreal mVolume;
+ int mLoops;
+ int mLooping;
+};
+
+//在使用QQtWavSound等函数之前,调用类的instance函数,+parent 初始化一下实例。
+//=QSound::play()
+QQTSHARED_EXPORT QQtWavSoundEffect* QQtWavSound ( QString localFile = "" );
+
+#endif // QQTAUDIOEFFECT_H
diff --git a/src/qqt_3rdparty.pri b/src/qqt_3rdparty.pri
index 198e185f..032dd5e4 100644
--- a/src/qqt_3rdparty.pri
+++ b/src/qqt_3rdparty.pri
@@ -122,6 +122,11 @@ contains (DEFINES, __MULTIMEDIA__) {
$$PWD/multimedia/dmmu/jz_cim.h \
$$PWD/multimedia/dmmu/graphics.h \
$$PWD/multimedia/dmmu/hal.h
+
+ #logic video manager
+ SOURCES += $$PWD/multimedia/qqtlogicvideomanager.cpp
+ HEADERS += $$PWD/multimedia/qqtlogicvideomanager.h
+
SOURCES += $$PWD/multimedia/qqtlogicpreviewwidget.cpp
HEADERS += $$PWD/multimedia/qqtlogicpreviewwidget.h
FORMS += $$PWD/multimedia/qqtlogicpreviewwidget.ui
diff --git a/src/qqt_header.pri b/src/qqt_header.pri
index 790b858f..f060d7a2 100644
--- a/src/qqt_header.pri
+++ b/src/qqt_header.pri
@@ -33,6 +33,7 @@ defineTest(add_include_QQt){
#multimedia
command += $${header_path}/multimedia
command += $${header_path}/multimedia/dmmu
+ command += $${header_path}/multimedia/libqwav
#charts
command += $${header_path}/charts
@@ -219,6 +220,22 @@ defineTest(add_defines_QQt){
contains (DEFINES, __MULTIMEDIA__) {
QT += multimedia
+ #AUDIO MODULE
+ #depend on libqwav
+ DEFINES += __QQTAUDIOSUPPORT__
+ contains(DEFINES, __QQTAUDIOSUPPORT__) {
+ win32 {
+ contains (DEFINES, QQT_LIBRARY) {
+ DEFINES += LIBQWAV_LIBRARY
+ } else:contains (DEFINES, QQT_STATIC_LIBRARY) {
+ DEFINES += LIBQWAV_STATIC_LIBRARY
+ } else { }
+ }
+ }
+
+ #VIDEO MODULE
+ DEFINES += __QQTVIDEOSUPPORT__
+
#LOGIC CAMERA PREVIEW
#depend on dmmu
DEFINES += __LOGICCAMERAMODULE__
diff --git a/src/qqt_source.pri b/src/qqt_source.pri
index 0f5cbb88..701dca61 100644
--- a/src/qqt_source.pri
+++ b/src/qqt_source.pri
@@ -36,10 +36,12 @@ contains (DEFINES, __WIN__) {
#core
SOURCES += \
$$PWD/core/qqtcore.cpp \
+ $$PWD/core/qqtorderedmap.cpp \
$$PWD/core/qqtdictionary.cpp \
$$PWD/core/qqtobjectmanager.cpp
HEADERS += \
$$PWD/core/qqtcore.h \
+ $$PWD/core/qqtorderedmap.h \
$$PWD/core/qqtdictionary.h \
$$PWD/core/qqtobjectmanager.h
@@ -200,8 +202,27 @@ contains (DEFINES, __MULTIMEDIA__) {
}
#audio
- SOURCES += $$PWD/multimedia/qqtaudiomanager.cpp
- HEADERS += $$PWD/multimedia/qqtaudiomanager.h
+ contains (DEFINES, __QQTAUDIOSUPPORT__){
+ SOURCES += $$PWD/multimedia/qqtaudiomanager.cpp
+ HEADERS += $$PWD/multimedia/qqtaudiomanager.h
+
+ #wav audio
+ SOURCES += $$PWD/multimedia/libqwav/libqwav.cpp
+ HEADERS += $$PWD/multimedia/libqwav/libqwav.h
+ HEADERS += $$PWD/multimedia/libqwav/libqwav_global.h
+ SOURCES += $$PWD/multimedia/qqtwavaudiomanager.cpp
+ HEADERS += $$PWD/multimedia/qqtwavaudiomanager.h
+ SOURCES += $$PWD/multimedia/qqtwavsoundeffect.cpp
+ HEADERS += $$PWD/multimedia/qqtwavsoundeffect.h
+ }
+
+ #video
+ contains (DEFINES, __QQTVIDEOSUPPORT__){
+ SOURCES += $$PWD/multimedia/qqtcamera.cpp
+ HEADERS += $$PWD/multimedia/qqtcamera.h
+ SOURCES += $$PWD/multimedia/qqtvideomanager.cpp
+ HEADERS += $$PWD/multimedia/qqtvideomanager.h
+ }
}
diff --git a/src/sql/qqtsql.cpp b/src/sql/qqtsql.cpp
index 54b0bcba..26b18a4b 100644
--- a/src/sql/qqtsql.cpp
+++ b/src/sql/qqtsql.cpp
@@ -6,59 +6,59 @@ QSqlDatabase newDatabaseConnection()
{
QUuid uuid = QUuid::createUuid();
//qDebug() << uuid.toString();
- return QSqlDatabase::addDatabase(DB_TYPE, uuid.toString());
+ return QSqlDatabase::addDatabase ( DB_TYPE, uuid.toString() );
}
//opened
//useDatabase
-void setDatabaseName(QSqlDatabase& db, QString dbName)
+void setDatabaseName ( QSqlDatabase& dbinst, QString dbName )
{
- if (db.isOpen())
- db.close();
+ if ( dbinst.isOpen() )
+ dbinst.close();
- db.setDatabaseName(QString("%1/%2").arg(DB_PATH).arg(dbName));
+ dbinst.setDatabaseName ( QString ( "%1" ).arg ( dbName ) );
- if (!db.open())
+ if ( !dbinst.open() )
{
- QMessageBox::warning(0, QObject::tr("QSQLITE %1 Error").arg(db.databaseName()),
- db.lastError().text());
+ QMessageBox::warning ( 0, QObject::tr ( "QSQLITE %1 Error" ).arg ( dbinst.databaseName() ),
+ dbinst.lastError().text() );
return;
}
}
-void openDatabase(QSqlDatabase& db)
+void openDatabase ( QSqlDatabase& dbinst )
{
- if (db.isOpen())
+ if ( dbinst.isOpen() )
return;
- if (!db.open())
+ if ( !dbinst.open() )
{
- QMessageBox::warning(0, QObject::tr("QSQLITE %1 Error").arg(db.databaseName()),
- db.lastError().text());
+ QMessageBox::warning ( 0, QObject::tr ( "QSQLITE %1 Error" ).arg ( dbinst.databaseName() ),
+ dbinst.lastError().text() );
return;
}
}
-void closeDatabase(QSqlDatabase& db)
+void closeDatabase ( QSqlDatabase& dbinst )
{
- db.close();
+ dbinst.close();
}
-void useDatabase(QSqlDatabase& db, QString dbName)
+void useDatabase ( QSqlDatabase& dbinst, QString dbName )
{
- setDatabaseName(db, dbName);
+ setDatabaseName ( dbinst, dbName );
}
-void deleteDatabaseConnection(QString connectionName)
+void deleteDatabaseConnection ( QString connectionName )
{
- QSqlDatabase::removeDatabase(connectionName);
+ QSqlDatabase::removeDatabase ( connectionName );
}
-void deleteDatabaseConnection(QSqlDatabase &db)
+void deleteDatabaseConnection ( QSqlDatabase& dbinst )
{
- QString connectionName = db.connectionName();
- deleteDatabaseConnection(connectionName);
+ QString connectionName = dbinst.connectionName();
+ deleteDatabaseConnection ( connectionName );
}
diff --git a/src/sql/qqtsql.h b/src/sql/qqtsql.h
index 46b9c795..fe86148a 100644
--- a/src/sql/qqtsql.h
+++ b/src/sql/qqtsql.h
@@ -55,16 +55,9 @@ enum
};
#define DB_TYPE "QSQLITE"
-#define DB_PATH "./db"
-
#define DB_PINYIN "PinYin.db"
#define DB_MANAGER "Manager.db"
#define DB_EVENT "SysEvent.db"
-#define DB_METHOD_PATH "Method"
-#define DB_DATA_PATH "Data"
-#define DB_QQT "System.db"
-#define DB_USER "User.db"
-#define DB_DATA "Data.db"
#define TABLE_USERINFO "User"
#define TABLE_AUTHORITY "Authority"
@@ -81,14 +74,14 @@ typedef QSqlDatabase QQtSqlDatabaseConnection;
QQTSHARED_EXPORT QSqlDatabase newDatabaseConnection();
/*已经将数据库打开,不必重复打开*/
-QQTSHARED_EXPORT void setDatabaseName(QSqlDatabase& db, QString dbName);
+QQTSHARED_EXPORT void setDatabaseName ( QSqlDatabase& dbinst, QString dbName );
//=setDatabaseName
-QQTSHARED_EXPORT void useDatabase(QSqlDatabase& db, QString dbName);
+QQTSHARED_EXPORT void useDatabase ( QSqlDatabase& dbinst, QString dbName );
-QQTSHARED_EXPORT void openDatabase(QSqlDatabase& db);
-QQTSHARED_EXPORT void closeDatabase(QSqlDatabase& db);
+QQTSHARED_EXPORT void openDatabase ( QSqlDatabase& dbinst );
+QQTSHARED_EXPORT void closeDatabase ( QSqlDatabase& dbinst );
-QQTSHARED_EXPORT void deleteDatabaseConnection(QString connectionName);
-QQTSHARED_EXPORT void deleteDatabaseConnection(QSqlDatabase& db);
+QQTSHARED_EXPORT void deleteDatabaseConnection ( QString connectionName );
+QQTSHARED_EXPORT void deleteDatabaseConnection ( QSqlDatabase& dbinst );
#endif // QQTSQLDEFINE_H
diff --git a/src/widgets/qqtwidgets.h b/src/widgets/qqtwidgets.h
index 5474f5ac..0b7acadd 100644
--- a/src/widgets/qqtwidgets.h
+++ b/src/widgets/qqtwidgets.h
@@ -50,7 +50,6 @@ typedef struct QQTSHARED_EXPORT tagBtnIconTable
QString& operator [] ( int index );
} TBtnIconTable;
-
QQTSHARED_EXPORT void moveCenter ( QWidget* w );
QQTSHARED_EXPORT void moveRight ( QWidget* w );
QQTSHARED_EXPORT void moveFull ( QWidget* w );
diff --git a/test/giftest/giftestdialog.cpp b/test/giftest/giftestdialog.cpp
index bbd13e1a..e64ea2c9 100644
--- a/test/giftest/giftestdialog.cpp
+++ b/test/giftest/giftestdialog.cpp
@@ -32,9 +32,9 @@ GifTestDialog::GifTestDialog ( QWidget* parent ) :
pline() << res ( "../waiting.gif" );
pline() << QDir ( "." ).relativeFilePath ( "skin/yun.png" );
pline() << QDir ( res ( "../waiting.gif" ) ).absolutePath();
- ui->labelGif->setGifFile ( skin ( "waiting.gif" ) );
- ui->widgetGif->setGifFile ( skin ( "waiting.gif" ) );
- ui->widgetQQt->setPixmap ( skin ( "yun.png" ) );
+ ui->labelGif->setGifFile ( conf_skin ( "waiting.gif" ) );
+ ui->widgetGif->setGifFile ( conf_skin ( "waiting.gif" ) );
+ ui->widgetQQt->setPixmap ( conf_skin ( "yun.png" ) );
pline() << QMovie::supportedFormats();
}
diff --git a/test/osdtest/mainwindow.cpp b/test/osdtest/mainwindow.cpp
index 102f4cee..03de3b6a 100644
--- a/test/osdtest/mainwindow.cpp
+++ b/test/osdtest/mainwindow.cpp
@@ -7,7 +7,7 @@ MainWindow::MainWindow ( QWidget* parent ) :
ui ( new Ui::MainWindow )
{
ui->setupUi ( this );
- ui->widget_2->setPixmap ( qrc ( "a.png" ) );
+ ui->widget_2->setPixmap ( conf_qrc ( "a.png" ) );
}
MainWindow::~MainWindow()
diff --git a/test/svgtest/mainwindow.cpp b/test/svgtest/mainwindow.cpp
index 259fb045..5eefd707 100644
--- a/test/svgtest/mainwindow.cpp
+++ b/test/svgtest/mainwindow.cpp
@@ -13,29 +13,29 @@ MainWindow::MainWindow ( QWidget* parent ) :
ui ( new Ui::MainWindow )
{
ui->setupUi ( this );
- QString svg = QString ( qrc ( "aa.svg" ) );
+ QString svg = QString ( conf_qrc ( "aa.svg" ) );
ui->w->setSvgFile ( svg );
- ui->b0->iconTable() [BTN_NORMAL] = qrc ( "bt_stir.svg" );
- ui->b0->iconTable() [BTN_HOVER] = qrc ( "bt_stir.svg" );
- ui->b0->iconTable() [BTN_PRESS] = qrc ( "bt_stir_press.svg" );
+ ui->b0->iconTable() [BTN_NORMAL] = conf_qrc ( "bt_stir.svg" );
+ ui->b0->iconTable() [BTN_HOVER] = conf_qrc ( "bt_stir.svg" );
+ ui->b0->iconTable() [BTN_PRESS] = conf_qrc ( "bt_stir_press.svg" );
ui->b0->renderToVariable();
- ui->c0->iconTable() [BTN_NORMAL] = qrc ( "bt_stir.svg" );
- ui->c0->iconTable() [BTN_HOVER] = qrc ( "bt_stir.svg" );
- ui->c0->iconTable() [BTN_PRESS] = qrc ( "bt_stir_press.svg" );
+ ui->c0->iconTable() [BTN_NORMAL] = conf_qrc ( "bt_stir.svg" );
+ ui->c0->iconTable() [BTN_HOVER] = conf_qrc ( "bt_stir.svg" );
+ ui->c0->iconTable() [BTN_PRESS] = conf_qrc ( "bt_stir_press.svg" );
ui->c0->renderToVariable();
- ui->r0->iconTable() [BTN_NORMAL] = qrc ( "bt_stir.svg" );
- ui->r0->iconTable() [BTN_HOVER] = qrc ( "bt_stir.svg" );
- ui->r0->iconTable() [BTN_PRESS] = qrc ( "bt_stir_press.svg" );
+ ui->r0->iconTable() [BTN_NORMAL] = conf_qrc ( "bt_stir.svg" );
+ ui->r0->iconTable() [BTN_HOVER] = conf_qrc ( "bt_stir.svg" );
+ ui->r0->iconTable() [BTN_PRESS] = conf_qrc ( "bt_stir_press.svg" );
ui->r0->renderToVariable();
- ui->r1->iconTable() [BTN_NORMAL] = qrc ( "bt_stir.svg" );
- ui->r1->iconTable() [BTN_HOVER] = qrc ( "bt_stir.svg" );
- ui->r1->iconTable() [BTN_PRESS] = qrc ( "bt_stir_press.svg" );
+ ui->r1->iconTable() [BTN_NORMAL] = conf_qrc ( "bt_stir.svg" );
+ ui->r1->iconTable() [BTN_HOVER] = conf_qrc ( "bt_stir.svg" );
+ ui->r1->iconTable() [BTN_PRESS] = conf_qrc ( "bt_stir_press.svg" );
ui->r1->renderToVariable();
- ui->p0->setSvgFile ( qrc ( "bk_progress_background.svg" ),
- qrc ( "bk_progress_trunk.svg" ) );
+ ui->p0->setSvgFile ( conf_qrc ( "bk_progress_background.svg" ),
+ conf_qrc ( "bk_progress_trunk.svg" ) );
ui->p0->setRange ( 0, 100 );
ui->p0->setValue ( 60 );
diff --git a/test/videotest/AppRoot/skin/default.qss b/test/videotest/AppRoot/skin/default.qss
new file mode 100644
index 00000000..09e37969
--- /dev/null
+++ b/test/videotest/AppRoot/skin/default.qss
@@ -0,0 +1,24 @@
+/*spinbox 抬起样式*/
+QTimeEdit::up-button,QDoubleSpinBox::up-button,QSpinBox::up-button {
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button,QDoubleSpinBox::down-button,QSpinBox::down-button {
+ subcontrol-origin:border;
+ subcontrol-position:left;
+ width: 12px;
+}
+
+/*按钮按下样式*/
+QTimeEdit::up-button:pressed,QDoubleSpinBox::up-button:pressed,QSpinBox::up-button:pressed{
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button:pressed,QDoubleSpinBox::down-button:pressed,QSpinBox::down-button:pressed,QSpinBox::down-button:pressed{
+ subcontrol-position:left;
+ width: 12px;
+}
diff --git a/test/videotest/android/AndroidManifest.xml b/test/videotest/android/AndroidManifest.xml
new file mode 100644
index 00000000..44733f0a
--- /dev/null
+++ b/test/videotest/android/AndroidManifest.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/videotest/android/res/drawable-hdpi/ic_launcher_round.png b/test/videotest/android/res/drawable-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..3e1aeefe
Binary files /dev/null and b/test/videotest/android/res/drawable-hdpi/ic_launcher_round.png differ
diff --git a/test/videotest/android/res/drawable-hdpi/icon.png b/test/videotest/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest/android/res/drawable-hdpi/icon.png differ
diff --git a/test/videotest/android/res/drawable-ldpi/ic_launcher_round.png b/test/videotest/android/res/drawable-ldpi/ic_launcher_round.png
new file mode 100644
index 00000000..66178784
Binary files /dev/null and b/test/videotest/android/res/drawable-ldpi/ic_launcher_round.png differ
diff --git a/test/videotest/android/res/drawable-ldpi/icon.png b/test/videotest/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest/android/res/drawable-ldpi/icon.png differ
diff --git a/test/videotest/android/res/drawable-mdpi/ic_launcher_round.png b/test/videotest/android/res/drawable-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..22d1ab6d
Binary files /dev/null and b/test/videotest/android/res/drawable-mdpi/ic_launcher_round.png differ
diff --git a/test/videotest/android/res/drawable-mdpi/icon.png b/test/videotest/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest/android/res/drawable-mdpi/icon.png differ
diff --git a/test/videotest/android/res/drawable-xhdpi/ic_launcher_round.png b/test/videotest/android/res/drawable-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest/android/res/drawable-xhdpi/ic_launcher_round.png differ
diff --git a/test/videotest/android/res/drawable-xxhdpi/ic_launcher_round.png b/test/videotest/android/res/drawable-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest/android/res/drawable-xxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest/android/res/drawable-xxxhdpi/ic_launcher_round.png b/test/videotest/android/res/drawable-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest/android/res/drawable-xxxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest/main.cpp b/test/videotest/main.cpp
new file mode 100644
index 00000000..219ca126
--- /dev/null
+++ b/test/videotest/main.cpp
@@ -0,0 +1,11 @@
+#include "mainwindow.h"
+#include
+
+int main ( int argc, char* argv[] )
+{
+ QQtApplication a ( argc, argv );
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/videotest/mainwindow.cpp b/test/videotest/mainwindow.cpp
new file mode 100644
index 00000000..d44793b4
--- /dev/null
+++ b/test/videotest/mainwindow.cpp
@@ -0,0 +1,141 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow ( QWidget* parent ) :
+ QMainWindow ( parent ),
+ ui ( new Ui::MainWindow )
+{
+ ui->setupUi ( this );
+
+ QVideoProbe* prob = new QVideoProbe ( this );
+ QCamera* camera = new QCamera ( QCameraInfo::defaultCamera() );
+ camera->setCaptureMode ( QCamera::CaptureVideo );
+ prob->setSource ( camera );
+ connect ( prob, SIGNAL ( videoFrameProbed ( const QVideoFrame& ) ),
+ this, SLOT ( slotTestProbe ( const QVideoFrame& ) ) );
+ connect ( ui->pushButton_3, SIGNAL ( released() ), camera, SLOT ( start() ) );
+
+ return;
+
+ input = new QQtVideoInput ( this );
+ pline() << input->defaultCamera();
+ pline() << input ->availableCameras();
+
+ QCameraInfo inf = input->defaultCamera();
+ ui->textBrowser->append ( QString ( "Camera:%1 [default]" ).arg ( inf.deviceName() ) );
+ ui->textBrowser->append ( QString ( " description:%1" ).arg ( inf.description() ) );
+ ui->textBrowser->append ( QString ( " position:%1" ).arg ( inf.position() ) );
+ ui->textBrowser->append ( QString ( " orientation:%1" ).arg ( inf.orientation() ) );
+ ui->textBrowser->append ( QString ( " isNull:%1" ).arg ( inf.isNull() ) );
+ ui->textBrowser->append ( "" );
+
+ QListIterator itor ( input->availableCameras() );
+ while ( itor.hasNext() )
+ {
+ const QCameraInfo& inf = itor.next();
+ ui->textBrowser->append ( QString ( "Camera:%1 [index]" ).arg ( inf.deviceName() ) );
+ ui->textBrowser->append ( QString ( " description:%1" ).arg ( inf.description() ) );
+ ui->textBrowser->append ( QString ( " position:%1" ).arg ( inf.position() ) );
+ ui->textBrowser->append ( QString ( " orientation:%1" ).arg ( inf.orientation() ) );
+ ui->textBrowser->append ( QString ( " isNull:%1" ).arg ( inf.isNull() ) );
+ ui->textBrowser->append ( "" );
+ }
+
+ pline() << input->viewFinderSettings().pixelFormat();
+ pline() << input->camera()->supportedViewfinderPixelFormats();
+ ui->textBrowser->append ( QString ( "Camera PixelFormat: [default]" ) );
+ ui->textBrowser->append ( QString ( " %1" ).arg ( input->viewFinderSettings().pixelFormat() ) );
+ QListIterator itor1 ( input->camera()->supportedViewfinderPixelFormats() );
+ while ( itor1.hasNext() )
+ {
+ const QVideoFrame::PixelFormat& fmt = itor1.next();
+ ui->textBrowser->append ( QString ( " %1 [index]" ).arg ( fmt ) );
+ }
+ ui->textBrowser->append ( "" );
+
+ connect ( input, SIGNAL ( readyRead ( QImage ) ), this, SLOT ( slotImageComing ( QImage ) ) );
+ connect ( input, SIGNAL ( readyReadCapture ( QImage ) ), this, SLOT ( slotCapture ( QImage ) ) );
+
+ //input2 = new QQtVideoInput ( this );
+ //connect ( input2, SIGNAL ( readyRead ( QImage ) ), this, SLOT ( slotImageComing2 ( QImage ) ) );
+
+ //QThread* thread = new QThread();
+ //input2->moveToThread ( thread );
+ //thread->start();
+
+ connect ( ui->pushButton_3, SIGNAL ( released() ), input, SLOT ( capture() ) );
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::slotImageComing ( QImage img )
+{
+ ui->qqtwidget->setPixmap ( img );
+}
+
+void MainWindow::slotImageComing2 ( QImage img )
+{
+ ui->qqtwidget_2->setPixmap ( img );
+ ui->qqtwidget_2->update();
+}
+
+void MainWindow::slotCapture ( QImage image )
+{
+ ui->qqtwidget_3->setPixmap ( image );
+}
+
+void MainWindow::slotTestProbe ( const QVideoFrame& frame )
+{
+ if ( !frame.isValid() )
+ return;
+
+ QVideoFrame cloneFrame ( frame );
+ /**
+ * frame 可读
+ */
+ if ( !cloneFrame.map ( QAbstractVideoBuffer::ReadOnly ) )
+ return;
+
+ return;
+
+ /**
+ * 处理frame
+ */
+
+ //Android下的视频格式是怎么回事?需要转换吗?
+
+ const QImage _image ( cloneFrame.bits(),
+ cloneFrame.width(),
+ cloneFrame.height(),
+ QVideoFrame::imageFormatFromPixelFormat ( cloneFrame.pixelFormat() ) );
+
+ //需要对水平方向反转。
+ //Windows,现在的图像保存能成功,直接显示,程序会异常退出。使用QImage的mirrored函数进行了水平翻转,可以正常显示。
+ //水平翻转是为了不崩溃,正常显示图像。必选。
+ //垂直翻转是为了上下显示正常。
+ const QImage image = _image.mirrored ( true, true );
+
+ /**
+ * frame 不可读
+ */
+ cloneFrame.unmap();
+
+ //emit readyRead ( image );
+ slotImageComing ( image );
+ return ;
+}
+
+void MainWindow::on_pushButton_clicked()
+{
+ input->start();
+ input2->start();
+}
+
+void MainWindow::on_pushButton_2_clicked()
+{
+ input->stop();
+ input2->stop();
+}
diff --git a/test/videotest/mainwindow.h b/test/videotest/mainwindow.h
new file mode 100644
index 00000000..26004c13
--- /dev/null
+++ b/test/videotest/mainwindow.h
@@ -0,0 +1,37 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow ( QWidget* parent = 0 );
+ ~MainWindow();
+
+public slots:
+ void slotImageComing ( QImage );
+ void slotImageComing2 ( QImage );
+ void slotCapture ( QImage );
+
+ void slotTestProbe ( const QVideoFrame& frame );
+private slots:
+ void on_pushButton_clicked();
+
+ void on_pushButton_2_clicked();
+
+private:
+ Ui::MainWindow* ui;
+
+ QQtVideoInput* input;
+ QQtVideoInput* input2;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/videotest/mainwindow.ui b/test/videotest/mainwindow.ui
new file mode 100644
index 00000000..dcb15597
--- /dev/null
+++ b/test/videotest/mainwindow.ui
@@ -0,0 +1,128 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 475
+ 343
+
+
+
+ videotest
+
+
+
+ -
+
+
+ 0
+
+
+
+ Camera Information
+
+
+
-
+
+
+
+
+
+
+ Preview
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Preview
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Stop
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Capture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+
+
+ QQtWidget
+ QWidget
+
+
+
+
+
+
diff --git a/test/videotest/videotest.pro b/test/videotest/videotest.pro
new file mode 100644
index 00000000..fa6d2c93
--- /dev/null
+++ b/test/videotest/videotest.pro
@@ -0,0 +1,67 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-10-06T08:16:10
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = videotest
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui
+
+include($${PWD}/../../multi-link/add_base_manager.pri)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+add_version(1,0,0,0)
+add_deploy()
+add_deploy_config($${PWD}/AppRoot)
+add_dependent_manager(QQt)
+#add_dependent_manager(QQtMediaExtention)
+system(touch main.cpp)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+equals(QSYS_PRIVATE, macOS) {
+ CONFIG += app_bundle
+}
+
+contains(QSYS_PRIVATE, Android|AndroidX86) {
+ CONFIG += mobility
+ MOBILITY =
+ DISTFILES += \
+ android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $${PWD}/android
+}
+
+message ($${TARGET} config $${CONFIG})
+message ($${TARGET} DEFINE $${DEFINES})
+message ($${TARGET} prelink $${QMAKE_PRE_LINK})
+message ($${TARGET} postlink $${QMAKE_POST_LINK})
diff --git a/test/videotest2/AppRoot/skin/default.qss b/test/videotest2/AppRoot/skin/default.qss
new file mode 100644
index 00000000..09e37969
--- /dev/null
+++ b/test/videotest2/AppRoot/skin/default.qss
@@ -0,0 +1,24 @@
+/*spinbox 抬起样式*/
+QTimeEdit::up-button,QDoubleSpinBox::up-button,QSpinBox::up-button {
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button,QDoubleSpinBox::down-button,QSpinBox::down-button {
+ subcontrol-origin:border;
+ subcontrol-position:left;
+ width: 12px;
+}
+
+/*按钮按下样式*/
+QTimeEdit::up-button:pressed,QDoubleSpinBox::up-button:pressed,QSpinBox::up-button:pressed{
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button:pressed,QDoubleSpinBox::down-button:pressed,QSpinBox::down-button:pressed,QSpinBox::down-button:pressed{
+ subcontrol-position:left;
+ width: 12px;
+}
diff --git a/test/videotest2/android/AndroidManifest.xml b/test/videotest2/android/AndroidManifest.xml
new file mode 100644
index 00000000..0a81f5c7
--- /dev/null
+++ b/test/videotest2/android/AndroidManifest.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/videotest2/android/res/drawable-hdpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..3e1aeefe
Binary files /dev/null and b/test/videotest2/android/res/drawable-hdpi/ic_launcher_round.png differ
diff --git a/test/videotest2/android/res/drawable-hdpi/icon.png b/test/videotest2/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest2/android/res/drawable-hdpi/icon.png differ
diff --git a/test/videotest2/android/res/drawable-ldpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-ldpi/ic_launcher_round.png
new file mode 100644
index 00000000..66178784
Binary files /dev/null and b/test/videotest2/android/res/drawable-ldpi/ic_launcher_round.png differ
diff --git a/test/videotest2/android/res/drawable-ldpi/icon.png b/test/videotest2/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest2/android/res/drawable-ldpi/icon.png differ
diff --git a/test/videotest2/android/res/drawable-mdpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..22d1ab6d
Binary files /dev/null and b/test/videotest2/android/res/drawable-mdpi/ic_launcher_round.png differ
diff --git a/test/videotest2/android/res/drawable-mdpi/icon.png b/test/videotest2/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest2/android/res/drawable-mdpi/icon.png differ
diff --git a/test/videotest2/android/res/drawable-xhdpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest2/android/res/drawable-xhdpi/ic_launcher_round.png differ
diff --git a/test/videotest2/android/res/drawable-xxhdpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest2/android/res/drawable-xxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest2/android/res/drawable-xxxhdpi/ic_launcher_round.png b/test/videotest2/android/res/drawable-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest2/android/res/drawable-xxxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest2/main.cpp b/test/videotest2/main.cpp
new file mode 100644
index 00000000..6ea22d25
--- /dev/null
+++ b/test/videotest2/main.cpp
@@ -0,0 +1,18 @@
+#include "mainwindow.h"
+#include
+
+int main ( int argc, char* argv[] )
+{
+
+ //高DPI下,需要支持
+#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
+ QApplication::setAttribute ( Qt::AA_EnableHighDpiScaling );
+ QApplication::setAttribute ( Qt::AA_UseHighDpiPixmaps );
+#endif
+
+ QQtApplication a ( argc, argv );
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/videotest2/mainwindow.cpp b/test/videotest2/mainwindow.cpp
new file mode 100644
index 00000000..a32e387d
--- /dev/null
+++ b/test/videotest2/mainwindow.cpp
@@ -0,0 +1,38 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow ( QWidget* parent ) :
+ QMainWindow ( parent ),
+ ui ( new Ui::MainWindow )
+{
+ ui->setupUi ( this );
+
+ manager = new QQtVideoManager ( this );
+ pline() << manager->availableCameras();
+
+ //设置输入
+ connect ( ui->pushButton, SIGNAL ( clicked ( bool ) ), manager, SLOT ( startInput() ) );
+ connect ( ui->pushButton_2, SIGNAL ( clicked ( bool ) ), manager, SLOT ( stopInput() ) );
+ connect ( ui->pushButton_3, SIGNAL ( clicked ( bool ) ), manager, SLOT ( capture() ) );
+
+ //设置输出
+ manager->viewFinder() = ui->qqtwidget;
+
+ //设置截图输出
+ //使用Wrapper建立信号和槽关系......
+ QQtVideoOutput* output1 = new QQtVideoOutput ( this );
+ output1->viewFinder() = ui->qqtwidget_2;
+
+ //建立输入、输出关系
+ connect ( manager, SIGNAL ( readyRead ( QImage ) ), manager, SLOT ( outputImage ( QImage ) ) );
+ connect ( manager, SIGNAL ( readyReadCapture ( QImage ) ), output1, SLOT ( setPixmap ( QImage ) ) );
+
+ //输入由页面控制,这里开启输出
+ manager->startOutput();
+ output1->start();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
diff --git a/test/videotest2/mainwindow.h b/test/videotest2/mainwindow.h
new file mode 100644
index 00000000..8fa58d7e
--- /dev/null
+++ b/test/videotest2/mainwindow.h
@@ -0,0 +1,24 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow ( QWidget* parent = 0 );
+ ~MainWindow();
+
+private:
+ Ui::MainWindow* ui;
+
+ QQtVideoManager* manager;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/videotest2/mainwindow.ui b/test/videotest2/mainwindow.ui
new file mode 100644
index 00000000..7f2e0559
--- /dev/null
+++ b/test/videotest2/mainwindow.ui
@@ -0,0 +1,111 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ videotest2
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+ 16777215
+ 40
+
+
+
+
+
+ 0
+ 0
+ 81
+ 31
+
+
+
+ Preview
+
+
+
+
+
+ 100
+ 0
+ 81
+ 31
+
+
+
+ Stop
+
+
+
+
+
+ 200
+ 0
+ 81
+ 31
+
+
+
+
+ 0
+ 0
+
+
+
+ Capture
+
+
+
+
+
+
+
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+
+
+ QQtWidget
+ QWidget
+
+
+
+
+
+
diff --git a/test/videotest2/videotest2.pro b/test/videotest2/videotest2.pro
new file mode 100644
index 00000000..c445affc
--- /dev/null
+++ b/test/videotest2/videotest2.pro
@@ -0,0 +1,67 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-10-06T08:16:10
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = videotest2
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui
+
+include($${PWD}/../../multi-link/add_base_manager.pri)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+add_version(1,0,0,0)
+add_deploy()
+add_deploy_config($${PWD}/AppRoot)
+add_dependent_manager(QQt)
+#add_dependent_manager(QQtMediaExtention)
+system(touch main.cpp)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+equals(QSYS_PRIVATE, macOS) {
+ CONFIG += app_bundle
+}
+
+contains(QSYS_PRIVATE, Android|AndroidX86) {
+ CONFIG += mobility
+ MOBILITY =
+ DISTFILES += \
+ android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $${PWD}/android
+}
+
+message ($${TARGET} config $${CONFIG})
+message ($${TARGET} DEFINE $${DEFINES})
+message ($${TARGET} prelink $${QMAKE_PRE_LINK})
+message ($${TARGET} postlink $${QMAKE_POST_LINK})
diff --git a/test/videotest3/AppRoot/skin/default.qss b/test/videotest3/AppRoot/skin/default.qss
new file mode 100644
index 00000000..09e37969
--- /dev/null
+++ b/test/videotest3/AppRoot/skin/default.qss
@@ -0,0 +1,24 @@
+/*spinbox 抬起样式*/
+QTimeEdit::up-button,QDoubleSpinBox::up-button,QSpinBox::up-button {
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button,QDoubleSpinBox::down-button,QSpinBox::down-button {
+ subcontrol-origin:border;
+ subcontrol-position:left;
+ width: 12px;
+}
+
+/*按钮按下样式*/
+QTimeEdit::up-button:pressed,QDoubleSpinBox::up-button:pressed,QSpinBox::up-button:pressed{
+ subcontrol-origin:border;
+ subcontrol-position:right;
+ width: 12px;
+}
+
+QTimeEdit::down-button:pressed,QDoubleSpinBox::down-button:pressed,QSpinBox::down-button:pressed,QSpinBox::down-button:pressed{
+ subcontrol-position:left;
+ width: 12px;
+}
diff --git a/test/videotest3/android/AndroidManifest.xml b/test/videotest3/android/AndroidManifest.xml
new file mode 100644
index 00000000..dcf0c1e4
--- /dev/null
+++ b/test/videotest3/android/AndroidManifest.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/videotest3/android/res/drawable-hdpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-hdpi/ic_launcher_round.png
new file mode 100644
index 00000000..3e1aeefe
Binary files /dev/null and b/test/videotest3/android/res/drawable-hdpi/ic_launcher_round.png differ
diff --git a/test/videotest3/android/res/drawable-hdpi/icon.png b/test/videotest3/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest3/android/res/drawable-hdpi/icon.png differ
diff --git a/test/videotest3/android/res/drawable-ldpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-ldpi/ic_launcher_round.png
new file mode 100644
index 00000000..66178784
Binary files /dev/null and b/test/videotest3/android/res/drawable-ldpi/ic_launcher_round.png differ
diff --git a/test/videotest3/android/res/drawable-ldpi/icon.png b/test/videotest3/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest3/android/res/drawable-ldpi/icon.png differ
diff --git a/test/videotest3/android/res/drawable-mdpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-mdpi/ic_launcher_round.png
new file mode 100644
index 00000000..22d1ab6d
Binary files /dev/null and b/test/videotest3/android/res/drawable-mdpi/ic_launcher_round.png differ
diff --git a/test/videotest3/android/res/drawable-mdpi/icon.png b/test/videotest3/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest3/android/res/drawable-mdpi/icon.png differ
diff --git a/test/videotest3/android/res/drawable-xhdpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-xhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..88ee6f7d
Binary files /dev/null and b/test/videotest3/android/res/drawable-xhdpi/ic_launcher_round.png differ
diff --git a/test/videotest3/android/res/drawable-xxhdpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-xxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..e5c37c2d
Binary files /dev/null and b/test/videotest3/android/res/drawable-xxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest3/android/res/drawable-xxxhdpi/ic_launcher_round.png b/test/videotest3/android/res/drawable-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 00000000..85e68717
Binary files /dev/null and b/test/videotest3/android/res/drawable-xxxhdpi/ic_launcher_round.png differ
diff --git a/test/videotest3/cameracontrollerform.cpp b/test/videotest3/cameracontrollerform.cpp
new file mode 100644
index 00000000..8cfca17a
--- /dev/null
+++ b/test/videotest3/cameracontrollerform.cpp
@@ -0,0 +1,37 @@
+#include "cameracontrollerform.h"
+#include "ui_cameracontrollerform.h"
+#include
+
+CameraControllerForm::CameraControllerForm ( QWidget* parent ) :
+ QWidget ( parent ),
+ ui ( new Ui::CameraControllerForm )
+{
+ ui->setupUi ( this );
+ ui->horizontalSlider->setRange ( 0, 10000 );
+ ui->horizontalSlider->setSingleStep ( 200 );
+}
+
+CameraControllerForm::~CameraControllerForm()
+{
+ delete ui;
+}
+
+void CameraControllerForm::on_radioButton_toggled ( bool checked )
+{
+ if ( checked )
+ emit isomodel ( false );
+ pline() << checked;
+}
+
+void CameraControllerForm::on_radioButton_2_toggled ( bool checked )
+{
+ if ( checked )
+ emit isomodel ( true );
+ pline() << checked;
+}
+
+void CameraControllerForm::on_horizontalSlider_valueChanged ( int value )
+{
+ pline() << value;
+ emit isovalue ( value );
+}
diff --git a/test/videotest3/cameracontrollerform.h b/test/videotest3/cameracontrollerform.h
new file mode 100644
index 00000000..0ca3034c
--- /dev/null
+++ b/test/videotest3/cameracontrollerform.h
@@ -0,0 +1,34 @@
+#ifndef CAMERACONTROLLERFORM_H
+#define CAMERACONTROLLERFORM_H
+
+#include
+
+namespace Ui {
+class CameraControllerForm;
+}
+
+class CameraControllerForm : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit CameraControllerForm ( QWidget* parent = 0 );
+ ~CameraControllerForm();
+
+signals:
+ //auto:true, manual:false
+ void isomodel ( bool );
+ void isovalue ( int );
+
+private slots:
+ void on_radioButton_toggled ( bool checked );
+
+ void on_radioButton_2_toggled ( bool checked );
+
+ void on_horizontalSlider_valueChanged ( int value );
+
+private:
+ Ui::CameraControllerForm* ui;
+};
+
+#endif // CAMERACONTROLLERFORM_H
diff --git a/test/videotest3/cameracontrollerform.ui b/test/videotest3/cameracontrollerform.ui
new file mode 100644
index 00000000..8479e585
--- /dev/null
+++ b/test/videotest3/cameracontrollerform.ui
@@ -0,0 +1,90 @@
+
+
+ CameraControllerForm
+
+
+
+ 0
+ 0
+ 152
+ 322
+
+
+
+ Form
+
+
+ -
+
+
+ 0
+
+
+
+ 曝光
+
+
+
-
+
+
-
+
+
+ ISO
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ ManuISO
+
+
+
+ -
+
+
+ AutoISO
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 225
+
+
+
+
+
+
+
+
+ 对焦
+
+
+
+
+ 白平衡
+
+
+
+
+
+
+
+
+
diff --git a/test/videotest3/main.cpp b/test/videotest3/main.cpp
new file mode 100644
index 00000000..6ea22d25
--- /dev/null
+++ b/test/videotest3/main.cpp
@@ -0,0 +1,18 @@
+#include "mainwindow.h"
+#include
+
+int main ( int argc, char* argv[] )
+{
+
+ //高DPI下,需要支持
+#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
+ QApplication::setAttribute ( Qt::AA_EnableHighDpiScaling );
+ QApplication::setAttribute ( Qt::AA_UseHighDpiPixmaps );
+#endif
+
+ QQtApplication a ( argc, argv );
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/videotest3/mainwindow.cpp b/test/videotest3/mainwindow.cpp
new file mode 100644
index 00000000..a582a0f1
--- /dev/null
+++ b/test/videotest3/mainwindow.cpp
@@ -0,0 +1,84 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow ( QWidget* parent ) :
+ QMainWindow ( parent ),
+ ui ( new Ui::MainWindow )
+{
+ ui->setupUi ( this );
+
+ manager = new QQtVideoManager ( this );
+
+ //设置输入
+ connect ( ui->pushButton, SIGNAL ( clicked ( bool ) ), manager, SLOT ( startInput() ) );
+ connect ( ui->pushButton_2, SIGNAL ( clicked ( bool ) ), manager, SLOT ( stopInput() ) );
+ connect ( ui->pushButton_3, SIGNAL ( clicked ( bool ) ), manager, SLOT ( capture() ) );
+
+ //设置输出
+ manager->viewFinder() = ui->qqtwidget;
+
+ //设置截图输出
+ //使用Wrapper建立信号和槽关系......
+ QQtVideoOutput* output1 = new QQtVideoOutput ( this );
+ output1->viewFinder() = ui->qqtwidget_2;
+
+ //建立输入、输出关系
+ connect ( manager, SIGNAL ( readyRead ( QImage ) ), manager, SLOT ( outputImage ( QImage ) ) );
+ connect ( manager, SIGNAL ( readyReadCapture ( QImage ) ), output1, SLOT ( setPixmap ( QImage ) ) );
+
+ //建立照相机图像控制关系
+ pline() << manager->expose()->supportedIsoSensitivities();
+ form = new CameraControllerForm();
+ form->show();
+ connect ( form, SIGNAL ( isovalue ( int ) ), manager->expose(), SLOT ( setManualIsoSensitivity ( int ) ) );
+ connect ( form, SIGNAL ( isomodel ( bool ) ), this, SLOT ( slotISOModelChanged ( bool ) ) );
+
+ //输入由页面控制,这里开启输出
+ manager->startOutput();
+ output1->start();
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::slotISOModelChanged ( bool iso )
+{
+ pline() << iso;
+ if ( iso )
+ {
+ manager->expose()->setAutoIsoSensitivity();
+ }
+ else
+ {
+
+ }
+}
+
+void MainWindow::moveEvent ( QMoveEvent* event )
+{
+ form->setGeometry ( geometry().left() - 140, geometry().top(), 120, geometry().height() );
+}
+
+void MainWindow::resizeEvent ( QResizeEvent* event )
+{
+ QSize size = event->size();
+ form->setFixedHeight ( size.height() );
+}
+
+
+void MainWindow::closeEvent ( QCloseEvent* event )
+{
+ form->close();
+}
+
+void MainWindow::showEvent ( QShowEvent* event )
+{
+ form->setGeometry ( geometry().left() - 140, geometry().top(), 120, geometry().height() );
+}
+
+void MainWindow::hideEvent ( QHideEvent* event )
+{
+ form->hide();
+}
diff --git a/test/videotest3/mainwindow.h b/test/videotest3/mainwindow.h
new file mode 100644
index 00000000..6e077dd0
--- /dev/null
+++ b/test/videotest3/mainwindow.h
@@ -0,0 +1,41 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow ( QWidget* parent = 0 );
+ ~MainWindow();
+
+public slots:
+ void slotISOModelChanged ( bool );
+
+private:
+ Ui::MainWindow* ui;
+
+ QQtVideoManager* manager;
+ CameraControllerForm* form;
+
+ // QWidget interface
+protected:
+ virtual void moveEvent ( QMoveEvent* event ) override;
+ virtual void resizeEvent ( QResizeEvent* event ) override;
+
+ // QWidget interface
+protected:
+ virtual void closeEvent ( QCloseEvent* event ) override;
+ virtual void showEvent ( QShowEvent* event ) override;
+ virtual void hideEvent ( QHideEvent* event ) override;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/videotest3/mainwindow.ui b/test/videotest3/mainwindow.ui
new file mode 100644
index 00000000..d391d503
--- /dev/null
+++ b/test/videotest3/mainwindow.ui
@@ -0,0 +1,105 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 400
+ 300
+
+
+
+ videotest2
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+ 16777215
+ 40
+
+
+
+
+
+ 10
+ 10
+ 71
+ 16
+
+
+
+ Preview
+
+
+
+
+
+ 100
+ 10
+ 80
+ 16
+
+
+
+ Stop
+
+
+
+
+
+ 200
+ 10
+ 80
+ 16
+
+
+
+ Capture
+
+
+
+
+
+
+
+
+
+ TopToolBarArea
+
+
+ false
+
+
+
+
+
+
+
+ QQtWidget
+ QWidget
+
+
+
+
+
+
diff --git a/test/videotest3/videotest3.pro b/test/videotest3/videotest3.pro
new file mode 100644
index 00000000..f3229f4f
--- /dev/null
+++ b/test/videotest3/videotest3.pro
@@ -0,0 +1,70 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-10-06T08:16:10
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = videotest3
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp \
+ cameracontrollerform.cpp
+
+HEADERS += \
+ mainwindow.h \
+ cameracontrollerform.h
+
+FORMS += \
+ mainwindow.ui \
+ cameracontrollerform.ui
+
+include($${PWD}/../../multi-link/add_base_manager.pri)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+add_version(1,0,0,0)
+add_deploy()
+add_deploy_config($${PWD}/AppRoot)
+add_dependent_manager(QQt)
+#add_dependent_manager(QQtMediaExtention)
+system(touch main.cpp)
+
+#-------------------------------------------------
+#用户工程配置
+#-------------------------------------------------
+equals(QSYS_PRIVATE, macOS) {
+ CONFIG += app_bundle
+}
+
+contains(QSYS_PRIVATE, Android|AndroidX86) {
+ CONFIG += mobility
+ MOBILITY =
+ DISTFILES += \
+ android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $${PWD}/android
+}
+
+message ($${TARGET} config $${CONFIG})
+message ($${TARGET} DEFINE $${DEFINES})
+message ($${TARGET} prelink $${QMAKE_PRE_LINK})
+message ($${TARGET} postlink $${QMAKE_POST_LINK})
diff --git a/test/voicetest/mainwindow.cpp b/test/voicetest/mainwindow.cpp
index d186a46c..57cc75f5 100644
--- a/test/voicetest/mainwindow.cpp
+++ b/test/voicetest/mainwindow.cpp
@@ -89,11 +89,11 @@ MainWindow::MainWindow ( QWidget* parent ) :
//e.play();
//响
- e.setSource ( QUrl::fromLocalFile ( res ( "9733.wav" ) ) );
+ e.setSource ( QUrl::fromLocalFile ( conf_res ( "9733.wav" ) ) );
//e.play();
//响
- //QSound::play ( res ( "9733.wav" ) );
+ //QSound::play ( conf_res ( "9733.wav" ) );
//响
//QApplication::beep();
diff --git a/test/voicetest2/AppRoot/res/9612.wav b/test/voicetest2/AppRoot/res/9612.wav
new file mode 100644
index 00000000..01fa1b13
Binary files /dev/null and b/test/voicetest2/AppRoot/res/9612.wav differ
diff --git a/test/voicetest2/AppRoot/res/9733.wav b/test/voicetest2/AppRoot/res/9733.wav
new file mode 100644
index 00000000..20a4c68f
Binary files /dev/null and b/test/voicetest2/AppRoot/res/9733.wav differ
diff --git a/test/voicetest2/AppRoot/res/9763.wav b/test/voicetest2/AppRoot/res/9763.wav
new file mode 100644
index 00000000..91b8faad
Binary files /dev/null and b/test/voicetest2/AppRoot/res/9763.wav differ
diff --git a/test/voicetest2/AppRoot/res/9767.wav b/test/voicetest2/AppRoot/res/9767.wav
new file mode 100644
index 00000000..be47993e
Binary files /dev/null and b/test/voicetest2/AppRoot/res/9767.wav differ
diff --git a/test/voicetest2/android/AndroidManifest.xml b/test/voicetest2/android/AndroidManifest.xml
new file mode 100644
index 00000000..6d919dad
--- /dev/null
+++ b/test/voicetest2/android/AndroidManifest.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/voicetest2/android/res/drawable-hdpi/ic_launcher.png b/test/voicetest2/android/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000..445bb11b
Binary files /dev/null and b/test/voicetest2/android/res/drawable-hdpi/ic_launcher.png differ
diff --git a/test/voicetest2/android/res/drawable-hdpi/icon.png b/test/voicetest2/android/res/drawable-hdpi/icon.png
new file mode 100644
index 00000000..e1aadcbd
Binary files /dev/null and b/test/voicetest2/android/res/drawable-hdpi/icon.png differ
diff --git a/test/voicetest2/android/res/drawable-ldpi/ic_launcher.png b/test/voicetest2/android/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 00000000..cb129452
Binary files /dev/null and b/test/voicetest2/android/res/drawable-ldpi/ic_launcher.png differ
diff --git a/test/voicetest2/android/res/drawable-ldpi/icon.png b/test/voicetest2/android/res/drawable-ldpi/icon.png
new file mode 100644
index 00000000..3eaa29bd
Binary files /dev/null and b/test/voicetest2/android/res/drawable-ldpi/icon.png differ
diff --git a/test/voicetest2/android/res/drawable-mdpi/ic_launcher.png b/test/voicetest2/android/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000..15876f47
Binary files /dev/null and b/test/voicetest2/android/res/drawable-mdpi/ic_launcher.png differ
diff --git a/test/voicetest2/android/res/drawable-mdpi/icon.png b/test/voicetest2/android/res/drawable-mdpi/icon.png
new file mode 100644
index 00000000..f35a8cb2
Binary files /dev/null and b/test/voicetest2/android/res/drawable-mdpi/icon.png differ
diff --git a/test/voicetest2/android/res/drawable-xhdpi/ic_launcher.png b/test/voicetest2/android/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000..3eaa29bd
Binary files /dev/null and b/test/voicetest2/android/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/test/voicetest2/android/res/drawable-xxhdpi/ic_launcher.png b/test/voicetest2/android/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 00000000..f35a8cb2
Binary files /dev/null and b/test/voicetest2/android/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/test/voicetest2/android/res/drawable-xxxhdpi/ic_launcher.png b/test/voicetest2/android/res/drawable-xxxhdpi/ic_launcher.png
new file mode 100644
index 00000000..e1aadcbd
Binary files /dev/null and b/test/voicetest2/android/res/drawable-xxxhdpi/ic_launcher.png differ
diff --git a/test/voicetest2/main.cpp b/test/voicetest2/main.cpp
new file mode 100644
index 00000000..c11c5e09
--- /dev/null
+++ b/test/voicetest2/main.cpp
@@ -0,0 +1,18 @@
+#include "mainwindow.h"
+#include
+#include
+#include
+
+int main ( int argc, char* argv[] )
+{
+ QQtApplication a ( argc, argv );
+
+ MainWindow w;
+ w.show();
+
+#ifdef __ANDROID__
+ w.showMaximized();
+#endif
+
+ return a.exec();
+}
diff --git a/test/voicetest2/mainwindow.cpp b/test/voicetest2/mainwindow.cpp
new file mode 100644
index 00000000..36075c47
--- /dev/null
+++ b/test/voicetest2/mainwindow.cpp
@@ -0,0 +1,598 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+MainWindow::MainWindow ( QWidget* parent ) :
+ QMainWindow ( parent ),
+ ui ( new Ui::MainWindow )
+{
+ ui->setupUi ( this );
+
+ connect ( &manager, SIGNAL ( readyRead() ), this, SLOT ( readyRead() ) );
+
+ connect ( &wavRecManager, SIGNAL ( readyRead() ), this, SLOT ( wavRecReadyRead() ) );
+ connect ( &wavFileManager, SIGNAL ( readyRead() ), this, SLOT ( wavFileReadyRead() ) );
+
+ QList ladInfo;
+ ladInfo = QAudioDeviceInfo::availableDevices ( QAudio::AudioInput );
+ QListIterator itor ( ladInfo );
+ pline() << "本机音频输入设备列表";
+
+ while ( itor.hasNext() )
+ pline() << itor.next().deviceName();
+
+ pline() << "默认输入设备" << QAudioDeviceInfo::defaultInputDevice().deviceName();
+ pline() << "输入设备详细信息";
+ itor.toFront();
+
+ while ( itor.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor.next();
+ pline() << adInfo.deviceName();
+ pline() << adInfo.supportedByteOrders();
+ pline() << adInfo.supportedChannelCounts();
+ pline() << adInfo.supportedCodecs();
+ pline() << adInfo.supportedSampleRates();
+ pline() << adInfo.supportedSampleSizes();
+ pline() << adInfo.supportedSampleTypes();
+ }
+
+
+ QList ladOutputInfo;
+ ladOutputInfo = QAudioDeviceInfo::availableDevices ( QAudio::AudioOutput );
+ QListIterator itor2 ( ladOutputInfo );
+ pline() << "本机音频输出设备列表";
+
+ while ( itor2.hasNext() )
+ pline() << itor2.next().deviceName();
+
+ pline() << "默认输出设备" << QAudioDeviceInfo::defaultOutputDevice().deviceName();
+ pline() << "输出设备详细信息";
+ itor2.toFront();
+
+ while ( itor2.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor2.next();
+ pline() << adInfo.deviceName();
+ pline() << adInfo.supportedByteOrders();
+ pline() << adInfo.supportedChannelCounts();
+ pline() << adInfo.supportedCodecs();
+ pline() << adInfo.supportedSampleRates();
+ pline() << adInfo.supportedSampleSizes();
+ pline() << adInfo.supportedSampleTypes();
+ }
+
+
+ pline() << "..........................";
+
+ connect ( ui->inputListWidget->selectionModel(), SIGNAL ( currentRowChanged ( QModelIndex, QModelIndex ) ),
+ this, SLOT ( currentInputRowChanged ( QModelIndex, QModelIndex ) ) );
+ connect ( ui->outputListWidget->selectionModel(), SIGNAL ( currentRowChanged ( QModelIndex, QModelIndex ) ),
+ this, SLOT ( currentOutputRowChanged ( QModelIndex, QModelIndex ) ) );
+
+// on_pushButton_2_clicked();
+// ui->inputListWidget->setCurrentRow ( 0 );
+// ui->outputListWidget->setCurrentRow ( 0 );
+// ui->inputListWidget->setFocus();
+
+ ui->inHS->setRange ( 0, 100 );
+ ui->inHS->setValue ( 100 );
+
+ ui->outHS->setRange ( 0, 100 );
+ ui->outHS->setValue ( 100 );
+
+ //pline() << QSoundEffect::supportedMimeTypes();
+
+ QSoundEffect e;
+ e.setLoopCount ( 1 );
+ e.setVolume ( 0.9f );
+ e.setMuted ( false );
+
+ //不响
+ QUrl u;
+ u.setUrl ( "http://xmdx.sc.chinaz.com/Files/DownLoad/sound1/201802/9733.wav" );
+ e.setSource ( u );
+ //e.play();
+
+ //响
+ e.setSource ( QUrl::fromLocalFile ( conf_res ( "9733.wav" ) ) );
+ //e.play();
+
+ //响
+ //QSound::play ( conf_res ( "9733.wav" ) );
+
+ //响
+ QQtWavSoundEffect e1;
+ //e1.play ( conf_res ( "9733.wav" ) );
+
+ //响
+ //QApplication::beep();
+
+ //建议初始化
+ QQtWavSoundEffect::Instance ( this );
+
+ //可以多次循环调用。
+ QQtWavSound ( conf_res ( "9733.wav" ) );
+
+ //QQtSleep ( 3000 );
+
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+QAudioDeviceInfo MainWindow::findInputAudioDeviceInfoByName ( QString devName )
+{
+ QList ladInfo;
+ ladInfo = QQtAudioManager::availableInputDevices();
+ QListIterator itor ( ladInfo );
+
+ while ( itor.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor.next();
+
+ if ( devName == adInfo.deviceName() )
+ return adInfo;
+ }
+}
+
+QAudioDeviceInfo MainWindow::findOutputAudioDeviceInfoByName ( QString devName )
+{
+ QList ladInfo;
+ ladInfo = QQtAudioManager::availableOutputDevices();
+ QListIterator itor ( ladInfo );
+
+ while ( itor.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor.next();
+
+ if ( devName == adInfo.deviceName() )
+ return adInfo;
+ }
+}
+
+
+void MainWindow::on_pushButton_2_clicked()
+{
+ ui->inputListWidget->clear();
+
+ QList ladInfo;
+ ladInfo = QQtAudioManager::availableInputDevices();
+ QListIterator itor ( ladInfo );
+ pline() << "本机音频输入设备列表";
+
+ while ( itor.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor.next();
+ pline() << adInfo.deviceName();
+ ui->inputListWidget->addItem ( adInfo.deviceName() );
+ }
+
+
+ ui->outputListWidget->clear();
+
+ QList ladOutputInfo;
+ ladOutputInfo = QQtAudioManager::availableOutputDevices();
+ QListIterator itor2 ( ladOutputInfo );
+ pline() << "本机音频输出设备列表";
+
+ while ( itor2.hasNext() )
+ {
+ QAudioDeviceInfo adInfo = itor2.next();
+ pline() << adInfo.deviceName();
+ ui->outputListWidget->addItem ( adInfo.deviceName() );
+ }
+
+}
+
+void MainWindow::currentInputRowChanged ( QModelIndex cur, QModelIndex )
+{
+ /*在清空设备列表时,clear函数,会调用多次这个函数。在这里用cur valid加以过滤,否则,程序会崩溃退出。*/
+ if ( !cur.isValid() )
+ return;
+
+ ui->inBit->clear();
+ ui->inChn->clear();
+ ui->intRate->clear();
+
+
+ QString name = cur.data().toString();
+ QAudioDeviceInfo dev = findInputAudioDeviceInfoByName ( name );
+
+ if ( dev.isNull() )
+ return;
+
+ QList size = dev.supportedSampleSizes();
+ QListIterator itor ( size );
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->inBit->addItem ( s0 );
+ }
+
+ itor = dev.supportedChannelCounts();
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->inChn->addItem ( s0 );
+ }
+
+ itor = dev.supportedSampleRates();
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->intRate->addItem ( s0 );
+ }
+
+}
+
+void MainWindow::currentOutputRowChanged ( QModelIndex cur, QModelIndex )
+{
+ if ( !cur.isValid() )
+ return;
+
+ ui->outBit->clear();
+ ui->outChn->clear();
+ ui->outRate->clear();
+
+
+ QString name = cur.data().toString();
+ QAudioDeviceInfo dev = findOutputAudioDeviceInfoByName ( name );
+
+ if ( dev.isNull() )
+ return;
+
+ QList size = dev.supportedSampleSizes();
+ QListIterator itor ( size );
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->outBit->addItem ( s0 );
+ }
+
+ itor = dev.supportedChannelCounts();
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->outChn->addItem ( s0 );
+ }
+
+ itor = dev.supportedSampleRates();
+
+ while ( itor.hasNext() )
+ {
+ QString s0 = QString::number ( itor.next() );
+ ui->outRate->addItem ( s0 );
+ }
+}
+
+/*
+ * 处理声音三要点
+ * 声音的格式 ,也就是声音三要素,输入一个、输出一个,manager对其分开管理,但是建议用户合并为一个置等。通道数、采样位宽、采样率
+ * 声音设备 ,输入一个、输出一个,manager管理start\stop等接口,manager内部的inputManager和outputManager负责其他接口。
+ * 声音设备的读写出入口 ,manager管理,包括可读信号和写入函数。
+*/
+void MainWindow::on_pushButton_clicked()
+{
+ /*这里是自定义输入、输出设备*/
+ QString name = QQtAudioManager::defaultInputDevice().deviceName();
+
+ if ( ui->inputListWidget->currentIndex().isValid() )
+ name = ui->inputListWidget->currentIndex().data().toString();
+
+ QAudioDeviceInfo dev = findInputAudioDeviceInfoByName ( name );
+
+ name = QQtAudioManager::defaultOutputDevice().deviceName();
+
+ if ( ui->outputListWidget->currentIndex().isValid() )
+ name = ui->outputListWidget->currentIndex().data().toString();
+
+ QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
+
+ /*使用默认输入、输出设备*/
+ //如果开启这段代码,页面上的输入、输出设备选择,就仅仅是个显示了,不具备操作能力。
+ /*
+ dev = QQtAudioManager::defaultInputDevice();
+ devOut = QQtAudioManager::defaultOutputDevice();
+ */
+
+ //把设备设进manager去
+ manager.inputDeviceInfo() = dev;
+ manager.outputDeviceInfo() = devOut;
+
+ //这里保证输入、输出使用格式相等 或者 不同
+ //如果格式不同,在mac电脑上本地输入输出设备是可以使用的,但是对于连接的语音蓝牙话筒,却是不可以使用的,原因未知。
+ //格式相同的时候,实在是太好用啦。
+ //这个建议默认就相同,但是,在QQtAudioManager当中,并没有直接将其相等处理,如果用户在readyRead槽函数里,可以更改采样率进行某些特殊处理。一般不需要差异处理的,相等就行了。
+// int inBit = ui->inBit->currentIndex().data().toInt();
+// int inChn = ui->inChn->currentIndex().data().toInt();
+// int inRate = ui->intRate->currentIndex().data().toInt();
+// QAudioFormat inFmt;
+// inFmt.setChannelCount ( inChn );
+// inFmt.setSampleSize ( inBit );
+// inFmt.setSampleRate ( inRate );
+// inFmt.setCodec ( "audio/pcm" );
+// manager.inputAudioFormat() = inFmt;
+
+ QAudioFormat outFmt = manager.outputDeviceInfo().preferredFormat();
+
+ int outBit = outFmt.sampleSize(), outChn = outFmt.channelCount(), outRate = outFmt.sampleRate();
+
+ if ( ui->outBit->currentIndex().isValid() )
+ outBit = ui->outBit->currentIndex().data().toInt();
+
+ if ( ui->outChn->currentIndex().isValid() )
+ outChn = ui->outChn->currentIndex().data().toInt();
+
+ if ( ui->outRate->currentIndex().isValid() )
+ outRate = ui->outRate->currentIndex().data().toInt();
+
+ outFmt.setChannelCount ( outChn );
+ outFmt.setSampleSize ( outBit );
+ outFmt.setSampleRate ( outRate );
+ outFmt.setCodec ( "audio/pcm" );
+
+ manager.inputAudioFormat() = outFmt;
+ manager.outputAudioFormat() = outFmt;
+
+ pline() << "in prefer" << dev.preferredFormat().channelCount() << dev.preferredFormat().sampleRate() <<
+ dev.preferredFormat().sampleSize();
+
+ pline() << "out prefer" << devOut.preferredFormat().channelCount() << devOut.preferredFormat().sampleRate() <<
+ devOut.preferredFormat().sampleSize();
+
+ pline() << "in" << manager.inputAudioFormat().channelCount() << manager.inputAudioFormat().sampleRate() <<
+ manager.inputAudioFormat().sampleSize();
+
+ pline() << "out" << manager.outputAudioFormat().channelCount() << manager.outputAudioFormat().sampleRate() <<
+ manager.outputAudioFormat().sampleSize();
+
+ manager.startInput();
+ manager.startOutput();
+}
+
+void MainWindow::readyRead()
+{
+ //这里是用户实现,任何用户希望做的事情,都在这里做完。
+ //可以 录音、保存文件
+ //可以 直接播放
+ //可以 混音 +保存 +播放...
+ //可以 消音
+ //可以 将pcm转换为其他格式音频
+ //可以 降噪
+ //可以 ...
+ //ptime();//11-12ms 是个10ms timer
+ QByteArray bytes = manager.readAll();
+ manager.write ( bytes );
+}
+
+void MainWindow::wavRecReadyRead()
+{
+ QByteArray bytes = wavRecManager.readAll();
+ //pline() << "recording:" << bytes.size();
+ wavFileManager.write ( bytes );
+}
+
+void MainWindow::wavFileReadyRead()
+{
+ QByteArray bytes = wavFileManager.readAll();
+ //pline() << "playing:" << bytes.size();
+ wavRecManager.write ( bytes );
+}
+
+void MainWindow::on_pushButton_3_clicked()
+{
+ manager.stopInput();
+ manager.stopOutput();
+}
+
+/*bug:Qt 设置音量会报错退出*/
+void MainWindow::on_inHS_valueChanged ( int value )
+{
+ return;
+
+ if ( !manager.inputDevice() )
+ return;
+
+ qreal linearVolume;
+// qreal linearVolume = QAudio::convertVolume ( value / qreal ( 100.0 ),
+// QAudio::LogarithmicVolumeScale,
+// QAudio::LinearVolumeScale );
+
+// pline() << "输入音量" << value << linearVolume << qRound ( linearVolume * 100 ) ;
+ manager.inputManager()->setVolume ( qRound ( linearVolume * 100 ) );
+}
+
+/*bug:Qt 设置音量会报错退出*/
+void MainWindow::on_outHS_valueChanged ( int value )
+{
+ return;
+
+ if ( !manager.outputDevice() )
+ return;
+
+ qreal vol = qreal ( value ) / 100;
+ pline() << "输出音量" << vol ;
+ manager.outputManager()->setVolume ( vol );
+}
+
+void MainWindow::on_pushButton_4_clicked()
+{
+ manager.inputAudioFormat() = QQtAudioManager::defaultOutputDevice().preferredFormat();
+ manager.outputAudioFormat() = QQtAudioManager::defaultOutputDevice().preferredFormat();
+
+ pline() << "in prefer" << QQtAudioManager::defaultInputDevice().preferredFormat().channelCount() <<
+ QQtAudioManager::defaultInputDevice().preferredFormat().sampleRate() <<
+ QQtAudioManager::defaultInputDevice().preferredFormat().sampleSize();
+
+ pline() << "out prefer" << QQtAudioManager::defaultOutputDevice().preferredFormat().channelCount() <<
+ QQtAudioManager::defaultOutputDevice().preferredFormat().sampleRate() <<
+ QQtAudioManager::defaultOutputDevice().preferredFormat().sampleSize();
+
+ pline() << "in" << manager.inputAudioFormat().channelCount() << manager.inputAudioFormat().sampleRate() <<
+ manager.inputAudioFormat().sampleSize();
+
+ pline() << "out" << manager.outputAudioFormat().channelCount() << manager.outputAudioFormat().sampleRate() <<
+ manager.outputAudioFormat().sampleSize();
+
+ manager.startDefaultInput();
+ manager.startDefaultOutput();
+}
+
+void MainWindow::on_pushButton_5_clicked()
+{
+ QString name = QQtAudioManager::defaultOutputDevice().deviceName();
+
+ if ( ui->outputListWidget->currentIndex().isValid() )
+ name = ui->outputListWidget->currentIndex().data().toString();
+
+ QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
+
+ QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
+ QQtWavSound()->setLoops ( 3 );
+ QQtWavSound ( conf_res ( "9733.wav" ) );
+}
+
+void MainWindow::on_pushButton_6_clicked()
+{
+ QString name = QQtAudioManager::defaultOutputDevice().deviceName();
+
+ if ( ui->outputListWidget->currentIndex().isValid() )
+ name = ui->outputListWidget->currentIndex().data().toString();
+
+ QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
+
+ QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
+ QQtWavSound ( conf_res ( "9763.wav" ) );
+ //QSound::play ( conf_res("9763.wav"));
+}
+
+void MainWindow::on_pushButton_7_clicked()
+{
+ QString name = QQtAudioManager::defaultOutputDevice().deviceName();
+
+ if ( ui->outputListWidget->currentIndex().isValid() )
+ name = ui->outputListWidget->currentIndex().data().toString();
+
+ QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
+
+ QQtWavSoundEffect::Instance()->useCustomOutputDevice ( devOut );
+ QQtWavSound()->setLoops ( 1 );
+ QQtWavSound ( conf_res ( "9612.wav" ) );
+}
+
+#ifdef __ANDROID__
+#define TMPFILE "/sdcard/temp.wav"
+#else
+#define TMPFILE "./temp.wav"
+#endif
+
+void MainWindow::on_pushButton_8_clicked()
+{
+ //不需要停止录音?需要
+ //android 不支持./temp.wav....
+
+ //record
+ QString name = QQtAudioManager::defaultInputDevice().deviceName();
+ if ( ui->inputListWidget->currentIndex().isValid() )
+ name = ui->inputListWidget->currentIndex().data().toString();
+ QAudioDeviceInfo input = findInputAudioDeviceInfoByName ( name );
+
+
+ QAudioFormat outFmt = input.preferredFormat();
+ int outBit = outFmt.sampleSize(), outChn = outFmt.channelCount(), outRate = outFmt.sampleRate();
+ if ( ui->inBit->currentIndex().isValid() )
+ outBit = ui->inBit->currentIndex().data().toInt();
+ if ( ui->inChn->currentIndex().isValid() )
+ outChn = ui->inChn->currentIndex().data().toInt();
+ if ( ui->intRate->currentIndex().isValid() )
+ outRate = ui->intRate->currentIndex().data().toInt();
+
+ outFmt.setChannelCount ( outChn );
+ outFmt.setSampleSize ( outBit );
+ outFmt.setSampleRate ( outRate );
+ outFmt.setCodec ( "audio/pcm" );
+
+ wavRecManager.inputDeviceInfo() = input;
+ wavRecManager.inputAudioFormat() = outFmt;
+
+ //save wav file
+ wavFileManager.outputAudioFormat() = wavRecManager.inputAudioFormat();
+ wavFileManager.setOutputSourceFile ( TMPFILE );
+
+ pline() << "record:" << wavRecManager.inputDeviceInfo().deviceName() << wavRecManager.inputAudioFormat();
+ pline() << "save:" << wavFileManager.outputSourceFile() << wavFileManager.outputAudioFormat();
+
+ //内部存在自动关停。对wav写自动关停,会导致文件被重写。这个函数是录音重新开始,所以可以自动关停。
+ wavFileManager.startOutput();
+ wavRecManager.startInput();
+}
+
+void MainWindow::on_pushButton_9_clicked()
+{
+ //不需要停止放音?需要
+
+ //read wav file
+ wavFileManager.setInputSourceFile ( TMPFILE );
+
+ //play record
+ QString name = QQtAudioManager::defaultOutputDevice().deviceName();
+ if ( ui->outputListWidget->currentIndex().isValid() )
+ name = ui->outputListWidget->currentIndex().data().toString();
+ QAudioDeviceInfo devOut = findOutputAudioDeviceInfoByName ( name );
+
+ QAudioFormat outFmt = devOut.preferredFormat();
+ int outBit = outFmt.sampleSize(), outChn = outFmt.channelCount(), outRate = outFmt.sampleRate();
+ if ( ui->outBit->currentIndex().isValid() )
+ outBit = ui->outBit->currentIndex().data().toInt();
+ if ( ui->outChn->currentIndex().isValid() )
+ outChn = ui->outChn->currentIndex().data().toInt();
+ if ( ui->outRate->currentIndex().isValid() )
+ outRate = ui->outRate->currentIndex().data().toInt();
+ outFmt.setChannelCount ( outChn );
+ outFmt.setSampleSize ( outBit );
+ outFmt.setSampleRate ( outRate );
+ outFmt.setCodec ( "audio/pcm" );
+
+ wavRecManager.outputAudioFormat() = outFmt;
+ wavRecManager.outputDeviceInfo() = devOut;
+
+ pline() << "file:" << wavFileManager.inputSourceFile() << wavFileManager.inputAudioFormat();
+ pline() << "play:" << wavRecManager.outputDeviceInfo().deviceName() << wavRecManager.outputAudioFormat();
+
+ //内部存在自动关停。
+ wavRecManager.startOutput();
+ wavFileManager.startInput();
+}
+
+void MainWindow::on_pushButton_10_clicked()
+{
+ wavRecManager.stopInput();
+ wavFileManager.stopOutput();
+}
+
+void MainWindow::on_pushButton_11_clicked()
+{
+ wavFileManager.stopInput();
+ wavRecManager.stopOutput();
+}
+
+void MainWindow::on_pushButton_12_clicked()
+{
+ //android support 16bit but 24bit
+ QQtWavSoundEffect* e0 = QQtWavSound();
+ e0->setTimerInterval ( 100 );
+ QQtWavSound ( conf_res ( "9767.wav" ) );
+}
diff --git a/test/voicetest2/mainwindow.h b/test/voicetest2/mainwindow.h
new file mode 100644
index 00000000..0b513861
--- /dev/null
+++ b/test/voicetest2/mainwindow.h
@@ -0,0 +1,67 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow ( QWidget* parent = 0 );
+ ~MainWindow();
+
+ QAudioDeviceInfo findInputAudioDeviceInfoByName ( QString devName );
+
+ QAudioDeviceInfo findOutputAudioDeviceInfoByName ( QString devName );
+
+private slots:
+ void on_pushButton_2_clicked();
+ void currentInputRowChanged ( QModelIndex, QModelIndex );
+ void currentOutputRowChanged ( QModelIndex, QModelIndex );
+ void on_pushButton_clicked();
+ void readyRead();
+
+ //录音到wav
+ void wavRecReadyRead();
+ //读取rec wav播放
+ void wavFileReadyRead();
+ void on_pushButton_3_clicked();
+
+ void on_inHS_valueChanged ( int value );
+
+ void on_outHS_valueChanged ( int value );
+
+ void on_pushButton_4_clicked();
+
+ void on_pushButton_5_clicked();
+
+ void on_pushButton_6_clicked();
+
+ void on_pushButton_7_clicked();
+
+ void on_pushButton_8_clicked();
+
+ void on_pushButton_9_clicked();
+
+ void on_pushButton_10_clicked();
+
+ void on_pushButton_11_clicked();
+
+ void on_pushButton_12_clicked();
+
+private:
+ Ui::MainWindow* ui;
+ QQtAudioManager manager;
+
+ QQtAudioManager wavRecManager;
+ QQtWavAudioManager wavFileManager;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/voicetest2/mainwindow.ui b/test/voicetest2/mainwindow.ui
new file mode 100644
index 00000000..96a25a1a
--- /dev/null
+++ b/test/voicetest2/mainwindow.ui
@@ -0,0 +1,273 @@
+
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 751
+ 367
+
+
+
+ MainWindow
+
+
+
+ -
+
+
+ 0
+
+
+
+ AudioManager
+
+
+
-
+
+
-
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ input format
+
+
+
+ -
+
+
+ input device
+
+
+
+
+
+ -
+
+
-
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ output format
+
+
+
+ -
+
+
+ output device
+
+
+
+
+
+ -
+
+
+
-
+
+
+ start take voice and play
+
+
+
+ -
+
+
+ start take voice
+and play (default device)
+
+
+
+ -
+
+
+ stop (optional)
+
+
+
+ -
+
+
+ refresh device list
+
+
+
+
+
+
+
+
+
+
+ WavAudioManager
+
+
+ -
+
+
+
-
+
+
+ sound effect 1
+
+
+
+ -
+
+
+ sound effect 2
+
+
+
+ -
+
+
+ sound effect 3
+
+
+
+ -
+
+
+ sound effect 4
+
+
+
+
+
+
+ -
+
+
+
-
+
+
+ record 0
+
+
+
+ -
+
+
+ stop record
+
+
+
+ -
+
+
+ play record 0
+
+
+
+ -
+
+
+ stop playing
+
+
+
+
+
+
+ -
+
+
+
-
+
+
+ input volume
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ output volume
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 183
+ 20
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 129
+
+
+
+
+
+
+
+
+ Tab 3
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/voicetest2/voicetest.qrc b/test/voicetest2/voicetest.qrc
new file mode 100644
index 00000000..3e46be4e
--- /dev/null
+++ b/test/voicetest2/voicetest.qrc
@@ -0,0 +1,8 @@
+
+
+ AppRoot/res/9733.wav
+ AppRoot/res/9612.wav
+ AppRoot/res/9763.wav
+ AppRoot/res/9767.wav
+
+
diff --git a/test/voicetest2/voicetest2.pro b/test/voicetest2/voicetest2.pro
new file mode 100644
index 00000000..a2d4e3b1
--- /dev/null
+++ b/test/voicetest2/voicetest2.pro
@@ -0,0 +1,70 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2018-02-08T20:04:18
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = voicetest2
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+
+HEADERS += \
+ mainwindow.h
+
+FORMS += \
+ mainwindow.ui
+
+CONFIG += mobility
+MOBILITY =
+
+#这句话很重要 启动拷贝很多东西
+system (touch main.cpp)
+
+include (../../multi-link/multi-link/add_base_manager.pri)
+
+contains(QSYS_PRIVATE, Android|AndroidX86) {
+ CONFIG += mobility
+ MOBILITY =
+ DISTFILES += \
+ $${PWD}/android/AndroidManifest.xml
+
+ ANDROID_PACKAGE_SOURCE_DIR = $${PWD}/android
+}
+
+RESOURCES += \
+ voicetest.qrc
+
+#这个的设置有特点,要先设置
+add_version (1,0,0,0)
+
+#先发布App
+#app从build到deploy
+add_deploy()
+
+#后发布依赖
+#libQQt从sdk到build和deploy
+add_dependent_manager(QQt)
+
+#发布配置文件 把AppRoot里的配置项目拷贝到运行目录和发布目录
+add_deploy_config($${PWD}/AppRoot)
+
+message($$ANDROID_EXTRA_LIBS)