LINUX.ORG.RU

Сообщения Xuch

 

Прошу помощи с кросс-компиляцией библиотеки qt-gstreamer (QtGstreamer) для ARM

Всем доброго времени суток! Мучаюсь с компиляцией библиотеки qt-gstreamer-0.10.1 под целевую плату на ARM процессоре. Работаю под Ubuntu Trusty (14.04). Для начала потренировался собрать из исходников под рабочую систему Trusty для i386. После некоторых танцев с бубном это удалось успешно. Но вот с кросс-компиляцией ничего не получается.

В качестве зависимостей там указываются:

* Qt 4 - Required for building everything
* Boost - Required for building QtGLib
* Automoc 4 - Required for the build system to generate moc files properly
* GStreamer - Required to build QtGStreamer
* GStreamer base library - Used for building the qwidgetvideosink element
* GStreamer app library - Required to build QtGStreamerUtils
* GStreamer interfaces library - Required to build QtGStreamer
* GStreamer video library - Used for building the qwidgetvideosink element
* GLib - Required to build QtGLib
* GObject - Required to build QtGLib
* Flex - Required to build codegen, a helper code generator
* Bison - Required to build codegen, a helper code generator
* Doxygen - Used to generate the API documentation

Но дальше мне не совсем понятно. Когда я скомпилировал automoc4 под ARM и положил его в мой Target ARM SDK, при попытке собрать QtGstreamer вылетала ошибка shell, что /usr/bin/automoc4 не найден и посему он не может сгенерировать файлы и т.д. Хорошо, установил automoc4 под Trusty (i386), теперь на это он не ругается, но не может собрать codegen. Спустя какое-то количество танцев codegen собрался успешно, в папке build/codegen появился исполняемый файл (естественно для ARM), но далее при попытке сборки QtGstreamer выдает ошибку shell, что codegen не может быть запущен, т.к. имеет неправильный формат (короче он пытается его исполнить под текущей системой i386).

Пробовал запускать cmake с опцией -DQTGSTREAMER_CODEGEN=OFF, но это не помогает - пишет, что неизвестная переменная -QTGSTREAMER_CODEGEN игнорируется и все равно собирает codegen.

Фиг с ним, подсунул ему в папку с ARM SDK automoc4, собранный ранее под i386. В итоге codegen собрался нормально, но далее линкер не видит библиотеку libglib-2.0.so, которая на самом деле в папке libs с SDK есть.

Как я собираю. Для удобства сделал файлик environment-setup следующего содержания:

SDK_PATH=/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit
if [ -z "$ZSH_NAME" ] && [ "x$0" = "x./environment-setup" ]; then
    echo "Error: This script needs to be sourced. Please run as \". ./environment-setup\""
    exit 1
else
    if [ -n "$BASH_SOURCE" ]; then
        SDK_PATH=/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit
    fi
    SDK_PATH=/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit
    export SDK_PATH
fi
export TOOLCHAIN_PATH=/home/aroma/CodeSourcery/Sourcery_G++_Lite/
export TARGET_SYS=arm-none-linux-gnueabi
#export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
export PATH=$SDK_PATH/bin:$TOOLCHAIN_PATH/bin:$PATH
export CPATH=$SDK_PATH/$TARGET_SYS/usr/include:$CPATH
export LIBTOOL_SYSROOT_PATH=$SDK_PATH/$TARGET_SYS
export PKG_CONFIG_SYSROOT_DIR=$SDK_PATH/$TARGET_SYS
export PKG_CONFIG_PATH=$SDK_PATH/$TARGET_SYS/usr/lib/pkgconfig
export CONFIG_SITE=$SDK_PATH/site-config
#export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
export OE_QMAKE_CC=${TARGET_SYS}-gcc
export OE_QMAKE_CXX=${TARGET_SYS}-g++
export OE_QMAKE_LINK=${TARGET_SYS}-g++
export OE_QMAKE_AR=${TARGET_SYS}-ar
export OE_QMAKE_LIBDIR_QT=${SDK_PATH}/${TARGET_SYS}/usr/lib
export OE_QMAKE_INCDIR_QT=${SDK_PATH}/${TARGET_SYS}/usr/include/qtopia
export OE_QMAKE_MOC=${SDK_PATH}/bin/moc4
export OE_QMAKE_UIC=${SDK_PATH}/bin/uic4
export OE_QMAKE_UIC3=${SDK_PATH}/bin/uic34
export OE_QMAKE_RCC=${SDK_PATH}/bin/rcc4
export OE_QMAKE_QDBUSCPP2XML=${SDK_PATH}/bin/qdbuscpp2xml4
export OE_QMAKE_QDBUSXML2CPP=${SDK_PATH}/bin/qdbusxml2cpp4
export OE_QMAKE_QT_CONFIG=${SDK_PATH}/${TARGET_SYS}/usr/share/qtopia/mkspecs/qconfig.pri
export QMAKESPEC=${SDK_PATH}/${TARGET_SYS}/usr/share/qtopia/mkspecs/linux-g++
export OE_QMAKE_LDFLAGS="-L${SDK_PATH}/${TARGET_SYS}/usr/lib -Wl,-rpath-link,${SDK_PATH}/${TARGET_SYS}/usr/lib -Wl,-O1 -Wl,--hash-style=gnu"
export OE_QMAKE_STRIP="echo"
export PS1="\[\e[32;1m\][qt-gstreamer-cmake]\[\e[0m\]:\w> "
export GSTREAMER_BASE_LIBRARY=${SDK_PATH}/${TARGET_SYS}/usr/lib/libgstbase-0.10.so

Перед сборкой подгружаю его командой #source environment-setup.

Далее сделал файлик arm-toolchain.cmake следующего содержания:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_SYSTEM_PROCESSOR ARM)
SET(CMAKE_C_COMPILER arm-none-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER arm-none-linux-gnueabi-g++)
SET(CMAKE_FIND_ROOT_PATH /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_PREFIX_PATH /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib)
SET(Boost_INCLUDE_DIR /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost)

При конфигурировании cmake вроде как корректно находит нужные библиотеки (кроме странности с gobject-2.0 - там почему-то он лезет в папку с заголовочными файлами):

#cmake -DCMAKE_TOOLCHAIN_FILE=arm_toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/target-bin -DQTGSTREAMER_CODEGEN=OFF ..
-- The C compiler identification is GNU 4.3.3
-- The CXX compiler identification is GNU 4.3.3
-- Check for working C compiler: /home/aroma/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-gcc
-- Check for working C compiler: /home/aroma/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /home/aroma/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-g++
-- Check for working CXX compiler: /home/aroma/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-g++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Looking for Q_WS_X11
-- Looking for Q_WS_X11 - not found
-- Looking for Q_WS_WIN
-- Looking for Q_WS_WIN - not found
-- Looking for Q_WS_QWS
-- Looking for Q_WS_QWS - found
-- Looking for Q_WS_MAC
-- Looking for Q_WS_MAC - not found
-- Found Qt4: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/bin/qmake (found version "4.7.2") 
-- Boost version: 1.45.0
-- Found PkgConfig: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/bin/pkg-config (found version "0.23") 
-- checking for module 'gstreamer-0.10'
--   found gstreamer-0.10, version 0.10.32
-- checking for module 'gstreamer-base-0.10'
--   found gstreamer-base-0.10, version 0.10.32
-- Found GSTREAMER_BASE_LIBRARY: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstbase-0.10.so
-- Found GSTREAMER_BASE_INCLUDE_DIR: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/gstreamer-0.10
-- Found GStreamer: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstreamer-0.10.so (Required is at least version "0.10.31") 
-- checking for module 'gstreamer-plugins-base-0.10'
--   found gstreamer-plugins-base-0.10, version 0.10.32
-- checking for module 'gstreamer-app-0.10'
--   found gstreamer-app-0.10, version 0.10.32
-- Found GSTREAMER_APP_LIBRARY: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstapp-0.10.so
-- Found GSTREAMER_APP_INCLUDE_DIR: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/gstreamer-0.10
-- checking for module 'gstreamer-interfaces-0.10'
--   found gstreamer-interfaces-0.10, version 0.10.32
-- Found GSTREAMER_INTERFACES_LIBRARY: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstinterfaces-0.10.so
-- Found GSTREAMER_INTERFACES_INCLUDE_DIR: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/gstreamer-0.10
-- checking for module 'gstreamer-video-0.10'
--   found gstreamer-video-0.10, version 0.10.32
-- Found GSTREAMER_VIDEO_LIBRARY: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstvideo-0.10.so
-- Found GSTREAMER_VIDEO_INCLUDE_DIR: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/gstreamer-0.10
-- Found GStreamerPluginsBase: TRUE (Required is at least version "0.10.31") 
-- checking for module 'glib-2.0'
--   found glib-2.0, version 2.24.1
-- Found GLIB2: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libglib-2.0.so  
-- checking for module 'gobject-2.0'
--   found gobject-2.0, version 2.24.1
-- Found GObject: /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/glib-2.0  
-- Found FLEX: /usr/bin/flex (found version "2.5.35") 
-- Found BISON: /usr/bin/bison (found version "3.0.2") 
-- Found Doxygen: /usr/bin/doxygen (found version "1.8.6") 
-- Could NOT find DOXYFILE_IN (missing:  DOXYFILE_IN) 

-----------------------------------------------------------------------------
-- The following external packages were located on your system.
-- This installation will have the extra features provided by these packages.
-----------------------------------------------------------------------------
   * Qt 4 - Required for building everything
   * Boost - Required for building QtGLib
   * Automoc 4 - Required for the build system to generate moc files properly
   * GStreamer - Required to build QtGStreamer
   * GStreamer base library - Used for building the qwidgetvideosink element
   * GStreamer app library - Required to build QtGStreamerUtils
   * GStreamer interfaces library - Required to build QtGStreamer
   * GStreamer video library - Used for building the qwidgetvideosink element
   * GLib - Required to build QtGLib
   * GObject - Required to build QtGLib
   * Flex - Required to build codegen, a helper code generator
   * Bison - Required to build codegen, a helper code generator
   * Doxygen - Used to generate the API documentation

-----------------------------------------------------------------------------
-- Congratulations! All external packages have been found.
-----------------------------------------------------------------------------

-- Configuring done
CMake Warning (dev) in src/QGlib/CMakeLists.txt:
  Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
  interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Target "QtGLib" has an INTERFACE_LINK_LIBRARIES property which differs from
  its LINK_INTERFACE_LIBRARIES properties.

  INTERFACE_LINK_LIBRARIES:

    /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libQtCoreE.so;gobject-2.0;gthread-2.0;rt;glib-2.0;/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libQtCoreE.so

  LINK_INTERFACE_LIBRARIES:

    /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libQtCoreE.so

This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) in src/QGst/CMakeLists.txt:
  Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
  interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Target "QtGStreamer" has an INTERFACE_LINK_LIBRARIES property which differs
  from its LINK_INTERFACE_LIBRARIES properties.

  INTERFACE_LINK_LIBRARIES:

    QtGLib;gobject-2.0;gthread-2.0;rt;glib-2.0;/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstreamer-0.10.so;/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstinterfaces-0.10.so;QtGLib

  LINK_INTERFACE_LIBRARIES:

    QtGLib

This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) in src/QGst/CMakeLists.txt:
  Policy CMP0022 is not set: INTERFACE_LINK_LIBRARIES defines the link
  interface.  Run "cmake --help-policy CMP0022" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Target "QtGStreamerUtils" has an INTERFACE_LINK_LIBRARIES property which
  differs from its LINK_INTERFACE_LIBRARIES properties.

  INTERFACE_LINK_LIBRARIES:

    QtGStreamer;/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstreamer-0.10.so;/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib/libgstapp-0.10.so;QtGStreamer

  LINK_INTERFACE_LIBRARIES:

    QtGStreamer

This warning is for project developers.  Use -Wno-dev to suppress it.

-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    QTGSTREAMER_CODEGEN


-- Build files have been written to: /home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/build

Далее пытаюсь собирать: #make Выдает ошибку:

make
[  1%] [FLEX][analyzer] Building scanner with flex 2.5.35
[  2%] [BISON][parser] Building parser with bison 3.0.2
parser.y: warning: 6 shift/reduce conflicts [-Wconflicts-sr]
Scanning dependencies of target codegen
[  4%] Building CXX object codegen/CMakeFiles/codegen.dir/analyzer.cpp.o
In file included from /home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/codegen/yystype.h:29,
                 from analyzer.l:20:
/home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/build/codegen/parser.hpp:74: error: 'CodeGen' was not declared in this scope
/home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/build/codegen/parser.hpp:74: error: 'codegen' was not declared in this scope
/home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/build/codegen/analyzer.cpp:2253: warning: 'int yy_top_state()' defined but not used
make[2]: *** [codegen/CMakeFiles/codegen.dir/analyzer.cpp.o] Error 1
make[1]: *** [codegen/CMakeFiles/codegen.dir/all] Error 2
make: *** [all] Error 2

Лезу в файл build/codegen/parcer.hpp и добавляю перед определением функции #include <generator.h> и заново пытаюсь собрать:

make
Scanning dependencies of target codegen
[  1%] Building CXX object codegen/CMakeFiles/codegen.dir/analyzer.cpp.o
/home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/build/codegen/analyzer.cpp:2253: warning: 'int yy_top_state()' defined but not used
[  2%] Building CXX object codegen/CMakeFiles/codegen.dir/parser.cpp.o
[  4%] Building CXX object codegen/CMakeFiles/codegen.dir/generator.cpp.o
Linking CXX executable codegen
[  7%] Built target codegen
Scanning dependencies of target QtGLib_automoc
Generating connect.moc
[  7%] Built target QtGLib_automoc
[  8%] Generating gen.cpp
Scanning dependencies of target QtGLib
[ 10%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/QtGLib_automoc.cpp.o
[ 11%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/quark.cpp.o
[ 13%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/type.cpp.o
[ 14%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/paramspec.cpp.o
[ 16%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/object.cpp.o
[ 17%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/value.cpp.o
[ 19%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/signal.cpp.o
[ 20%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/error.cpp.o
[ 22%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/connect.cpp.o
In file included from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/aux_/has_begin.hpp:17,
                 from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/aux_/begin_end_impl.hpp:21,
                 from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/begin_end.hpp:18,
                 from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/aux_/at_impl.hpp:17,
                 from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/at.hpp:18,
                 from /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/multi_index_container.hpp:23,
                 from /home/aroma/workspace-bvi/libs/qt-gstreamer-0.10.1/src/QGlib/connect.cpp:25:
/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/has_xxx.hpp:344:9: warning: "BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION" is not defined
/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/has_xxx.hpp:357:9: warning: "BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES" is not defined
/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/has_xxx.hpp:386:9: warning: "BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION" is not defined
/home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/include/boost/boost/mpl/has_xxx.hpp:459:8: warning: "BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE" is not defined
[ 23%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/wrap.cpp.o
[ 25%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/init.cpp.o
[ 26%] Building CXX object src/QGlib/CMakeFiles/QtGLib.dir/gen.cpp.o
Linking CXX shared library libQtGLib-2.0.so
/home/aroma/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lgobject-2.0
collect2: ld returned 1 exit status
make[2]: *** [src/QGlib/libQtGLib-2.0.so.0.10.1] Error 1
make[1]: *** [src/QGlib/CMakeFiles/QtGLib.dir/all] Error 2
make: *** [all] Error 2

Ошибка - не видит библиотеку gobject-2.0, хотя в папке /home/aroma/ti-ezsdk_dm816x-evm_5_05_02_00/linux-devkit/arm-none-linux-gnueabi/usr/lib сама библиотека libgobject-2.0.so есть и прекрасно себя чувствует.

Застрял на этом месте. Прошу любой помощи! Заранее всем большое спасибо за внимание

 , ,

Xuch
()

GLib проблема с потоками GMainLoop

Всем привет! Опять я в ступоре, мысли кончились, на сей раз проблема с GMainLoop и блокированием потока. Есть не-default GMainContext, к которому приаттачены отдельными потоками секундный таймер и слушающий TCP-сервер. Проблема в том, что когда подключается клиент, таймер перестает работать. Отключается клиент - работа таймера восстанавливается. Как побороть данную проблему? Ниже привожу полный код.

main.h:

/*
 * main.h
 *
 *  Created on: Jan 15, 2014
 *      Author: xuch
 */

#ifndef MAIN_H_
#define MAIN_H_

using namespace std;

#include <stdio.h>
#include <glib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>
#include <syslog.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>

GMainLoop *main_loop;

static int daemon_proc;

typedef void Sigfunc(int);   /* for signal handlers */
#define SA struct sockaddr
#define LISTENQ         1024

class Dat
{
public:
	Dat(void);
	int Status;
};


class ControlServer
{
public:
	Dat *CData;
	GMainContext *Ctx;
	ControlServer(Dat *, GMainContext *, const char *, const char *);
	int GThStart();

private:
  char host[254];
  char port[254];

  static bool Handler(GIOChannel *, GIOCondition, gpointer);
  static bool GStartStatic(gpointer);
  static bool GStartStatic2(gpointer);
  int TcpListen(const char *, const char *, socklen_t *);
  void ErrQuit(const char *, ...);
  static void ErrSys(const char *, ...);
  static void ErrDoIt(int, int, const char *, va_list);
  void Listen(int, int);
  int Close(int);
  int SetSockOpt(int, int, int, const void *, int);
};

class Parent
{
public:
	GMainLoop *MainLoop;
	Parent(const char *, const char *);
	~Parent(void);
	void Start(size_t);
	void Init(void);
	void StartTimer(void);
private:
	Dat *Data;
	GMainContext *Context;
	ControlServer *Srv;
	static gboolean TimeoutCallback(gpointer);
	static gboolean TimeoutCallback2(gpointer);
	static gpointer SecTimer(gpointer);
};

#endif /* MAIN_H_ */

main.cpp:

/*
 * main.cpp
 *
 *  Created on: Jan 15, 2014
 *      Author: xuch
 */

#include "main.h"

using namespace std;

int main(void)
{
	Parent *Par;

	printf("Starting main...\n");
	Par = new Parent("127.0.0.1", "54321");
	Par->StartTimer();
	Par->RunMainLoop();
	delete Par;
}

Parent::Parent(const char *ip, const char *port)
{
	Data = new Dat();
	Context = g_main_context_new();
	Srv = new ControlServer(Data, Context, ip, port);
	MainLoop = g_main_loop_new(Context, false);
}

Parent::~Parent()
{
	delete Data;
	delete Srv;
}

void Parent::Start(size_t interval)
{
	g_thread_init(NULL);

	Srv->GThStart();	// Start listen TCP Server
	main_loop = g_main_loop_new(NULL, FALSE);
	g_timeout_add_seconds(interval, TimeoutCallback, Data);
	g_main_loop_run(main_loop);
}

void Parent::RunMainLoop()
{
	g_main_loop_run(MainLoop);
}

gpointer Parent::SecTimer(gpointer data)
{
	Parent *Prnt = (Parent *) data;
	GSource *Source = g_timeout_source_new(1000);	// 1 second interval
	g_source_set_callback(Source, TimeoutCallback, Prnt->Data, NULL);
	g_source_attach(Source, Prnt->Context);
	g_source_unref(Source);
	return NULL;
}

gboolean Parent::TimeoutCallback(gpointer data)
{
	Dat *Data = (Dat *) data;
	Data->Status++;
	printf("%ld-> Timeout Callback! Status now: '%d'\n", time(NULL), Data->Status);
	return TRUE;
}

void Parent::StartTimer()
{
	GError *error = NULL;

	g_thread_init(NULL);

	Srv->GThStart();	// Start listen TCP Server

	GThread *t = g_thread_create(SecTimer, this, TRUE, &error);
	g_thread_join(t);
}

ControlServer::ControlServer(Dat *data, GMainContext * gtx, const char *ip, const char *prt)
{
	CData = data;
	Ctx = gtx;
	strcpy(host, ip);
	strcpy(port, prt);
}

bool ControlServer::Handler(GIOChannel *in, GIOCondition condition, gpointer data)
{
  Dat *Dt = (Dat *) data;
  struct sockaddr_storage income;
  int insock, newsock;
  socklen_t income_len;
  struct sockaddr peer;
  socklen_t size;
  int count = 0;

  insock = g_io_channel_unix_get_fd(in);
  income_len = sizeof(income);
  newsock = accept(insock, (struct sockaddr *) &income, &income_len);

  size = sizeof(peer);
  getpeername(newsock, &peer, &size);
  struct sockaddr_in *ipv4 = (struct sockaddr_in *) &peer;

  printf("%ld-> New Client connected -> ", time(NULL));
  printf("Host IP:Port '%s:%d'\n", inet_ntoa(ipv4->sin_addr), ipv4->sin_port);

  do
  {
	  const int len = 1024 * 1024;
	  char buf[len + 1];
	  bzero(buf, len + 1);
	  count = recv(newsock, buf, len, 0);
	  buf[len] = '\0';
	  Dt->Status++;
	  printf("%ld-> Received string: '%s'; Dat.Status = %d\n", time(NULL), buf, Dt->Status);

  } while (count > 0);

  printf("%ld-> Connection closed for Host IP:Port '%s:%d'; Dat.Status = %d\n", time(NULL), inet_ntoa(ipv4->sin_addr), ipv4->sin_port, Dt->Status);

  return true;
}

bool ControlServer::GStartStatic(gpointer data)
{
  ControlServer *CServer = (ControlServer *) data;

  int listenfd;
  socklen_t addr_len;
  GIOChannel *Channel;
  GSource *Source;

  listenfd = CServer->TcpListen(CServer->host, CServer->port, &addr_len);
  Channel = g_io_channel_unix_new(listenfd);
  Source = g_io_create_watch(Channel, G_IO_IN);
  g_source_set_callback(Source, (GSourceFunc) Handler, (gpointer) CServer->CData, NULL);
  g_source_attach(Source, CServer->Ctx);
  g_source_unref(Source);

  return false;
}

int ControlServer::GThStart()
{
	GError *error;
	GThread *t = g_thread_create((GThreadFunc) GStartStatic, this, TRUE, &error);
	g_thread_join(t);
	return 0;
}

void ControlServer::ErrDoIt(int errno_flag, int level, const char *fmt, va_list ap)
{
  int errno_save, n;
  char buf[254 + 1];

  errno_save = errno;

#ifdef HAVE_VSNPRINTF
  vsnprintf(buf, CHAR_BUF_SIZE, fmt, ap);
#else
  vsprintf(buf, fmt, ap);
#endif
  n = strlen(buf);
  if (errno_flag)
    snprintf(buf + n, 254 - n, ": %s", strerror(errno_save));
  strcat(buf, "\n");

  if (daemon_proc)
    {
      syslog(level, buf);
    }
  else
    {
      fflush(stdout);
      fputs(buf, stderr);
      fflush(stderr);
    }
  return;
}

void ControlServer::ErrQuit(const char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  ErrDoIt(0, LOG_ERR, fmt, ap);
  va_end(ap);
  exit(1);
}

void ControlServer::ErrSys(const char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  ErrDoIt(1, LOG_ERR, fmt, ap);
  va_end(ap);
  exit(1);
}

int ControlServer::Close(int fd)
{
  return close(fd);
}

int ControlServer::SetSockOpt(int sock_fd, int level, int opt_name, const void *opt_val, int opt_len)
{
  return setsockopt(sock_fd, level, opt_name, opt_val, opt_len);
}

void ControlServer::Listen(int fd, int backlog)
{
  char *ptr;

  if ((ptr = getenv("LISTENQ")) != NULL)
    backlog = atoi(ptr);

  if (listen(fd, backlog) < 0)
    ErrSys("listen error");
}

int ControlServer::TcpListen(const char *host, const char *serv, socklen_t *addrlenp)
{
  int listen_fd, n;
  const int on = 1;
  struct addrinfo hints, *res, *res_save;

  bzero(&hints, sizeof(struct addrinfo));
  hints.ai_flags = AI_PASSIVE;
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;

  if ((n = getaddrinfo(host, serv, &hints, &res)) != 0)
    {
      ErrQuit("TcpListen error for %s. %s: %s\n", host, serv, gai_strerror(n));
    }
  res_save = res;

  do
    {
      listen_fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
      if (listen_fd < 0)
        continue;

      SetSockOpt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
      if (bind(listen_fd, res->ai_addr, res->ai_addrlen) == 0)
        break;

      Close(listen_fd);

    } while ((res = res->ai_next) != NULL);

  if (res == NULL)
    {
      ErrSys("TcpListen error for %s, %s", host, serv);
    }

  Listen(listen_fd, LISTENQ);
  if (addrlenp)
    *addrlenp = res->ai_addrlen;
  return listen_fd;
}

Dat::Dat()
{
	Status = 0;
}

 

Xuch
()

gstreamer - как узнать длительность mpegts файла?

Всем доброго времени суток! Что-то я в тупике оказался.. Подскажите можно ли как-то через gstreamer узнать длительность видео-файла не проигрывая его? Т.е. есть путь к файлу, нужно узнать его длительность. Казалось бы простейшая задача, но решить ее пока никак не удается...

Буду рад любым мыслям и предложениям.

 

Xuch
()

Портирование проекта MS Visual Studio в линукс

Всем доброго времени суток! Вопрос к линух гуру - есть довольно большой проект, который разрабатывался под Windows 7 в среде MS Visual Studio, по сути - проприетарная система видеонаблюдения. На разработку ушло около года.

Сейчас начальство требует приложение переписать под Linux, т.к. на компьютеры вместо Win7 будет ставиться Debian.

В никсах есть небольшой опыт работы во FreeBSD (настройка как сетевого шлюза), немного работал в RedHat. Но программированием, тем более с выводом графики (motion jpeg с камер видеонаблюдения) в никсах никогда не занимался. В Visual Studio всё просто, куча библиотек и стандартных элементов, накидал и пошел писать специфические для данного приложения вещи, а как с этим в линуксе? Каждый элемент управления писать с нуля? Бррр...

Подскажите пжл с чего начать и вообще насколько трудозатратен такой переход?

Xuch
()

RSS подписка на новые темы