Я действительно не знаю libvlc, но вот как вы можете удалить SDL на основе этого конкретного примера.
Удаление SDL
В этом примере есть несколько различных функций, которые вы должны передать в функция обратного вызова libvlc...
libvlc_video_set_callbacks(mp, lock, unlock, display, &ctx);
Теперь, чтобы полностью понять, что делает эта функция блокировки, вам нужно немного разобраться в многопоточности и в том, как изображение хранится в памяти.
По сути, чтобы убедиться, что ничто не обращается к области памяти, которую libvlc использует во время записи в нее, он «блокирует» нечто, известное как мьютекс. Если вы попытаетесь заблокировать мьютекс, который уже заблокирован чем-то другим, текущее выполнение будет ждать, пока он не будет разблокирован.
Если бы вы получили доступ к этим пикселям, пока он был наполовину написан, можете ли вы представить, насколько это было бы ужасно? Он может быть написан наполовину, и вы затем будете использовать его для сохранения в файл yuv. Это было бы весьма катастрофично.
Второе, что делает функция блокировки, — указывает область памяти, которую vlc может использовать для загрузки кадра изображения. В этом примере для этого используется SDL_Surface, но вы можете создать свою собственную если будете осторожны.
Итак, если вы используете только libvlc, вам нужно найти альтернативу этим вещам.
Я пойду в обратном порядке от списка выше. В примере они используют SDL_Surface, однако, если вы не можете его использовать, вам придется создать свою собственную структуру в памяти для хранения данных пикселей, если вы хотите их извлечь. Простой способ — создать массив символов правильного размера. Я буду использовать структуру ctx так, как это удобно: я знаю, что вы просили не использовать ее, но в данном случае она весьма полезна, поскольку нам нужно передать несколько фрагментов информации в функцию блокировки.
struct ctx
{
unsigned char *pixeldata;
};
Теперь где-то в вашей основной функции вам нужно будет создать область в памяти. Если вы знаете размер видео и количество используемых битов на пиксель (bpp): это довольно просто. Но будьте очень осторожны, если вы не сделаете это правильно: вы можете получить повреждение памяти.
ctx.pixeldata = new unsigned char[width * height * bpp];
Обязательно удалите это правильно в конце программы...
delete[] ctx.pixeldata;
Следующее — это мьютекс. Это не обязательно, однако вы можете столкнуться с проблемами, как я упоминал выше. Если вы хотите использовать мьютекс, вам нужно будет указать функцию разблокировки в libvlc_video_set_callbacks (вы можете указать NULL для разблокировки, если вы не хотите использовать мьютекс).
Проблема в том, какой мьютекс вы будете использовать для этой цели (если вы хотите его использовать, что я и предлагаю вам сделать)? Если вы используете более новый стандарт C++11, вы можете использовать std::mutex. Если это не так, вам придется найти что-то еще, например библиотеку многопоточности. или написать что-то подобное самостоятельно. Если вы используете С++ 11, вы должны добавить это в структуру ctx...
#include <mutex>
struct ctx
{
unsigned char *pixeldata;
std::mutex imagemutex;
};
Теперь о самой функции блокировки.
static void *lock(void *data, void **p_pixels)
{
struct ctx *ctx = data;
ctx->imagemutex.lock()
*p_pixels = ctx->pixeldata;
return NULL;
}
Ваша функция разблокировки будет примерно такой...
static void unlock(void *data, void *id, void *const *p_pixels)
{
struct ctx *ctx = data;
ctx->unlock();
assert(id == NULL);
}
И всякий раз, когда вы хотите безопасно получить доступ к этим пиксельным данным...
ctx->imagemutex.lock();
/* Access Data Here */
ctx->imagemutex.unlock();
Использование SDL
Я хотел добавить кое-что вкратце о SDL. Хотя его можно использовать для отображения видео на экране, вам это не нужно. Лично, если вы не настолько опытны, я бы посоветовал вам продолжать использовать SDL и удалить код отображения далее в примере. В этом примере он обрабатывает память за вас, поэтому это немного проще, чем писать собственный безопасный код, если вы не знаете, как это сделать.
person
AdmiralJonB
schedule
13.05.2013
libvlc_video_set_callbacks
можно использовать для того, что показано в этом руководстве, но я думаю, что для моей цели мне не нужен SDL. - person user2273364   schedule 13.05.2013SDL_LockMutex(ctx.mutex); SDL_BlitSurface(ctx.surf, NULL, screen, &rect); SDL_UnlockMutex(ctx.mutex);
- person olevegard   schedule 13.05.2013