first commit
This commit is contained in:
805
project/fm_viewer/core/fm_strings.cpp
Normal file
805
project/fm_viewer/core/fm_strings.cpp
Normal file
@@ -0,0 +1,805 @@
|
||||
#include "fm_strings.h"
|
||||
#define DEBUG_FM_STRINGS 0
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#if (FM_STR_TYPE2)
|
||||
QMap<QString,QStringList> FMS::strings = QMap<QString,QStringList>();
|
||||
#else // FM_STR_TYPE2
|
||||
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
QMap<QString,QString> FMS::jps = QMap<QString,QString>();
|
||||
#endif // MODEL_KOREAN_ONLY
|
||||
|
||||
#if(RM_MODEL == RM_MODEL_TYPE_ADT_CAPS || RM_MODEL == RM_MODEL_TYPE_TB4000 || RM_MODEL == RM_MODEL_TYPE_BV2000 || SUB_MODEL_KEIYO_KR || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
QMap<QString,QString> FMS::kos = QMap<QString,QString>();
|
||||
#endif
|
||||
|
||||
#if(SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
QMap<QString,QString> FMS::ens = QMap<QString,QString>();
|
||||
#endif
|
||||
#endif // FM_STR_TYPE2
|
||||
|
||||
bool FMS::_loaded = false;
|
||||
|
||||
#if (FM_STR_TYPE2)
|
||||
void FMS::load()
|
||||
{
|
||||
if(QFile::exists(":/raw/strings.txt"))
|
||||
{
|
||||
QFile f(":/raw/strings.txt");
|
||||
if (f.open(QIODevice::ReadOnly))
|
||||
{
|
||||
QTextStream in(&f);
|
||||
in.setCodec("UTF-8");
|
||||
while (!in.atEnd())
|
||||
{
|
||||
QString line = in.readLine();
|
||||
QStringList lst = line.split("|");
|
||||
QString key = lst.first();
|
||||
lst.removeFirst();
|
||||
FMS::strings.insert(key,lst);
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
QString FMS::txtLine(const char* key)
|
||||
{
|
||||
return txt(key).replace("\\n","\n");
|
||||
}
|
||||
QString FMS::txt(const char* key)
|
||||
{
|
||||
if(!_loaded) {
|
||||
load();
|
||||
_loaded = true;
|
||||
}
|
||||
return txt(key,RMLanguage::instance()->language());
|
||||
}
|
||||
|
||||
QString FMS::txt(const char* key,RMLanguage::LANGUAGE_TYPE type)
|
||||
{
|
||||
if(!strings.contains(key)) {
|
||||
qInfo() << "KEY NOT FOUND:" << key << __FUNCTION__;
|
||||
return "";
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
switch (type) {
|
||||
case RMLanguage::LANGUAGE_JP:
|
||||
idx = 1;
|
||||
break;
|
||||
case RMLanguage::LANGUAGE_KR:
|
||||
idx = 0;
|
||||
break;
|
||||
case RMLanguage::LANGUAGE_EN:
|
||||
idx = 2;
|
||||
break;
|
||||
}
|
||||
QStringList l = strings[key];
|
||||
if(l.size() > idx) {
|
||||
return l.at(idx);
|
||||
}
|
||||
qInfo() << "LANGUAGE NOT FOUND:" << key << "type:" << type << __FUNCTION__;
|
||||
return "";
|
||||
}
|
||||
#else // FM_STR_TYPE2
|
||||
void FMS::load()
|
||||
{
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_TBD360) // ENG
|
||||
jps.insert("report","Report");
|
||||
jps.insert("map","Map");
|
||||
jps.insert("language","Language");
|
||||
|
||||
jps.insert("file_type","Type");
|
||||
jps.insert("file_name","File Name");
|
||||
jps.insert("file_duration","Duration");
|
||||
|
||||
jps.insert("restart_msg","The application must restart in order to enable/disable H/W acceleration");
|
||||
|
||||
// ビューア情報
|
||||
jps.insert("viewer_info","Viewer Info.");
|
||||
|
||||
jps.insert("capture","Capture");
|
||||
jps.insert("close","Close");
|
||||
jps.insert("minimize","Minimize");
|
||||
jps.insert("low_speed","Low Speed");
|
||||
jps.insert("high_speed","High Speed");
|
||||
jps.insert("flip_h","Flip Horizontal");
|
||||
jps.insert("flip_v","Flip Vertical");
|
||||
|
||||
// フロント・リア切替え
|
||||
jps.insert("swap","Swap Screen");
|
||||
|
||||
jps.insert("mode_360","Camera Mode");
|
||||
jps.insert("zoom_360","Zoom Mode");
|
||||
jps.insert("reset_360","Reset Camera");
|
||||
|
||||
jps.insert("fullscreen","Full Screen");
|
||||
|
||||
jps.insert("graph_zoom_in","Zoom In");
|
||||
jps.insert("graph_zoom_out","Zoom Out");
|
||||
|
||||
jps.insert("brightness","Brightness");
|
||||
jps.insert("contrast","Contrast");
|
||||
jps.insert("play_speed","Speed");
|
||||
jps.insert("volume_mute","Mute");
|
||||
jps.insert("volume_un_mute","Unmute");
|
||||
|
||||
jps.insert("play_backward","Seek backward");
|
||||
jps.insert("play_forward","Seek forward");
|
||||
|
||||
jps.insert("play_play","Play");
|
||||
jps.insert("play_stop","Stop");
|
||||
jps.insert("play_file_previous","Previous File");
|
||||
jps.insert("play_file_next","Next File");
|
||||
jps.insert("open","Open");
|
||||
jps.insert("play_pause","Pause");
|
||||
|
||||
jps.insert("backup","Backup");
|
||||
|
||||
jps.insert("viewer_sw_version","S/W Version");
|
||||
jps.insert("hw_accel","Graphic Accelation");
|
||||
|
||||
jps.insert("ok","OK");
|
||||
jps.insert("cancel","Cancel");
|
||||
jps.insert("change","Change");
|
||||
|
||||
// 入力,確認
|
||||
jps.insert("input","Input");
|
||||
jps.insert("confirm","Confirm");
|
||||
jps.insert("old","Previous");
|
||||
// 間違ったパスワード
|
||||
jps.insert("password_wrong","Wrong Password");
|
||||
|
||||
// 注意
|
||||
jps.insert("warning","Warning");
|
||||
|
||||
jps.insert("save","Save");
|
||||
|
||||
// 初期値
|
||||
jps.insert("default","Default");
|
||||
|
||||
// 緯度
|
||||
jps.insert("lat","LAT:");
|
||||
|
||||
//経度
|
||||
jps.insert("lon","LON:");
|
||||
|
||||
// 録画ファイルがあるフォルダを選択
|
||||
jps.insert("open_message","Select the folder");
|
||||
#else
|
||||
|
||||
#if (SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
ens.insert("report","Report");
|
||||
ens.insert("map","Map");
|
||||
ens.insert("language","Language");
|
||||
ens.insert("auto_select","Auto");
|
||||
|
||||
|
||||
ens.insert("file_type","Type");
|
||||
ens.insert("file_name","File Name");
|
||||
ens.insert("file_duration","Duration");
|
||||
|
||||
ens.insert("file_date","Date");
|
||||
ens.insert("file_size","Size");
|
||||
|
||||
ens.insert("restart_msg","The application must restart in order to enable/disable H/W acceleration");
|
||||
|
||||
// ビューア情報
|
||||
ens.insert("viewer_info","Viewer Info.");
|
||||
|
||||
ens.insert("capture","Capture");
|
||||
ens.insert("close","Close");
|
||||
ens.insert("minimize","Minimize");
|
||||
ens.insert("maximize","Maximize");
|
||||
ens.insert("restore_window","Restore Window");
|
||||
ens.insert("low_speed","Low Speed");
|
||||
ens.insert("high_speed","High Speed");
|
||||
ens.insert("flip_h","Flip Horizontal");
|
||||
ens.insert("flip_v","Flip Vertical");
|
||||
|
||||
// フロント・リア切替え
|
||||
ens.insert("swap","Swap Screen");
|
||||
|
||||
ens.insert("mode_360","Camera Mode");
|
||||
ens.insert("zoom_360","Zoom Mode");
|
||||
ens.insert("reset_360","Reset Camera");
|
||||
|
||||
ens.insert("fullscreen","Full Screen");
|
||||
|
||||
ens.insert("graph_zoom_in","Zoom In");
|
||||
ens.insert("graph_zoom_out","Zoom Out");
|
||||
|
||||
ens.insert("brightness","Brightness");
|
||||
ens.insert("contrast","Contrast");
|
||||
ens.insert("play_speed","Speed");
|
||||
ens.insert("volume_mute","Mute");
|
||||
ens.insert("volume_un_mute","Unmute");
|
||||
|
||||
ens.insert("play_backward","Seek backward");
|
||||
ens.insert("play_forward","Seek forward");
|
||||
|
||||
ens.insert("play_play","Play");
|
||||
ens.insert("play_stop","Stop");
|
||||
ens.insert("play_file_previous","Previous File");
|
||||
ens.insert("play_file_next","Next File");
|
||||
ens.insert("open","Open");
|
||||
ens.insert("play_pause","Pause");
|
||||
|
||||
ens.insert("backup","Backup");
|
||||
|
||||
ens.insert("viewer_sw_version","S/W Version");
|
||||
ens.insert("hw_accel","Graphic Accelation");
|
||||
|
||||
ens.insert("ok","OK");
|
||||
ens.insert("cancel","Cancel");
|
||||
ens.insert("change","Change");
|
||||
|
||||
// 入力,確認
|
||||
ens.insert("input","Input");
|
||||
ens.insert("confirm","Confirm");
|
||||
ens.insert("old","Previous");
|
||||
// 間違ったパスワード
|
||||
ens.insert("password_wrong","Wrong Password");
|
||||
|
||||
// 注意
|
||||
ens.insert("warning","Warning");
|
||||
|
||||
ens.insert("save","Save");
|
||||
|
||||
// 初期値
|
||||
ens.insert("default","Default");
|
||||
|
||||
// 緯度
|
||||
ens.insert("lat","LAT:");
|
||||
|
||||
//経度
|
||||
ens.insert("lon","LON:");
|
||||
|
||||
// 録画ファイルがあるフォルダを選択
|
||||
ens.insert("open_message","Select the folder");
|
||||
#endif // BV5000 ENG
|
||||
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
// 파일 저장
|
||||
// ファイルの保存
|
||||
jps.insert("backup_title",FM_WSTR(L"バックアップ中"));
|
||||
|
||||
// 파일 종류
|
||||
jps.insert("type_event",FM_WSTR(L"衝撃検知"));
|
||||
jps.insert("type_manual",FM_WSTR(L"手動"));
|
||||
jps.insert("type_parking_normal",FM_WSTR(L"駐車監視"));
|
||||
jps.insert("type_parking",FM_WSTR(L"パーキング"));
|
||||
jps.insert("type_parking_event",FM_WSTR(L"駐車衝撃"));
|
||||
jps.insert("type_normal",FM_WSTR(L"常時"));
|
||||
#endif // #if !(MODEL_KOREAN_ONLY)
|
||||
|
||||
#if(SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
ens.insert("type_event","EVENT");
|
||||
ens.insert("type_manual","MANUAL");
|
||||
ens.insert("type_parking_normal","PARKING");
|
||||
ens.insert("type_parking","PARKING");
|
||||
ens.insert("type_parking_event","PAKING.E");
|
||||
ens.insert("type_normal","NORMAL");
|
||||
#endif // #if(SUPPORT_LANGUAGE_INSERT)
|
||||
|
||||
#if (RC_LANGUAGE==0x0412 || MODEL_KOREAN_ONLY)
|
||||
kos.insert("type_event",FM_WSTR(L"이벤트"));
|
||||
kos.insert("type_manual",FM_WSTR(L"수동"));
|
||||
kos.insert("type_parking_normal",FM_WSTR(L"주차감시"));
|
||||
kos.insert("type_parking",FM_WSTR(L"주차"));
|
||||
kos.insert("type_parking_event",FM_WSTR(L"주차E"));
|
||||
kos.insert("type_normal",FM_WSTR(L"상시"));
|
||||
kos.insert("restart_msg",FM_WSTR(L"설정 적용을 위해 뷰어를 다시 시작 합니다."));
|
||||
kos.insert("report",FM_WSTR(L"보고서"));
|
||||
kos.insert("map",FM_WSTR(L"지도"));
|
||||
kos.insert("language",FM_WSTR(L"언어"));
|
||||
kos.insert("file_type",FM_WSTR(L"분류"));
|
||||
kos.insert("file_name",FM_WSTR(L"파일명"));
|
||||
kos.insert("file_date",FM_WSTR(L"날짜"));
|
||||
kos.insert("file_duration",FM_WSTR(L"재생시간"));
|
||||
kos.insert("file_size",FM_WSTR(L"크기")); // タイプ
|
||||
|
||||
kos.insert("viewer_info",FM_WSTR(L"S/W 정보"));
|
||||
kos.insert("speed_warning",FM_WSTR(L"GPS 속도는 실제 속도와 다를 수 있습니다."));
|
||||
kos.insert("capture",FM_WSTR(L"JPG 저장"));
|
||||
kos.insert("capture_desc",FM_WSTR(L"현재 화면을 JPEG 파일로 저장 합니다"));
|
||||
|
||||
kos.insert("close",FM_WSTR(L"닫기"));
|
||||
kos.insert("minimize",FM_WSTR(L"최소화"));
|
||||
kos.insert("maximize",FM_WSTR(L"최대화"));
|
||||
kos.insert("restore_window",FM_WSTR(L"이전 크기로 복원"));
|
||||
kos.insert("low_speed",FM_WSTR(L"저속"));
|
||||
kos.insert("high_speed",FM_WSTR(L"고속"));
|
||||
kos.insert("flip_h",FM_WSTR(L"좌우반전"));
|
||||
kos.insert("flip_v",FM_WSTR(L"상하반전"));
|
||||
kos.insert("swap",FM_WSTR(L"전후방 화면 전환"));
|
||||
kos.insert("indoor",FM_WSTR(L"실내외 화면 전환"));
|
||||
kos.insert("fullscreen",FM_WSTR(L"전체화면"));
|
||||
kos.insert("graph_zoom_in",FM_WSTR(L"확대"));
|
||||
kos.insert("graph_zoom_out",FM_WSTR(L"축소"));
|
||||
kos.insert("brightness",FM_WSTR(L"밝기조정"));
|
||||
kos.insert("contrast",FM_WSTR(L"대비조정"));
|
||||
kos.insert("play_speed",FM_WSTR(L"재생속도"));
|
||||
kos.insert("volume_mute",FM_WSTR(L"음량"));
|
||||
kos.insert("volume_un_mute",FM_WSTR(L"음량"));
|
||||
|
||||
kos.insert("play_backward",FM_WSTR(L"1초 이전으로 이동"));
|
||||
kos.insert("play_forward",FM_WSTR(L"1초 이후로 이동"));
|
||||
|
||||
kos.insert("play_play",FM_WSTR(L"재생"));
|
||||
kos.insert("play_stop",FM_WSTR(L"정지"));
|
||||
kos.insert("play_file_previous",FM_WSTR(L"이전 파일"));
|
||||
kos.insert("play_file_next",FM_WSTR(L"다음 파일"));
|
||||
kos.insert("open",FM_WSTR(L"파일 열기"));
|
||||
kos.insert("open_title",FM_WSTR(L"파일 열기"));
|
||||
kos.insert("play_pause",FM_WSTR(L"일시 정지"));
|
||||
kos.insert("backup_title",FM_WSTR(L"파일 저장"));
|
||||
kos.insert("file_exist",FM_WSTR(L"이 위치에 같은 이름의 파일이 있습니다."));
|
||||
kos.insert("apply_rule",FM_WSTR(L"동일한 작업을 다음의"));
|
||||
kos.insert("after_files",FM_WSTR(L"파일에도 적용"));
|
||||
kos.insert("skip",FM_WSTR(L"건너뛰기"));
|
||||
kos.insert("overwrite",FM_WSTR(L"덮어쓰기"));
|
||||
kos.insert("auto_select",FM_WSTR(L"자동선택"));
|
||||
kos.insert("select_language",FM_WSTR(L"언어 선택"));
|
||||
kos.insert("enter_file_name",FM_WSTR(L"파일명을 입력해 주십시오"));
|
||||
kos.insert("front_suffix",FM_WSTR(L"전방"));
|
||||
kos.insert("rear_suffix",FM_WSTR(L"후방"));
|
||||
kos.insert("save_jpg_fail",FM_WSTR(L"JPEG 파일 생성 실패"));
|
||||
|
||||
kos.insert("thumbnail",FM_WSTR(L"썸네일보기"));
|
||||
kos.insert("register",FM_WSTR(L"적발원부"));
|
||||
kos.insert("save_video",FM_WSTR(L"영상저장"));
|
||||
|
||||
kos.insert("reset_360",FM_WSTR(L"초기화"));
|
||||
kos.insert("save_360",FM_WSTR(L"파일로 저장"));
|
||||
|
||||
//
|
||||
kos.insert("backup_title",FM_WSTR(L"파일 저장중..."));
|
||||
|
||||
kos.insert("change_folder",FM_WSTR(L"폴더 선택"));
|
||||
kos.insert("backup",FM_WSTR(L"파일 저장"));
|
||||
kos.insert("viewer_sw_version",FM_WSTR(L"Viewer S/W 버전 정보"));
|
||||
kos.insert("hw_accel",FM_WSTR(L"H/W 가속 설정"));
|
||||
kos.insert("pw_message",FM_WSTR(L"암호 (4 자 이상 20 자 이하) 생성."));
|
||||
kos.insert("password",FM_WSTR(L"암호"));
|
||||
kos.insert("password_new",FM_WSTR(L"신규 암호"));
|
||||
kos.insert("password_input",FM_WSTR(L"암호 입력"));
|
||||
kos.insert("password_change",FM_WSTR(L"암호 변경"));
|
||||
kos.insert("ok",FM_WSTR(L"확인"));
|
||||
kos.insert("cancel",FM_WSTR(L"취소"));
|
||||
kos.insert("change",FM_WSTR(L"변경"));
|
||||
kos.insert("input",FM_WSTR(L"입력"));
|
||||
kos.insert("confirm",FM_WSTR(L"확인"));
|
||||
kos.insert("old",FM_WSTR(L"이전"));
|
||||
kos.insert("password_wrong",FM_WSTR(L"잘못된 암호"));
|
||||
kos.insert("invalid_media",FM_WSTR(L"재생할 수 없는 파일입니다"));
|
||||
kos.insert("warning",FM_WSTR(L"주의"));
|
||||
kos.insert("file_not_exist",FM_WSTR(L"파일이 존재하지 않습니다"));
|
||||
|
||||
kos.insert("save",FM_WSTR(L"저장"));
|
||||
kos.insert("default",FM_WSTR(L"초기화"));
|
||||
kos.insert("lat",FM_WSTR(L"위도"));
|
||||
kos.insert("lon",FM_WSTR(L"경도"));
|
||||
kos.insert("open_message",FM_WSTR(L"녹화 파일이 있는 폴더를 선택"));
|
||||
|
||||
kos.insert("password",FM_WSTR(L"비밀번호설정"));
|
||||
|
||||
#endif // SUPPORT_LANGUAGE_INSERT || MODEL_KOREAN_ONLY
|
||||
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
jps.insert("settings",FM_WSTR(L"設定"));
|
||||
#endif // MODEL_KOREAN_ONLY
|
||||
kos.insert("settings",FM_WSTR(L"설정"));
|
||||
ens.insert("settings",FM_WSTR(L"Settings"));
|
||||
|
||||
#if(SUPPORT_LANGUAGE_INSERT || RM_MODEL == RM_MODEL_TYPE_MH9000)
|
||||
ens.insert("open_title","Open");
|
||||
ens.insert("select_language","Select language");
|
||||
|
||||
#endif // #if(SUPPORT_LANGUAGE_INSERT)
|
||||
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
jps.insert("info",FM_WSTR(L"ビューアー情報"));
|
||||
#endif // #if !(MODEL_KOREAN_ONLY)
|
||||
|
||||
#if(SUPPORT_LANGUAGE_INSERT)
|
||||
kos.insert("info",FM_WSTR(L"뷰어정보"));
|
||||
ens.insert("info",FM_WSTR(L"Viewer Info."));
|
||||
#endif // #if(SUPPORT_LANGUAGE_INSERT)
|
||||
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
jps.insert("report","\xe3\x83\xac\xe3\x83\x9d\xe3\x83\xbc\xe3\x83\x88");
|
||||
jps.insert("map","\xe5\x9c\xb0\xe5\x9b\xb3");
|
||||
jps.insert("language","\xe8\xa8\x80\xe8\xaa\x9e\xe9\x81\xb8\xe6\x8a\x9e");
|
||||
|
||||
jps.insert("file_type","\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\x97"); // タイプ
|
||||
jps.insert("file_name","\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe5\x90\x8d"); // ファイル名
|
||||
jps.insert("file_date",FM_WSTR(L"ファイル日付")); // ファイル名
|
||||
jps.insert("file_duration","\xe9\x8c\xb2\xe7\x94\xbb\xe6\x99\x82\xe9\x96\x93"); // 録画時間
|
||||
jps.insert("file_size",FM_WSTR(L"サイズ")); // タイプ
|
||||
|
||||
// 재기동 경고 再起動します
|
||||
jps.insert("restart_msg","\xe5\x86\x8d\xe8\xb5\xb7\xe5\x8b\x95\xe3\x81\x97\xe3\x81\xbe\xe3\x81\x99");
|
||||
|
||||
// ビューア情報
|
||||
jps.insert("viewer_info","\xe3\x83\x93\xe3\x83\xa5\xe3\x83\xbc\xe3\x82\xa2\xe6\x83\x85\xe5\xa0\xb1");
|
||||
|
||||
//速度はGPS算出値となります。実際の速度とは異なります。
|
||||
jps.insert("speed_warning","\xe9\x80\x9f\xe5\xba\xa6\xe3\x81\xaf\x47\x50\x53\xe7\xae\x97\xe5\x87\xba\xe5\x80\xa4\xe3\x81\xa8\xe3\x81\xaa\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82\xe5\xae\x9f\xe9\x9a\x9b\xe3\x81\xae\xe9\x80\x9f\xe5\xba\xa6\xe3\x81\xa8\xe3\x81\xaf\xe7\x95\xb0\xe3\x81\xaa\xe3\x82\x8a\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82");
|
||||
|
||||
jps.insert("capture","\x4a\x50\x47 \xe4\xbf\x9d\xe5\xad\x98");
|
||||
jps.insert("capture_desc",FM_WSTR(L"キャプチャーをJPEGで保存します"));
|
||||
//
|
||||
jps.insert("close","\xe9\x96\x89\xe3\x81\x98\xe3\x82\x8b"); // 閉じる
|
||||
jps.insert("minimize","\xe6\x9c\x80\xe5\xb0\x8f\xe5\x8c\x96"); // 最小化
|
||||
jps.insert("maximize","\xe6\x9c\x80\xe5\xa4\xa7\xe5\x8c\x96"); // 最大化
|
||||
jps.insert("restore_window","\xe5\x85\x83\xe3\x81\xab\xe6\x88\xbb\xe3\x81\x99\xef\xbc\x88\xe7\xb8\xae\xe5\xb0\x8f\xef\xbc\x89"); // 元に戻す(縮小)
|
||||
jps.insert("low_speed","\xe4\xbd\x8e\xe9\x80\x9f");
|
||||
jps.insert("high_speed","\xe9\xab\x98\xe9\x80\x9f \x28 \x31\x33\x30 \x4b\x6d\x2f\x68 \xe4\xbb\xa5\xe4\xb8\x8a \x29");
|
||||
jps.insert("flip_h","\xe5\xb7\xa6\xe5\x8f\xb3\xe5\x8f\x8d\xe8\xbb\xa2"); // 左右反転
|
||||
jps.insert("flip_v","\xe4\xb8\x8a\xe4\xb8\x8b\xe5\x8f\x8d\xe8\xbb\xa2"); // 上下反転
|
||||
|
||||
|
||||
// フロント・リア切替え
|
||||
// フロント・サブ切替え
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
|
||||
jps.insert("swap",FM_WSTR(L"フロント・サブ切替え"));
|
||||
#else
|
||||
// フロント・リア切替え
|
||||
#if (SUB_MODEL_KEIYO_360)
|
||||
jps.insert("swap",FM_WSTR(L"360度・ワイド切り替え"));
|
||||
#else // SUB_MODEL_KEIYO_360
|
||||
jps.insert("swap",FM_WSTR(L"フロント・リア切替え"));
|
||||
#endif // SUB_MODEL_KEIYO_360
|
||||
#endif
|
||||
jps.insert("indoor",FM_WSTR(L"室内・外切替え"));
|
||||
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_FC_DR232W) // 最大化,フルスクリーン
|
||||
// フルスクリーン
|
||||
jps.insert("fullscreen","\xe3\x83\x95\xe3\x83\xab\xe3\x82\xb9\xe3\x82\xaf\xe3\x83\xaa\xe3\x83\xbc\xe3\x83\xb3");
|
||||
#else
|
||||
jps.insert("fullscreen","\xe6\x9c\x80\xe5\xa4\xa7\xe5\x8c\x96");
|
||||
#endif
|
||||
|
||||
jps.insert("graph_zoom_in","\xe6\x8b\xa1\xe5\xa4\xa7"); // 拡大
|
||||
jps.insert("graph_zoom_out","\xe7\xb8\xae\xe5\xb0\x8f"); // 縮小
|
||||
|
||||
jps.insert("brightness","\xe6\x98\x8e\xe3\x82\x8b\xe3\x81\x95"); // 明るさ
|
||||
jps.insert("contrast","\xe3\x82\xb3\xe3\x83\xb3\xe3\x83\x88\xe3\x83\xa9\xe3\x82\xb9\xe3\x83\x88"); // コントラスト
|
||||
jps.insert("play_speed","\xe5\x86\x8d\xe7\x94\x9f\xe9\x80\x9f\xe5\xba\xa6"); // 再生速度
|
||||
|
||||
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_FC_DR232W) // 音量
|
||||
jps.insert("volume_mute","\xe9\x9f\xb3\xe9\x87\x8f"); // 音量
|
||||
jps.insert("volume_un_mute","\xe9\x9f\xb3\xe9\x87\x8f");
|
||||
#else
|
||||
jps.insert("volume_mute","\xe6\xb6\x88\xe9\x9f\xb3\xe3\x83\xa2\xe3\x83\xbc\xe3\x83\x89");
|
||||
jps.insert("volume_un_mute","\xe3\x83\x9f\xe3\x83\xa5\xe3\x83\xbc\xe3\x83\x88\xe3\x81\xae\xe8\xa7\xa3\xe9\x99\xa4");
|
||||
#endif
|
||||
|
||||
|
||||
#if (SEEK_STEP_SIZE == 10)
|
||||
jps.insert("play_backward","\x31\x30\xe7\xa7\x92\xe5\x89\x8d\xe3\x81\xb8"); // 10秒前へ
|
||||
jps.insert("play_forward","\x31\x30\xe7\xa7\x92\xe9\x80\xb2\xe3\x82\x80"); // 10秒進む
|
||||
#else
|
||||
jps.insert("play_backward","\x31\xe7\xa7\x92\xe5\x89\x8d\xe3\x81\xb8");
|
||||
jps.insert("play_forward","\x31\xe7\xa7\x92\xe9\x80\xb2\xe3\x82\x80");
|
||||
#endif
|
||||
jps.insert("play_play","\xe5\x86\x8d\xe7\x94\x9f"); // 再生
|
||||
jps.insert("play_stop","\xe5\x81\x9c\xe6\xad\xa2"); // 停止
|
||||
jps.insert("play_file_previous","\xe5\x89\x8d\xe3\x81\xae\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab"); // 前のファイル <- \xe4\xbb\xa5\xe5\x89\x8d\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab
|
||||
jps.insert("play_file_next","\xe6\xac\xa1\xe3\x81\xae\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab");
|
||||
jps.insert("open","\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x82\x92\xe9\x96\x8b\xe3\x81\x8f");
|
||||
jps.insert("play_pause","\xe4\xb8\x80\xe6\x99\x82\xe5\x81\x9c\xe6\xad\xa2");
|
||||
jps.insert("open_title",FM_WSTR(L"ファイルOPEN"));
|
||||
|
||||
|
||||
//
|
||||
jps.insert("backup_title",FM_WSTR(L"ファイルの保存"));
|
||||
|
||||
jps.insert("file_exist",FM_WSTR(L"この場所に同じ名前のファイルがあります。"));
|
||||
|
||||
jps.insert("apply_rule",FM_WSTR(L"同じ処理を次の"));
|
||||
jps.insert("after_files",FM_WSTR(L"個の競合に適用"));
|
||||
|
||||
jps.insert("skip",FM_WSTR(L"スキップ"));
|
||||
|
||||
jps.insert("overwrite",FM_WSTR(L"置き換える"));
|
||||
|
||||
jps.insert("auto_select",FM_WSTR(L"自動"));
|
||||
|
||||
jps.insert("select_language",FM_WSTR(L"言語を選択してください"));
|
||||
|
||||
jps.insert("enter_file_name",FM_WSTR(L"ファイル名を入れてください。"));
|
||||
|
||||
jps.insert("front_suffix",FM_WSTR(L"前方"));
|
||||
jps.insert("rear_suffix",FM_WSTR(L"後方"));
|
||||
|
||||
jps.insert("save_jpg_fail",FM_WSTR(L"JPEGファイル生成に失敗しました。"));
|
||||
|
||||
jps.insert("change_folder",FM_WSTR(L"フォルダー変更"));
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_BV2000 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
|
||||
jps.insert("backup","\xe3\x82\xb3\xe3\x83\x94\xe3\x83\xbc"); // コピー
|
||||
#else
|
||||
jps.insert("backup","\xe4\xbf\x9d\xe5\xad\x98");
|
||||
#endif
|
||||
|
||||
// Viewer S/W バージョン情報
|
||||
jps.insert("viewer_sw_version","\x56\x69\x65\x77\x65\x72 \x53\x2f\x57 \xe3\x83\x90\xe3\x83\xbc\xe3\x82\xb8\xe3\x83\xa7\xe3\x83\xb3\xe6\x83\x85\xe5\xa0\xb1");
|
||||
// ハードウェアアクセラレーション
|
||||
jps.insert("hw_accel","\xe3\x83\x8f\xe3\x83\xbc\xe3\x83\x89\xe3\x82\xa6\xe3\x82\xa7\xe3\x82\xa2\xe3\x82\xa2\xe3\x82\xaf\xe3\x82\xbb\xe3\x83\xa9\xe3\x83\xac\xe3\x83\xbc\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3");
|
||||
|
||||
jps.insert("directx_audio",FM_WSTR(L"DirectX Audio でサウンド再生"));
|
||||
|
||||
// パスワード作成(4文字以上20文字以内)生成。
|
||||
jps.insert("pw_message","\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89\xe4\xbd\x9c\xe6\x88\x90\xef\xbc\x88\x34\xe6\x96\x87\xe5\xad\x97\xe4\xbb\xa5\xe4\xb8\x8a\x32\x30\xe6\x96\x87\xe5\xad\x97\xe4\xbb\xa5\xe5\x86\x85\xef\xbc\x89\xe7\x94\x9f\xe6\x88\x90\xe3\x80\x82");
|
||||
|
||||
// パスワード
|
||||
jps.insert("password","\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89");
|
||||
|
||||
// パスワード作成
|
||||
jps.insert("password_new","\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89\xe4\xbd\x9c\xe6\x88\x90");
|
||||
|
||||
// パスワード入力
|
||||
jps.insert("password_input","\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89\xe5\x85\xa5\xe5\x8a\x9b");
|
||||
// パスワード変更
|
||||
jps.insert("password_change","\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89\xe5\xa4\x89\xe6\x9b\xb4");
|
||||
|
||||
|
||||
jps.insert("ok","\x4f\x4b");
|
||||
|
||||
jps.insert("cancel","\xe3\x82\xad\xe3\x83\xa3\xe3\x83\xb3\xe3\x82\xbb\xe3\x83\xab"); // キャンセル
|
||||
|
||||
jps.insert("change","\xe5\xa4\x89\xe6\x9b\xb4"); // 変更
|
||||
|
||||
// 入力,確認
|
||||
jps.insert("input","\xe5\x85\xa5\xe5\x8a\x9b"); // 入力
|
||||
jps.insert("confirm","\xe7\xa2\xba\xe8\xaa\x8d"); // 確認
|
||||
jps.insert("old","\xe4\xbb\xa5\xe5\x89\x8d"); // 以前
|
||||
|
||||
//jps.insert("file_open_title","\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\x4f\x50\x45\x4e")
|
||||
|
||||
|
||||
// 間違ったパスワード
|
||||
jps.insert("password_wrong","\xe9\x96\x93\xe9\x81\x95\xe3\x81\xa3\xe3\x81\x9f\xe3\x83\x91\xe3\x82\xb9\xe3\x83\xaf\xe3\x83\xbc\xe3\x83\x89");
|
||||
|
||||
// 注意
|
||||
jps.insert("warning","\xe6\xb3\xa8\xe6\x84\x8f");
|
||||
jps.insert("file_not_exist",FM_WSTR(L"ファイルがありません"));
|
||||
|
||||
// \x4a\x50\x47 \xe4\xbf\x9d\xe5\xad\x98
|
||||
// 保存 \xe4\xbf\x9d\xe5\xad\x98
|
||||
jps.insert("save","\xe4\xbf\x9d\xe5\xad\x98");
|
||||
|
||||
// 初期値
|
||||
jps.insert("default","\xe5\x88\x9d\xe6\x9c\x9f\xe5\x80\xa4");
|
||||
|
||||
// 緯度
|
||||
jps.insert("lat","\xe7\xb7\xaf\xe5\xba\xa6");
|
||||
|
||||
//経度
|
||||
jps.insert("lon","\xe7\xb5\x8c\xe5\xba\xa6");
|
||||
|
||||
// 録画ファイルがあるフォルダを選択
|
||||
jps.insert("open_message","\xe9\x8c\xb2\xe7\x94\xbb\xe3\x83\x95\xe3\x82\xa1\xe3\x82\xa4\xe3\x83\xab\xe3\x81\x8c\xe3\x81\x82\xe3\x82\x8b\xe3\x83\x95\xe3\x82\xa9\xe3\x83\xab\xe3\x83\x80\xe3\x82\x92\xe9\x81\xb8\xe6\x8a\x9e");
|
||||
|
||||
|
||||
// ファイル分割
|
||||
jps.insert("split_files",FM_WSTR(L"ファイル分割"));
|
||||
|
||||
#endif // #if !(MODEL_KOREAN_ONLY)
|
||||
|
||||
#if(RM_MODEL == RM_MODEL_TYPE_ADT_CAPS)
|
||||
kos.insert("report","\xeb\xb3\xb4\xea\xb3\xa0\xec\x84\x9c");
|
||||
kos.insert("map","\xec\xa7\x80\xeb\x8f\x84");
|
||||
kos.insert("language","\xec\x96\xb8\xec\x96\xb4");
|
||||
kos.insert("viewer_info","\xeb\xb7\xb0\xec\x96\xb4\xec\xa0\x95\xeb\xb3\xb4");
|
||||
kos.insert("capture","\xed\x99\x94\xeb\xa9\xb4\xec\xba\xa1\xec\xb3\x90");
|
||||
kos.insert("setup","");
|
||||
kos.insert("close","\xeb\x8b\xab\xea\xb8\xb0"); // 닫기
|
||||
kos.insert("minimize","\xec\xb5\x9c\xec\x86\x8c\xed\x99\x94"); // 최소화
|
||||
kos.insert("low_speed","\xec\xa0\x80\xec\x86\x8d");
|
||||
kos.insert("high_speed","\xea\xb3\xa0\xec\x86\x8d \x28 \x31\x33\x30 \x4b\x6d\x2f\x68 \xec\x9d\xb4\xec\x83\x81 \x29");
|
||||
|
||||
kos.insert("flip_h","\xed\x99\x94\xeb\xa9\xb4\xec\xa2\x8c\xec\x9a\xb0\xeb\xb0\x98\xec\xa0\x84");
|
||||
kos.insert("flip_v","\xed\x99\x94\xeb\xa9\xb4\xec\x83\x81\xed\x95\x98\xeb\xb0\x98\xec\xa0\x84");
|
||||
kos.insert("swap","\xec\xb1\x84\xeb\x84\x90\xec\xa0\x84\xed\x99\x98");
|
||||
kos.insert("fullscreen","\xec\xa0\x84\xec\xb2\xb4\xed\x99\x94\xeb\xa9\xb4");
|
||||
kos.insert("graph_zoom_in","\xed\x99\x95\xeb\x8c\x80");
|
||||
kos.insert("graph_zoom_out","\xec\xb6\x95\xec\x86\x8c");
|
||||
|
||||
kos.insert("brightness","\xeb\xb0\x9d\xea\xb8\xb0\xec\xa1\xb0\xec\xa0\x95");
|
||||
kos.insert("contrast","\xeb\x8c\x80\xeb\xb9\x84\xec\xa1\xb0\xec\xa0\x95");
|
||||
kos.insert("play_speed","\xec\x9e\xac\xec\x83\x9d\xec\x86\x8d\xeb\x8f\x84");
|
||||
kos.insert("volume_mute","\xec\x9d\x8c\xec\x86\x8c\xea\xb1\xb0");
|
||||
kos.insert("volume_un_mute","\xec\x9d\x8c\xec\x86\x8c\xea\xb1\xb0 \xed\x95\xb4\xec\xa0\x9c");
|
||||
|
||||
kos.insert("play_backward","\x31\xec\xb4\x88\xed\x9b\x84\xeb\xb0\xa9\xec\x9d\xb4\xeb\x8f\x99");
|
||||
kos.insert("play_play","\xec\x9e\xac\xec\x83\x9d\xec\x8b\x9c\xec\x9e\x91");
|
||||
kos.insert("play_stop","\xec\xa0\x95\xec\xa7\x80");
|
||||
kos.insert("play_forward","\x31\xec\xb4\x88\xec\xa0\x84\xeb\xb0\xa9\xec\x9d\xb4\xeb\x8f\x99");
|
||||
kos.insert("play_file_previous","\xec\x9d\xb4\xec\xa0\x84\xed\x8c\x8c\xec\x9d\xbc\xec\x9e\xac\xec\x83\x9d");
|
||||
kos.insert("play_file_next","\xeb\x8b\xa4\xec\x9d\x8c\xed\x8c\x8c\xec\x9d\xbc\xec\x9e\xac\xec\x83\x9d");
|
||||
kos.insert("open","\xed\x8c\x8c\xec\x9d\xbc\xec\x97\xb4\xea\xb8\xb0");
|
||||
kos.insert("play_pause","\xec\x9d\xbc\xec\x8b\x9c\xec\xa0\x95\xec\xa7\x80");
|
||||
kos.insert("backup","\xed\x8c\x8c\xec\x9d\xbc\xeb\xb3\xb4\xec\xa1\xb4");
|
||||
kos.insert("viewer_sw_version","\xeb\xb7\xb0\xec\x96\xb4 \x53\x2f\x57 \xeb\xb2\x84\xec\xa0\x84 \xec\xa0\x95\xeb\xb3\xb4");
|
||||
kos.insert("hw_accel","\x48\x2f\x57 \xea\xb7\xb8\xeb\x9e\x98\xed\x94\xbd \xea\xb0\x80\xec\x86\x8d \xec\x82\xac\xec\x9a\xa9");
|
||||
#endif
|
||||
#endif // ENG
|
||||
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_MH9000)
|
||||
jps.insert("select_fr",FM_WSTR(L"フロント l リア"));
|
||||
jps.insert("select_lr",FM_WSTR(L"左サイド l 右サイド"));
|
||||
jps.insert("select_front",FM_WSTR(L"フロント"));
|
||||
jps.insert("select_rear",FM_WSTR(L"リア"));
|
||||
jps.insert("select_left",FM_WSTR(L"左サイド"));
|
||||
jps.insert("select_right",FM_WSTR(L"右サイド"));
|
||||
jps.insert("select_asst",FM_WSTR(L"サブカメラ"));
|
||||
jps.insert("select_indoor",FM_WSTR(L"車内カメラ"));
|
||||
kos.insert("select_fr",FM_WSTR(L"전후방"));
|
||||
kos.insert("select_lr",FM_WSTR(L"좌우측"));
|
||||
kos.insert("select_front",FM_WSTR(L"전방"));
|
||||
kos.insert("select_rear",FM_WSTR(L"후방"));
|
||||
kos.insert("select_left",FM_WSTR(L"좌측"));
|
||||
kos.insert("select_right",FM_WSTR(L"우측"));
|
||||
kos.insert("select_asst",FM_WSTR(L"보조캠"));
|
||||
kos.insert("select_indoor",FM_WSTR(L"실내캠"));
|
||||
ens.insert("select_fr","Front|Rear");
|
||||
ens.insert("select_lr",FM_WSTR(L"Left|Right"));
|
||||
ens.insert("select_front",FM_WSTR(L"Front"));
|
||||
ens.insert("select_rear",FM_WSTR(L"Rear"));
|
||||
ens.insert("select_left",FM_WSTR(L"Left"));
|
||||
ens.insert("select_right",FM_WSTR(L"Right"));
|
||||
ens.insert("select_asst",FM_WSTR(L"Assistant"));
|
||||
ens.insert("select_indoor",FM_WSTR(L"Indoor"));
|
||||
#endif //
|
||||
|
||||
#if (DEBUG_FM_STRINGS)
|
||||
QFile logFile("C:\\home\\temp2\\fmviewer.txt");
|
||||
if (logFile.open(QFile::WriteOnly | QFile::Text))
|
||||
{
|
||||
QTextStream ts(&logFile);
|
||||
ts.setCodec("UTF-8");
|
||||
foreach (QString key, kos.keys())
|
||||
{
|
||||
ts << "\"" << key << "\",\"" << kos[key] << "\",\"" << jps[key] << "\",\"" << ens[key] << "\"\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if (MODEL_KOREAN_ONLY)
|
||||
QString FMS::txt(const char* key,RMLanguage::LANGUAGE_TYPE type) {
|
||||
Q_UNUSED(type)
|
||||
return FMS::txt(key);
|
||||
}
|
||||
#else // #if !(MODEL_KOREAN_ONLY)
|
||||
QString FMS::txt(const char* key,RMLanguage::LANGUAGE_TYPE type) {
|
||||
if(!_loaded) {
|
||||
load();
|
||||
_loaded = true;
|
||||
}
|
||||
QMap<QString,QString>* l = NULL;
|
||||
switch (type) {
|
||||
case RMLanguage::LANGUAGE_JP:
|
||||
l = &FMS::jps;
|
||||
break;
|
||||
#if (RC_LANGUAGE == 0x0412)
|
||||
case RMLanguage::LANGUAGE_KR:
|
||||
l = &FMS::kos;
|
||||
break;
|
||||
#endif // #if (RC_LANGUAGE == 0x0412)
|
||||
#if(SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL == RM_MODEL_TYPE_EMT_KR)
|
||||
case RMLanguage::LANGUAGE_EN:
|
||||
l = &FMS::ens;
|
||||
break;
|
||||
#endif // #if(SUB_MODEL_BV5000)
|
||||
}
|
||||
if(l->contains(key)) {
|
||||
return l->value(key);
|
||||
} else {
|
||||
qInfo() << "STN:!!!" << key << RMLanguage::instance()->language() <<__FUNCTION__;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
#endif // #if !(MODEL_KOREAN_ONLY)
|
||||
QString FMS::txt(const char* key)
|
||||
{
|
||||
if(!_loaded) {
|
||||
load();
|
||||
_loaded = true;
|
||||
}
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_KEIYO1 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_MBJ5010 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_TBD360 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_FC_DR232W || \
|
||||
RM_MODEL == RM_MODEL_TYPE_AN6000 || \
|
||||
RM_MODEL == RM_MODEL_TYPE_XLDR_88)
|
||||
//qInfo() << jps.contains(key) << key << ":" << jps[key] << __FUNCTION__;
|
||||
//qInfo() << key << QString::fromUtf8(jps[key]) << __FUNCTION__;
|
||||
#if (MODEL_KOREAN_ONLY)
|
||||
return kos[key];
|
||||
#else // MODEL_KOREAN_ONLY
|
||||
return jps[key];
|
||||
#endif // MODEL_KOREAN_ONLY
|
||||
#elif(RM_MODEL == RM_MODEL_TYPE_ADT_CAPS)
|
||||
return kos[key];//QString::fromUtf8(kos[key]);
|
||||
#elif (SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000)
|
||||
QMap<QString,QString>* l = NULL;
|
||||
switch (RMLanguage::instance()->language()) {
|
||||
case RMLanguage::LANGUAGE_JP:
|
||||
l = &FMS::jps;
|
||||
break;
|
||||
case RMLanguage::LANGUAGE_KR:
|
||||
l = &FMS::kos;
|
||||
break;
|
||||
case RMLanguage::LANGUAGE_EN:
|
||||
l = &FMS::ens;
|
||||
break;
|
||||
}
|
||||
if(l->contains(key)) {
|
||||
return l->value(key);
|
||||
} else {
|
||||
qInfo() << "STN:!!!" << key << RMLanguage::instance()->language() <<__FUNCTION__;
|
||||
return "";
|
||||
}
|
||||
#elif (RC_LANGUAGE == 0x0412)
|
||||
if(!kos.contains(key) || kos.contains(key) == NULL) {
|
||||
qInfo() << "LANGUAGE ERROR:" << key << __FUNCTION__ ;
|
||||
return "";
|
||||
}
|
||||
return kos[key];
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#if(SUPPORT_LANGUAGE_INSERT)
|
||||
// 1:KR 2:JP, 3:EN
|
||||
void FMS::insert_if_not_exist(int type,QString key, QString text)
|
||||
{
|
||||
QMap<QString,QString>* l = NULL;
|
||||
switch (type) {
|
||||
case 2:
|
||||
l = &FMS::jps;
|
||||
break;
|
||||
case 3:
|
||||
l = &FMS::ens;
|
||||
break;
|
||||
case 1:
|
||||
l = &FMS::kos;
|
||||
break;
|
||||
}
|
||||
|
||||
//qInfo() << type << key << text << __FUNCTION__;
|
||||
|
||||
if(l != NULL && !l->contains(key)) {
|
||||
l->insert(key,text);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // #SUPPORT_LANGUAGE_INSERT
|
||||
#endif // FM_STR_TYPE2
|
||||
|
||||
|
||||
|
||||
|
||||
47
project/fm_viewer/core/fm_strings.h
Normal file
47
project/fm_viewer/core/fm_strings.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef FM_STRINGS_H
|
||||
#define FM_STRINGS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include "rm_include.h"
|
||||
|
||||
|
||||
class FMS : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
static bool _loaded;
|
||||
public:
|
||||
explicit FMS(QObject *parent = nullptr) : QObject(parent){}
|
||||
|
||||
#if (FM_STR_TYPE2)
|
||||
static QMap<QString,QStringList> strings;
|
||||
#else // FM_STR_TYPE2
|
||||
#if !(MODEL_KOREAN_ONLY)
|
||||
static QMap<QString,QString> jps;
|
||||
#endif
|
||||
|
||||
#if(RM_MODEL == RM_MODEL_TYPE_ADT_CAPS || RM_MODEL == RM_MODEL_TYPE_TB4000 || RM_MODEL == RM_MODEL_TYPE_BV2000 || SUB_MODEL_KEIYO_KR || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
static QMap<QString,QString> kos;
|
||||
#endif
|
||||
|
||||
#if(SUB_MODEL_BV5000 || RM_MODEL == RM_MODEL_TYPE_MH9000 || RM_MODEL_TYPE_EMT_KR)
|
||||
static QMap<QString,QString> ens;
|
||||
#endif
|
||||
#endif // FM_STR_TYPE2
|
||||
|
||||
static void load();
|
||||
static QString txt(const char* key);
|
||||
static QString txt(const char* key,RMLanguage::LANGUAGE_TYPE type);
|
||||
static QString txtLine(const char* key);
|
||||
|
||||
#if(SUPPORT_LANGUAGE_INSERT)
|
||||
// 1:JP, 2:EN, 3:KR
|
||||
static void insert_if_not_exist(int type,QString key, QString text);
|
||||
#endif // SUB_MODEL_BV5000
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // FM_STRINGS_H
|
||||
678
project/fm_viewer/core/fm_video_split.cpp
Normal file
678
project/fm_viewer/core/fm_video_split.cpp
Normal file
@@ -0,0 +1,678 @@
|
||||
#include "fm_video_split.h"
|
||||
#if (SUPPORT_AVI_SPLIT)
|
||||
|
||||
#include <QStyleOption>
|
||||
#include <QPainter>
|
||||
#include "../ui/QProgressIndicator.h"
|
||||
|
||||
#if !(USE_FFMPEG_TO_SPLIT)
|
||||
//#include "../data/rm_format_avi.h"
|
||||
//#include "../data/fileio.h"
|
||||
#else
|
||||
extern "C" {
|
||||
//#define __STDC_FORMAT_MACROS
|
||||
//#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
}
|
||||
#endif // #if (USE_FFMPEG_TO_SPLIT)
|
||||
|
||||
FMProgressDialog* FMVideoSplit::progress = NULL;
|
||||
|
||||
FMVideoSplit::FMVideoSplit(QString path)
|
||||
{
|
||||
_path = path;
|
||||
idx = NULL;
|
||||
}
|
||||
|
||||
#if !(USE_FFMPEG_TO_SPLIT)
|
||||
|
||||
#define A4_CHAR_TO_NUM(cs) ((((int32_t)cs[3])<<24)|(((int32_t)cs[2])<<16)|(((int32_t)cs[1])<<8)|(((int32_t)cs[0])))
|
||||
void FMVideoSplit::run()
|
||||
{
|
||||
QString document = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
|
||||
bFirstVideo = true;
|
||||
QString dest = QDir::cleanPath(document + QDir::separator() + QFileInfo(_path).baseName() + "_F" + ".AVI");
|
||||
if(QFile(dest).exists()) {
|
||||
QFile(dest).remove();
|
||||
}
|
||||
|
||||
convert(_path,dest);
|
||||
|
||||
bFirstVideo = false;
|
||||
dest = QDir::cleanPath(document + QDir::separator() + QFileInfo(_path).baseName() + "_R" + ".AVI");
|
||||
|
||||
if(QFile(dest).exists()) {
|
||||
QFile(dest).remove();
|
||||
}
|
||||
convert(_path,dest);
|
||||
|
||||
emit done();
|
||||
|
||||
}
|
||||
void FMVideoSplit::convert(QString path,QString dest)
|
||||
{
|
||||
FILE *file = _wfopen(path.toStdWString().c_str(),L"rb");
|
||||
memset(&root,0,sizeof(_RIFF_TREE));
|
||||
fread(&root.tag,4,1,file);
|
||||
fread(&root.size,4,1,file);
|
||||
fread(&root.type,4,1,file);
|
||||
root.offset = ftell(file);
|
||||
|
||||
//debugPrint(&root);
|
||||
|
||||
bFirstVideoStreamFound = false;
|
||||
readTree(file,&root,0);
|
||||
|
||||
root.offset_w = root.offset;
|
||||
//debugTree(&root);
|
||||
makeOffset(&root);
|
||||
makeIndex(&root);
|
||||
root.size_w += 4;
|
||||
//debugTree(&root);
|
||||
|
||||
//QString dest = "C:\\home\\temp\\copy2.avi";
|
||||
// QByteArray ba = str1.toLocal8Bit();
|
||||
//const char *c_str2 = ba.data();
|
||||
//FILE *wf = fopen(dest.toLocal8Bit().data(),"wb");
|
||||
FILE *wf = _wfopen(dest.toStdWString().c_str(),L"wb");
|
||||
saveTree(&root,file,wf);
|
||||
fclose(wf);
|
||||
fclose(file);
|
||||
|
||||
//qInfo() << "---------------------------------------------------";
|
||||
//
|
||||
free(idx);
|
||||
idx = NULL;
|
||||
freeTree(&root);
|
||||
|
||||
|
||||
QThread::msleep(100);
|
||||
}
|
||||
void FMVideoSplit::debugPrint(RIFF_TREE* item)
|
||||
{
|
||||
QString tab = "";
|
||||
for(int i=0;i<item->depth;i++) {
|
||||
tab += " ";
|
||||
}
|
||||
// RIFF_TREE* p = item->depth;
|
||||
// while(p != NULL) {
|
||||
// p = p->parent;
|
||||
// }
|
||||
|
||||
if(item->tag == A4_CHAR_TO_NUM("LIST") || item->tag == A4_CHAR_TO_NUM("RIFF")) {
|
||||
qInfo() << tab + QString().sprintf("OFFSET: %d",item->offset) +
|
||||
QString().sprintf(" W_OFFSET: %d COUNT:%d",item->offset_w,item->count) +
|
||||
QString().sprintf(" TAG:[%c%c%c%c]",(char)((item->tag >> 0) & 0xFF),(char)((item->tag >> 8) & 0xFF),(char)((item->tag >> 16) & 0xFF),(char)((item->tag >> 24) & 0xFF)) +
|
||||
QString().sprintf(" TYPE:[%c%c%c%c]",(char)(item->type >> 0 & 0xFF),(char)(item->type >> 8 & 0xFF),(char)(item->type >> 16 & 0xFF),(char)((item->type >> 24) & 0xFF)) +
|
||||
QString().sprintf(" SIZE: %d",item->size) + QString().sprintf(" SIZE_W: %d REMOVE:%d",item->size_w, item->remove);
|
||||
}
|
||||
else {
|
||||
qInfo() << tab + QString().sprintf("OFFSET: %d",item->offset) +
|
||||
QString().sprintf(" W_OFFSET: %d",item->offset_w) +
|
||||
QString().sprintf(" TAG:[%c%c%c%c]",(char)((item->tag >> 0) & 0xFF),(char)((item->tag >> 8) & 0xFF),(char)((item->tag >> 16) & 0xFF),(char)((item->tag >> 24) & 0xFF)) +
|
||||
QString().sprintf(" SIZE: %d",item->size) + QString().sprintf(" SIZE_W: %d REMOVE:%d",item->size_w, item->remove);
|
||||
}
|
||||
|
||||
}
|
||||
void FMVideoSplit::debugTree(RIFF_TREE* p)
|
||||
{
|
||||
//p->parent = NULL;
|
||||
debugPrint(p);
|
||||
int32_t sz = 0;
|
||||
for(int i=0;i<p->count;i++) {
|
||||
if(p->type == A4_CHAR_TO_NUM("movi")) {
|
||||
|
||||
// sz += 8;
|
||||
// sz = sz + p->childs[i].size + (p->childs[i].size % 2);
|
||||
// qInfo() << "+" << sz;
|
||||
}
|
||||
else {
|
||||
//p->childs[i].parent = NULL;
|
||||
debugTree(&p->childs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(p->type == A4_CHAR_TO_NUM("movi")) {
|
||||
qInfo() << "MOVI SIZE:" << sz;
|
||||
}
|
||||
}
|
||||
void FMVideoSplit::freeTree(RIFF_TREE* p)
|
||||
{
|
||||
if(p->childs != NULL) {
|
||||
// CHILD 가 존재할 경우 처리
|
||||
for(int i=0;i<p->count;i++) {
|
||||
if(p->childs[i].childs != NULL) {
|
||||
freeTree(&p->childs[i]);
|
||||
}
|
||||
}
|
||||
// SUB 가 없을 경우
|
||||
//debugPrint(parent);
|
||||
free(p->childs);
|
||||
}
|
||||
}
|
||||
void FMVideoSplit::saveTree(RIFF_TREE* p,FILE* read,FILE* write)
|
||||
{
|
||||
if(p->remove != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//debugPrint(p);
|
||||
int roffset_w = p->offset_w - 8;
|
||||
if(p->count > 0) {
|
||||
roffset_w -= 4; // TYPE
|
||||
}
|
||||
fseek(write,roffset_w,SEEK_SET);
|
||||
|
||||
|
||||
|
||||
fwrite(&p->tag,4,1,write);
|
||||
fwrite(&p->size_w,4,1,write);
|
||||
|
||||
|
||||
if(p->count > 0) {
|
||||
if(p->count > 0) {
|
||||
fwrite(&p->type,4,1,write);
|
||||
}
|
||||
for(int i=0;i<p->count;i++) {
|
||||
saveTree(&p->childs[i],read,write);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if(p->tag == A4_CHAR_TO_NUM("idx1")) {
|
||||
fwrite(idx,p->size_w,1,write);
|
||||
}
|
||||
else {
|
||||
// 그냥 이동하면 데이터 영역임
|
||||
fseek(read,p->offset,SEEK_SET);
|
||||
void* buffer = malloc(p->size);
|
||||
fread(buffer,p->size_w,1,read);
|
||||
|
||||
if(p->tag == A4_CHAR_TO_NUM("avih")) {
|
||||
AVIHeader* h = (AVIHeader*)buffer;
|
||||
h->NumberOfStreams = 3;
|
||||
//qInfo() << "NumberOfStreams:" << h->NumberOfStreams << "h->DataLength:" << h->DataLength ;
|
||||
}
|
||||
|
||||
fwrite(buffer,p->size_w,1,write);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
// OFFSET 우선 처리하고 index 처리
|
||||
void FMVideoSplit::makeIndex(RIFF_TREE* p)
|
||||
{
|
||||
RIFF_TREE* movi = NULL;
|
||||
for(int i=0;i<p->count;i++) {
|
||||
if(p->childs[i].type == A4_CHAR_TO_NUM("movi")) {
|
||||
movi = &p->childs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
//qInfo() << "MOV:" << movi->count << movi->count * 16;
|
||||
|
||||
idx = (int32_t*)malloc(movi->count * 16);
|
||||
int realCount = 0;
|
||||
for(int i=0;i<movi->count;i++) {
|
||||
RIFF_TREE* t = &movi->childs[i];
|
||||
|
||||
if(t->tag == A4_CHAR_TO_NUM("01dc")) {
|
||||
t->tag = A4_CHAR_TO_NUM("00dc");
|
||||
}
|
||||
else if (t->tag == A4_CHAR_TO_NUM("02wb")) {
|
||||
t->tag = A4_CHAR_TO_NUM("01wb");
|
||||
}
|
||||
else if (t->tag == A4_CHAR_TO_NUM("03tx")) {
|
||||
t->tag = A4_CHAR_TO_NUM("02tx");
|
||||
}
|
||||
int ri = realCount * 4;
|
||||
idx[ri + 0] = t->tag;
|
||||
idx[ri + 1] = 16;
|
||||
idx[ri + 2] = t->offset_w - 8;
|
||||
idx[ri + 3] = t->size;
|
||||
|
||||
if(t->remove != 1) {
|
||||
realCount++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RIFF_TREE* idx1 = NULL;
|
||||
for(int i=0;i<p->count;i++) {
|
||||
if(p->childs[i].tag == A4_CHAR_TO_NUM("idx1")) {
|
||||
idx1 = &p->childs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
idx1->size_w = realCount * 16;
|
||||
int diff = (idx1->size - (realCount * 16));
|
||||
p->size_w -= diff;
|
||||
//qInfo() << "IDX:" << idx1->size << idx1->size_w << "DIFF:" << diff;
|
||||
|
||||
}
|
||||
|
||||
// TREE 탐색하며 OFFSET 생성, SIZE 는 유지
|
||||
void FMVideoSplit::makeOffset(RIFF_TREE* p)
|
||||
{
|
||||
// if(p->remove != 0) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
int offset = p->offset_w; // SIZE + TAG 는 항상 존재
|
||||
|
||||
for(int i=0;i<p->count;i++) {
|
||||
|
||||
if(p->childs[i].remove == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int add = 8;
|
||||
if(p->childs[i].tag == A4_CHAR_TO_NUM("LIST")) {
|
||||
add += 4;
|
||||
}
|
||||
|
||||
// 쓰기 옵셋
|
||||
p->childs[i].offset_w = offset + add;
|
||||
|
||||
// if(p->childs[i].offset_w != p->childs[i].offset) {
|
||||
// qInfo() << offset << "--------------------------------------------";
|
||||
// debugPrint(&p->childs[i]);
|
||||
// qInfo() << add << "--------------------------------------------";
|
||||
// }
|
||||
|
||||
|
||||
if(p->childs[i].count > 0) {
|
||||
p->childs[i].size_w = 4; //???
|
||||
makeOffset(&p->childs[i]);
|
||||
}
|
||||
else if (p->childs[i].remove == 0){
|
||||
p->childs[i].size_w = p->childs[i].size;
|
||||
}
|
||||
|
||||
if(p->childs[i].remove == 0) {
|
||||
|
||||
|
||||
p->size_w = p->size_w + p->childs[i].size_w + (p->childs[i].size_w % 2);
|
||||
p->size_w += 8;
|
||||
|
||||
// if(p->type == A4_CHAR_TO_NUM("movi")) {
|
||||
// debugPrint(&p->childs[i]);
|
||||
// qInfo() << i << p->size_w;
|
||||
// }
|
||||
|
||||
// if(p->childs[i].tag == A4_CHAR_TO_NUM("LIST")) {
|
||||
// p->size_w += 4;
|
||||
// }
|
||||
|
||||
offset += 8; // TAG+SIZE
|
||||
offset += p->childs[i].size_w;
|
||||
|
||||
// PAD 2
|
||||
if(offset % 2 == 1) {
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
//parent->childs[i].offset = offset;
|
||||
}
|
||||
|
||||
}
|
||||
void FMVideoSplit::resizeTree(RIFF_TREE* item,int count)
|
||||
{
|
||||
// qInfo() << "REALLOC-----------" << count;
|
||||
// debugPrint(item);
|
||||
// qInfo() << "------------------";
|
||||
|
||||
RIFF_TREE* temp = (RIFF_TREE*)malloc(sizeof(_RIFF_TREE) * count);
|
||||
memset(temp,0,sizeof(_RIFF_TREE) * count);
|
||||
|
||||
memcpy(temp,item->childs,sizeof(_RIFF_TREE) * item->count);
|
||||
free(item->childs);
|
||||
item->childs = temp;
|
||||
}
|
||||
void FMVideoSplit::readTree(FILE* file, RIFF_TREE* p, int32_t depth)
|
||||
{
|
||||
const int buffer_count = 100;
|
||||
int current_buffer_count = 100;
|
||||
// if(p->type != A4_CHAR_TO_NUM("movi")) {
|
||||
// qInfo() << "CHECK:" << p->offset + p->size << "TELL:" << ftell(file);
|
||||
// }
|
||||
|
||||
while (ftell(file)<(p->offset + p->size - 4))
|
||||
{
|
||||
if(p->childs == NULL) {
|
||||
p->childs = (RIFF_TREE*)malloc(sizeof(_RIFF_TREE) * buffer_count);
|
||||
memset(p->childs,0,sizeof(_RIFF_TREE) * buffer_count);
|
||||
current_buffer_count = buffer_count;
|
||||
}
|
||||
|
||||
if(p->count + 1 >= current_buffer_count) {
|
||||
current_buffer_count += buffer_count;
|
||||
// 기존 레코드 복사
|
||||
resizeTree(p,current_buffer_count);
|
||||
}
|
||||
|
||||
RIFF_TREE* item = &p->childs[p->count];
|
||||
fread(&item->tag,4,1,file);
|
||||
fread(&item->size,4,1,file);
|
||||
item->offset = ftell(file); // SIZE 읽은 후 OFFSET 지정
|
||||
item->depth = depth + 1;
|
||||
//item->parent = p;
|
||||
|
||||
// 리스트만 처리
|
||||
if(item->tag == A4_CHAR_TO_NUM("LIST")) {
|
||||
|
||||
item->offset += 4; // LIST 는 TYPE 이 존재하여 추가
|
||||
fread(&item->type,4,1,file);
|
||||
//debugPrint(item);
|
||||
readTree(file,item,item->depth + 1);
|
||||
|
||||
// if(item->type == A4_CHAR_TO_NUM("movi")) {
|
||||
// item->remove = 1;
|
||||
// }
|
||||
}
|
||||
else {
|
||||
//if(p->type != A4_CHAR_TO_NUM("movi")) {
|
||||
//debugPrint(item);
|
||||
//}
|
||||
|
||||
if(item->tag == A4_CHAR_TO_NUM("strh")) {
|
||||
void* v = malloc(item->size);
|
||||
fread(v,item->size,1,file);
|
||||
_STRHeader* h = (_STRHeader*)v;
|
||||
if(h->DataType[0] == 'v' && h->DataType[1] == 'i' && h->DataType[2] == 'd' && h->DataType[3] == 's')
|
||||
{
|
||||
if(bFirstVideoStreamFound) {
|
||||
if(bFirstVideo) {
|
||||
p->remove = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!bFirstVideo) {
|
||||
p->remove = 1;
|
||||
}
|
||||
}
|
||||
bFirstVideoStreamFound = true;
|
||||
}
|
||||
//qInfo() << "STRH" << h->DataType;
|
||||
}
|
||||
|
||||
// if(item->tag == A4_CHAR_TO_NUM("idx1")) {
|
||||
// item->remove = 1;
|
||||
// }
|
||||
|
||||
if(item->tag == A4_CHAR_TO_NUM("01dc") && bFirstVideo) {
|
||||
item->remove = 1;
|
||||
}
|
||||
else if(item->tag == A4_CHAR_TO_NUM("00dc") && !bFirstVideo) {
|
||||
item->remove = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 2 BIT PAD
|
||||
int32_t seek = item->offset + item->size;
|
||||
if(seek % 2 == 1) {
|
||||
seek += 1;
|
||||
}
|
||||
fseek(file,seek,SEEK_SET);
|
||||
}
|
||||
p->count += 1;
|
||||
}
|
||||
resizeTree(p,p->count);
|
||||
}
|
||||
#else // (USE_FFMPEG_TO_SPLIT)
|
||||
// MP4 의 경우 PCM 오디오 인코딩이 안됨
|
||||
// MOV 의 경우 PCM 이 되나 미디어 플레이어에서 재생안됨
|
||||
// https://cpp.hotexamples.com/examples/-/-/avformat_write_header/cpp-avformat_write_header-function-examples.html
|
||||
bool FMVideoSplit::start(QString path)
|
||||
{
|
||||
//av_register_all();
|
||||
|
||||
QString outFile = "C:\\home\\temp\\test.mov";
|
||||
char buffer[1024] = {0,};
|
||||
qInfo() << path << __FUNCTION__;
|
||||
const AVOutputFormat *ofmt = NULL;
|
||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
AVPacket *pkt = NULL;
|
||||
//const char *in_filename, *out_filename;
|
||||
int ret, i;
|
||||
int stream_index = 0;
|
||||
int *stream_mapping = NULL;
|
||||
int stream_mapping_size = 0;
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
qInfo() << "Could not allocate AVPacket";
|
||||
// fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// d->format_ctx->probesize = 8000000;
|
||||
// d->format_ctx->max_analyze_duration = 8000000;
|
||||
// ret = avformat_find_stream_info(d->format_ctx, NULL);
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, path.toUtf8().constData(), 0, 0)) < 0) {
|
||||
qInfo() << "Could not open input file " << path;
|
||||
// fprintf(stderr, "Could not open input file '%s'", .toUtf8().constData());
|
||||
goto end;
|
||||
}
|
||||
// ifmt_ctx->probesize = 8000000;
|
||||
// ifmt_ctx->max_analyze_duration = 8000000;
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
|
||||
qInfo() << "Failed to retrieve input stream information";
|
||||
//fprintf(stderr, "Failed to retrieve input stream information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, path.toUtf8().constData(), 0);
|
||||
|
||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, outFile.toUtf8().constData());
|
||||
if (!ofmt_ctx) {
|
||||
qInfo() << "Could not create output context";
|
||||
//fprintf(stderr, "Could not create output context\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
||||
stream_mapping = (int*)av_calloc(stream_mapping_size, sizeof(*stream_mapping));
|
||||
if (!stream_mapping) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ofmt = ofmt_ctx->oformat;
|
||||
|
||||
bool bVideo = false;
|
||||
|
||||
int subtitle_stream = -1;
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||
AVCodecParameters *in_codecpar = in_stream->codecpar;
|
||||
|
||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
||||
stream_mapping[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// bVideo
|
||||
if(in_codecpar->codec_type == AVMEDIA_TYPE_VIDEO && !bVideo) {
|
||||
|
||||
bVideo = true;
|
||||
//qInfo() << "TEST" << __FUNCTION__;
|
||||
stream_mapping[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(in_codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
|
||||
//qInfo() << "TEST" << __FUNCTION__;
|
||||
//stream_mapping[i] = -1;
|
||||
//continue;
|
||||
}
|
||||
|
||||
if(in_codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
|
||||
subtitle_stream = i;
|
||||
in_codecpar->codec_id = AV_CODEC_ID_MOV_TEXT;//AV_CODEC_ID_TEXT;
|
||||
//in_codecpar->codec_id = AV_CODEC_ID_TEXT;
|
||||
//qInfo() << "TEST" << __FUNCTION__;
|
||||
//stream_mapping[i] = -1;
|
||||
//continue;
|
||||
}
|
||||
|
||||
|
||||
stream_mapping[i] = stream_index++;
|
||||
|
||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
||||
if (!out_stream) {
|
||||
qInfo() << "Failed allocating output stream";
|
||||
//fprintf(stderr, "Failed allocating output stream\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
|
||||
if (ret < 0) {
|
||||
qInfo() << "Failed to copy codec parameters";
|
||||
//fprintf(stderr, "Failed to copy codec parameters\n");
|
||||
goto end;
|
||||
}
|
||||
out_stream->codecpar->codec_tag = 0;
|
||||
}
|
||||
// AUDIO STREAM
|
||||
//open_audio(ofmt_ctx, audio_codec, &audio_st, opt);
|
||||
|
||||
av_dump_format(ofmt_ctx, 0, outFile.toUtf8().constData(), 1);
|
||||
|
||||
if (!(ofmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&ofmt_ctx->pb, outFile.toUtf8().constData(), AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
qInfo() << "Could not open output file " << outFile;
|
||||
//fprintf(stderr, "Could not open output file '%s'", outFile.toUtf8().constData());
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/31846650/avformat-write-header-return-error-code-when-trying-to-write-pcmu-encoded-frame
|
||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
memset(buffer,0,1024);
|
||||
av_strerror(ret,buffer,1024);
|
||||
qInfo() << "Error occurred when opening output file" << buffer;
|
||||
// fprintf(stderr, "Error occurred when opening output file\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
AVStream *in_stream, *out_stream;
|
||||
|
||||
ret = av_read_frame(ifmt_ctx, pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
in_stream = ifmt_ctx->streams[pkt->stream_index];
|
||||
if (pkt->stream_index >= stream_mapping_size ||
|
||||
stream_mapping[pkt->stream_index] < 0) {
|
||||
av_packet_unref(pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
// SUB TITLE 일 경우
|
||||
if(in_stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
qInfo() << (const char*)pkt->data << __FUNCTION__;
|
||||
}
|
||||
|
||||
pkt->stream_index = stream_mapping[pkt->stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt->stream_index];
|
||||
//log_packet(ifmt_ctx, pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
|
||||
pkt->pos = -1;
|
||||
//log_packet(ofmt_ctx, pkt, "out");
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
qInfo() << "Error muxing packet";
|
||||
//fprintf(stderr, "Error muxing packet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
/* close output */
|
||||
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
av_freep(&stream_mapping);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
//fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // USE_FFMPEG_TO_SPLIT
|
||||
|
||||
|
||||
|
||||
FMProgressDialog::FMProgressDialog(QWidget *parent, QString title) : QDialog(parent)
|
||||
{
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||
setModal(true);
|
||||
setStyleSheet("FMProgressDialog{ background-color: #3a3a3a; border: 3px solid #666666;}"); //
|
||||
setFixedSize(120,120);
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(20);
|
||||
layout->setAlignment(Qt::AlignCenter);
|
||||
QLabel* top = new QLabel(this);
|
||||
top->setAlignment(Qt::AlignCenter);
|
||||
top->setText(title); // QString::fromWCharArray(L"ファイル分割中")
|
||||
top->setStyleSheet("font-family: MS PGothic; font-style: bold;font-size:14px; color : #6699FF");
|
||||
layout->addWidget(top);
|
||||
|
||||
|
||||
indicator = new QProgressIndicator(this);
|
||||
indicator->setFixedSize(120,50);
|
||||
indicator->setColor(QColor(0x6699FF));
|
||||
indicator->show();
|
||||
indicator->startAnimation();
|
||||
layout->addWidget(indicator);
|
||||
|
||||
// QLabel* bottom = new QLabel(this);
|
||||
// bottom->setAlignment(Qt::AlignCenter);
|
||||
// bottom->setText(QString::fromWCharArray(L"8〜30秒かかります"));
|
||||
// bottom->setStyleSheet("font-family: MS PGothic; font-style: black;font-size:18px; color : #FFFFFF");
|
||||
// layout->addWidget(bottom);
|
||||
|
||||
}
|
||||
|
||||
void FMProgressDialog::paintEvent(QPaintEvent *pe)
|
||||
{
|
||||
Q_UNUSED(pe);
|
||||
|
||||
QStyleOption o;
|
||||
o.initFrom(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
|
||||
}
|
||||
|
||||
|
||||
#endif // #if (SUPPORT_AVI_SPLIT)
|
||||
86
project/fm_viewer/core/fm_video_split.h
Normal file
86
project/fm_viewer/core/fm_video_split.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef FM_VIDEO_SPLIT_H
|
||||
#define FM_VIDEO_SPLIT_H
|
||||
#if (SUPPORT_AVI_SPLIT)
|
||||
|
||||
#include <QObject>
|
||||
#include <QtCore>
|
||||
#include <QDialog>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// MP4 의 경우 PCM 오디오 인코딩이 안됨
|
||||
// MOV 의 경우 PCM 이 되나 미디어 플레이어에서 재생안됨
|
||||
// AVI RIFF 처리로 분리 해야함..
|
||||
// https://cpp.hotexamples.com/examples/-/-/avformat_write_header/cpp-avformat_write_header-function-examples.html
|
||||
#define USE_FFMPEG_TO_SPLIT 0
|
||||
|
||||
#if !(USE_FFMPEG_TO_SPLIT)
|
||||
#include "../data/rm_format_avi.h"
|
||||
#endif // USE_FFMPEG_TO_SPLIT
|
||||
|
||||
|
||||
class QProgressIndicator;
|
||||
class FMProgressDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FMProgressDialog(QWidget *parent, QString title);
|
||||
QProgressIndicator* indicator;
|
||||
private:
|
||||
void paintEvent(QPaintEvent *pe) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct _RIFF_TREE
|
||||
{
|
||||
int32_t tag;
|
||||
int32_t type;
|
||||
int32_t offset;
|
||||
int32_t offset_w;
|
||||
int32_t size;
|
||||
int32_t size_w;
|
||||
int32_t depth;
|
||||
int32_t remove; // 제거
|
||||
//_RIFF_TREE* parent; // REALLOCATE 로 링크가 깨짐 readTree 내부에서만 사용
|
||||
int32_t count;
|
||||
_RIFF_TREE* childs;
|
||||
} RIFF_TREE;
|
||||
|
||||
class FMVideoSplit : public QObject, public QRunnable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FMVideoSplit(QString path);
|
||||
//bool start(QString path);
|
||||
virtual void run();
|
||||
|
||||
static FMProgressDialog* progress;
|
||||
|
||||
private:
|
||||
|
||||
#if !(USE_FFMPEG_TO_SPLIT)
|
||||
|
||||
QString _path;
|
||||
|
||||
int32_t *idx;
|
||||
|
||||
bool bFirstVideo;
|
||||
bool bFirstVideoStreamFound;
|
||||
RIFF_TREE root;
|
||||
void debugPrint(RIFF_TREE* item);
|
||||
void debugTree(RIFF_TREE* p);
|
||||
void freeTree(RIFF_TREE* p);
|
||||
void makeOffset(RIFF_TREE* p);
|
||||
void makeIndex(RIFF_TREE* p);
|
||||
void saveTree(RIFF_TREE* p,FILE* read, FILE* write);
|
||||
void resizeTree(RIFF_TREE* item,int count);
|
||||
void readTree(FILE* file, RIFF_TREE* p,int32_t depth);
|
||||
void convert(QString path,QString dest);
|
||||
#endif
|
||||
signals:
|
||||
void done();
|
||||
};
|
||||
#endif // (SUPPORT_AVI_SPLIT)
|
||||
#endif // FM_VIDEO_SPLIT_H
|
||||
260
project/fm_viewer/core/rm_excel_report.cpp
Normal file
260
project/fm_viewer/core/rm_excel_report.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
#include "rm_excel_report.h"
|
||||
#include "../rm_app.h"
|
||||
#include "../rm_include.h"
|
||||
#include "../fm_dimensions.h"
|
||||
#include "../ui/rm_dialog_map.h"
|
||||
#include "../ui/rm_widget_map.h"
|
||||
#include "../core/rm_math.h"
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
|
||||
// Screen Capture
|
||||
#include <QPixmap>
|
||||
#include <QScreen>
|
||||
#include <QGuiApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QDialog>
|
||||
#include <QDate>
|
||||
#include <QDateTime>
|
||||
|
||||
#if (USE_JP_ADDRESS)
|
||||
#include "../data/fm_address.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
float QAspectScaleFit(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float scaleW = (float)destSize.width() / (float)sourceSize.width();
|
||||
float scaleH = (float)destSize.height() / (float)sourceSize.height();
|
||||
return MIN(scaleW, scaleH);
|
||||
}
|
||||
|
||||
|
||||
// Fit
|
||||
QRect QRectAspectFitRect(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float destScale = QAspectScaleFit(sourceSize, destRect);
|
||||
|
||||
float newWidth = (float)sourceSize.width() * destScale;
|
||||
float newHeight = (float)sourceSize.height() * destScale;
|
||||
|
||||
float dWidth = (((float)destSize.width() - newWidth) / 2.0f);
|
||||
float dHeight = (((float)destSize.height() - newHeight) / 2.0f);
|
||||
|
||||
QRect rect = QRect(dWidth + destRect.left(), dHeight + destRect.top(), newWidth, newHeight);
|
||||
return rect;
|
||||
}
|
||||
*/
|
||||
|
||||
RMExcelReport::RMExcelReport(QObject *parent) : QAxObject("Excel.Application",parent)
|
||||
{
|
||||
_workbooks = NULL;
|
||||
_workbook = NULL;
|
||||
_sheets = NULL;
|
||||
_sheet = NULL;
|
||||
_shapes = NULL;
|
||||
_picture = NULL;
|
||||
}
|
||||
|
||||
void RMExcelReport::clearAll()
|
||||
{
|
||||
// 순서대로 제거해야함!!
|
||||
if(_picture != NULL) {
|
||||
delete _picture;
|
||||
_picture = NULL;
|
||||
}
|
||||
if(_shapes != NULL) {
|
||||
delete _shapes;
|
||||
_shapes = NULL;
|
||||
}
|
||||
if(_sheet != NULL) {
|
||||
delete _sheet;
|
||||
_sheet = NULL;
|
||||
}
|
||||
if(_sheets != NULL) {
|
||||
delete _sheets;
|
||||
_sheets = NULL;
|
||||
}
|
||||
if(_workbook != NULL) {
|
||||
delete _workbook;
|
||||
_workbook = NULL;
|
||||
}
|
||||
if(_workbooks != NULL) {
|
||||
delete _workbooks;
|
||||
_workbooks = NULL;
|
||||
}
|
||||
}
|
||||
#if (USE_JP_ADDRESS)
|
||||
bool RMExcelReport::prepare(QString& path,QDateTime* pDateTime, double lon, double lat)
|
||||
#else
|
||||
bool RMExcelReport::prepare(QString& path,QDateTime* pDateTime)
|
||||
#endif
|
||||
{
|
||||
#if (RM_MODEL != RM_MODEL_TYPE_XLDR_88)
|
||||
Q_UNUSED(pDateTime)
|
||||
#endif // !RM_MODEL_TYPE_XLDR_88
|
||||
QDateTime date = QDateTime::currentDateTime();
|
||||
|
||||
|
||||
_workbooks = querySubObject("Workbooks");
|
||||
if(_workbooks == NULL)
|
||||
{
|
||||
clearAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 저장 완료
|
||||
QString tempReportPath = QDir::cleanPath(RMApp::appPath(RMApp::CAPTURE) + "/_report" + date.toString("yyyy_MMdd_HHmmss") + ".xls");
|
||||
QFile::copy(":/report/report.xls",tempReportPath);
|
||||
QFile::setPermissions(tempReportPath,QFile::permissions(tempReportPath) | QFileDevice::WriteOther);
|
||||
// qInfo() << tempReportPath;
|
||||
|
||||
// QDir::toNativeSeparators(last);
|
||||
|
||||
|
||||
|
||||
QString srcPath = QDir::toNativeSeparators(tempReportPath);
|
||||
|
||||
|
||||
|
||||
_workbook = _workbooks->querySubObject( "Open(const QString&)", srcPath );
|
||||
if(_workbook == NULL) {
|
||||
clearAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 경고 표시 방지
|
||||
_workbook->setProperty("DisplayAlerts", false);
|
||||
_sheets = _workbook->querySubObject( "Worksheets" );
|
||||
if(_sheets == NULL)
|
||||
{
|
||||
clearAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
// sheet 가져옴
|
||||
_sheet = _sheets->querySubObject( "Item( int )", 1 );
|
||||
if(_sheet == NULL)
|
||||
{
|
||||
clearAll();
|
||||
return false;
|
||||
}
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
|
||||
|
||||
//qInfo() << time << __FUNCTION__;
|
||||
QAxObject * range;
|
||||
|
||||
// 보고서 작성일을 기준으로 생성
|
||||
QDateTime current = QDateTime::currentDateTime();
|
||||
|
||||
range = _sheet->querySubObject("Range(AQ2)");
|
||||
range->setProperty("Value",current.toString("yyyy"));
|
||||
|
||||
range = _sheet->querySubObject("Range(AU2)");
|
||||
range->setProperty("Value",current.toString("MM"));
|
||||
|
||||
range = _sheet->querySubObject("Range(AX2)");
|
||||
range->setProperty("Value",current.toString("dd"));
|
||||
|
||||
// 사고 발생일은 데이터 시간
|
||||
range = _sheet->querySubObject("Range(H12)");
|
||||
range->setProperty("Value",pDateTime->toString("yyyy-MM-dd"));
|
||||
|
||||
QString pam = pDateTime->time().hour() > 12 ? "PM" : "AM";
|
||||
|
||||
range = _sheet->querySubObject("Range(W12)");
|
||||
range->setProperty("Value",pam + " " + pDateTime->toString("HH") + QString::fromUtf8("\xe6\x99\x82") + pDateTime->toString("mm"));
|
||||
|
||||
#if (USE_JP_ADDRESS)
|
||||
|
||||
if(IS_VALID_LOCATION(lon,lat))
|
||||
{
|
||||
// 발생장소
|
||||
if(FMAddress::instance()->open()) {
|
||||
QStringList res;
|
||||
if(FMAddress::instance()->search(lon,lat,res)) {
|
||||
|
||||
range = _sheet->querySubObject("Range(H14)");
|
||||
QString address = (res.at(0) + " " + res.at(1) + " " + res.at(2) + " " + res.at(3) + "-" + res.at(4));
|
||||
range->setProperty("Value",address);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // USE_JP_ADDRESS
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
QPixmap originalPixmap = screen->grabWindow(RMApp::instance()->pMainWindow->winId());
|
||||
|
||||
QPainter painter(&originalPixmap);
|
||||
|
||||
#if !(DO_NOT_USE_MAP)
|
||||
// 지도 크기로 생성
|
||||
#if (USE_WEBVIEW2)
|
||||
QPixmap mapPixmap;
|
||||
#else // #if (USE_WEBVIEW2)
|
||||
QPixmap mapPixmap(RMDialogMap::instance()->_map->size());
|
||||
// 그린다
|
||||
// qInfo() << RMDialogMap::instance()->isGPSExist();
|
||||
if(RMDialogMap::instance()->isGPSExist()) {
|
||||
RMDialogMap::instance()->_map->render(&mapPixmap);
|
||||
}
|
||||
#endif // #if (USE_WEBVIEW2)
|
||||
|
||||
// 지도 그릴 영역
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
|
||||
QRect targetRect = QRect(699,285,352,391);
|
||||
#else
|
||||
QRect targetRect = QRect(681,331,339,358);
|
||||
#endif
|
||||
|
||||
QRect cropSrc = QRect();
|
||||
cropSrc.setSize(targetRect.size());
|
||||
QRect cropRect = QRectAspectFitRect(targetRect.size(),cropSrc);
|
||||
#if (DUAL_VIEWER)
|
||||
QPixmap cropped = mapPixmap.copy(0,(358-225)/2,cropRect.width(),cropRect.height());
|
||||
#else
|
||||
// 크롭
|
||||
QPixmap cropped = mapPixmap.copy(cropRect);
|
||||
#endif
|
||||
|
||||
// 지도 그림
|
||||
painter.drawPixmap(targetRect.left(),targetRect.top(),targetRect.width(),targetRect.height(),cropped);
|
||||
#endif // #if !(DO_NOT_USE_MAP)
|
||||
|
||||
// 저장 (엑셀에서 불러오기 위해)
|
||||
QString tempImagePath = QDir::cleanPath(RMApp::appPath(RMApp::CAPTURE) + "/_report" + date.toString("yyyy_MMdd_HHmmss") + ".jpg");
|
||||
QFile imageFile(tempImagePath);
|
||||
if(imageFile.exists())
|
||||
{
|
||||
QFile::remove(tempImagePath);
|
||||
}
|
||||
imageFile.open(QIODevice::WriteOnly);
|
||||
originalPixmap.save(&imageFile, "JPG");
|
||||
imageFile.close();
|
||||
|
||||
// 엑셀파일 이미지 영역
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_XLDR_88)
|
||||
QRect imageRect(33,633,507,507*MAIN_WINDOW_HEIGHT/MAIN_WINDOW_WIDTH);
|
||||
#else
|
||||
QRect imageRect(781,409,480,480*MAIN_WINDOW_HEIGHT/MAIN_WINDOW_WIDTH);
|
||||
#endif
|
||||
QRect destRect = QRectAspectFitRect(originalPixmap.size(),imageRect);
|
||||
|
||||
_shapes = _sheet->querySubObject("Shapes");
|
||||
_picture = _shapes->querySubObject("AddPicture( QString&, bool, bool, double, double, double, double)",QDir::toNativeSeparators(tempImagePath),true,true,destRect.left(),destRect.top(),destRect.width(),destRect.height());
|
||||
|
||||
|
||||
_workbook->dynamicCall("SaveAs (const QString&)", QDir::toNativeSeparators(path));
|
||||
_workbook->dynamicCall("Close()");
|
||||
|
||||
clearAll();
|
||||
dynamicCall("Quit()");
|
||||
QFile::remove(tempReportPath);
|
||||
QFile::remove(tempImagePath);
|
||||
return true;
|
||||
}
|
||||
30
project/fm_viewer/core/rm_excel_report.h
Normal file
30
project/fm_viewer/core/rm_excel_report.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef RM_EXCEL_REPORT_H
|
||||
#define RM_EXCEL_REPORT_H
|
||||
|
||||
#include <QAxObject>
|
||||
|
||||
class RMExcelReport : public QAxObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMExcelReport(QObject *parent = nullptr);
|
||||
#if (USE_JP_ADDRESS)
|
||||
bool prepare(QString& path,QDateTime* pDateTime, double lon, double lat);
|
||||
#else
|
||||
bool prepare(QString& path,QDateTime* pDateTime);
|
||||
#endif
|
||||
private:
|
||||
void clearAll();
|
||||
QAxObject* _workbooks;
|
||||
QAxObject* _workbook;
|
||||
QAxObject* _sheets;
|
||||
QAxObject* _sheet;
|
||||
|
||||
QAxObject* _shapes;
|
||||
QAxObject* _picture;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // RM_EXCEL_REPORT_H
|
||||
79
project/fm_viewer/core/rm_key_event.cpp
Normal file
79
project/fm_viewer/core/rm_key_event.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "rm_key_event.h"
|
||||
#include "ui/fm_button.h"
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
|
||||
|
||||
RMKeyEvent::RMKeyEvent(QObject *parent) : QObject(parent)
|
||||
{
|
||||
_lastKey = -1;
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
void RMKeyEvent::pressed(int key)
|
||||
{
|
||||
// KEY PRESS + MOUSE PRESS 동시 처리할 경우
|
||||
if(_enabled && exist(key) && _lastKey != key)
|
||||
{
|
||||
// 이전 pressed 된 이후 released 안된 버튼 존재할 경우
|
||||
if(_lastKey != -1)
|
||||
{
|
||||
released(_lastKey);
|
||||
}
|
||||
|
||||
_lastKey = key;
|
||||
switch (key) {
|
||||
case Qt::Key_Right:
|
||||
// qInfo() << "F1 start";
|
||||
emit pressedF1();
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
//qInfo() << "B1 start";
|
||||
emit pressedB1();
|
||||
break;
|
||||
case Qt::Key_F:
|
||||
//qInfo() << "FF start";
|
||||
emit pressedFF();
|
||||
break;
|
||||
case Qt::Key_D:
|
||||
//qInfo() << "FF start";
|
||||
emit pressedBF();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RMKeyEvent::released(int key)
|
||||
{
|
||||
FMButton* btn = qobject_cast<FMButton*>(sender());
|
||||
if(btn != NULL) {
|
||||
btn->blockFor(100);
|
||||
}
|
||||
|
||||
if(_enabled && exist(key) && key == _lastKey)
|
||||
{
|
||||
_lastKey = -1;
|
||||
switch (key) {
|
||||
case Qt::Key_Right:
|
||||
// qInfo() << "F1 end";
|
||||
emit releasedF1();
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
//qInfo() << "B1 end";
|
||||
emit releasedB1();
|
||||
break;
|
||||
case Qt::Key_F:
|
||||
//qInfo() << "FF end";
|
||||
emit releasedFF();
|
||||
break;
|
||||
case Qt::Key_D:
|
||||
//qInfo() << "FF end";
|
||||
emit releasedBF();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
74
project/fm_viewer/core/rm_key_event.h
Normal file
74
project/fm_viewer/core/rm_key_event.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef RM_KEY_EVENT_H
|
||||
#define RM_KEY_EVENT_H
|
||||
#include "../rm_include.h"
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
|
||||
#include <QObject>
|
||||
#include <QKeyEvent>
|
||||
|
||||
class RMKeyEvent : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMKeyEvent(QObject *parent = nullptr);
|
||||
static RMKeyEvent* instance()
|
||||
{
|
||||
static RMKeyEvent * _instance = 0;
|
||||
if ( _instance == 0 ) {
|
||||
_instance = new RMKeyEvent();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
void pressed(int key);
|
||||
void released(int key);
|
||||
inline static bool exist(int key)
|
||||
{
|
||||
return (key == Qt::Key_Left || key == Qt::Key_Right || key == Qt::Key_F || key == Qt::Key_D);
|
||||
}
|
||||
inline bool exist()
|
||||
{
|
||||
return (_lastKey != -1);
|
||||
}
|
||||
|
||||
void setEnabled(bool enabled)
|
||||
{
|
||||
_enabled = enabled;
|
||||
_lastKey = -1;
|
||||
}
|
||||
|
||||
private:
|
||||
int _lastKey;
|
||||
bool _enabled;
|
||||
signals:
|
||||
|
||||
void pressedF1();
|
||||
void releasedF1();
|
||||
void pressedB1();
|
||||
void releasedB1();
|
||||
void pressedFF();
|
||||
void releasedFF();
|
||||
void pressedBF();
|
||||
void releasedBF();
|
||||
|
||||
public slots:
|
||||
void onPressedF1()
|
||||
{
|
||||
pressed(Qt::Key_Right);
|
||||
}
|
||||
void onReleasedF1()
|
||||
{
|
||||
released(Qt::Key_Right);
|
||||
}
|
||||
void onPressedB1()
|
||||
{
|
||||
pressed(Qt::Key_Left);
|
||||
}
|
||||
void onReleasedB1()
|
||||
{
|
||||
released(Qt::Key_Left);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #if (USE_RM_KEYBOARD_EVENT)
|
||||
|
||||
#endif // RM_KEY_EVENT_H
|
||||
136
project/fm_viewer/core/rm_language.cpp
Normal file
136
project/fm_viewer/core/rm_language.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "rm_language.h"
|
||||
#if(LIVE_LANGUAGE_CHANGE)
|
||||
#include <QDebug>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include "../rm_settings.h"
|
||||
#include "../rm_include.h"
|
||||
#include "fm_strings.h"
|
||||
#include <QLocale>
|
||||
#if (INITIAL_LANGUAGE_AUTO)
|
||||
bool RMLanguage::isAuto = true;
|
||||
#else
|
||||
bool RMLanguage::isAuto = false;
|
||||
#endif
|
||||
|
||||
RMLanguage::RMLanguage(QObject *parent) : QObject(parent)
|
||||
{
|
||||
#if (FIXED_ENGLISH)
|
||||
RMLanguage::isAuto = false;
|
||||
_currentLanguage = LANGUAGE_EN;
|
||||
#else
|
||||
RMLanguage::isAuto = RMSettings::instance()->autoLanguage();
|
||||
_currentLanguage = (LANGUAGE_TYPE)RMSettings::instance()->language();
|
||||
#endif
|
||||
_list = new QHash<qint64,QHash<int,QString>*>();
|
||||
}
|
||||
RMLanguage::LANGUAGE_TYPE RMLanguage::systemLanguage()
|
||||
{
|
||||
QString lan = QLocale::system().name();
|
||||
#if (LIVE_LANGUAGE2)
|
||||
if(lan.contains("JP",Qt::CaseInsensitive))
|
||||
{
|
||||
return RMLanguage::LANGUAGE_JP;
|
||||
}
|
||||
else if (lan.contains("KR",Qt::CaseInsensitive)) {
|
||||
return RMLanguage::LANGUAGE_KR;
|
||||
}
|
||||
return RMLanguage::LANGUAGE_EN;
|
||||
#else // #if (LIVE_LANGUAGE2)
|
||||
#if (LANGUAGE_REMOVE_ENG) // WATEX
|
||||
return RMLanguage::LANGUAGE_JP;
|
||||
#else
|
||||
if(lan.contains("JP",Qt::CaseInsensitive))
|
||||
{
|
||||
return RMLanguage::LANGUAGE_JP;
|
||||
}
|
||||
return RMLanguage::LANGUAGE_EN;
|
||||
#endif
|
||||
#endif // #if (LIVE_LANGUAGE2)
|
||||
}
|
||||
|
||||
|
||||
#if (LIVE_LANGUAGE2)
|
||||
void RMLanguage::append(const char* key,RMLanguage::TEXT_TYPE type,QObject* control)
|
||||
{
|
||||
qint64 object_key = (qint64)control;
|
||||
//qInfo() << control << "key:" << key;
|
||||
QHash<int,QString>* info = _list->value(object_key);
|
||||
if(info == NULL)
|
||||
{
|
||||
info = new QHash<int,QString>();
|
||||
_list->insert(object_key,info);
|
||||
}
|
||||
info->insert((LANGUAGE_JP | type),FMS::txt(key,LANGUAGE_JP));
|
||||
info->insert((LANGUAGE_EN | type),FMS::txt(key,LANGUAGE_EN));
|
||||
info->insert((LANGUAGE_KR | type),FMS::txt(key,LANGUAGE_KR));
|
||||
}
|
||||
#else // LIVE_LANGUAGE2
|
||||
void RMLanguage::append(RMLanguage::LANGUAGE_TYPE language,RMLanguage::TEXT_TYPE type, QObject* control,QString str)
|
||||
{
|
||||
//QMutableHashIterator itr = _list->iterator;
|
||||
//_controls->append(control);
|
||||
qint64 key = (qint64)control;
|
||||
//qInfo() << control << "key:" << key;
|
||||
QHash<int,QString>* info = _list->value(key);
|
||||
if(info == NULL)
|
||||
{
|
||||
info = new QHash<int,QString>();
|
||||
_list->insert(key,info);
|
||||
}
|
||||
info->insert((language | type),str);
|
||||
//info->insert((LANGUAGE_EN | type),"TEST");
|
||||
//qInfo()<< "insert:" << str;
|
||||
}
|
||||
#endif // LIVE_LANGUAGE2
|
||||
|
||||
void RMLanguage::setLanguage(RMLanguage::LANGUAGE_TYPE language)
|
||||
{
|
||||
#if (FIXED_ENGLISH)
|
||||
Q_UNUSED(language);
|
||||
#else
|
||||
_currentLanguage = language;
|
||||
refresh();
|
||||
RMSettings::instance()->setLanguage(_currentLanguage);
|
||||
emit languageChange(_currentLanguage);
|
||||
#endif
|
||||
}
|
||||
void RMLanguage::remove(QObject* control)
|
||||
{
|
||||
qint64 key = (qint64)control;
|
||||
_list->remove(key);
|
||||
}
|
||||
void RMLanguage::refresh()
|
||||
{
|
||||
RMLanguage::LANGUAGE_TYPE language = _currentLanguage;
|
||||
foreach (qint64 key, _list->keys()) {
|
||||
|
||||
QHash<int,QString>* info = _list->value(key);
|
||||
// qInfo() << control;
|
||||
|
||||
QObject* control = (QObject*)key;
|
||||
if(control->inherits("QPushButton"))
|
||||
{
|
||||
QString str = info->value(language | TOOLTIP_TEXT);
|
||||
QPushButton* btn = (QPushButton*)control;
|
||||
if(str.length() > 0)
|
||||
{
|
||||
btn->setToolTip(str);
|
||||
}
|
||||
str = info->value(language | TITLE_TEXT);
|
||||
if(str.length() > 0)
|
||||
{
|
||||
btn->setText(str);
|
||||
}
|
||||
}
|
||||
else if (control->inherits("QLabel"))
|
||||
{
|
||||
QLabel* lb = (QLabel*)control;
|
||||
QString str = info->value(language | TITLE_TEXT);
|
||||
//qInfo() << info->values();
|
||||
lb->setText(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
134
project/fm_viewer/core/rm_language.h
Normal file
134
project/fm_viewer/core/rm_language.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#ifndef RM_LANGUAGE_H
|
||||
#define RM_LANGUAGE_H
|
||||
#if(LIVE_LANGUAGE_CHANGE)
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
|
||||
// 등록(append)하여 자동으로 변경되는 타입(Button,Label)과
|
||||
// signal/slot 방식으로 처리 (TableWidget Header.. etc)
|
||||
class RMLanguage : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LANGUAGE_JP = 1 << 0, // 1
|
||||
LANGUAGE_EN = 1 << 1, // 2
|
||||
#if (RC_LANGUAGE == 0x0412)
|
||||
LANGUAGE_KR = 1 << 2, // 4
|
||||
#endif
|
||||
} LANGUAGE_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TITLE_TEXT = 1 << 8,
|
||||
TOOLTIP_TEXT = 1 << 9,
|
||||
} TEXT_TYPE;
|
||||
|
||||
explicit RMLanguage(QObject *parent = NULL);
|
||||
|
||||
static RMLanguage* instance()
|
||||
{
|
||||
static RMLanguage * _instance = NULL;
|
||||
if ( _instance == 0 ) {
|
||||
_instance = new RMLanguage();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
static RMLanguage::LANGUAGE_TYPE systemLanguage();
|
||||
static bool isAuto;
|
||||
#if !(REMOVE_OLD_C)
|
||||
static bool isJP() // 제거예정
|
||||
{
|
||||
#if (FIXED_ENGLISH)
|
||||
return false;
|
||||
#else
|
||||
return (RMLanguage::instance()->language() == RMLanguage::LANGUAGE_JP);
|
||||
#endif
|
||||
}
|
||||
#endif // #if !(REMOVE_OLD_C)
|
||||
static QString languageTag()
|
||||
{
|
||||
#if (LANGUAGE_REMOVE_ENG)
|
||||
return "";
|
||||
#else // LANGUAGE_REMOVE_ENG
|
||||
#if (FIXED_ENGLISH)
|
||||
return "_en";
|
||||
#else // FIXED_ENGLISH
|
||||
#if (SUB_MODEL_BV5000 == 1 || RM_MODEL == 16 || SUPPORT_MULTI_LANGUAGE)
|
||||
switch(RMLanguage::instance()->language()) {
|
||||
case RMLanguage::LANGUAGE_EN:
|
||||
return "_en";
|
||||
case RMLanguage::LANGUAGE_JP:
|
||||
return "_jp";
|
||||
case RMLanguage::LANGUAGE_KR:
|
||||
return "";
|
||||
}
|
||||
#else
|
||||
return (RMLanguage::instance()->language() == RMLanguage::LANGUAGE_EN) ? "_en" : "";
|
||||
#endif //SUB_MODEL_BV5000
|
||||
#endif // FIXED_ENGLISH
|
||||
#endif // LANGUAGE_REMOVE_ENG
|
||||
return "";
|
||||
}
|
||||
|
||||
#if (LIVE_LANGUAGE2)
|
||||
void append(const char* key,RMLanguage::TEXT_TYPE type,QObject* control);
|
||||
#else // LIVE_LANGUAGE2
|
||||
void append(RMLanguage::LANGUAGE_TYPE language,RMLanguage::TEXT_TYPE type, QObject* control,QString str);
|
||||
void appendENGToolTip(QObject* control,QString str)
|
||||
{
|
||||
#if (LANGUAGE_REMOVE_ENG)
|
||||
Q_UNUSED(control)
|
||||
Q_UNUSED(str)
|
||||
#else
|
||||
append(RMLanguage::LANGUAGE_EN,RMLanguage::TOOLTIP_TEXT,control,str);
|
||||
#endif
|
||||
}
|
||||
#endif // LIVE_LANGUAGE2
|
||||
|
||||
|
||||
void remove(QObject* control);
|
||||
|
||||
void setLanguage(RMLanguage::LANGUAGE_TYPE language);
|
||||
RMLanguage::LANGUAGE_TYPE language()
|
||||
{
|
||||
#if (FIXED_ENGLISH)
|
||||
return RMLanguage::LANGUAGE_EN;
|
||||
#else
|
||||
return _currentLanguage;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 0:자동, 1:일본어, 2:영어, 3:한국어
|
||||
int languageIndex() {
|
||||
if(RMLanguage::isAuto) {
|
||||
return 0;
|
||||
}
|
||||
switch (_currentLanguage) {
|
||||
case LANGUAGE_JP:
|
||||
return 2;
|
||||
case LANGUAGE_EN:
|
||||
return 3;
|
||||
#if (RC_LANGUAGE == 0x0412)
|
||||
case LANGUAGE_KR:
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
RMLanguage::LANGUAGE_TYPE _currentLanguage;
|
||||
|
||||
QHash<qint64,QHash<int,QString>*>* _list;
|
||||
signals:
|
||||
void languageChange(RMLanguage::LANGUAGE_TYPE language);
|
||||
|
||||
};
|
||||
|
||||
#endif // LIVE_LANGUAGE_CHANGE
|
||||
#endif // RM_LANGUAGE_H
|
||||
64
project/fm_viewer/core/rm_math.cpp
Normal file
64
project/fm_viewer/core/rm_math.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "rm_math.h"
|
||||
#include <qmath.h>
|
||||
|
||||
float QAspectScaleFit(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float scaleW = (float)destSize.width() / (float)sourceSize.width();
|
||||
float scaleH = (float)destSize.height() / (float)sourceSize.height();
|
||||
return qMin(scaleW, scaleH);
|
||||
}
|
||||
QRect QRectFRound(QRectF r)
|
||||
{
|
||||
double xmin = floor(r.left());
|
||||
double ymin = floor(r.top());
|
||||
|
||||
double width = ceil(r.width() + (r.left()-xmin));
|
||||
double height = ceil(r.height() + (r.top()-ymin));
|
||||
return QRect(xmin,ymin,width,height);
|
||||
}
|
||||
|
||||
// Fit
|
||||
QRect QRectAspectFitRect(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float destScale = QAspectScaleFit(sourceSize, destRect);
|
||||
|
||||
float newWidth = (float)sourceSize.width() * destScale;
|
||||
float newHeight = (float)sourceSize.height() * destScale;
|
||||
|
||||
float dWidth = (((float)destSize.width() - newWidth) / 2.0f);
|
||||
float dHeight = (((float)destSize.height() - newHeight) / 2.0f);
|
||||
|
||||
QRect rect = QRect(dWidth + destRect.left(), dHeight + destRect.top(), newWidth, newHeight);
|
||||
return rect;
|
||||
}
|
||||
QRect QRectCenter(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
int xo = (destRect.width() - sourceSize.width()) / 2;
|
||||
int yo = (destRect.height() - sourceSize.height()) / 2;
|
||||
return QRect(destRect.left()+xo,destRect.top()+yo,sourceSize.width(),sourceSize.height());
|
||||
}
|
||||
|
||||
QRect QRectAspectFillRect(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float destScale = QAspectScaleFill(sourceSize, destRect);
|
||||
|
||||
float newWidth = (float)sourceSize.width() * destScale;
|
||||
float newHeight = (float)sourceSize.height() * destScale;
|
||||
|
||||
float dWidth = (((float)destSize.width() - newWidth) / 2.0f);
|
||||
float dHeight = (((float)destSize.height() - newHeight) / 2.0f);
|
||||
|
||||
// l,t,r,b
|
||||
QRect rect = QRect(dWidth + destRect.left(), dHeight + destRect.top(), newWidth, newHeight);
|
||||
return rect;
|
||||
}
|
||||
float QAspectScaleFill(QSize sourceSize, QRect destRect)
|
||||
{
|
||||
QSize destSize = destRect.size();
|
||||
float scaleW = (float)destSize.width() / (float)sourceSize.width();
|
||||
float scaleH = (float)destSize.height() / (float)sourceSize.height();
|
||||
return qMax(scaleW, scaleH);
|
||||
}
|
||||
13
project/fm_viewer/core/rm_math.h
Normal file
13
project/fm_viewer/core/rm_math.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef RM_MATH_H
|
||||
#define RM_MATH_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QRectF>
|
||||
|
||||
QRect QRectAspectFitRect(QSize sourceSize, QRect destRect);
|
||||
float QAspectScaleFit(QSize sourceSize, QRect destRect);
|
||||
QRect QRectAspectFillRect(QSize sourceSize, QRect destRect);
|
||||
float QAspectScaleFill(QSize sourceSize, QRect destRect);
|
||||
QRect QRectFRound(QRectF r);
|
||||
QRect QRectCenter(QSize sourceSize, QRect destRect);
|
||||
#endif // RM_MATH_H
|
||||
161
project/fm_viewer/core/rm_play_process.cpp
Normal file
161
project/fm_viewer/core/rm_play_process.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#include "rm_play_process.h"
|
||||
#include "rm_player.h"
|
||||
#include "../ui/rm_widget_video_list.h"
|
||||
#include "../data/rm_video_item_loader.h"
|
||||
#include <QThreadPool>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
|
||||
|
||||
bool RMPlayProcess::bConnected = false;
|
||||
bool RMPlayProcess::bProcessing = false;
|
||||
|
||||
#if (PLAYER_ONLY_LIBRARY_MODE)
|
||||
void RMPlayProcess::connectEvents()
|
||||
{
|
||||
if(RMPlayProcess::bConnected == false) {
|
||||
RMPlayProcess::bConnected = true;
|
||||
|
||||
// 리스트에서 파일 플레이 요청되면 로딩 시작
|
||||
//connect(listWidget,SIGNAL(listSelected(RMVideoItem*)),this,SLOT(onVideoLoadingStart(RMVideoItem*)));
|
||||
RMPlayer* player = RMPlayer::instance();
|
||||
|
||||
// 플레이 중 버튼 상태 업데이트
|
||||
connect(player,SIGNAL(playEvent(PLAY_EVENT, RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT, RMVideoItem*)));
|
||||
|
||||
}
|
||||
}
|
||||
#else // PLAYER_ONLY_LIBRARY_MODE
|
||||
void RMPlayProcess::connectEvents(RMWidgetVideoList* listWidget)
|
||||
{
|
||||
_loadingItem = NULL;
|
||||
|
||||
if(RMPlayProcess::bConnected == false) {
|
||||
RMPlayProcess::bConnected = true;
|
||||
|
||||
// 리스트에서 파일 플레이 요청되면 로딩 시작
|
||||
connect(listWidget,SIGNAL(listSelected(RMVideoItem*)),this,SLOT(onVideoLoadingStart(RMVideoItem*)));
|
||||
RMPlayer* player = RMPlayer::instance();
|
||||
|
||||
// 비디오 로딩 종료시
|
||||
//connect(player,SIGNAL(mediaLoadEnd(RMVideoItem*)),SLOT(onVideoLoadingEnd(RMVideoItem*)));
|
||||
|
||||
// 플레이 중 버튼 상태 업데이트
|
||||
connect(player,SIGNAL(playEvent(PLAY_EVENT, RMVideoItem*)),SLOT(onPlayEvent(PLAY_EVENT, RMVideoItem*)));
|
||||
|
||||
}
|
||||
}
|
||||
#endif // #else // PLAYER_ONLY_LIBRARY_MODE
|
||||
void RMPlayProcess::onVideoLoadingStart(RMVideoItem* item)
|
||||
{
|
||||
//qInfo() << item << __FUNCTION__;
|
||||
RMPlayProcess::bProcessing = true;
|
||||
// QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
// 기존 item 및 설정 초기화
|
||||
RMPlayer* player = RMPlayer::instance();
|
||||
#if !(PLAY_CONTINUE_EVENT)
|
||||
connect(player,SIGNAL(playerClearedDone()),SLOT(onPlayerClearDone()));
|
||||
#endif
|
||||
// cpu limit https://technet.microsoft.com/en-us/library/ff384148(v=ws.10).aspx
|
||||
// sid wmic useraccount get name,sid
|
||||
|
||||
_loadingItem = item; // 먼저 설정하고..
|
||||
player->stop(); // 플레이어 종료
|
||||
|
||||
//#if (USE_LIBRARY_MODE)
|
||||
// if(RMPlayer::libraryInstance != NULL) {
|
||||
// RMPlayer::libraryInstance->stop();
|
||||
// }
|
||||
//#endif // USE_LIBRARY_MODE
|
||||
}
|
||||
|
||||
#if !(PLAY_CONTINUE_EVENT)
|
||||
void RMPlayProcess::onPlayerClearDone()
|
||||
{
|
||||
RMPlayer* player = RMPlayer::instance();
|
||||
disconnect(player,SIGNAL(playerClearedDone()),this,SLOT(onPlayerClearDone()));
|
||||
|
||||
if (_loadingItem != NULL)
|
||||
{
|
||||
#if (!PRE_LOAD_SENSOR_DATA)
|
||||
// 센서 정보 로딩
|
||||
connect(_loadingItem,SIGNAL(loadAVIInfoEnd()),SLOT(onInfoLoadingEnd()),Qt::UniqueConnection); // -> 로딩완료시
|
||||
|
||||
// qInfo() << "2. start sensor data loading ----------------- ";
|
||||
// Loader delete???
|
||||
// GPS, 및 기타 센서 정보 가져오기
|
||||
// QRunnable 은 자동으로 delete 됨
|
||||
RMVideoItemLoader* loader = new RMVideoItemLoader(_loadingItem);
|
||||
QThreadPool::globalInstance()->start(loader,LOADER_THREAD_PRIORITY);
|
||||
_loadingItem = NULL;
|
||||
#else
|
||||
RMPlayer::instance()->onLoad(_loadingItem);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (!PRE_LOAD_SENSOR_DATA)
|
||||
void RMPlayProcess::onInfoLoadingEnd() // 현재 사용되지 않는다.????
|
||||
{
|
||||
RMVideoItem* item = qobject_cast <RMVideoItem*>(QObject::sender());
|
||||
|
||||
// 연결해제
|
||||
disconnect(item,SIGNAL(loadAVIInfoEnd()),this,SLOT(onInfoLoadingEnd()));
|
||||
|
||||
//#if (USE_LIBRARY_MODE)
|
||||
// if(RMApp::isTB5000 && RMPlayer::libraryInstance != NULL) {
|
||||
// RMPlayer::libraryInstance->onLoad(item);
|
||||
// return;
|
||||
// }
|
||||
//#endif // USE_LIBRARY_MODE
|
||||
|
||||
// 동영상 로딩시작 및 플레이
|
||||
RMPlayer::instance()->onLoad(item);
|
||||
}
|
||||
#endif
|
||||
|
||||
void RMPlayProcess::onPlayEvent(PLAY_EVENT event, RMVideoItem* item)
|
||||
{
|
||||
Q_UNUSED(item)
|
||||
if(event == PLAY_DID_LOADED)
|
||||
{
|
||||
//QApplication::restoreOverrideCursor();
|
||||
RMPlayProcess::bProcessing = false;
|
||||
if(item != NULL)
|
||||
{
|
||||
// _plotWidget->onUpdateGraph(item);
|
||||
|
||||
// no sensor 의 경우 update map 처리하면 onUpdateMap 처리됨
|
||||
// emit _mapWidget->updateMap(item);
|
||||
}
|
||||
}
|
||||
#if (PLAY_CONTINUE_EVENT)
|
||||
else if (event == PLAY_DID_CLEARED && _loadingItem != NULL)
|
||||
{
|
||||
// DELAY 처리해도 멈추는 증상 발생함.
|
||||
// RMPlayer::instance()->onLoad(_loadingItem);
|
||||
// qInfo() << "START LOAD NEXT FILE" << __FUNCTION__ << __LINE__;
|
||||
// _loadingItem = NULL;
|
||||
//#if (SUPPORT_LIBRARY_MODE)
|
||||
// onStartNext();
|
||||
// const int mWait = 100;
|
||||
//#else // SUPPORT_LIBRARY_MODE
|
||||
const int mWait = 1;
|
||||
//#endif // SUPPORT_LIBRARY_MODE
|
||||
QTimer::singleShot(mWait,Qt::PreciseTimer,this,SLOT(onStartNext()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void RMPlayProcess::onStartNext()
|
||||
{
|
||||
//#if !(PLAYER_ONLY_LIBRARY_MODE)
|
||||
// FIXED_SLEEP; //qInfo() << "START LOAD NEXT FILE" << __FUNCTION__ << __LINE__;
|
||||
//#endif//
|
||||
//qInfo() << "::onStartNext" << _loadingItem->title();
|
||||
RMPlayer::instance()->onLoad(_loadingItem);
|
||||
_loadingItem = NULL;
|
||||
}
|
||||
60
project/fm_viewer/core/rm_play_process.h
Normal file
60
project/fm_viewer/core/rm_play_process.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef RM_PLAY_PROCESS_H
|
||||
#define RM_PLAY_PROCESS_H
|
||||
|
||||
#include "../rm_include.h"
|
||||
#include "rm_player_base.h"
|
||||
#include <QObject>
|
||||
class RMVideoItem;
|
||||
class RMWidgetVideoList;
|
||||
class RMPlayProcess : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static RMPlayProcess* instance()
|
||||
{
|
||||
static RMPlayProcess * _instance = 0;
|
||||
if ( _instance == 0 ) {
|
||||
_instance = new RMPlayProcess();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
// STOP (PLAY_DID_CLEARED) 이벤트 발생시 다음 파일 로딩 중인지 확인해서
|
||||
// 화면 깜빡거리지 않도록 처리
|
||||
bool isLoadingNextFile() {
|
||||
return (_loadingItem != NULL);
|
||||
}
|
||||
|
||||
// 모든 윈도우 및 instance 생성 후 연결해야함
|
||||
#if (PLAYER_ONLY_LIBRARY_MODE)
|
||||
void connectEvents();
|
||||
#else // PLAYER_ONLY_LIBRARY_MODE
|
||||
void connectEvents(RMWidgetVideoList* listWidget);
|
||||
#endif // PLAYER_ONLY_LIBRARY_MODE
|
||||
|
||||
// 다른 프로세스 중지
|
||||
static bool bProcessing;
|
||||
private:
|
||||
static bool bConnected;
|
||||
RMVideoItem* _loadingItem;
|
||||
|
||||
private slots:
|
||||
|
||||
void onPlayEvent(PLAY_EVENT event, RMVideoItem* item);
|
||||
|
||||
// Play Control (from mainWindow)
|
||||
#if (PLAYER_ONLY_LIBRARY_MODE)
|
||||
public slots:
|
||||
#endif
|
||||
void onVideoLoadingStart(RMVideoItem* item); // 1. 플레이 시작
|
||||
#if !(PLAY_CONTINUE_EVENT)
|
||||
void onPlayerClearDone(); // 2. 기존 파일 unload 종료
|
||||
#endif
|
||||
|
||||
#if (!PRE_LOAD_SENSOR_DATA)
|
||||
void onInfoLoadingEnd(); // 3. 파일 센서 정보 읽어 오기
|
||||
#endif
|
||||
void onStartNext();
|
||||
//void onVideoLoadingEnd(RMVideoItem* item); // 4. Player 에서 Video Loading 완료
|
||||
};
|
||||
|
||||
#endif // RM_PLAY_PROCESS_H
|
||||
1786
project/fm_viewer/core/rm_player.cpp
Normal file
1786
project/fm_viewer/core/rm_player.cpp
Normal file
File diff suppressed because it is too large
Load Diff
383
project/fm_viewer/core/rm_player.h
Normal file
383
project/fm_viewer/core/rm_player.h
Normal file
@@ -0,0 +1,383 @@
|
||||
#ifndef RM_PLAYER_H
|
||||
#define RM_PLAYER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qslider.h>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "rm_constants.h"
|
||||
#include "rm_include.h"
|
||||
#include "rm_player_base.h"
|
||||
#include "rm_player_zoom.h"
|
||||
|
||||
|
||||
#define DEBUG_RM_PLAYER 0
|
||||
#define USE_RM_D2_PLAYER 0
|
||||
#define CAPTURE_DEBUG 0
|
||||
|
||||
class RMVideoItem;
|
||||
class RMFrameSlider;
|
||||
|
||||
#if (MODEL_BBVIEWER)
|
||||
class RMEQWidget;
|
||||
#endif
|
||||
|
||||
#define DEBUG_HIGH_SPEED_STOP 0
|
||||
#define REMOVE_CLOCK_UPDATE_WHEN_SEEKING 1
|
||||
#define STEP_SEEK_DURATION 34
|
||||
|
||||
|
||||
//extern const int g_PlaySpeed1XIndex;
|
||||
|
||||
#if (MODEL_BBVIEWER)
|
||||
#define PLAY_SPEED_COUNT 5
|
||||
#elif (RM_MODEL == RM_MODEL_TYPE_TB4000 || RM_MODEL_EMT_KR)
|
||||
#define PLAY_SPEED_COUNT 5
|
||||
#else
|
||||
#define PLAY_SPEED_COUNT 4
|
||||
#endif
|
||||
extern float g_PlaySpeedList[PLAY_SPEED_COUNT];
|
||||
|
||||
extern int DEFAULT_SPEED_INDEX;
|
||||
|
||||
class RMPlayer : public RMPlayerZoom
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static RMPlayer* instance()
|
||||
{
|
||||
static RMPlayer * _instance = 0;
|
||||
if ( _instance == NULL ) {
|
||||
_instance = new RMPlayer();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
//#if (USE_LIBRARY_MODE) // 360 DLL
|
||||
// static RMPlayer* libraryInstance;
|
||||
//#endif //
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
// 는 _isSwapped() 와는 별도로 사용자 swap 상태만 확인하기 위해 사용
|
||||
bool isSwapped() { return _swaped; }
|
||||
#endif
|
||||
void stop() override;
|
||||
|
||||
QString currentTimeString(double* lat, double* lon);
|
||||
#if (PENTA_CHANNEL)
|
||||
void changeCHMode(RMApp::ChannelMode mode) override;
|
||||
#endif
|
||||
void updateSpeedForce(qreal speed)
|
||||
{
|
||||
_speedValue = speed;
|
||||
updateSpeed(_speedValue);
|
||||
}
|
||||
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
void setMuteButton(FMButton* btn) {
|
||||
_muteButton = btn;
|
||||
}
|
||||
#endif // #if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
void setSlider(QSlider* slider) {
|
||||
_slider = slider;
|
||||
|
||||
// PRESSED -> MOVED -> RELEASED 순서대로 호출 되도록 이벤트 처리해야함
|
||||
// 노브가 아닌 지점 CLICK 시에는 Slider는 (Slider)PRESSED 이벤트 만 호출됨 (RMSlider 내부에서 구현)
|
||||
// PRESSED 이벤트 발생시 KNOB 가 false 일 경우 released 이벤트 발생하지 않으니 별도의 처리 하지 말아야함
|
||||
connect(_slider, SIGNAL(sliderPressedWithKnob(bool)),SLOT(onSliderPress(bool))); // 이벤트 두번씩 발생함
|
||||
|
||||
connect(_slider, SIGNAL(sliderMoved(int)),SLOT(onSliderMove(int))); // 슬라이더 컨트롤
|
||||
connect(_slider, SIGNAL(mouseReleased()),SLOT(onSliderRelease()));
|
||||
}
|
||||
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
void setVolumeSlider(QSlider* slider) {
|
||||
_volumeSlider = slider;
|
||||
connect(_volumeSlider, SIGNAL(sliderPressed()), SLOT(onSetVolume()));
|
||||
connect(_volumeSlider, SIGNAL(valueChanged(int)), SLOT(onSetVolume()));
|
||||
onSetVolume();
|
||||
}
|
||||
#endif // RM_MODEL_TYPE_TB4000
|
||||
|
||||
void setSpeedSlider(QSlider* slider, QLabel* label) {
|
||||
_speedLabel = label;
|
||||
connect(slider, SIGNAL(mouseReleased()),SLOT(onSpeedSliderReleased()));
|
||||
connect(slider, SIGNAL(sliderMoved(int)),SLOT(onSpeedSliderMoved(int)));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// SLIDER 이동중에는 강제 PAUSE
|
||||
bool _pauseWhileSeek;
|
||||
|
||||
QTimer* _captureTimer;
|
||||
QTimer* _captureWatcher;
|
||||
//#if (SEEK_BY_SLIDER)
|
||||
// QTimer* _seekPositionTimer;
|
||||
// void startSeekTimer();
|
||||
//#endif
|
||||
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
int _seekAcceleration; // 가속
|
||||
QTimer* _seekPressedTimer; // Slider 이동 타이머
|
||||
QTimer* _seekReleasedTimer; // Seek Update 타이머
|
||||
QTimer* _seekUpdateTimer; // Pressed 중간 Seek Update 타이머
|
||||
void startSeekUpdateTimer();
|
||||
void stopSeekUpdateTimer() override;
|
||||
|
||||
bool isSeekProcessing() override
|
||||
{
|
||||
return (_seekPressedTimer != NULL || _seekReleasedTimer != NULL || _seekUpdateTimer != NULL);
|
||||
}
|
||||
|
||||
//#else
|
||||
// QElapsedTimer _stepTimer;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void timerEvent(QTimerEvent *e);
|
||||
|
||||
public:
|
||||
|
||||
explicit RMPlayer(QObject *parent = 0);
|
||||
|
||||
RMVideoItem* getCurrentItem()
|
||||
{
|
||||
return _currentItem;
|
||||
}
|
||||
QDateTime currentTime(double* lon = NULL,double* lat = NULL);
|
||||
|
||||
VIDEO_MODE videoMode()
|
||||
{
|
||||
return _videoMode;
|
||||
}
|
||||
|
||||
FAV::AVPlayer* playerF()
|
||||
{
|
||||
return _playerF;
|
||||
}
|
||||
|
||||
QWidget* playWidgetF()
|
||||
{
|
||||
return _videoOutputF->widget();
|
||||
}
|
||||
#if ((!SINGLE_CH_VIEWER && !TOGGLE_PLAYER) || DUAL_VIEWER || DUAL_VIDEO_WIDGET)
|
||||
QWidget* playWidgetR()
|
||||
{
|
||||
return _videoOutputR->widget();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
FAV::AVPlayer* playerR()
|
||||
{
|
||||
return _playerR;
|
||||
}
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
|
||||
#if (RM_MODEL_360)
|
||||
// SWAP 되더라도 메인 Renderer 는 항상 _videoOutputF 임
|
||||
FAV::VideoRenderer* mainRenderer() {
|
||||
return _videoOutputF;
|
||||
}
|
||||
FAV::VideoRenderer* renderer360() {
|
||||
#if (SINGLE_CH_VIEWER)
|
||||
return _videoOutputF;
|
||||
#else // SINGLE_CH_VIEWER
|
||||
return _swaped ? _videoOutputR : _videoOutputF;
|
||||
#endif // SINGLE_CH_VIEWER
|
||||
}
|
||||
#endif // RM_MODEL_360
|
||||
|
||||
//void setSliderFrame(RMFrameSlider* frame); // 슬라이더 설정
|
||||
#if (MODEL_BBVIEWER)
|
||||
void setEQFrame(RMEQWidget* eq);
|
||||
#endif
|
||||
// 비디오 캡쳐 요청
|
||||
bool requestVideoCapture();
|
||||
|
||||
qreal speedValue()
|
||||
{
|
||||
return _speedValue;
|
||||
}
|
||||
#if (SUPPORT_WIDE_MODE)
|
||||
/**
|
||||
* @brief 현재 재생중인 영상이 WIDE 모드 지원 영상일 경우
|
||||
* @return
|
||||
*/
|
||||
bool itemIsWideMode();
|
||||
|
||||
/**
|
||||
* @brief 현재 재생중인 모드가 WIDE 모드일 경우
|
||||
* @return
|
||||
*/
|
||||
bool isWideMode();
|
||||
#endif // SUPPORT_WIDE_MODE
|
||||
|
||||
#if (RM_TESTING)
|
||||
FAV::LibAVFilterVideo* _testFilterF;
|
||||
void applyTestFilter(QString filter);
|
||||
#endif
|
||||
|
||||
qint64 titleSeconds; // 슬라이더에 표시된 시간 (Capture 등에서 동기화 처리위해 사용)
|
||||
|
||||
public slots:
|
||||
|
||||
void requestVideoCaptureProcess();
|
||||
|
||||
// Slider Control
|
||||
void onSliderPress(bool bKnob);
|
||||
void onSliderMove(int value);
|
||||
void onSliderRelease();
|
||||
|
||||
//void onPlotMove(qreal ratio);
|
||||
|
||||
|
||||
// 사용자 정지
|
||||
void onUserStop();
|
||||
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
void onSeekForwardStart();
|
||||
void onSeekBackwardStart();
|
||||
void onSeekFrameForwardStart();
|
||||
#if (PLAY_SYNC_FIX2)
|
||||
void onSeekFrameBackwardStart();
|
||||
#endif // PLAY_SYNC_FIX2
|
||||
void onSeekStepEnd();
|
||||
#endif
|
||||
|
||||
#if (PLAYER_ONLY_LIBRARY_MODE)
|
||||
void clear();
|
||||
void create();
|
||||
#endif // PLAYER_ONLY_LIBRARY_MODE
|
||||
|
||||
bool prepareForCapture();
|
||||
void onCaptureSavedFront(const QString& path);
|
||||
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
void onCaptureSavedRear(const QString& path);
|
||||
void toggleSwap(bool forceEmit = false);
|
||||
#endif
|
||||
|
||||
#if (TRI_CHANNEL || TRI_CHANNEL2)
|
||||
void toggleIndoor(bool forceEmit = false); // 후방 <-> 실내
|
||||
#endif
|
||||
#if (SUPPORT_WIDE_MODE)
|
||||
void toggleWide(); // NORMAL <-> WIDE
|
||||
#endif // SUPPORT_WIDE_MODE
|
||||
|
||||
void onSpeedSliderMoved(int position);
|
||||
void onSpeedSliderReleased();
|
||||
|
||||
|
||||
private:
|
||||
// 재생시간이 AVI:60260 VIDEO(Audio):59281 일 경우
|
||||
// 현재 POSITION + step 을
|
||||
// 실제 재생시간을 N 분할 하여 사용자가 보기 적합한 간격으로 표시함
|
||||
// eg 988.0166667 msec 씩 이동할 경우
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
quint64 _stepPosition();
|
||||
//#else
|
||||
// quint64 _stepPosition(int step=1); // +1,-1
|
||||
#endif
|
||||
bool _isLastStep();
|
||||
|
||||
|
||||
// 이벤트 블럭처리함
|
||||
void blockEvents(int msec,bool b_show_indicator = false);
|
||||
|
||||
// pause 된 상태에서도 positionChanged 가 계속호출되어 방지용
|
||||
// int timeToSliderValue(qint64 time);
|
||||
qint64 ratioToSliderValue(qreal ratio);
|
||||
|
||||
QString _captureDir;
|
||||
QList<QString>* _captureFileList;
|
||||
|
||||
|
||||
// 통합관리 + 화면갱신을 위한 seek 구분
|
||||
void seek(qint64 pos,bool refresh) override;
|
||||
|
||||
// 정지된 상태에서 SEEK 를 통해 화면 갱신
|
||||
void updatePausedScreen();
|
||||
|
||||
void seekFrontOnly(qint64 pos,bool refresh);
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
void seekRearOnly(qint64 pos,bool refresh);
|
||||
#endif
|
||||
|
||||
// 후방만 갱신
|
||||
#if (!(SINGLE_CH_VIEWER || TOGGLE_PLAYER) || PENTA_CHANNEL)
|
||||
void updatePausedScreenRearOnly();
|
||||
#endif
|
||||
void updatePausedScreenFrontOnly();
|
||||
void clearCaptureTimer();
|
||||
void clearCaptureWatcher();
|
||||
|
||||
//void clearSliderReleaseTimer();
|
||||
|
||||
// Rear 는 V+H Flip 모두 지원
|
||||
void updateRearFlip();
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_TELEBIT)
|
||||
void updateFrontFlip();
|
||||
#endif
|
||||
|
||||
// 메인 clock 과 각 player 의 clock 동기화
|
||||
void clear_seek_timer();
|
||||
void sync_clock();
|
||||
|
||||
|
||||
|
||||
private slots:
|
||||
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
void onSeekUpdate(); // 업데이트 후 타이머 제거하지 않음
|
||||
void onSeekLastUpdate(); // 업데이트 후 타이머 제거
|
||||
void onSeekPressed();
|
||||
#endif
|
||||
|
||||
#if (CAPTURE_DEBUG)
|
||||
void onSeekCapture();
|
||||
void onImageCaptured(const QImage& image);
|
||||
void onCaptureFailed();
|
||||
#endif
|
||||
|
||||
//#if !(FORCE_SINGLE_PLAYER)
|
||||
// 이벤트 블럭 해제 (전후방 swap 중에 별도 이벤트 받지 못하도록 처리)
|
||||
void onReleaseBlockEvent();
|
||||
//#endif
|
||||
|
||||
// 캡쳐 대기 완료
|
||||
void onReadyForCapture();
|
||||
|
||||
// 캡쳐 실패
|
||||
void onFailToCapture();
|
||||
|
||||
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
void onUpdateCHMode() override;
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
|
||||
// 동기화 시작 타이머
|
||||
void on_sync_timer_restarted();
|
||||
|
||||
// 처음으로 이동
|
||||
void onPlayRestart();
|
||||
//----------------------------------------------------------------------------------------------
|
||||
signals:
|
||||
|
||||
|
||||
void videoCaptureDone(QList<QString>* list);
|
||||
void swapChanged(bool swap);
|
||||
|
||||
|
||||
|
||||
#if (H265_SUPPORT)
|
||||
void show_indicator(bool show);
|
||||
#endif
|
||||
|
||||
void cancelFullScreen();
|
||||
|
||||
void userStop();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // RM_PLAYER_H
|
||||
2931
project/fm_viewer/core/rm_player_base.cpp
Normal file
2931
project/fm_viewer/core/rm_player_base.cpp
Normal file
File diff suppressed because it is too large
Load Diff
481
project/fm_viewer/core/rm_player_base.h
Normal file
481
project/fm_viewer/core/rm_player_base.h
Normal file
@@ -0,0 +1,481 @@
|
||||
#ifndef RM_PLAY_CONTROL_H
|
||||
#define RM_PLAY_CONTROL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimerEvent>
|
||||
#include <QSlider>
|
||||
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "../fav/fav.h"
|
||||
#include "../rm_include.h"
|
||||
#include "../fm_event_types.h"
|
||||
|
||||
|
||||
// 단말기 별로 설정 가능
|
||||
typedef enum
|
||||
{
|
||||
VIDEO_MODE_UNDEFINED = 0,
|
||||
VIDEO_MODE_OPENGL_ES = 1,
|
||||
VIDEO_MODE_WINDOW = 2,
|
||||
} VIDEO_MODE;
|
||||
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
typedef enum
|
||||
{
|
||||
STEP_MODE_NONE = 0, // 일반 재생
|
||||
STEP_MODE_F1 = 1, // 1초 전방 이동
|
||||
STEP_MODE_B1 = 2, // 2초 후방 이동
|
||||
STEP_MODE_FF = 3, // 1 Frame 전방 이동
|
||||
#if (PLAY_SYNC_FIX2)
|
||||
STEP_MODE_BF = 4, // 1 Frame 후방 이동
|
||||
#endif
|
||||
} STEP_MODE;
|
||||
#endif
|
||||
|
||||
// Video Seek 방식 (KeyFrameSeek 처리하면 안됨)
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
|
||||
#define VIDEO_SEEK_TYPE FAV::KeyFrameSeek //AccurateSeek
|
||||
#else
|
||||
#define VIDEO_SEEK_TYPE FAV::AccurateSeek // FAV::AccurateSeek, KeyFrameSeek
|
||||
#endif
|
||||
|
||||
#define INITIAL_VIDEO_POSITION 1 // msec
|
||||
#define PLAYER_MUTE_INTERVAL 10 // //const int kMuteInterval = 10;//100;
|
||||
#if (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W)
|
||||
#define PLAYER_SYNC_INTERVAL 300 //const int kSyncInterval = 500;
|
||||
#else
|
||||
#define PLAYER_SYNC_INTERVAL 500 //const int kSyncInterval = 500;
|
||||
#endif
|
||||
#define PLAYER_VOLUME_INTERVAL 0.1 // const qreal kVolumeInterval = 0.1;
|
||||
#define PLAYER_END_LIMIT 0 // 영상 마지막에 깨진 패킷 등이 있거나, 실제 영상 길이가 짧은 경우가 있어
|
||||
// 종료 시간은 duration 보다 n 초 빠르게 처리함
|
||||
#define PLAYER_START_LIMIT 50 // 실제 0 POS 은 이동하기 어렵고 33 정도
|
||||
|
||||
class FMButton;
|
||||
class RMVideoItem;
|
||||
class QOpenGLContext;
|
||||
|
||||
#if (USE_DRAG_ZOOM)
|
||||
class FMDragZoomWidget;
|
||||
#endif // #if (USE_DRAG_ZOOM)
|
||||
class RMPlayerBase : public QObject
|
||||
{
|
||||
friend class RMFrameVideoBase;
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit RMPlayerBase(QObject *parent = 0);
|
||||
#if (PLAY_CONTINUE_EVENT)
|
||||
virtual void stop(); // 종료 bUserStop == 사용자가 강제 종료
|
||||
#else
|
||||
void stop();
|
||||
#endif
|
||||
|
||||
// 전/후방 스텝모드 모두 종료
|
||||
virtual bool isSeekProcessing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void endStepMode() {
|
||||
_stepMode = STEP_MODE_NONE;
|
||||
}
|
||||
|
||||
FAV::VideoRenderer* _rendererFBackup;
|
||||
FAV::VideoRenderer* _rendererRBackup;
|
||||
|
||||
// 화면에 업데이트 하지 않도록 처리
|
||||
void pauseRenderer()
|
||||
{
|
||||
_rendererFBackup = _playerF->renderer();
|
||||
_playerF->setRenderer(NULL);
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
_rendererRBackup = _playerR->renderer();
|
||||
_playerR->setRenderer(NULL);
|
||||
#endif
|
||||
|
||||
#if (TRI_CHANNEL)
|
||||
_rendererRBackup = _playerI->renderer();
|
||||
_playerI->setRenderer(NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
//! \brief 채널 모드 변경
|
||||
//! \param mode : 변경할 모드
|
||||
virtual void changeCHMode(RMApp::ChannelMode mode){Q_UNUSED(mode)}
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
#if (TOGGLE_PLAYER)
|
||||
bool _tempSwapInResetPlayer; // PLAYER 초기화 중 임시로 SWAP 복구 처리되고 있는 경우
|
||||
#endif
|
||||
|
||||
// 전체화면 전환시 비율 조정
|
||||
|
||||
// void updateMainPlayerAspect(FAV::VideoRenderer::OutAspectRatioMode mode)
|
||||
// {
|
||||
// // TOGGLE 처리할 수 있어 전부 변경
|
||||
// _videoOutputF->setOutAspectRatioMode(mode);
|
||||
// _videoOutputR->setOutAspectRatioMode(mode);
|
||||
// }
|
||||
|
||||
public:
|
||||
QString lastError;
|
||||
FAV::VideoRenderer* _videoOutputF;
|
||||
#if ((!SINGLE_CH_VIEWER && !TOGGLE_PLAYER) || DUAL_VIEWER || PENTA_CHANNEL)
|
||||
FAV::VideoRenderer* _videoOutputR;
|
||||
#endif
|
||||
|
||||
#if (KEEP_ROI_ON_CAPTURE)
|
||||
int _roiX, _roiY, _roiW, _roiH; ///< 화면 CROP 영역 pixel
|
||||
int _roiX2, _roiY2, _roiW2, _roiH2; ///< 후방 화면 CROP 영역 pixel
|
||||
#endif // KEEP_ROI_ON_CAPTURE
|
||||
|
||||
#if (USE_DRAG_ZOOM)
|
||||
bool isROI()
|
||||
{
|
||||
return (_hROIFilter != NULL);
|
||||
}
|
||||
bool isROIRear()
|
||||
{
|
||||
return (_hROIFilterRear != NULL);
|
||||
}
|
||||
#endif // #if (USE_DRAG_ZOOM)
|
||||
|
||||
QSize frameSize();
|
||||
#if ((!SINGLE_CH_VIEWER && !TOGGLE_PLAYER) || DUAL_VIEWER || PENTA_CHANNEL)
|
||||
/**
|
||||
* @brief 2CH 프레임 크기
|
||||
* @return 없을 경우 0,0
|
||||
*/
|
||||
QSize rearFrameSize();
|
||||
#endif // SINGLE_CH_VIEWER
|
||||
|
||||
#if (SUPPORT_LIBRARY_MODE)
|
||||
/**
|
||||
* @brief 360(1:1) 영상 존재여부
|
||||
* @return 1,2CH 모두 확인하여 1:1 영상 존재할 경우 true
|
||||
*/
|
||||
bool isContain360Frame();
|
||||
#endif
|
||||
|
||||
#if (TOPDOWN_360_QUAD_MODE)
|
||||
FAV::VideoRenderer* _videoOutput2; // 우상단
|
||||
FAV::VideoRenderer* _videoOutput3; // 좌하단
|
||||
FAV::VideoRenderer* _videoOutput4; // 우하단
|
||||
void setQuadMode(bool quad);
|
||||
#endif // TOPDOWN_360_QUAD_MODE
|
||||
|
||||
#if (PAUSED_FRAME_REFRESH)
|
||||
// 정지 상태에서 프레임 필터 업데이트
|
||||
// 필터, MODE: 0=생성,1=해제,2=UPDATE
|
||||
void applyPausedFilter(FAV::VideoRenderer* out,FAV::LibAVFilterVideo* filter,int mode);
|
||||
#else // PAUSED_FRAME_UPDATE
|
||||
#if (USE_DRAG_ZOOM)
|
||||
void updatePausedScreen();
|
||||
#endif // USE_DRAG_ZOOM
|
||||
#endif // PAUSED_FRAME_UPDATE
|
||||
|
||||
#if (USE_DRAG_ZOOM)
|
||||
FMDragZoomWidget* _roiWidget;
|
||||
FMDragZoomWidget* _roiWidgetRear;
|
||||
FAV::LibAVFilterVideo* _hROIFilter;
|
||||
FAV::LibAVFilterVideo* _hROIFilterRear;
|
||||
void resetROIRear();
|
||||
void resetROI();
|
||||
|
||||
void setROIWidget(FMDragZoomWidget* widget);
|
||||
void setROIWidgetRear(FMDragZoomWidget* widget);
|
||||
void EnableROIWidget(bool enabled);
|
||||
#endif // #if (USE_DRAG_ZOOM)
|
||||
|
||||
protected:
|
||||
|
||||
FAV::VideoRendererId _renderID; // 비디오 랜더링 ID
|
||||
FAV::AVPlayer* _playerF; // 전방 (MULTI PLAYER 에서는 포인터만 할당)
|
||||
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
FAV::AVPlayer* _playerR; // 후방 (MULTI PLAYER 에서는 포인터만 할당)
|
||||
#endif
|
||||
|
||||
#if (TRI_CHANNEL)
|
||||
FAV::AVPlayer* _playerI; // 실내
|
||||
#endif
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
FAV::AVPlayer* _players[5]; // 전후방 포함 (FRONT,REAR,LEFT,RIGHT,SUB)
|
||||
|
||||
//! \brief 이벤트 제거
|
||||
void _clearPlayerConnection();
|
||||
//! \brief 이벤트 연결, 정리
|
||||
void _updatePlayerConnection();
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
FAV::VideoRenderer* _videoOutputZOOMMain;
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER)) // DUAL 은 사용함
|
||||
FAV::VideoRenderer* _videoOutputZOOMSub;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// 메인 클럭 (전/후방 동기화를 관리)
|
||||
int _timer_id;
|
||||
bool _sync_time;
|
||||
FAV::AVClock* _clock;
|
||||
QTimer* _sync_restart_timer;
|
||||
qint64 _lastPosition;
|
||||
|
||||
#if (TOGGLE_PLAYER)
|
||||
void resetPlayer(); // 전후방 변경되어 있을 경우 복구
|
||||
void restorePlayer();
|
||||
#endif
|
||||
|
||||
#if (START_FROM_FIRST_FRAME)
|
||||
qreal _startPTS;
|
||||
#endif
|
||||
|
||||
// Player
|
||||
VIDEO_MODE _videoMode;
|
||||
|
||||
#if (TRI_CHANNEL || TRI_CHANNEL2)
|
||||
bool _ch3mode; // 후방화면에 실내 영상 처리
|
||||
#endif
|
||||
|
||||
// SEEK
|
||||
// step 처리중 (다시 플레이시)
|
||||
#if (PLAY_SEEK_FILE_MOVE)
|
||||
|
||||
#if (USE_RM_KEYBOARD_EVENT)
|
||||
STEP_MODE _stepMode;
|
||||
bool _firstStep; // 파일 오픈 후 처음 step
|
||||
#endif
|
||||
#endif
|
||||
// 슬라이드 이동중에는 강제 PAUSE 하는 것이 좋겠는데...
|
||||
//bool _sliderMoving; // 슬라이드 이동중에는 다음파일로 이동하지 않도록
|
||||
|
||||
bool _stepping; // ?? 사용하지 않는것 같은데 제거
|
||||
|
||||
bool _refreshSeeking; // 화면갱신을 위해 SEEK
|
||||
qint64 _pausePosition; // 처리하지 않으면 전방으로 이동함
|
||||
|
||||
// CONTROL + EVENT
|
||||
QSlider* _slider; // "
|
||||
#if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
FMButton* _muteButton; // 참조용
|
||||
QSlider* _volumeSlider; // "
|
||||
#endif // #if !(RM_MODEL == RM_MODEL_TYPE_TB4000)
|
||||
|
||||
bool _forceStop; // control -> 사용자 중지
|
||||
bool _pausedState; // 현재 플레이어는 정지된 상태 (임시 저장)
|
||||
// media change 또는 position 종료시 naturla end 2회 발생할 수 있음
|
||||
bool _onNaturalEnd;
|
||||
bool _sliderMoving; // 슬라이더로 포지션 변경 (중)
|
||||
|
||||
qreal _speedValue;
|
||||
QLabel* _speedLabel;
|
||||
// 플레이 중 버퍼 일시 중지
|
||||
bool _muteIfRequired;
|
||||
|
||||
// Video Data
|
||||
RMVideoItem* _currentItem;
|
||||
// 후방 파일 존재 (전방 파일 처리후 사용해야함)
|
||||
// 전방에 후방 파일을 설정했을 경우 (1개 파일만 존재하는 경우) -> 로딩하지 않는다.
|
||||
QString _realRearFile();
|
||||
|
||||
|
||||
// 이벤트 처리하지 않는다
|
||||
QTimer* _blockTimer;
|
||||
bool _eventBlocking;
|
||||
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
FAV::AVPlayer* mainScreenPlayer() {
|
||||
return _isSwaped() ? _playerR : _playerF;
|
||||
}
|
||||
|
||||
FAV::AVPlayer* subScreenPlayer() {
|
||||
#if (TRI_CHANNEL)
|
||||
if(_isSwaped()) {
|
||||
return _playerF;
|
||||
}
|
||||
return _ch3mode ? _playerI : _playerR;
|
||||
#else // TRI_CHANNEL
|
||||
return _isSwaped() ? _playerF : _playerR;
|
||||
#endif // TRI_CHANNEL
|
||||
}
|
||||
|
||||
FAV::VideoRenderer* _currentVideoRenderer(FAV::AVPlayer* player)
|
||||
{
|
||||
#if (TOGGLE_PLAYER)
|
||||
Q_UNUSED(player)
|
||||
return _videoOutputF;
|
||||
#else // TOGGLE_PLAYER
|
||||
if(player == _playerF) {
|
||||
return _isSwaped() ? _videoOutputR : _videoOutputF;
|
||||
}
|
||||
else if (player == _playerR) {
|
||||
return _isSwaped() ? _videoOutputF : _videoOutputR;
|
||||
}
|
||||
return NULL;
|
||||
#endif // TOGGLE_PLAYER
|
||||
}
|
||||
|
||||
bool _swaped;
|
||||
//bool _rear_swaped;
|
||||
|
||||
// 전방, 후방 파일만 존재하는 경우 _playerF 에 rear 파일을 로딩해서 처리
|
||||
// SWAP 확인하려면 _swaped 및 _rear_swaped 모두 확인해야함
|
||||
bool _isSwaped()
|
||||
{
|
||||
// 둘다 swaped 인 경우 false
|
||||
// player swap 상태일 경우 _rear_swaped 인 경우는 swap 이 아님, player swap 상태가 아닌 경우 _rear_swap 상태일 경우 swap 상태임
|
||||
return _swaped;// ? !_rear_swaped : _rear_swaped;
|
||||
}
|
||||
#endif // SINGLE_CH_VIEWER
|
||||
|
||||
|
||||
// media change 상태에서 로딩하면 loaded 가 true 되어 있지 않음
|
||||
void playOrPause(bool forcePlay);
|
||||
void updateSpeed(qreal speed);
|
||||
// 슬라이드 이동 등에서 mute 처리함 (timer > 0 자동 릴리즈)
|
||||
void muteIfRequired(int timer);
|
||||
void unMuteIfMuted();
|
||||
bool _isMuted();
|
||||
|
||||
|
||||
|
||||
// 화면 CLEAR (BLACK)
|
||||
virtual void clearScreen(bool front);
|
||||
|
||||
// 통합관리 + 화면갱신을 위한 seek 구분
|
||||
virtual void seek(qint64 pos,bool refresh);
|
||||
|
||||
// 강제 pause / unpause
|
||||
void _pause(bool bPause, bool waitUntil = false, qint64 pos = -1);
|
||||
|
||||
// 전후방 seek 가 모두 종료 되었을 때 동기화 타이머를 다시 시작한다
|
||||
void restart_sync_timer();
|
||||
public:
|
||||
#if (TRI_CHANNEL || TRI_CHANNEL2)
|
||||
bool isIndoor() {
|
||||
return _ch3mode;
|
||||
}
|
||||
#endif // TRI_CHANNEL
|
||||
protected:
|
||||
int _playerStopCount; // 전후방 동시 종료시 모두 종료된 상황을 확인하기 위해 count 처리
|
||||
void _createVideoPlayers(); // 초기 플레이어 생성
|
||||
void _configureVideoRenderers(); // 파일 set 상태에 따라 renderer 설정
|
||||
void _setItemToPlayers(RMVideoItem* item); // 파일 set
|
||||
virtual void stopSeekUpdateTimer();
|
||||
|
||||
//virtual void _updateEQFilter(bool bForce = false){Q_UNUSED(bForce)}
|
||||
|
||||
signals:
|
||||
void playEvent(PLAY_EVENT event, RMVideoItem* item);
|
||||
void positionChanged(qint64 current,qint64 total); // 다른 컨트롤에 상태 변경 신호
|
||||
|
||||
|
||||
#if !(PLAY_CONTINUE_EVENT)
|
||||
void playerClearedDone(); // STOP/UNLOAD 완료시 처리
|
||||
#endif
|
||||
|
||||
protected slots:
|
||||
// 소리 정지 해제 (slide move)
|
||||
void onUnMuteIfRequired();
|
||||
void onSetVolume();
|
||||
void onMute();
|
||||
|
||||
void updateSlider(qint64 value); //
|
||||
void updateSlider(); //
|
||||
|
||||
void changeClockType();
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
void onMediaChangedM(FAV::MediaStatus mediaStatus);
|
||||
#else // PENTA_CHANNEL
|
||||
void onMediaChangedF(FAV::MediaStatus mediaStatus);
|
||||
|
||||
#if !(FORCE_SINGLE_PLAYER)
|
||||
void onMediaChangedR(FAV::MediaStatus mediaStatus);
|
||||
#endif // #if (FORCE_SINGLE_PLAYER)
|
||||
#if (TRI_CHANNEL)
|
||||
void onMediaChangedI(FAV::MediaStatus mediaStatus);
|
||||
#endif
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
void onPositionChanged(qint64 value);
|
||||
|
||||
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
void onStoppedM();
|
||||
void onSeekFinishedM(qint64 pos);
|
||||
#else // PENTA_CHANNEL
|
||||
void onSeekFinishedF(qint64 pos);
|
||||
void onStoppedF();
|
||||
#if !(FORCE_SINGLE_PLAYER)
|
||||
void onStoppedR();
|
||||
void onSeekFinishedR(qint64 pos);
|
||||
#endif // FORCE_SINGLE_PLAYER
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
void onFirstFrame(qreal pts);
|
||||
#if(PROFILE_BUILD)
|
||||
void onFirstFrameR(qreal pts);
|
||||
#endif //
|
||||
|
||||
#if (FIXED_FPS_DURATION && (!FORCE_BREAK_EOF || PREVENT_OVER_DURATION_RENDER))
|
||||
void onMediaEnded();
|
||||
#endif
|
||||
|
||||
void onRestoreRenderer();
|
||||
|
||||
void onTest();
|
||||
// void onTest2();
|
||||
// void onTest3();
|
||||
|
||||
public slots:
|
||||
void onPlayOrPause();
|
||||
|
||||
#if (PENTA_CHANNEL)
|
||||
virtual void onUpdateCHMode() {}
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
// 파일리스트 클릭시 발생
|
||||
void onLoad(RMVideoItem* item);
|
||||
void onStartPause();
|
||||
#if (PENTA_CHANNEL)
|
||||
void onPlayerM(const FAV::AVError&);
|
||||
#else // PENTA_CHANNEL
|
||||
void onPlayerF(const FAV::AVError&);
|
||||
#if !(FORCE_SINGLE_PLAYER || SINGLE_CH_VIEWER || TOGGLE_PLAYER)
|
||||
void onPlayerR(const FAV::AVError&);
|
||||
#endif
|
||||
|
||||
#if (TRI_CHANNEL)
|
||||
void onPlayerI(const FAV::AVError&);
|
||||
#endif
|
||||
#endif // PENTA_CHANNEL
|
||||
|
||||
#if (PAUSED_FRAME_REFRESH)
|
||||
#if (USE_DRAG_ZOOM)
|
||||
void zoomPausedScreen(bool bFront, bool clear, bool onStartStop);
|
||||
#endif // #if (USE_DRAG_ZOOM)
|
||||
#endif // PAUSED_CROP_FRAME
|
||||
|
||||
#if (USE_DRAG_ZOOM)
|
||||
void onClearROI(bool bStartStop = false); // 지난 영역 제거
|
||||
void onClearROIRear(bool bStartStop = false); // 지난 영역 제거
|
||||
void onROISelected(double fx, double fy, double width, double height);
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
void onROISelectedRear(double fx, double fy, double width, double height);
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif // #if (USE_DRAG_ZOOM)
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // RM_PLAY_CONTROL_H
|
||||
700
project/fm_viewer/core/rm_player_zoom.cpp
Normal file
700
project/fm_viewer/core/rm_player_zoom.cpp
Normal file
@@ -0,0 +1,700 @@
|
||||
#include "rm_player_zoom.h"
|
||||
|
||||
#if (USE_EQ_FILTER)
|
||||
#include "../ui/rm_slider.h"
|
||||
#endif
|
||||
#include "rm_utility.h"
|
||||
|
||||
#if (MODEL_360 || RM_MODEL_360 || ZOOM_SHADER || PAUSED_FRAME_REFRESH)
|
||||
#include "fav/OpenGLVideo.h"
|
||||
#include "fav/OpenGLRendererBase.h"
|
||||
#endif
|
||||
|
||||
#if (ZOOM_SHADER)
|
||||
RMPlayerZoom::RMPlayerZoom(QObject *parent) : RMPlayerBase(parent)
|
||||
{
|
||||
|
||||
}
|
||||
// ZOOM 모드 시작
|
||||
void RMPlayerZoom::startZoom(bool mainVideo)
|
||||
{
|
||||
|
||||
}
|
||||
// ZOOM 종료
|
||||
void RMPlayerZoom::stopZoom(bool mainVideo)
|
||||
{
|
||||
|
||||
}
|
||||
// ZOOM 위치 변경 + 프레임 크기가 확정되기 전에는 return false
|
||||
bool RMPlayerZoom::updateZoom(float x, float y, bool mainVideo)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else //ZOOM_SHADER
|
||||
RMPlayerZoom::RMPlayerZoom(QObject *parent) : RMPlayerBase(parent)
|
||||
{
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
zoomTargetMain = NULL;
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
zoomTargetSub = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !(DO_NOT_USE_FLIP)
|
||||
#if !(USE_SHADER_FLIP)
|
||||
_hMainFilter = NULL;
|
||||
_hRearFilter = NULL;
|
||||
#endif //
|
||||
|
||||
_bHFlipMain = false;
|
||||
_bVFlipMain = false;
|
||||
_bHFlipSub = false;
|
||||
_bVFlipSub = false;
|
||||
#endif // ?USE_SHADER_FLIP
|
||||
|
||||
#if (USE_EQ_FILTER)
|
||||
_brightness = -1000; // -1 ~ 1
|
||||
_contrast = -1000; // 0.0 ~ 2.0
|
||||
_hEQFilterF = NULL;
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
_hEQFilterR = NULL;
|
||||
#endif // #if (!SINGLE_CH_VIEWER)
|
||||
#endif // USE_EQ_FILTER
|
||||
|
||||
#if (RESIZE_FILTER)
|
||||
_hResizeFilterF = NULL;
|
||||
_hResizeFilterR = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
QWidget* RMPlayerZoom::startZoom(bool mainVideo)
|
||||
{
|
||||
//qInfo() << "START ZOOM";
|
||||
#if !(SINGLE_CH_VIEWER || TOGGLE_PLAYER)
|
||||
FAV::AVPlayer* player = mainVideo ? mainScreenPlayer() : subScreenPlayer();
|
||||
#else
|
||||
FAV::AVPlayer* player = _playerF;
|
||||
#endif
|
||||
if(player->videoOutputs().length() == 0)
|
||||
{
|
||||
qDebug() << "NO OUTPUTS" << __FUNCTION__;
|
||||
return NULL;
|
||||
}
|
||||
#if !(SINGLE_CH_VIEWER || TOGGLE_PLAYER)
|
||||
FAV::VideoRenderer* zt = NULL;
|
||||
if (mainVideo) {
|
||||
zt = zoomTargetMain = player->videoOutputs().first();
|
||||
}
|
||||
else {
|
||||
zt = zoomTargetSub = player->videoOutputs().first();
|
||||
}
|
||||
#else
|
||||
|
||||
#if (DUAL_VIEWER && MODEL_360)
|
||||
FAV::VideoRenderer* zt = NULL;
|
||||
if (mainVideo) {
|
||||
zt = zoomTargetMain = player->videoOutputs().first();
|
||||
}
|
||||
else {
|
||||
zt = zoomTargetSub = player->videoOutputs().at(1); // 1,2,3
|
||||
}
|
||||
#else
|
||||
FAV::VideoRenderer*zt = zoomTargetMain = player->videoOutputs().first();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
zt->setRegionOfInterest(QRectF(0.25,0.25,0.5,0.5));
|
||||
|
||||
// QSize vSize = zt->videoFrameSize() / 2;
|
||||
// zt->setRegionOfInterest(QRect(vSize.width()/2,vSize.height()/2,vSize.width(),vSize.height()));
|
||||
|
||||
FAV::VideoRenderer* vr = NULL;
|
||||
if (mainVideo) {
|
||||
if(_videoOutputZOOMMain == NULL)
|
||||
{
|
||||
// ZOOM Rendered
|
||||
_videoOutputZOOMMain = FAV::VideoRenderer::create(_renderID);
|
||||
// 비율을 고정할 경우 setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation) +
|
||||
// setOutAspectRatio(16.0 / 9.0); 사용
|
||||
_videoOutputZOOMMain->setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation);
|
||||
_videoOutputZOOMMain->setOutAspectRatio(16.0 / 9.0);
|
||||
vr = _videoOutputZOOMMain;
|
||||
}
|
||||
}
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
else {
|
||||
if(_videoOutputZOOMSub == NULL)
|
||||
{
|
||||
// ZOOM Rendered
|
||||
_videoOutputZOOMSub = FAV::VideoRenderer::create(_renderID);
|
||||
_videoOutputZOOMSub->setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation);
|
||||
_videoOutputZOOMSub->setOutAspectRatio(16.0 / 9.0);
|
||||
vr = _videoOutputZOOMSub;
|
||||
}
|
||||
}
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
|
||||
player->addVideoRenderer(vr);
|
||||
|
||||
if(player->isPaused() ) {
|
||||
player->seek(MIN(player->position(),player->duration()));
|
||||
}
|
||||
|
||||
#if (DUAL_VIEWER && MODEL_360) // 360 ONLY
|
||||
vr->opengl()->setDualMode(1); // 2D
|
||||
vr->opengl()->setDualFront(mainVideo); // 전후방
|
||||
|
||||
#if (USE_ZOOM_WH_RATIO)
|
||||
// 해상도 높이가 1/2 로 다시 처리 해야함
|
||||
QSize r = _playerF->videoResolution();
|
||||
float wr = ((double)r.width()) / ((double)r.height() / 2.0) ;
|
||||
vr->setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation);
|
||||
vr->setOutAspectRatio(wr); // 16.0/9.0
|
||||
#endif // USE_ZOOM_WH_RATIO
|
||||
#endif
|
||||
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
return mainVideo ? _videoOutputZOOMMain->widget() : _videoOutputZOOMSub->widget();
|
||||
#else
|
||||
return _videoOutputZOOMMain->widget();
|
||||
#endif
|
||||
}
|
||||
void RMPlayerZoom::stopZoom(bool mainVideo)
|
||||
{
|
||||
//qInfo() << "STOP ZOOM";
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
FAV::VideoRenderer* zt = mainVideo ? zoomTargetMain : zoomTargetSub;
|
||||
#else
|
||||
FAV::VideoRenderer* zt = zoomTargetMain;
|
||||
#endif
|
||||
if(zt == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 복구 처리 해야함 + 다음파일 재생시 비디오 크기에 따라 다시 조절 해야함
|
||||
zt->setRegionOfInterest(QRectF(0,0,0,0));
|
||||
|
||||
if(mainVideo) {
|
||||
#if !(SINGLE_CH_VIEWER || TOGGLE_PLAYER)
|
||||
mainScreenPlayer()->removeVideoRenderer(_videoOutputZOOMMain);
|
||||
#else
|
||||
_playerF->removeVideoRenderer(_videoOutputZOOMMain);
|
||||
#endif
|
||||
delete _videoOutputZOOMMain;
|
||||
_videoOutputZOOMMain = NULL;
|
||||
zoomTargetMain = NULL;
|
||||
}
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
else
|
||||
{
|
||||
#if (DUAL_VIEWER)
|
||||
_playerF->removeVideoRenderer(_videoOutputZOOMSub);
|
||||
#else
|
||||
subScreenPlayer()->removeVideoRenderer(_videoOutputZOOMSub);
|
||||
#endif
|
||||
delete _videoOutputZOOMSub;
|
||||
_videoOutputZOOMSub = NULL;
|
||||
zoomTargetSub = NULL;
|
||||
}
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
}
|
||||
|
||||
#if (USE_ZOOM_WH_RATIO)
|
||||
void RMPlayerZoom::updateZoomAspectRatio()
|
||||
{
|
||||
// 해상도 높이가 1/2 로 다시 처리 해야함
|
||||
QSize r = _playerF->videoResolution();
|
||||
float wr = ((double)r.width()) / ((double)r.height() / 2.0) ;
|
||||
if(_videoOutputZOOMMain != NULL) {
|
||||
_videoOutputZOOMMain->setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation);
|
||||
_videoOutputZOOMMain->setOutAspectRatio(wr); // 16.0/9.0
|
||||
}
|
||||
if(_videoOutputZOOMSub != NULL) {
|
||||
_videoOutputZOOMSub->setOutAspectRatioMode(FAV::VideoRenderer::CustomAspectRation);
|
||||
_videoOutputZOOMSub->setOutAspectRatio(wr); // 16.0/9.0
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool RMPlayerZoom::updateZoom(float x, float y, bool mainVideo)
|
||||
{
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
FAV::VideoRenderer* zt = mainVideo ? zoomTargetMain : zoomTargetSub;
|
||||
#else
|
||||
FAV::VideoRenderer* zt = zoomTargetMain;
|
||||
#endif
|
||||
if(zt != NULL)
|
||||
{
|
||||
// y 를 0.001 로 처리하면 깨지는 증상이 발생함
|
||||
x = ((int)(x * 100.0)) / 100.0;
|
||||
y = ((int)(y * 100.0)) / 100.0;
|
||||
|
||||
//x = 0.152256;
|
||||
// Ratio(0~1.0) 로 변경하면 해상도 변경시 문제 없음
|
||||
zt->setRegionOfInterest(QRectF(x,y,0.5,0.5));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RMPlayerZoom::clearScreen(bool front)
|
||||
{
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
|
||||
#if (DUAL_VIEWER)
|
||||
FAV::VideoRenderer* r = front ? _videoOutputF : _videoOutputR;
|
||||
#else
|
||||
FAV::AVPlayer* p = front ? _playerF : _playerR;
|
||||
FAV::VideoRenderer* r = _currentVideoRenderer(p);
|
||||
#endif
|
||||
if(r != NULL) {
|
||||
r->receive(FAV::VideoFrame());
|
||||
}
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
r = front ? _videoOutputZOOMMain : _videoOutputZOOMSub;
|
||||
if(r != NULL) {
|
||||
r->receive(FAV::VideoFrame());
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
if(_videoOutputF != NULL) {
|
||||
_videoOutputF->receive(FAV::VideoFrame());
|
||||
}
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
if(_videoOutputZOOMMain != NULL) {
|
||||
_videoOutputZOOMMain->receive(FAV::VideoFrame());
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
|
||||
//#if (MODEL_BBVIEWER)
|
||||
// emit playEvent(front ? PLAY_DID_CLEAR_SCREEN_F : PLAY_DID_CLEAR_SCREEN_R, NULL);
|
||||
//#endif
|
||||
}
|
||||
|
||||
#if (RESIZE_FILTER && !DO_NOT_USE_ZOOM)
|
||||
void RMPlayerZoom::resizeFilter(QSize size, bool bMain)
|
||||
{
|
||||
qInfo() << __FUNCTION__ << size;
|
||||
|
||||
if(size.width() < 0) {
|
||||
|
||||
if(_hResizeFilterF != NULL) {
|
||||
_hResizeFilterF->uninstall();
|
||||
delete _hResizeFilterF;
|
||||
_hResizeFilterF = NULL;
|
||||
}
|
||||
if(_hResizeFilterR != NULL) {
|
||||
_hResizeFilterR->uninstall();
|
||||
delete _hResizeFilterR;
|
||||
_hResizeFilterR = NULL;
|
||||
}
|
||||
updatePausedScreenFrontOnly();
|
||||
updatePausedScreenRearOnly();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
FAV::LibAVFilterVideo* f = bMain ? _hResizeFilterF : _hResizeFilterR;
|
||||
if(f != NULL)
|
||||
{
|
||||
f->uninstall();
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
//size *= 2.0;
|
||||
|
||||
//bilinear,, format=pix_fmts=yuv420p,
|
||||
QString filterString = QString().sprintf("scale=%d:%d:force_original_aspect_ratio=decrease:flags=lanczos",size.width(),size.height());
|
||||
qInfo() << filterString;
|
||||
// QString filterString = QString().sprintf("scale=%d:%d -sws_flags bilinear",size.width(),size.height());
|
||||
//QString filterString = QString().sprintf("format=pix_fmts=rgb24,scale=%d:%d",size.width(),size.height());
|
||||
if(bMain == true)
|
||||
{
|
||||
f = new FAV::LibAVFilterVideo(_playerF);
|
||||
f->installTo(_playerF);
|
||||
f->setOptions(filterString);
|
||||
_hResizeFilterF = f;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = new FAV::LibAVFilterVideo(_playerR);
|
||||
f->installTo(_playerR);
|
||||
f->setOptions(filterString);
|
||||
_hResizeFilterR = f;
|
||||
}
|
||||
updatePausedScreenFrontOnly();
|
||||
updatePausedScreenRearOnly();
|
||||
|
||||
}
|
||||
#endif //RESIZE_FILTER
|
||||
|
||||
|
||||
#if !(DO_NOT_USE_FLIP)
|
||||
#if (USE_SHADER_FLIP)
|
||||
void RMPlayerZoom::updateFlip(bool bMain)
|
||||
{
|
||||
if(bMain) {
|
||||
FAV::VideoRenderer* vr = _currentVideoRenderer(_playerF);
|
||||
vr->opengl()->setVFlip(_bVFlipMain);
|
||||
vr->opengl()->setHFlip(_bHFlipMain);
|
||||
vr->widget()->update();
|
||||
} else {
|
||||
FAV::VideoRenderer* vr = _currentVideoRenderer(_playerR);
|
||||
vr->opengl()->setVFlip(_bVFlipSub);
|
||||
vr->opengl()->setHFlip(_bHFlipSub);
|
||||
vr->widget()->update();
|
||||
}
|
||||
}
|
||||
#else // USE_SHADER_FLIP
|
||||
void RMPlayerZoom::updateFlip(bool bMain)
|
||||
{
|
||||
#if (PENTA_CHANNEL)
|
||||
if(_hMainFilter != NULL)
|
||||
{
|
||||
_hMainFilter->uninstall();
|
||||
delete _hMainFilter;
|
||||
_hMainFilter = NULL;
|
||||
}
|
||||
if(_hRearFilter != NULL)
|
||||
{
|
||||
_hRearFilter->uninstall();
|
||||
delete _hRearFilter;
|
||||
_hRearFilter = NULL;
|
||||
}
|
||||
QString filterString = "format=pix_fmts=rgb24";
|
||||
if(_bHFlipMain || _bVFlipMain )
|
||||
{
|
||||
_hMainFilter = new FAV::LibAVFilterVideo(_playerF);
|
||||
_hMainFilter->installTo(_playerF);
|
||||
if(_bHFlipMain) {
|
||||
filterString += ",hflip";
|
||||
}
|
||||
if(_bVFlipMain) {
|
||||
filterString += ",vflip";
|
||||
}
|
||||
_hMainFilter->setOptions(filterString);
|
||||
}
|
||||
updatePausedScreenFrontOnly();
|
||||
|
||||
if(_playerR != NULL) {
|
||||
if(_bHFlipMain || _bVFlipMain ) { // PENTA 는 SUB가 없음
|
||||
_hRearFilter = new FAV::LibAVFilterVideo(_playerR);
|
||||
_hRearFilter->installTo(_playerR);
|
||||
if(_bHFlipSub) {
|
||||
filterString += ",hflip";
|
||||
}
|
||||
if(_bVFlipSub) {
|
||||
filterString += ",vflip";
|
||||
}
|
||||
_hRearFilter->setOptions(filterString);
|
||||
}
|
||||
updatePausedScreenRearOnly();
|
||||
}
|
||||
#else // PENTA_CHANNEL
|
||||
FAV::LibAVFilterVideo* f = bMain ? _hMainFilter : _hRearFilter;
|
||||
if(f != NULL)
|
||||
{
|
||||
f->uninstall();
|
||||
delete f;
|
||||
f = NULL;
|
||||
}
|
||||
QString filterString = "format=pix_fmts=rgb24";
|
||||
if(bMain == true)
|
||||
{
|
||||
if(_bHFlipMain == false && _bVFlipMain == false)
|
||||
{
|
||||
_hMainFilter = NULL;
|
||||
updatePausedScreenFrontOnly();
|
||||
return;
|
||||
}
|
||||
f = new FAV::LibAVFilterVideo(_playerF);
|
||||
f->installTo(_playerF);
|
||||
|
||||
if(_bHFlipMain) {
|
||||
filterString += ",hflip";
|
||||
}
|
||||
if(_bVFlipMain) {
|
||||
filterString += ",vflip";
|
||||
}
|
||||
|
||||
f->setOptions(filterString);
|
||||
_hMainFilter = f;
|
||||
|
||||
updatePausedScreenFrontOnly();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_bHFlipSub == false && _bVFlipSub == false)
|
||||
{
|
||||
_hRearFilter = NULL;
|
||||
#if (TOGGLE_PLAYER)
|
||||
updatePausedScreenFrontOnly();
|
||||
#else // TOGGLE_PLAYER
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
updatePausedScreenRearOnly();
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif // TOGGLE_PLAYER
|
||||
return;
|
||||
}
|
||||
#if (TOGGLE_PLAYER)
|
||||
f = new FAV::LibAVFilterVideo(_playerF);
|
||||
f->installTo(_playerF);
|
||||
#else
|
||||
#if (TRI_CHANNEL)
|
||||
f = new FAV::LibAVFilterVideo(isIndoor() ? _playerI : _playerR);
|
||||
f->installTo(isIndoor() ? _playerI : _playerR);
|
||||
#else // TRI_CHANNEL
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
f = new FAV::LibAVFilterVideo(_playerR);
|
||||
f->installTo(_playerR);
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif // TRI_CHANNEL
|
||||
#endif
|
||||
if(_bHFlipSub) {
|
||||
filterString += ",hflip";
|
||||
}
|
||||
if(_bVFlipSub) {
|
||||
filterString += ",vflip";
|
||||
}
|
||||
f->setOptions(filterString);
|
||||
_hRearFilter = f;
|
||||
#if (TOGGLE_PLAYER)
|
||||
updatePausedScreenFrontOnly();
|
||||
#else
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
updatePausedScreenRearOnly();
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif // PENTA_CHANNEL
|
||||
}
|
||||
#endif // #if !(USE_SHADER_FLIP)
|
||||
void RMPlayerZoom::onToggleHFlipMain()
|
||||
{
|
||||
bool main = true;
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
if(_swaped)
|
||||
{
|
||||
_bHFlipSub =!_bHFlipSub;
|
||||
main = false;
|
||||
}
|
||||
else
|
||||
#endif // SINGLE_CH_VIEWER
|
||||
{
|
||||
_bHFlipMain =!_bHFlipMain;
|
||||
main = true;
|
||||
}
|
||||
updateFlip(main);
|
||||
}
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
void RMPlayerZoom::onToggleHFlipSub()
|
||||
{
|
||||
bool main;
|
||||
if(_swaped)
|
||||
{
|
||||
_bHFlipMain =!_bHFlipMain;
|
||||
main = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_bHFlipSub =!_bHFlipSub;
|
||||
main = false;
|
||||
}
|
||||
updateFlip(main);
|
||||
}
|
||||
void RMPlayerZoom::onToggleVFlipSub()
|
||||
{
|
||||
bool main;
|
||||
if(_swaped)
|
||||
{
|
||||
main = true;
|
||||
_bVFlipMain =!_bVFlipMain;
|
||||
}
|
||||
else
|
||||
{
|
||||
main = false;
|
||||
_bVFlipSub =!_bVFlipSub;
|
||||
}
|
||||
updateFlip(main);
|
||||
}
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
|
||||
void RMPlayerZoom::onToggleVFlipMain()
|
||||
{
|
||||
bool main;
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
if(_swaped)
|
||||
{
|
||||
main = false;
|
||||
_bVFlipSub =!_bVFlipSub;
|
||||
}
|
||||
else
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
{
|
||||
main = true;
|
||||
_bVFlipMain =!_bVFlipMain;
|
||||
}
|
||||
updateFlip(main);
|
||||
}
|
||||
|
||||
#endif // #if !(DO_NOT_USE_FLIP)
|
||||
|
||||
|
||||
|
||||
#if (USE_EQ_FILTER)
|
||||
|
||||
// 0~100 = -0.5 ~ 0.5
|
||||
void RMPlayerZoom::onSetBrightness()
|
||||
{
|
||||
RMSlider* slider = qobject_cast<RMSlider*>(sender());
|
||||
// 0~100 = -0.9 ~ 0.9
|
||||
_brightness = RMUtility::range(0.0f,100.0f,-0.3f,0.3f,(float)slider->value());
|
||||
//_brightness = RMUtility::range(0.0f,100.0f,-0.5f,0.5f,(float)slider->value());
|
||||
//qInfo() << "B:" << slider->value() << _brightness;
|
||||
_updateEQFilter();
|
||||
}
|
||||
|
||||
// 0~100 = 0.1 ~ 1.9
|
||||
void RMPlayerZoom::onSetContrast()
|
||||
{
|
||||
RMSlider* slider = qobject_cast<RMSlider*>(sender());
|
||||
_contrast = RMUtility::range(0.0f,100.0f,0.6f,1.4f,(float)slider->value());
|
||||
//_contrast = RMUtility::range(0.0f,100.0f,0.1f,1.9f,(float)slider->value());
|
||||
//qInfo() << "C:" << slider->value() << _contrast;
|
||||
_updateEQFilter();
|
||||
}
|
||||
void RMPlayerZoom::_updateEQFilter(bool bForce)
|
||||
{
|
||||
if(_brightness < 0.05f && _brightness > -0.05f)
|
||||
{
|
||||
_brightness = -1000.0f;
|
||||
}
|
||||
if(_contrast > 0.95f && _contrast < 1.05f)
|
||||
{
|
||||
_contrast = -1000.0f;
|
||||
}
|
||||
|
||||
bool bExist = _brightness > -100.0f || _contrast > -100.0f;
|
||||
|
||||
if(bExist == false)
|
||||
{
|
||||
if(_hEQFilterF != NULL)
|
||||
{
|
||||
_hEQFilterF->uninstall();
|
||||
delete _hEQFilterF;
|
||||
_hEQFilterF = NULL;
|
||||
}
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
if(_hEQFilterR != NULL)
|
||||
{
|
||||
_hEQFilterR->uninstall();
|
||||
delete _hEQFilterR;
|
||||
_hEQFilterR = NULL;
|
||||
}
|
||||
#endif // #if (!SINGLE_CH_VIEWER)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 강제 삭제
|
||||
if(bForce) {
|
||||
if(_hEQFilterF != NULL)
|
||||
{
|
||||
_hEQFilterF->uninstall();
|
||||
delete _hEQFilterF;
|
||||
_hEQFilterF = NULL;
|
||||
}
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
if(_hEQFilterR != NULL)
|
||||
{
|
||||
_hEQFilterR->uninstall();
|
||||
delete _hEQFilterR;
|
||||
_hEQFilterR = NULL;
|
||||
}
|
||||
#endif // #if (!SINGLE_CH_VIEWER)
|
||||
}
|
||||
|
||||
|
||||
QString filterString = "format=pix_fmts=rgb24,eq=";
|
||||
if(_brightness > -100)
|
||||
{
|
||||
filterString += "brightness=";
|
||||
filterString += QString().sprintf("%.3f",_brightness);
|
||||
|
||||
if(_contrast > -100)
|
||||
{
|
||||
filterString += ":";
|
||||
}
|
||||
}
|
||||
if(_contrast > -100)
|
||||
{
|
||||
filterString += "contrast=";
|
||||
filterString += QString().sprintf("%.3f",_contrast);
|
||||
}
|
||||
//qInfo() << "filter:" << filterString;
|
||||
|
||||
if(_hEQFilterF == NULL)
|
||||
{
|
||||
_hEQFilterF = new FAV::LibAVFilterVideo(this);
|
||||
_hEQFilterF->installTo(_playerF);
|
||||
}
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
if(_hEQFilterR == NULL && _playerR != NULL)
|
||||
{
|
||||
_hEQFilterR = new FAV::LibAVFilterVideo(this);
|
||||
_hEQFilterR->installTo(_playerR);
|
||||
}
|
||||
#endif // #if (!SINGLE_CH_VIEWER)
|
||||
_hEQFilterF->setOptions(filterString);
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
if(_hEQFilterR != NULL) {
|
||||
_hEQFilterR->setOptions(filterString);
|
||||
}
|
||||
#endif // #if (!SINGLE_CH_VIEWER)
|
||||
|
||||
}
|
||||
updatePausedScreenFrontOnly();
|
||||
#if (!SINGLE_CH_VIEWER && !(TOGGLE_PLAYER))
|
||||
updatePausedScreenRearOnly();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#if (!(SINGLE_CH_VIEWER || TOGGLE_PLAYER) || PENTA_CHANNEL)
|
||||
void RMPlayerZoom::updatePausedScreenRearOnly()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
void RMPlayerZoom::updatePausedScreenFrontOnly()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#if (RM_MODEL_360)
|
||||
void RMPlayerZoom::onClearROI()
|
||||
{
|
||||
#if (USE_DRAG_ZOOM)
|
||||
RMPlayerBase::onClearROI();
|
||||
#endif // USE_DRAG_ZOOM
|
||||
|
||||
//FAV::VideoRenderer* vr = playerF()->renderer();
|
||||
_videoOutputF->opengl()->clearROI();
|
||||
_videoOutputF->widget()->update();
|
||||
if(_videoOutputF->opengl()->mode() == 0) {
|
||||
_videoOutputF->setOutAspectRatioMode(FAV::VideoRenderer::VideoAspectRatio);
|
||||
}
|
||||
#if (REAR_VIEW_ZOOM)
|
||||
_videoOutputR->opengl()->clearROI();
|
||||
_videoOutputR->widget()->update();
|
||||
if(_videoOutputR->opengl()->mode() == 0) {
|
||||
_videoOutputR->setOutAspectRatioMode(FAV::VideoRenderer::VideoAspectRatio);
|
||||
}
|
||||
#endif // REAR_VIEW_ZOOM
|
||||
}
|
||||
#endif // RM_MODEL_360
|
||||
#endif // //ZOOM_SHADER
|
||||
126
project/fm_viewer/core/rm_player_zoom.h
Normal file
126
project/fm_viewer/core/rm_player_zoom.h
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef RM_PLAYER_ZOOM_H
|
||||
#define RM_PLAYER_ZOOM_H
|
||||
|
||||
#include "rm_player_base.h"
|
||||
|
||||
#if (ZOOM_SHADER)
|
||||
class RMPlayerZoom : public RMPlayerBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RMPlayerZoom(QObject *parent = nullptr);
|
||||
|
||||
// ZOOM 모드 시작
|
||||
void startZoom(bool mainVideo);
|
||||
|
||||
// ZOOM 종료
|
||||
void stopZoom(bool mainVideo);
|
||||
|
||||
// ZOOM 위치 변경 + 프레임 크기가 확정되기 전에는 return false
|
||||
bool updateZoom(float x, float y, bool mainVideo);
|
||||
};
|
||||
#else // ZOOM_SHADER
|
||||
class RMPlayerZoom : public RMPlayerBase
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
#if !(DO_NOT_USE_FLIP)
|
||||
bool _bHFlipMain;
|
||||
bool _bVFlipMain;
|
||||
bool _bHFlipSub;
|
||||
bool _bVFlipSub;
|
||||
#endif
|
||||
|
||||
#if (USE_EQ_FILTER)
|
||||
float _brightness;
|
||||
float _contrast;
|
||||
|
||||
FAV::LibAVFilterVideo* _hEQFilterF;
|
||||
#if (!SINGLE_CH_VIEWER)
|
||||
FAV::LibAVFilterVideo* _hEQFilterR;
|
||||
#endif // SINGLE_CH_VIEWER
|
||||
protected:
|
||||
void _updateEQFilter(bool bForce = false);
|
||||
private:
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if (RESIZE_FILTER)
|
||||
FAV::LibAVFilterVideo* _hResizeFilterF;
|
||||
FAV::LibAVFilterVideo* _hResizeFilterR;
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit RMPlayerZoom(QObject *parent = nullptr);
|
||||
#if !(DO_NOT_USE_ZOOM)
|
||||
|
||||
void resizeFilter(QSize size, bool mainVideo);
|
||||
|
||||
// ZOOM 모드 시작
|
||||
QWidget* startZoom(bool mainVideo);
|
||||
|
||||
// ZOOM 종료
|
||||
void stopZoom(bool mainVideo);
|
||||
|
||||
// ZOOM 위치 변경 + 프레임 크기가 확정되기 전에는 return false
|
||||
bool updateZoom(float x, float y, bool mainVideo);
|
||||
|
||||
#if (USE_ZOOM_WH_RATIO)
|
||||
void updateZoomAspectRatio();
|
||||
#endif
|
||||
|
||||
// ZOOM TARGET 저장
|
||||
FAV::VideoRenderer* zoomTargetMain;
|
||||
#if !((SINGLE_CH_VIEWER || TOGGLE_PLAYER) && (!DUAL_VIEWER))
|
||||
FAV::VideoRenderer* zoomTargetSub;
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif // #if !(DO_NOT_USE_ZOOM)
|
||||
|
||||
#if !(DO_NOT_USE_FLIP)
|
||||
#if !(USE_SHADER_FLIP)
|
||||
FAV::LibAVFilterVideo* _hMainFilter;
|
||||
FAV::LibAVFilterVideo* _hRearFilter;
|
||||
#endif // !USE_SHADER_FLIP
|
||||
void updateFlip(bool bMain);
|
||||
#endif // USE_SHADER_FLIP
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
void clearScreen(bool front) override;
|
||||
//void _updateEQFilter() override;
|
||||
|
||||
private:
|
||||
#if (!(SINGLE_CH_VIEWER || TOGGLE_PLAYER) || PENTA_CHANNEL)
|
||||
virtual void updatePausedScreenRearOnly();
|
||||
#endif
|
||||
virtual void updatePausedScreenFrontOnly();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
#if !(DO_NOT_USE_FLIP)
|
||||
void onToggleHFlipMain();
|
||||
void onToggleVFlipMain();
|
||||
#if !(SINGLE_CH_VIEWER)
|
||||
void onToggleHFlipSub();
|
||||
void onToggleVFlipSub();
|
||||
#endif // #if !(SINGLE_CH_VIEWER)
|
||||
#endif
|
||||
|
||||
#if (RM_MODEL_360)
|
||||
void onClearROI();
|
||||
#endif
|
||||
|
||||
#if (USE_EQ_FILTER)
|
||||
// 0~100 = -0.9 ~ 0.9
|
||||
void onSetBrightness();
|
||||
|
||||
// 0~100 = 0.1 ~ 1.9
|
||||
void onSetContrast();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // ZOOM_SHADER
|
||||
#endif // RM_PLAYER_ZOOM_H
|
||||
340
project/fm_viewer/core/rm_usb.cpp
Normal file
340
project/fm_viewer/core/rm_usb.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
#include "rm_usb.h"
|
||||
#include <Windows.h>
|
||||
#include <dbt.h>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
#include "../cfg/rm_settings_cfg_emt_kr.h"
|
||||
#endif
|
||||
|
||||
#if (DETECT_SETTING_USB_EJECT || DETECT_USB_CHANGE)
|
||||
|
||||
rm_usb::rm_usb(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
_hDevNotify = NULL;
|
||||
_insertringDrive = 0;
|
||||
_removingDrive = 0;
|
||||
_openDrive = "";
|
||||
_irTimer = NULL;
|
||||
}
|
||||
rm_usb::~rm_usb()
|
||||
{
|
||||
if(_hDevNotify != NULL) {
|
||||
::UnregisterDeviceNotification(_hDevNotify);
|
||||
}
|
||||
_cancelIRTimer();
|
||||
}
|
||||
|
||||
// 항상 대문자로 리턴됨
|
||||
char rm_usb::_firstDriveFromMask( uint unitmask )
|
||||
{
|
||||
char i;
|
||||
|
||||
for (i = 0; i < 26; ++i)
|
||||
{
|
||||
if (unitmask & 0x1)
|
||||
break;
|
||||
unitmask = unitmask >> 1;
|
||||
}
|
||||
return( i + 'A' );
|
||||
}
|
||||
void rm_usb::_startIRTimer()
|
||||
{
|
||||
_cancelIRTimer();
|
||||
_irTimer = new QTimer(this);
|
||||
_irTimer->setSingleShot(true);
|
||||
_irTimer->setInterval(1000);
|
||||
connect(_irTimer,SIGNAL(timeout()),SLOT(onClearIR()));
|
||||
_irTimer->start();
|
||||
}
|
||||
void rm_usb::_cancelIRTimer()
|
||||
{
|
||||
if(_irTimer != NULL) {
|
||||
_irTimer->stop();
|
||||
delete _irTimer;
|
||||
_irTimer = NULL;
|
||||
}
|
||||
}
|
||||
void rm_usb::onClearIR()
|
||||
{
|
||||
_insertringDrive = 0;
|
||||
_removingDrive = 0;
|
||||
}
|
||||
|
||||
bool rm_usb::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
Q_UNUSED(result);
|
||||
#ifdef Q_OS_WIN32
|
||||
MSG *msg = (MSG *)message;
|
||||
if( WM_DEVICECHANGE == msg->message && DBT_DEVICEARRIVAL == msg->wParam )
|
||||
{
|
||||
DEV_BROADCAST_HDR* dev = (DEV_BROADCAST_HDR*)msg->lParam;
|
||||
if (dev->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)dev;
|
||||
char driver = _firstDriveFromMask(lpdbv->dbcv_unitmask);
|
||||
|
||||
// 다중 호출 방지 -> 처리 끝나면 초기화 해야 함
|
||||
if (_insertringDrive != driver)
|
||||
{
|
||||
_insertringDrive = driver;
|
||||
QString driver_letter(driver);
|
||||
driver_letter += ":";
|
||||
// qInfo() << "USB arrival detected:" << driver;
|
||||
*result = 1;
|
||||
emit usbChanged(true,driver_letter);
|
||||
_startIRTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( WM_DEVICECHANGE == msg->message && DBT_DEVICEREMOVECOMPLETE == msg->wParam )
|
||||
{
|
||||
DEV_BROADCAST_HDR* dev = (DEV_BROADCAST_HDR*)msg->lParam;
|
||||
if (dev->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)dev;
|
||||
char driver = _firstDriveFromMask(lpdbv->dbcv_unitmask);
|
||||
if (_removingDrive != driver)
|
||||
{
|
||||
_removingDrive = driver;
|
||||
QString driver_letter(driver);
|
||||
driver_letter += ":";
|
||||
// qInfo() << "USB departure detected:" << " driver:" << driver;
|
||||
*result = 1;
|
||||
emit usbChanged(false,driver_letter);
|
||||
_startIRTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // Q_OS_WIN32
|
||||
// Return false so that the event is propagated
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void rm_usb::registerEvent(QWidget *window)
|
||||
{
|
||||
if( window != nullptr )
|
||||
{
|
||||
#ifdef Q_OS_WIN32
|
||||
GUID WceusbshGUID = { 0x25dbce51, 0x6c8f, 0x4a72, 0x8a,0x6d,0xb5,0x4c,0x2b,0x4f,0xc8,0x35 };
|
||||
//GUID WusbrawGUID = {0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed };
|
||||
//GUID WusbGUID = {0x88BAE032, 0x5A81, 0x49f0, 0xBC, 0x3D, 0xA4, 0xFF, 0x13, 0x82, 0x16, 0xD6 };
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
||||
|
||||
::ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
|
||||
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
NotificationFilter.dbcc_classguid = WceusbshGUID;
|
||||
_hDevNotify = ::RegisterDeviceNotification((HANDLE)window->winId(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
if( NULL == _hDevNotify )
|
||||
{
|
||||
// Print error
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
bool rm_usb::isRemovablePath(QString path)
|
||||
{
|
||||
if(path.contains(":")) {
|
||||
QString driver = path.split(":").first();
|
||||
WCHAR diskName[4] = {0,};
|
||||
driver = driver.left(1) + ":\\";
|
||||
driver.toWCharArray(diskName);
|
||||
if(::GetDriveType(diskName) == DRIVE_REMOVABLE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void rm_usb::setOpenDriveWithPath(QString path)
|
||||
{
|
||||
if(rm_usb::isRemovablePath(path)) {
|
||||
_openDrive = path.left(1).toUpper() + ":";
|
||||
}
|
||||
}
|
||||
int rm_usb::isDeviceDriver(QString folder, bool loadCFG)
|
||||
{
|
||||
#if (RM_MODEL_TB) // RM_MODEL == RM_MODEL_TYPE_TB4000
|
||||
return QDir(folder).exists() && QDir(folder + QDir::separator() + QString("Video")).exists() && QDir(folder + QDir::separator() + QString("Photo")).exists();
|
||||
#elif (RM_MODEL_EMT_KR)
|
||||
// 각 모델별로 확인
|
||||
for(int i=0;i<CFG::model_names.size();i++) {
|
||||
QString path = folder + "Setting" + QDir::separator() + CFG::model_names.at(i) + "_setting.cfg";
|
||||
if(QFile::exists(path)) {
|
||||
// 설정파일 읽을 필요 없음
|
||||
if(!loadCFG) {
|
||||
return 0;
|
||||
}
|
||||
// checksum + 크기 + 모델코드 확인
|
||||
CFG_ERROR_CODE code = CFG::load(path);
|
||||
if(code != CFG_SUCCESS) {
|
||||
if(code == CFG_CHECKSUM_ERROR) {
|
||||
return code;
|
||||
}
|
||||
//qInfo() << path << " MODEL CODE:" << CFG::info.model << "ERROR:" << code << __FUNCTION__;
|
||||
}
|
||||
if(code == CFG_SUCCESS && CFG::info.model == CFG::model_codes[i])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// E:\Setting , NM5000_setting.cfg
|
||||
// Magnus : 5101
|
||||
// Trinity : 5102
|
||||
// Mirror5 : 5103
|
||||
// Pro5 : 5104
|
||||
// 360X : 5105
|
||||
|
||||
return 999;
|
||||
#else //
|
||||
return false;
|
||||
#endif;
|
||||
}
|
||||
|
||||
// Disk 의 볼륨명이 모델명과 동일함
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
QString rm_usb::getRemovableDisk()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
WCHAR szLogicalDrives[MAX_PATH * sizeof(TCHAR)];
|
||||
DWORD dwByte = ::GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
|
||||
|
||||
for(DWORD i=0; i<dwByte / 4; i++)
|
||||
{
|
||||
WCHAR* diskName = &szLogicalDrives[i * 4];
|
||||
UINT type = ::GetDriveType(diskName);
|
||||
if(DRIVE_REMOVABLE == type)
|
||||
{
|
||||
#if (!NO_SD_CHECK)
|
||||
QString diskLetter = QString::fromUtf16((const ushort*)diskName);
|
||||
|
||||
diskLetter.replace("\\","");
|
||||
|
||||
diskLetter = "\\\\.\\" + diskLetter;
|
||||
|
||||
// qInfo() << "check disk name:" << diskLetter;
|
||||
// empty media check
|
||||
HANDLE hDisk = ::CreateFile(reinterpret_cast<LPCWSTR>(diskLetter.utf16()),
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if(hDisk == INVALID_HANDLE_VALUE || hDisk == NULL)
|
||||
{
|
||||
//qInfo() << "INVALID_HANDLE_VALUE" << diskLetter << "type" << type;
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD dwBytesReturned;
|
||||
ULONG MediaChangeCount;
|
||||
BOOL res = ::DeviceIoControl( hDisk,
|
||||
IOCTL_STORAGE_CHECK_VERIFY,
|
||||
NULL,
|
||||
0,
|
||||
&MediaChangeCount,
|
||||
sizeof(ULONG),
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
::CloseHandle(hDisk);
|
||||
if(res == FALSE)
|
||||
{
|
||||
//qInfo() << "empty" << QString::fromUtf16((const ushort*)diskName) << "type" << type;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
QString diskPath = QString::fromUtf16((const ushort*)diskName);
|
||||
// 설정파일 존재 확인
|
||||
if(isDeviceDriver(diskPath,false) == 0) {
|
||||
return diskPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
#else // TB
|
||||
QString rm_usb::getRemovableDisk(QString volume)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
WCHAR szLogicalDrives[MAX_PATH * sizeof(TCHAR)];
|
||||
DWORD dwByte = ::GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
|
||||
|
||||
for(DWORD i=0; i<dwByte / 4; i++)
|
||||
{
|
||||
WCHAR* diskName = &szLogicalDrives[i * 4];
|
||||
UINT type = ::GetDriveType(diskName);
|
||||
if(DRIVE_REMOVABLE == type)
|
||||
{
|
||||
|
||||
#if (!NO_SD_CHECK)
|
||||
QString diskLetter = QString::fromUtf16((const ushort*)diskName);
|
||||
|
||||
diskLetter.replace("\\","");
|
||||
|
||||
diskLetter = "\\\\.\\" + diskLetter;
|
||||
|
||||
// qInfo() << "check disk name:" << diskLetter;
|
||||
// empty media check
|
||||
HANDLE hDisk = ::CreateFile(reinterpret_cast<LPCWSTR>(diskLetter.utf16()),
|
||||
FILE_READ_DATA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if(hDisk == INVALID_HANDLE_VALUE || hDisk == NULL)
|
||||
{
|
||||
//qInfo() << "INVALID_HANDLE_VALUE" << diskLetter << "type" << type;
|
||||
continue;
|
||||
}
|
||||
|
||||
DWORD dwBytesReturned;
|
||||
ULONG MediaChangeCount;
|
||||
BOOL res = ::DeviceIoControl( hDisk,
|
||||
IOCTL_STORAGE_CHECK_VERIFY,
|
||||
NULL,
|
||||
0,
|
||||
&MediaChangeCount,
|
||||
sizeof(ULONG),
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
::CloseHandle(hDisk);
|
||||
if(res == FALSE)
|
||||
{
|
||||
//qInfo() << "empty" << QString::fromUtf16((const ushort*)diskName) << "type" << type;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
WCHAR volumeNameW[MAX_PATH * sizeof(TCHAR)] = {0,};
|
||||
|
||||
::GetVolumeInformation(diskName,volumeNameW, 1024, NULL, NULL, NULL, NULL, MAX_PATH);
|
||||
|
||||
QString volumeName = QString::fromUtf16((const ushort*)volumeNameW);
|
||||
QString diskPath = QString::fromUtf16((const ushort*)diskName);
|
||||
//qInfo() << volumeName << __FUNCTION__;
|
||||
if(volume.isEmpty() || volume.compare(volumeName,Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
diskPath = diskPath.replace("\\","");
|
||||
//rm_usb::current_driver = diskPath.at(0).toLatin1();
|
||||
return diskPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
#endif // #if (RM_MODEL_EMT_KR)
|
||||
#endif // #if (USE_SD_CARD_DETECT)
|
||||
74
project/fm_viewer/core/rm_usb.h
Normal file
74
project/fm_viewer/core/rm_usb.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef RM_USB_H
|
||||
#define RM_USB_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#include <QMainWindow>
|
||||
#include "../rm_include.h"
|
||||
|
||||
#if (DETECT_SETTING_USB_EJECT || DETECT_USB_CHANGE)
|
||||
class rm_usb : public QObject, public QAbstractNativeEventFilter
|
||||
{
|
||||
friend class RMWindowsDisk;
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit rm_usb(QObject *parent = 0);
|
||||
~rm_usb();
|
||||
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
|
||||
|
||||
//! \brief 지정된 볼륨의 USB 장치 탐색
|
||||
//! \param volume: 탐색할 볼륨명
|
||||
//! \return 탐색된 USB 폴더명
|
||||
#if (RM_MODEL_EMT_KR)
|
||||
static QString getRemovableDisk();
|
||||
#else // RM_MODEL_EMT_KR
|
||||
static QString getRemovableDisk(QString volume);
|
||||
#endif // RM_MODEL_EMT_KR
|
||||
QString _openDrive; ///!< 현재 사용된 드라이버
|
||||
|
||||
//! \brief 지정된 경로가 USB 디스크인지 확인
|
||||
//! \param volume
|
||||
//! \return true:YES
|
||||
static bool isRemovablePath(QString path);
|
||||
|
||||
//! \brief setopenDriveWithFolder
|
||||
//! 경로의 드라이버가 removeable 일 경우 _openDrive 지정
|
||||
//! \param path: 경로
|
||||
void setOpenDriveWithPath(QString path);
|
||||
|
||||
//! \brief 장치 드라이버인지 확인
|
||||
//! 내부의 폴더, 볼륨명 등으로 확인
|
||||
//! 설정파일도 읽고 검증
|
||||
//! \param path: 경로
|
||||
//! \return 0:success other:CFG_ERROR_CODE
|
||||
static int isDeviceDriver(QString path,bool loadCFG = false);
|
||||
|
||||
private:
|
||||
char _firstDriveFromMask(uint unitmask );
|
||||
char _insertringDrive; // 다중호출 방지, 현재 추가되고 있는 드라이브
|
||||
char _removingDrive; // " 제거되고 있는 드라이브
|
||||
QTimer* _irTimer; ///! 동시 다중호출 방지를 위해 사용하는 _insertringDrive, _removingDrive 초기화
|
||||
|
||||
|
||||
//! \brief 초기화(_insertringDrive,_removingDrive) 타이머 시작
|
||||
void _startIRTimer();
|
||||
|
||||
//! \brief 초기화(_insertringDrive,_removingDrive) 타이머 취소
|
||||
void _cancelIRTimer();
|
||||
|
||||
void* _hDevNotify;
|
||||
signals:
|
||||
void usbChanged(bool inserted, QString& drive); // or removed
|
||||
|
||||
//! \brief 잘못된 SD 카드
|
||||
//! \param code: CFG_ERROR_CODE
|
||||
void wrongSDCard(int code);
|
||||
public slots:
|
||||
void registerEvent(QWidget *window);
|
||||
|
||||
//! \brief _insertringDrive, _removingDrive 초기화
|
||||
void onClearIR();
|
||||
};
|
||||
|
||||
#endif // USE_SD_CARD_DETECT
|
||||
#endif // RM_USB_H
|
||||
12
project/fm_viewer/core/rm_utility.cpp
Normal file
12
project/fm_viewer/core/rm_utility.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "rm_utility.h"
|
||||
|
||||
RMUtility::RMUtility()
|
||||
{
|
||||
|
||||
}
|
||||
float RMUtility::range(float fmin, float fmax,float tmin, float tmax, float value)
|
||||
{
|
||||
const float newRange = tmax - tmin;
|
||||
const float oldRange = fmax - fmin;
|
||||
return ((((value - (fmin)) * newRange) / oldRange) + tmin);
|
||||
}
|
||||
14
project/fm_viewer/core/rm_utility.h
Normal file
14
project/fm_viewer/core/rm_utility.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef RM_UTILITY_H
|
||||
#define RM_UTILITY_H
|
||||
|
||||
|
||||
class RMUtility
|
||||
{
|
||||
public:
|
||||
RMUtility();
|
||||
|
||||
static float range(float fmin, float fmax,float tmin, float tmax, float value);
|
||||
|
||||
};
|
||||
|
||||
#endif // RM_UTILITY_H
|
||||
Reference in New Issue
Block a user