Я вообще ничинающий, поэтому прошу ногами не пинать .
Проблема такая: в памяти, в разных буферах, есть куча мелких по размеру мультимедийных данных (wav, mp3, midi, видео разных форматов), задача состоит в том, чтобы проиграть их, используя DirectShow, без предварительного сохранения в виде файлов на диск.
Искал поиском -- не нашёл простого способа. Нашёл пару аналогичных вопросов, либо висящих без ответов, либо ответы меня не устраивают.
Самые близкие темы: http://www.rsdn.ru/Forum/?mid=1163386
-- к сожалению, здесь в итоге предлагается строить решение на основе примера [DXSDK]\samples\Multimedia\DirectShow\Filters\Async\Memfile.
Насколько я понимаю, асинхронность для меня не принципиальна, а в данном примере она занимает центральную часть, и оттого всё выглядит слишком сложно... Неужели нельзя сделать проигрывание (рендеринг) данных из памяти более простым способом?
Казалось бы, не должно быть особой разницы, где лежат данные: в пямяти, или в файле. Казалось бы, наоборот, базовый механизм должен быть расчитан на работу с памятью, а подгружение данных из файла в эту память -- вообще левая (по отношению к DirectShow) работа.
) SAnatoly говорит, что использовал класс фильтра наследник CSource, выходной пин наследник CSourceStream. Но, к сожалению, здесь не приводится нужный код... Я не понимаю простой вещи: как передать буфер с данными, не заморачиваясь с разрезанием данных на самплы и пр. Всё, что нужно, это максимально просто (по реализации) скормить данные source-фильтру, и затем попросить граф-билдер зарендерить это дело. С передачей типов медиа-данных, думаю, разберусь сам (они заранее известны).
Пожалуйста, отзовитесь, кто знает и имел опыт. Спасибо.
Здравствуйте, _random, Вы писали:
_>Я вообще ничинающий, поэтому прошу ногами не пинать .
Рекомендую начать с начала, почитайте что такое DS фильтры, и с чем их едят
Начать можно с http://directshow.wonderu.com. На rsdn есть неплохие статьи, ищи поиском.
Идея такая тебе надо написать свой фильтр источник. Примеры которые ты просил выслать не могу, там много чего добавлено, кроме самого чтения из памяти. Кроме того в примерах от DS SDK есть два фильтра, синхронный и асинхронный, они будут понятнее и проще для вас. Начать рекомендую всетаки с теории. Без понимания принципа работы алокаторов и пинов смысла терзать исходники не много.
Re[2]: DirectShow: как проиграть данные из памяти?
Здравствуйте, SAnatoly, Вы писали:
SA> Рекомендую начать с начала, почитайте что такое DS фильтры, и с чем их едят
Это я уже проделал.
SA> Начать можно с http://directshow.wonderu.com. На rsdn есть неплохие статьи, ищи поиском.
Был, читал...
SA> Идея такая тебе надо написать свой фильтр источник.
Я запостил свой вопрос как раз после того, как начал его писать, этот фильтр-источник.
SA> Примеры которые ты просил выслать не могу, там много чего добавлено, кроме самого чтения из памяти.
Понятно, очень жаль...
SA> Кроме того в примерах от DS SDK есть два фильтра, синхронный и асинхронный, они будут понятнее и проще для вас.
Это которые тут: [DS SDK]\Samples\C++\DirectShow\Filters\?
Их тут вроде больше двух, т.к. вроде стало ясно, что использовать надо сладкую парочку: CSource & CSourceStream, то в данный момент я поглядываю на [DS SDK]\Samples\C++\DirectShow\Filters\Ball. К сожалению, там не совсем то, что надо, но я пытаюсь домысливать...
SA> Начать рекомендую всетаки с теории. Без понимания принципа работы алокаторов и пинов смысла терзать исходники не много.
С теории я уже второй день как начал... Но теории много, и захотелось немножко параллельно перейти к практике. Принципом работы алокаторов и пинов я и занимаюсь в данный момент.
Спасибо за содержательный ответ.
Re[3]: DirectShow: как проиграть данные из памяти?
SA>> Кроме того в примерах от DS SDK есть два фильтра, синхронный и асинхронный, они будут понятнее и проще для вас. _>Это которые тут: [DS SDK]\Samples\C++\DirectShow\Filters\? _>Их тут вроде больше двух, т.к. вроде стало ясно, что использовать надо сладкую парочку: CSource & CSourceStream, то в данный момент я поглядываю на [DS SDK]\Samples\C++\DirectShow\Filters\Ball. К сожалению, там не совсем то, что надо, но я пытаюсь домысливать...
Относительно Ball да его можно использовать. Но если у вас действительно отрывки файлов, то начать лучше с ASYNC. При этом для отладки можно использовать такой вариант. Допустим спроецировать файл в память, а потом его уже раздавать из памяти. Должно получиться тоже самое что и проигрывание стандартными средствами. Кроме того начать рекомендую с одного формата. Лучше AVI. при этом будьте осторожны с MediaType. Неправельное деклаирование типа выходного пина будет приводить к проблемам.
SA>> Начать рекомендую всетаки с теории. Без понимания принципа работы алокаторов и пинов смысла терзать исходники не много. _>С теории я уже второй день как начал... Но теории много, и захотелось немножко параллельно перейти к практике. Принципом работы алокаторов и пинов я и занимаюсь в данный момент.
Если и начинать с практики, то с компиляции уже имеющегося в примерах фильтра. За одно и выясните что такое BaseClasses и компилятор настроите. А потом уже его подгонять под свои нужды.
Re[4]: DirectShow: как проиграть данные из памяти?
Здравствуйте, SAnatoly, Вы писали:
SA> Относительно Ball да его можно использовать. Но если у вас действительно отрывки файлов, то начать лучше с ASYNC.
Я уже говорил в предыдущих постах, что там как-то уж слишком сложно (я имею в виду CAsyncIo и всех его вспомогательных друзей) для решения, казалось бы, простой задачи... Конечно, я допускаю, что это единственный возможный путь. Но с другой стороны, пока не понятно, зачем мне вся эта чехарда с асинхронностью?
У меня не "отрывки файлов" (кстати, не очень ясно, что имеется в виду), у меня в памяти большой объект, полученный по сети, с кучкой буферов, в каждом буфере лежит полный медиа-фрагмент, который был файлом на другой машине.
SA> При этом для отладки можно использовать такой вариант. Допустим спроецировать файл в память, а потом его уже раздавать из памяти. Должно получиться тоже самое что и проигрывание стандартными средствами.
Этим и занимается пример Async, насколько я понимаю. Но в моей задаче исходного файла как раз и нету, и создавать его в каком-нибудь TEMP-е -- очень криво, плюс в моём конкретном случае -- очень не желательно...
SA> Кроме того начать рекомендую с одного формата. Лучше AVI. при этом будьте осторожны с MediaType. Неправельное деклаирование типа выходного пина будет приводить к проблемам.
Ага, про это как раз и был тот твой пост, о котором я упоминал. Кстати, как там, получилось?
А начать я решил с mp3.
SA> Если и начинать с практики, то с компиляции уже имеющегося в примерах фильтра. За одно и выясните что такое BaseClasses и компилятор настроите. А потом уже его подгонять под свои нужды.
Я собрал и Async, и Ball, тут проблем нет. У меня проблема в том, что в моём примере, основанном на Ball, я просто не знаю, как реализовать FillBuffer( IMediaSample *pms ). Концептуально я понимаю, что мне надо по кусочкам отдавать данные из моего исходного буфера, вот и читаю доку по пинам...
И дочитался до того, что, дескать, для решения поставленной задачи мне нельзя наследоваться от CSource и CSourceStream, поскольку CSourceStream не поддерживает pull-модель (для поддержки которой требуется поддержка IAsyncReader). Про IAsyncReader сказано, что он разрабатывается для фильтров-источников, которые соединяются с фильтрами разбора -- а это как раз мой случай. Так ли это?
Короче, у меня уже определились конкретный вопрос: могу ли я использовать наследников CSource и CSourceStream для решения моей задачи? Правильно ли я понимаю, что использование CSourceStream автоматически приведёт к тому, что у меня будет использоваться push-модель в source-фильтре? Можно ли использовать push-модель в source-фильтре, чтобы потом не было проблем с авто-рендерингом разных медиа-типов?
SAnatoly, получилось ли у Вас тогда рендерить mp3-шки из памяти в том коде на основе этих двух классов?
Re[5]: DirectShow: как проиграть данные из памяти?
_>Короче, у меня уже определились конкретный вопрос: могу ли я использовать наследников CSource и CSourceStream для решения моей задачи? Правильно ли я понимаю, что использование CSourceStream автоматически приведёт к тому, что у меня будет использоваться push-модель в source-фильтре? Можно ли использовать push-модель в source-фильтре, чтобы потом не было проблем с авто-рендерингом разных медиа-типов?
Кажется, CSource и CSourceStream для решения моей задачи не подходят. В пине — наследнике CSourceStream — данные уже должны быть распарсены, разбиты на сэмплы (или мне самому придётся парсить). SAnatoly, похоже, решал другую задачу: у него под словами "куски mp3" подразумевались готовые, полученные откуда-то сэмплы. Таким образом, в природе не существует метода для решения моей задачи, более простого, чем на основе ASYNC-экзампла из DS.
Re[5]: DirectShow: как проиграть данные из памяти?
От:
Аноним
Дата:
28.03.07 01:12
Оценка:
Здравствуйте, _random, Вы писали:
_>Этим и занимается пример Async, насколько я понимаю. Но в моей задаче исходного файла как раз и нету, и создавать его в каком-нибудь TEMP-е -- очень криво, плюс в моём конкретном случае -- очень не желательно...
Насколько я помню, пример Async первым делом читает весь файл в буффер в памяти. Для нормальнного File Source это никуда не годиться, а для вас — то, что доктор прописал: выбросьте из кода всё связанное с файлами, дайте свой буффер и его размер и получите требемый результат.
Re[6]: DirectShow: как проиграть данные из памяти?
Здравствуйте, Аноним, Вы писали:
А>Насколько я помню, пример Async первым делом читает весь файл в буффер в памяти. Для нормальнного File Source это никуда не годиться, а для вас — то, что доктор прописал: выбросьте из кода всё связанное с файлами, дайте свой буффер и его размер и получите требемый результат.
Это я уже давно проделал, даже работает под win32 . Но самое обидное в том, что 1) этот пример не работает под WinCE (например на Windows Mobile 5 PPC) -- а мне как раз надо под WinCE; 2) мне не понравилось, отчего так сложно делается предельно простая вещь... так уж она, эта DS спроектирована, ничего не поделать.
Re[7]: DirectShow: как проиграть данные из памяти?
От:
Аноним
Дата:
07.04.07 00:21
Оценка:
Здравствуйте, _random, Вы писали:
_>Здравствуйте, Аноним, Вы писали:
А>>Насколько я помню, пример Async первым делом читает весь файл в буффер в памяти. Для нормальнного File Source это никуда не годиться, а для вас — то, что доктор прописал: выбросьте из кода всё связанное с файлами, дайте свой буффер и его размер и получите требемый результат.
_>1) этот пример не работает под WinCE (например на Windows Mobile 5 PPC) -- а мне как раз надо под WinCE;
Думаю, что это можно вылечить, если под WinCE есть DirectShow (ничего про СЕ не знаю).
_>2) мне не понравилось, отчего так сложно делается предельно простая вещь... так уж она, эта DS спроектирована, ничего не поделать.
Так это же DirectShow — тут ничего просто не делается, а BaseClasses — вопиющий пример того, как не следует писать библиотеки на С++, хотя и работает.
Re[8]: DirectShow: как проиграть данные из памяти?
От:
Аноним
Дата:
07.04.07 00:55
Оценка:
Да, кстати, AVI файлы играться с этим фильтром не будут — граф не построится.
Re[8]: DirectShow: как проиграть данные из памяти?
А>Думаю, что это можно вылечить, если под WinCE есть DirectShow (ничего про СЕ не знаю).
вылечить можно всё, но вопрос в том, сколько это займёт времени и сил
Re[9]: DirectShow: как проиграть данные из памяти?
А>Да, кстати, AVI файлы играться с этим фильтром не будут — граф не построится.
Я модифицировал этот фильтр так, чтобы он играл AVI -- и сделать это было не очень сложно
Re[9]: DirectShow: как проиграть данные из памяти?
От:
Аноним
Дата:
07.04.07 14:04
Оценка:
Здравствуйте, _random, Вы писали:
А>>Думаю, что это можно вылечить, если под WinCE есть DirectShow (ничего про СЕ не знаю). _>вылечить можно всё, но вопрос в том, сколько это займёт времени и сил
Не думаю, что в данном случае нужно много сил. Возможно, нужно просто изменить код регистрации фильтра.
к примеру, макрос, который генерит VC 2005 для ATL проектов:
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error"Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."#endif
наводит на мысль о том, что WinCE имеет какие-то ограничения по части threading model. Может ему, например, Threading Model фильтра не нравиться и надо его просто иначе зарегистрировать (типа Free вместо Both)? ИМХО, что-нибудь в таком духе.