Форум: "Media";
Текущий архив: 2007.05.27;
Скачать: [xml.tar.bz2];
ВнизПомогите разобраться с ф-цией ICCompress() Найти похожие ветки
← →
NeyroSpace © (2006-09-12 16:58) [0]Смотрю исходники и не совсем понимаю...
В нее передается параметр dwFlags = ICCOMPRESS_KEYFRAME, если ты хочешь сделать этот кадр ключевым.
Вопрос как часто нужно делать кадр ключевым?
Как я понимаю если при инициализации кодека получены флаги
VIDCF_TEMPORAL, и не получен VIDCF_FASTTEMPORALC, то при сжатии неключевого кадра, в ф-цию еще необходимо передавать предыдущий кадр.
Вопрос предыдущий сжатый или предыдущий несжатый кадр?
В сырцах зачем-то уже сжатый кадр расжимают и потом используют как предыдущий и немного запутался...
← →
SamBrook © (2006-09-12 23:05) [1]
> Вопрос как часто нужно делать кадр ключевым
Зависит от сюжета. Для быстроменяющихся - часто, для статических редко.
> Вопрос предыдущий сжатый или предыдущий несжатый кадр?
Для временной компрессии, как правило, используется результат применения XOR текущего и ключевого кадра. Поэтому он должен быть распакованным.
В целом: функция ICCompress работает неэффективно.
Лучше (и проще) пользоваться ICSeqCompressFrame(Start,End)
А еще лучше забыть про VFW и пользовать DirectShow
← →
NeyroSpace © (2006-09-13 09:21) [2]SamBrook © (12.09.06 23:05) [1]
Мне нужно сжимать кадры с вэб камеры. VFW вроде бы достаточно.
А у DirectShow я не знаю как получить поток сжатых кадров... Фильтры кодекоов в DSPack выдают поток сразу в файл, а мне б в MemoryStream надо. Может где-нить есть инфа по этому поводу?
← →
NeyroSpace © (2006-09-13 09:25) [3]И еще один вопросик. Для отслеживания текущего состояния кодека есть ф-ция обратного вызова. Но она почему-то возвращает все время одно и тоже. Нужно ли посылать кодеку дополнительные сообщения, чтобы он обновил информацию о своем состоянии?
← →
SamBrook © (2006-09-13 10:10) [4]
> А у DirectShow я не знаю как получить поток сжатых кадров.
> .. Фильтры кодекоов в DSPack выдают поток сразу в файл,
> а мне б в MemoryStream надо. Может где-нить есть инфа по
> этому поводу?
ISampleGrabber поможет.
← →
NeyroSpace © (2006-09-13 10:24) [5]>SamBrook © (13.09.06 10:10) [4]
Т.е. если в фильтре указать кодек, то SampleGrabber1Buffer будет возвращать сжатый кадр?
← →
SamBrook © (2006-09-13 10:32) [6]
> Т.е. если в фильтре указать кодек, то SampleGrabber1Buffer
> будет возвращать сжатый кадр?
SampleGrabber не делает ничего кроме "высовывания наружу" буфера.
← →
NeyroSpace © (2006-09-13 10:47) [7]>SampleGrabber не делает ничего кроме "высовывания наружу" буфера.
это понятно))
SampleGrabber1 => FilterGraph1 => Filter1 у него есть BaseFilter для выбора кодека.
Так как мне в данном случае получить сжатый кадр захваченый с вэбкамеры?
← →
SamBrook © (2006-09-13 11:28) [8]SampleGrabber можно вставить в любое место цепочки фильтров. Если после кодека - получите компрессированное изображение, если до - исходное
← →
NeyroSpace © (2006-09-13 11:39) [9]>SamBrook © (13.09.06 11:28) [8]
Хорошо, допустим я получил буфер с закодированым кадром, как я дальше его декодирую?
← →
SamBrook © (2006-09-13 11:44) [10]
> Хорошо, допустим я получил буфер с закодированым кадром,
> как я дальше его декодирую?
Похоже, я перестал что-то понимать...
Опишите свою задачу, пожалуйста
← →
NeyroSpace © (2006-09-13 11:56) [11]Задача простая:
1. Захватываем кадр с вэб-камеры
2. Сжимаем.
3. Пишем в MemoryStream
4. Читаем из MemoryStream
5. Разжимаем.
6. Выводим в окно.
1. Сделал при помощи DSPack.
2. Пытаюсь сделать при помощи VFW кодируя каждый кадр, полученный в процедуре SampleGrabber1Buffer().
3, 4. Тут потом будет TCP|IP.
Сейчас проблема именно с кодированием. Не получается запустить ICCompress с кодеками, у которых один ключевой кадр на несколько не ключевых (DivX, VidX). А например Microsoft Windows Media Video 9, VP31® Compressor и еще несколько работают.
По DSPack у меня не хватает информации, хелп там слабый, а примеры только с файлами.
← →
SamBrook © (2006-09-13 12:24) [12]п/п. 1-3 выполняются через DirectShow цепочкой
источник - кодек - SampleGrabber (пишем в память) - Null renderer.
в MSDN есть пример
← →
NeyroSpace © (2006-09-13 13:11) [13]Мне б с DSPack примерчик...
← →
NeyroSpace © (2006-09-13 15:27) [14]нет что-то не то...
Работаю с DSPack:
CaptureGraph.RenderStream(nil, nil, SourceFilter, SampleFilter, DestFilter);
SourceFilter - веб-камера.
SampleFilter - Filter2 в BaseFilter выбран видео кодек, например Cinepak by Radius.
DestFilter - SampleGrabber.
в процедуре SampleGrabberBuffer() проверяю BufferLen. Он не меняется! Т.е. такое ощущение что он указывает размер bmp.
← →
NeyroSpace © (2006-09-13 16:02) [15]Точно! Оказывается надо в настройках SampleGrabber:
1. SampleGrabber.MediaType убрать галочку Fixed Size Sample
2. SampleGrabber.MediaType в Sub Type поставить Automatic
Теперь осталось разобраться как декодировать ))
← →
NeyroSpace © (2006-09-13 18:09) [16]Вот интересно а как теперь декодировать?
Имеется последовательность сжатых кодеком кадров. Я даже не знаю какой из них ключевой...
Как эту последовательность декодировать?
Если использовать ICDecompress(), то нужно знать какой кадр ключевой, а какой нет. Кто-нить может пнуть в правильном направлении?
← →
Sambrook © (2006-09-13 19:50) [17]Извините, но по-моему Вы занимаетесь ерундой.
Зачем писать в MemoryStream если можно писать в файл, в котором будет содержаться исчерпывающая информация для декодера?
Если Вы хотите смоделировать видеосервер/клиент, то надо копать в сторону DirectPlay и сопрягать его с DirectShow как в серверной, так и клиентской части.
В справке по DirectX есть для этого все необходимое
← →
NeyroSpace © (2006-09-18 15:00) [18]Сделал! Как и хотел по кадрам кодирование/декодирование!
Диктую ответ на 1 вопрос билета:
Принцип работы синхрофазотрона...:-))
Примеров по использованию этих ф-ций в инете практически нет ((
Но! На официальном форуме DSPack нашелся человек, который выложил пример для всех жаждущих знания - Lee_Nover за что ему большое спасибо!
Он сконвертировал модуль VideoSequenceCompressor.cpp + *.h из состава VirtualDub-1.6.16-src в модуль VideoCoDec.pas + выложил примерчик готового сервера/клиента, который передает сжатое видео по сети. Правда программки немного глючат...
1. У него в примере неправильно устанавливается размер захватываемого кадра. Т.е. код вроде бы верный, он не срабатывает. Нужно сделать немного по другому.
2. В модуле VideoCoDec.pas ВОЗМОЖНО он несовсем корректно использует ф-цию ICCompress(). При работе с не ключевыми кадрами она должна получать указатель на предыдущий несжатый кадр и в этом месте код у него не самый понятный.
Поэтому на стороне клиента при декомпрессировании возникают глюки (изображение черезстрочное + виден только правый нижний угол (из-за 1), а например в DivX5 все плавает как в мыльном пузыре (из-за 2).
Тут можно скачать его мудуль и пример (для Delphi 7, но если ручками подправить, то работает и на Delphi 5):
http://members.lycos.co.uk/deneysdebeer/Downloads/stream.zip
или
http://download.dsplayer.de/OpenSource/StreamingDemo.zip
После 2х недель упорного бодания с дубом, дуб рухнул!
Пришлось сделать следующее:
В VideoCoDec.pas добавил следующие ф-ции для кодирования:
ICSeqCompressFrameStart()
ICSeqCompressFrame()
ICSeqCompressFrameEnd()
И + на сервере подправил инициализацию режима захвата.
Тонкости ICCompress() я так и не понял((, к сожалению в MSDN слишком скудное описание. Да MicroSoft и сам советует использовать ICSeq... т.к. они являются оберткой над ICCompress и сами выделяют буфер под предыдущий кадр. Т.е. ICSeqCompressFrameStart() + ICSeqCompressFrame() + ICSeqCompressFrameEnd() тоже самое, что и ICCompress().
Вот и все, декодирование я не правил. Теперь программа работает без глюков с любыми кодеками.
Тема, конечно, раскрыта не полностью, надо бы привести в порядок подправленный модуль и выложить... А еще лучше написать статейку...
Но я думаю кто захочет, тот разберется, ведь направление указано, а это главное!
Спасибо за внимание! ;-)
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2007.05.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.039 c