Получить изображение из видео.
Видео передается по сети, необходимо получить изображение из этого видео.
1. Какие существуют библиотеки для этого, помимо opencv и ffmpeg?
2. opencv можно научить читать видео из памяти?
Видео передается по сети, необходимо получить изображение из этого видео.
1. Какие существуют библиотеки для этого, помимо opencv и ffmpeg?
2. opencv можно научить читать видео из памяти?
Организация выделяет один адрес сети на отдел. Адрес сети задается, как IP = 130.20.0.0. IP адрес сетевого интерфейса сервера организации, подключенного к серверу отдела IP = 130.20.0.1 Количество компьютеров в сети 2 - 8181 компьютеров.
СервОрг--сеть1--СервОтдела---сеть2---8181комп
Как оптимально/правильно решить такую задачу?
Решения которые вижу.
1. Разбить сеть на куски по /19 маске. Но тогда в сети 1 будет много неиспользуемых адресов.
2. Cеть 1 - маска /16 ИП 130.20.0.1, 130.20.0.2
Сеть 2 - маска /19 ИП начинаются с 130.20.0.3
Использую libav* для сохранения кадров из видео.
Проблема в том, что если вызвать функцию decode несколько раз, то 2й и далее не верно обрабатываются.
1й раз такой вывод (все нормально работает):
[swscaler @ 0x8b48510]No accelerated colorspace conversion found from yuv420p to bgra.
good
2й (не находит потоки):
[mp3 @ 0x8ae5800]Header missing
Last message repeated 223 times
[mp3 @ 0x8af31c0]Could not find codec parameters (Audio: mp1, 0 channels, s16)
[mp3 @ 0x8af31c0]Estimating duration from bitrate, this may be inaccurate
av_find_stream_info
Подскажите, пожалуйста, где ошибка.
main.cpp
avcodec_init();
avcodec_register_all();
av_register_all();
char *data;
int size;
//fill data and size
...
decode(data, size);
decode(data, size);
video.cpp
int f_offset = 0;
int f_length = 0;
char *f_data = 0;
int64_t seekp(void *opaque, int64_t offset, int whence)
{
switch (whence)
{
case SEEK_SET:
if (offset > f_length || offset < 0)
return -1;
f_offset = offset;
return f_offset;
case SEEK_CUR:
if (f_offset + offset > f_length || f_offset + offset < 0)
return -1;
f_offset += offset;
return f_offset;
case SEEK_END:
if (offset > 0 || f_length + offset < 0)
return -1;
f_offset = f_length + offset;
return f_offset;
case AVSEEK_SIZE:
return f_length;
}
return -1;
}
int readp(void *opaque, uint8_t *buf, int buf_size)
{
if (f_offset == f_length)
return 0;
int length = buf_size <= (f_length - f_offset) ? buf_size : (f_length - f_offset);
memcpy(buf, f_data + f_offset, length);
f_offset += length;
return length;
}
bool decode(char *data, int length)
{
f_offset = 0;
f_length = length;
f_data = data;
int buffer_read_size = FF_MIN_BUFFER_SIZE;
uchar *buffer_read = (uchar *) av_mallocz(buffer_read_size + FF_INPUT_BUFFER_PADDING_SIZE);
AVProbeData pd;
pd.filename = "";
pd.buf_size = 4096 < f_length ? 4096 : f_length;
pd.buf = (uchar *) av_mallocz(pd.buf_size + AVPROBE_PADDING_SIZE);
memcpy(pd.buf, f_data, pd.buf_size);
AVInputFormat *pAVInputFormat = av_probe_input_format(&pd, 1);
if (pAVInputFormat == NULL)
{
std::cerr << "AVIF";
return false;
}
pAVInputFormat->flags |= AVFMT_NOFILE;
ByteIOContext ByteIOCtx;
if (init_put_byte(&ByteIOCtx, buffer_read, buffer_read_size, 0, NULL, readp, NULL, seekp) < 0)
{
std::cerr << "init_put_byte";
return false;
}
AVFormatContext *pFormatCtx;
if (av_open_input_stream(&pFormatCtx, &ByteIOCtx, "", pAVInputFormat, NULL) < 0)
{
std::cerr << "av_open_stream";
return false;
}
// Получаем информацию о потоке
if (av_find_stream_info(pFormatCtx) < 0)
{
std::cerr << "av_find_stream_info";
return false;
}
// Ищем первый поток видео
int video_stream;
video_stream = -1;
for (uint i = 0; i < pFormatCtx->nb_streams; ++i)
if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
{
video_stream = i;
break;
}
if (video_stream == -1)
{
std::cerr << "video_stream == -1";
return false;
}
// Берем указатель на контекст кодека потока видео
AVCodecContext *pCodecCtx;
pCodecCtx = pFormatCtx->streams[video_stream]->codec;
// Ищем декодер для потока видео
AVCodec *pCodec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL)
{
std::cerr << "pCodec == NULL";
return false;
}
// Открываем кодек
if (avcodec_open(pCodecCtx, pCodec) < 0)
{
std::cerr << "avcodec_open";
return false;
}
// Выделяем память под YUV видео фрейм
AVFrame *pFrame;
pFrame = avcodec_alloc_frame();
if (pFrame == NULL)
{
std::cerr << "pFrame == NULL";
return false;
}
// И под RGB фрейм
AVFrame *pFrameRGB;
pFrameRGB = avcodec_alloc_frame();
if (pFrameRGB == NULL)
{
std::cerr << "pFrameRGB == NULL";
return false;
}
// Определяем требуемый размер буфера и выделяем под него память
int numBytes;
numBytes = avpicture_get_size(PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);
uint8_t *buffer;
buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
if (buffer == NULL)
{
std::cerr << "buffer == NULL";
return false;
}
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);
SwsContext *swsctx;
swsctx = sws_getContext(
pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB32,
SWS_BILINEAR, NULL, NULL, NULL);
if (swsctx == NULL)
{
std::cerr << "swsctx == NULL";
return false;
}
// Читаем фреймы
AVPacket packet;
while (av_read_frame(pFormatCtx, &packet) >= 0)
{
// Это пакет из потока видео?
if (packet.stream_index == video_stream)
{
//колво декодированных фреймов
int frame_finished;
// Декодировать фрейм
avcodec_decode_video2(pCodecCtx, pFrame, &frame_finished, &packet);
// Мы получили фрейм?
if (frame_finished)
{
//трансофрмация
sws_scale(swsctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
std::cerr << "good";
av_close_input_stream(pFormatCtx);
return true;
}
else
std::cerr << "frame_finished == 0";
}
}
std::cerr << "av_read_frame < 0";
return false;
}
ffmpeg -version
FFmpeg 0.6.2-4:0.6.2-1ubuntu1
libavutil 50.15. 1 / 50.15. 1
libavcodec 52.72. 2 / 52.72. 2
libavformat 52.64. 2 / 52.64. 2
libavdevice 52. 2. 0 / 52. 2. 0
libavfilter 1.19. 0 / 1.19. 0
libswscale 0.11. 0 / 0.11. 0
libpostproc 51. 2. 0 / 51. 2. 0
Есть ручная китайская зарядка USB. Напряжение выхода на холостом ходу ~6.15В. Стандарт говорит про 5В. Отклонение ~23%. Насколько страшно заряжать плееры, книжки и другие гаджеты?
Есть необходимость в реальном времени наблюдать за ресурсами одной программы. Как в 'top' (или другой аналогичной) можно отфильтровать все кроме нужной программы. Заранее благодарен.
Знаком немного с «C» и «Linux».
Есть одна win-only программа для шифрования дисков. Формат раздела открытый. Хочу написать аналог для поднятия умений в системном программировании под linux. Программа будет только read-only.
Какие книги мне стоит прочитать? И как это вообще должно выглядеть?
Собственно сабж, есть стд функции?
...
\usepackage{graphicx}
...
\begin{figure}
\includegraphics[width=50mm]{test.eps}
\caption{Image}\label{l1}
\end{figure}
...
Так вот, после такого блока пропадают длинные и средние тире, т. е. "---" и "--". Эксперементальным путем было выяснено, что это из-за
\includegraphics[width=50mm]{test.eps}
И влияет только на страницу, где вставлен рисунок. Кто-то знает решения данной проблемы?
Как в gnuplot 4.2 в 3Д режиме убрать часть оси "Z"?
//показано на рисунке http://img227.imageshack.us/my.php?image=lin1pf8.gif
Уря!
Изменения можно прочитать http://www.alsa-project.org/main/index.php/Changes_v1.0.14_v1.0.15rc1.
Можно теперь смело забить на оффтопик, так как:
snd-emu10k1: Add support for E-Mu 0404 PCI.
/me ушел эксперементировать.
Вот читая slackbook, наткнулся на:
Перед тем, как извлечь дискету, CD-ROM или любой другой съёмный накопитель, который в данный момент примонтирован, вы должны сначала отмонтировать его. Это выполняется командой umount. Не спрашивайте, куда подевалась буква “n”, потому что мы не сможем ответить вам (правильно должно звучать “unmount” - прим. переводчика).
И собственно вопрос? может кто-то знает куда пропала "n"? :)
P. S. Гуглил плохо.
Недавно поствил себе Fedora 6 и решил перенести часть вендовых игр. Имеется интернет игра(Преферанс) GOLClient, запускаю ее под wine-0.9.36, а в консоле пишется:
WARNING: Trying to use ICMP (network ping) will fail unless running as root
Я правильно понимаю, что для использования ИСМП нужен рут? И как от этого можно было б избавится?
Посоветуйте, пжл, где искать.