LINUX.ORG.RU

Сообщения kulti

 

Потоковое вещание по HTTP

Имеется видео-поток, который нужно вещать по http. Происходит следующее:
1) клиент коннектится и забирает какой-то объем данных
2) начинает воспроизводить, но новые данные не принимает (я вижу на серверной стороне, что процесс отдачи данных остановился)
3) потом клиент возобновляет прием данных, а через какой-то время начинает жаловаться, что «Cache not filling»(это mplayer, а vlc пишет «main input error: ES_OUT_SET_(GROUP_)PCR is called too late (pts_delay increased to 1200 ms)»). видео, соответственно начинает замирать и дергаться.

Собственно, не понятно в чем проблема: клиент тупит(не забирает данные постоянно), сервер тупит(может, нужно самому контролировать битрейт отдваемых данных)? Может, нужно какие-то специфичные заголовки в http указать? Пробовал всякие no-cache и keep-alive варьировать. Если кто какую идею подкинет, куда копнуть, буду рад.

kulti
()

Mercurial поверх SVN

Все привет!

Хотел на работе весь код перетащить из SVN в Mercurial. Но я не один, и не всем удобно переходить. Так вот вопрос: можно ли сделать так, чтобы я работал как с mercurial, но на самом деле под ним был бы svn репозиторий, с которым могут работать другие? Или это как-то по другому делается? Если можно - киньте линк, что почитать. Спасибо.

kulti
()

Самописный dd не пишет в /dev/mtd

Есть у меня буфер, нужно его записать в /dev/mtd4, а оставшуюся часть раздела нулями забить. Делаю так:

    static const int dataBlockSize = 8192;
    int mtdBlockFd = open( "/dev/mtd4", O_WRONLY | O_CREAT | O_TRUNC, 0666 );
    int bytesWritten = 0;
    while( bytesInBufLeft > dataBlockSize )
    {
      bytesWritten = safe_write( mtdBlockFd, bufPtr, dataBlockSize );
      bytesInBufLeft -= bytesWritten;
      bufPtr += bytesWritten;
    }

    if( (bytesInBufLeft - dataBlockSize) > 0 )
    {
      bytesWritten = safe_write( mtdBlockFd, bufPtr, bytesInBufLeft - dataBlockSize );
    }

    do
    {
      static const char zeroBuf[dataBlockSize] = {0};
      bytesWritten = safe_write( mtdBlockFd, zeroBuf, dataBlockSize );
    } while( bytesWritten > 0);

safe_write подсмотрел, в dd, когда с просто write не работало, но и это не помогло:

int safe_write(int fd, const void *buf, int count)
{
  int n;

  do {
    n = write(fd, buf, count);
  } while (n < 0 && errno == EINTR);

  return n;
}

Кто-нибдудь что-нибудь подобное делал? В чем может быть косяк? Если вместо /dev/mtd4 имя простого файла указать, то в него все нормально пишется.

kulti
()

[C/C++]http клиент и сервер

Всем привет.

Нужна либа, которая реализует и http-клиент и http-сервер. Ограничений особо никаких нет, даже поддержка ssl не нужна. Главное - удобство. Пока сгуглил только libhttp, но может кто-нибудь что-то получше посоветует?

kulti
()

[FFMPEG]мануалов не существует?

Всем привет!

Как я понял, человеческого описания работы с ffmpeg не существует? Приходится читать доки нагенеренные доксидженом и разнообразные форумы, чтобы «догадаться» что за чем вызывать и какие параметры ставить руками. Например, мне нужно кодировать поток в flv:

  AVCodec* flvCodec = avcodec_find_encoder_by_name( "flv" );
  if( flvCodec == NULL )
  {
    cerr << "flv codec not found" << endl;
  }
  AVCodecContext* flvCodecCtx = avcodec_alloc_context();
  if( flvCodecCtx == NULL )
  {
    cerr << "flv codec ctx not alloc" << endl;
  }

  //вот тут нужно сделать "непонятное".
  flvCodecCtx->pix_fmt = PIX_FMT_YUV420P;

  //А непонятно оно потому, что "Initializes the AVCodecContext to use the given AVCodec".
  if( 0 != avcodec_open(flvCodecCtx, flvCodec) )
  {
    cerr << "flv codec not open" << endl;
  }

Или вот дальше делаю avcodec_encode_video(). А потом, я так понял, нужно хидеры flv'шные самому приклеить к этому буферу.

Собсна, вопрос в том, может, кто-нибудь натыкался на подробное описание работы с ffmpeg, где рассказано как читать/писать потоковое видео, какие преобразования нужно делать, а чего делать не следует?

UPD: Может, альтернативы какие существуют? Пусть даже обертки для ffmpeg, но с нормальным описанием?

 

kulti
()

[CMAKE]кросскомпиляция либы

Просто так либа собирается без проблем, но когда пытаюсь кросскомпилировать под mipsel, cmake отказывается находить ar.

Делаю так:

mkdir build_mipsel
cd build_mipsel
cmake -DCMAKE_TOOLCHAIN_FILE=../mipsel_toolchains.cmake ..
make VERBOSE=1

mipsel_toolchains.cmake такой:

set(CMAKE_SYSTEM_MAKE Linux)

set(CMAKE_C_COMPILER   mipsel-linux-gcc)
set(CMAKE_CXX_COMPILER mipsel-linux-g++)
set(CMAKE_AR mipsel-linux-ar)

set(CMAKE_FIND_ROOT_PATH /opt/toolchains/uclibc-crosstools)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

В выводе make VERBOSE=1 вместо /opt/toolchains/uclibc-crosstools/bin/mipsel-linux-ar пустая строка «» и пишет Error running link command: No such file or directory.

mipsel-linux-ar в системе, ессно, присутствует. Никак не пойму, какого gcc, g++ он находит, а ar нет?

 

kulti
()

[gprof]Результаты удивляют(по крайней мере меня)

Мозг просто схлопнулся. Может, кто подскажет, на что эти симптомы указывают?

Есть программа, которая в одном потоке данные принимает и пишет в циклический буфер, а в другом потоке, соответственно, читает их из буфера. Работа с буфером посторенна по такой схеме:

Запись:
1) Буфер полон? если да, то подожать и проверить еще раз, если нет, то
2) Взять указатель, куда писать. Записать. Передвинуть указатель.

Чтение:
1) Буфер пуст? если да, то подожать и проверить еще раз, если нет, то
2) Взять указатель, откуда читать. Обработать. Передвинуть указатель

 25.84      2.32     0.77 569435332     0.00     0.00  RingBuffer<char, PThreadMutex>::isEmpty()
  7.05      2.87     0.21 18397292     0.01     0.01  RingBuffer<char, PThreadMutex>::isFull()
  2.35      2.94     0.07 26900264     0.00     0.00  RingBuffer<char, PThreadMutex>::getWritePtr()
  1.34      2.98     0.04     6343     6.31     6.31  RingBuffer<char, PThreadMutex>::moveWritePtr()
  0.00      2.98     0.00    14115     0.00     0.00  RingBuffer<char, PThreadMutex>::moveReadPtr()
  0.00      2.98     0.00     8427     0.00     0.00  RingBuffer<char, PThreadMutex>::getReadPtr()

Первые две строчки вполне предсказуемы, а вот откуда берется различное количество вызовов для getWritePtr/moveWritePtr и getReadPtr/moveReadPtr, я, откровенно говоря, не понимаю. И то, что чтений больше записей.

Лишних потоков точно не создается(для проверки воткнул лог в начало и конец потоковых функций).

Если кто-то думает, что накосячил в коде, то вот так реализовано чтение из кольцевого буфера и запись содержимого в файл:

if( !thread->stream_data->isEmpty() )
{
  buf = thread->stream_data->getReadPtr();
  write( outfd, buf, msg_len );
  thread->stream_data->moveReadPtr();
}

kulti
()

Можно ли «победить» Disk sleep, езли знаю прогу?

Работаю с железякой через com-порт. Иногда при отключении питания в консоль вываливается «nothing to read. probably port disconnected.», и процесс виснет в D+

ps a|grep com

3038 pts/1 D+ 0:08 com /dev/ttyUSB0 115200

Перегружать комп совсем неудобно, а по другому, я так понял из гугла, никак. Может, такую прогу можно в какую-нить песочницу засунуть, чтобы перезапускать только эту песочницу, а не всю систему?

kulti
()

[MPEG-TS]Добавить свой пакет

Пытаюсь вставить в существующий mpeg-ts свои пакеты. Частота вставки раз в 100 пакетов по 188 байт. Первые четыре байта выставляю так:

  //set sync byte
  buf[0] = 0x47;
  //set PSI as 'payload unit start indicator' and PID = 0x16
  buf[1] = 0x00;
  buf[2] = 0x16;
  //set flags: scrambled(no), payload(yes), adaptation(no); and 'continuity counter' to counter
  buf[3] = 0x10 | (counter & 0x0f);
Остальные 184 байта забиты моей инфой. В результате видео начинает «сыпаться»(появляются квадратики). Может, есть какие-то подводные камни, и нужно делать что-то еще, кроме выставления синхронизационного бита и уникального PIDa со своим счетчиком?

PS. или может посоветуете спец-форум, где можно этот вопрос задать?

kulti
()

[libpqxx]Трабла с листенером

Пытаюсь заюзать механизм notify-listen, но никак не выходит. По заверешении пишет «Closing connection with outstanding listeners». Код примерно такой(выпилил проверку ошибок, чтобы не загромождать)

class DRM_KeyListener : public notify_listener
{
  public:
    DRM_KeyListener(connection &conn) : notify_listener(conn, "test_event"){};
    virtual void operator()(int be_pid)
    {
      cout << "notify received! " << be_pid << endl;
    };
};

int main(int argc, char **argv)
{
  ostringstream conn_string("");
  conn_string << "host=" << argv[1]
              << " user=" << argv[2]
              << " password=" << argv[3]
              << " dbname=" << argv[4];

  pqxx::connection conn_for_listener(conn_string.str());
  DRM_KeyListener* key_listener = new DRM_KeyListener(conn_for_listener);

  pqxx::connection conn(conn_string.str());
  pqxx::work xact(conn, "SampleSelect");
  string produceEventQuery("SELECT test.produce_test_event()");
  pqxx::result res = xact.exec(createKeyQuery);
  return 0;
}

kulti
()

[C]write упирается в 2147483647

Файловая систем ext3. Пишу в цикле много данных в файл обычным write'ом

int outfd = open( out_file_name, O_WRONLY|O_CREAT|O_TRUNC, 0644 );
while(!stopped)
{
  int byte_written = write( outfd, buf, bufsize );
}
При достижении размера в 2147483647 вываливается ошибка «File too large». getrlimit говорит, то ограничение на размер файла стоит в 4 гига
struct rlimit rlp;
if( 0 == getrlimit(RLIMIT_FSIZE, &rlp) )
  cout << rlp.rlim_cur << " " << rlp.rlim_max << endl;
Но этого все равно будет мало. Как писать файлы по 20+ гигов?

 

kulti
()

[проблема с bind]Прием мультикаста с разных ip, но одинаковых портов

Вещается несколько мультикаст потоков, но все на одинаковый порт. Я делаю так, чтобы создать сокет:

  struct sockaddr_in socket_address = {0};
  uint8_t opt;
  struct sockaddr_in sin = {0};

  int sockfd =  socket( AF_INET, SOCK_DGRAM, 0 );

  opt = 1;
  setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
  setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF, &window_size, sizeof(window_size) );
  setsockopt( sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt));

  sin.sin_family = AF_INET;
  sin.sin_port = htons(port);
  sin.sin_addr.s_addr = INADDR_ANY;

  bind(sockfd, (struct sockaddr *) &sin, sizeof(struct sockaddr_in);

а потом присоединяю его к группе:

  struct ip_mreq mreq = {0};

  mreq.imr_multiaddr.s_addr = ip;
  mreq.imr_interface.s_addr = htonl(INADDR_ANY);

  setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq));
Один экземпляр такой программы работает прекрасно, но когда пытаешь запустить еще один, то bind пишет ошибку «Address already in use».

Пробовал для sockaddr_in указывать конкретный ip, а не INADDR_ANY. Не помогло.

kulti
()

[network]TTL is nill

А вот если TTL в 0(ноль) выставить, то что будет? Пакеты будут доставляться всем, кто по эту сторону сетевухи, а за нее они не уйдут? Или так вообще нельзя делать, и минимальное допустимое значение это единица?

PS. попробовал ping -t 0 свой тачки. Пингуется.

 

kulti
()

[CMake]Работа с поддиректориями

Есть примерно такая структура директорий \root_project_dir Makefile \inc \ext_libs \other_stuff \src Makefile main.cpp \network Makefile networks.cpp \ui Makefile uis.cpp

В каждой директории make-файл собирает свои сpp и делает рекурсивный make -C по всем поддиректориям. Имхо, изврат какой-то. Хочу на cmake перейти, но никак не пойму, можно ли его заставить рекурсивно директории указанные собирать. Насколько я понял, придется все поддиректории в виде статических либ собирать и линковать с ними main.o. Или же есть возможность передать информацию об объектных файлах из поддиректорий?

 

kulti
()

copy_to_user: не понимаю, как посмотреть данные в kernel space

Пишу модуль ядра. Нашел в исходниках ядра стандартный обработчки приема udp: udp_recvmsg.

Пытаюсь задампить данные, которые в сокете(я так понимаю они в пространсве ядра, т.к. потом их copy_to_user):

skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
  goto out;

for( ; j < skb->len; ++j )
{
  printk("%x ", skb->data[j]);
}
Результат выглядит, откровенно говоря, как дамп неинициализированной памяти(всякие там de, ff etc)

А вот когда уже после skb_copy_datagram_iovec смотрю буфер, который в юзер спейсе находится, то в нем все хорошо:

unsigned char* buf = (unsigned char*)msg->msg_iov->iov_base
for( ; i < msg->msg_iov->iov_len; ++i )
{
  printk("%x ",buf[i]);
}

Посмотрел, как та самая skb_copy_datagram_iovec() работает. Для моего случая там вседа лишь memcpy_toiovec(которая копирует данные в юзер спейс) вызывается, т.е. отрабатывает вот этот кусочек:

/* Copy header. */
if (copy > 0) {
  if (copy > len)
    copy = len;
  if (memcpy_toiovec(to, skb->data + offset, copy))
    goto fault;
  if ((len -= copy) == 0)
    return 0;
  offset += copy;
}

Никак не пойму, как же тогда данные в kernel space посмотреть? Ведь то же самое, что копируется вроде вывожу.

kulti
()

Перехват и модификация udp-трафика

Мне необходимо перехватить udp-трафик и немного его модифицировать. Я это делаю с помощью модуля ядра. Проблема в том, что необходимо это сделать без пересобирания ядра, а в том, что есть, похоже отключен netfilter (я так решил, т.к. при попытке подгрузить модуль, использующий nf_register_hook, пишет «Unknown symbol nf_register_hook»).

Вот так я подменяю стандартный обработчик:

#include "linux/module.h"
#include "net/udp.h"

int (*orginalRecv)(struct kiocb*, struct sock*, struct msghdr*, size_t, int, int, int*);

int moniter_recv_udp(struct kiocb* iocb, struct sock* sk, struct msghdr*msg, size_t len, int noblock, int flags, int* addr_len)
{
    //тут надо что-то придумать
    return orginalRecv( iocb, sk, msg, len, noblock, flags, addr_len );
}


int init_module()
{
    orginalRecv = udp_prot.recvmsg;
    udp_prot.recvmsg = moniter_recv_udp;

    return 0;
}


void cleanup_module()
{
    udp_prot.recvmsg = orginalRecv;

}

Но никак не пойму, где там живет принимаемый буфер и как с ним работать. Вроде бы в sk->sk_receive_queue, т.е. вот так делаю и весь трафик блокируется:

int moniter_recv_udp(struct kiocb* iocb, struct sock* sk, struct msghdr*msg, size_t len, int noblock, int flags, int* addr_len)
{
    int ret = orginalRecv( iocb, sk, msg, len, noblock, flags, addr_len );

    sk->sk_receive_queue.next = sk->sk_receive_queue.prev = (struct sk_buff*)(&sk->sk_receive_queue);
    sk->sk_receive_queue.qlen = 0;

    return ret;
}

Может, подскажет кто?

kulti
()

Qt Сreator под оффтопиком

Никогда ничего mingw'ом не компилил, а тута вот понадобилось значит. Есть у меня свой виджет (в никсах все разумеется прекрасно работает). Собрал его под виндой - собрался. Стал компилить проект, который этот виджет за разные места трогает: undefined reference to <все места за которые его потрогали>. И куча других типа: undefined reference to `__CRT_MT'.

Если прям в Qt Creator собирать, то в окне с ошибками только первую пачку показывают.

Что делать? Как бороть?

kulti
()

QSettings: unable to load/save type xxx

У меня в коде есть структура, назовем ее для определенности MyStruct. Делаю все по науке:
typedef struct
{...}MyStruct;
Q_DECLARE_METATYPE(MyStruct)

Вызов qRegisterMetaType<MyStruct>(); до первого использования не забыл воткнуть.

НО! Во время выполнения сыпятся QT'шные ворнинги: "QVariant::load: unable to load type ххх" и "QVariant::save: unable to save type ххх". Сеттинг естественно тоже не загружается/сохраняется.

ЧЯДНТ?

kulti
()

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