Browse Source

Add video source list and fix a lot of bugs

master
Krisjanis Rijnieks 11 years ago
parent
commit
4ae87c6259
  1. 9
      src/MediaServer/DirectoryWatcher.h
  2. 52
      src/MediaServer/MediaServer.cpp
  3. 7
      src/MediaServer/MediaServer.h
  4. 4
      src/Sources/BaseSource.cpp
  5. 1
      src/Sources/BaseSource.h
  6. 8
      src/Sources/ImageSource.cpp
  7. 14
      src/Sources/VideoSource.cpp
  8. 141
      src/SourcesEditor.cpp
  9. 12
      src/SourcesEditor.h
  10. 24
      src/ui/RadioList.cpp
  11. 1
      src/ui/RadioList.h

9
src/MediaServer/DirectoryWatcher.h

@ -28,9 +28,18 @@ class VideoPathFilter : public BasePathFilter {
virtual ~VideoPathFilter() {};
bool accept(const Poco::Path& path) const {
#ifdef TARGET_RASPBERRY_PI
return !Poco::File(path).isHidden() &&
(ofIsStringInString(path.toString(), ".mp4") ||
ofIsStringInString(path.toString(), ".h264"));
#else
return !Poco::File(path).isHidden() &&
(ofIsStringInString(path.toString(), ".mp4") ||
ofIsStringInString(path.toString(), ".h264")||
ofIsStringInString(path.toString(), ".mov") ||
ofIsStringInString(path.toString(), ".avi") ||
ofIsStringInString(path.toString(), ".mpeg"));
#endif
}
};

52
src/MediaServer/MediaServer.cpp

@ -28,9 +28,6 @@ namespace piMapper {
std::vector<std::string>& MediaServer::getImagePaths() {
return imageWatcher.getFilePaths();
}
std::vector<std::string>& MediaServer::getVideoPaths() {
return videoWatcher.getFilePaths();
}
std::vector<std::string> MediaServer::getImageNames() {
std::vector<std::string> imageNames;
@ -44,6 +41,25 @@ namespace piMapper {
return imageNames;
}
std::vector<std::string>& MediaServer::getVideoPaths() {
return videoWatcher.getFilePaths();
}
std::vector<std::string> MediaServer::getVideoNames() {
cout << "nuVideos: " << getNumVideos() << endl;
std::vector<std::string> videoNames;
for (int i = 0; i < getNumVideos(); i++) {
// Split video path
std::vector<std::string> pathParts = ofSplitString(getVideoPaths()[i], "/");
// And get only the last piece
std::string name = pathParts[pathParts.size()-1];
videoNames.push_back(name);
}
return videoNames;
}
BaseSource* MediaServer::loadMedia(string &path, int mediaType) {
// Chose load method depending on type
if (mediaType == SourceType::SOURCE_TYPE_IMAGE) {
@ -97,13 +113,11 @@ namespace piMapper {
}
void MediaServer::unloadImage(string& path) {
ImageSource* source = static_cast<ImageSource*>(getSourceByPath(path));
// Decrease reference count of the image
//referenceCount[path]--;
ofLogNotice("MediaServer") << "Unload image, current reference count: " << source->referenceCount;
source->referenceCount--;
// Unload only if reference count is less or equal to 0
cout << "referenceCount: " << source->referenceCount << endl;
ofLogNotice("MediaServer") << "New reference count: " << source->referenceCount;
if (source->referenceCount > 0) {
ofLogNotice("MediaServer") << "Not unloading image as it is being referenced elsewhere";
return;
@ -114,9 +128,12 @@ namespace piMapper {
ofLogNotice("MediaServer") << ss.str();
// Destroy image source
if (loadedSources.count(path)) {
//loadedSources[path]->clear();
delete loadedSources[path];
loadedSources.erase(path);
ofLogNotice("MediaServer") << "Source count BEFORE image removal: " << loadedSources.size() << endl;
loadedSources[path]->clear();
std::map<std::string, BaseSource*>::iterator it = loadedSources.find(path);
delete it->second;
loadedSources.erase(it);
ofLogNotice("MediaServer") << "Source count AFTER image removal: " << loadedSources.size() << endl;
ofNotifyEvent(onImageUnloaded, path, this);
return;
}
@ -139,7 +156,6 @@ namespace piMapper {
// If is loaded
if (isVideoLoaded) {
// Increase reference count of this source
//referenceCount[path]++;
videoSource->referenceCount++;
std::stringstream refss;
refss << "Current reference count for " << path << " = " << videoSource->referenceCount;
@ -175,14 +191,15 @@ namespace piMapper {
return;
}
// Reference count 0 or less, let's unload the video
std::stringstream ss;
ss << "Removing video " << path;
ofLogNotice("MediaServer") << ss.str();
ofLogNotice("MediaServer") << "Removing video " << path;
// Distroy video source
if (loadedSources.count(path)) {
loadedSources[path]->clear();
delete loadedSources[path];
loadedSources.erase(path);
ofLogNotice("MediaServer") << "Source count before video removal: " << loadedSources.size() << endl;
videoSource->clear();
std::map<std::string, BaseSource*>::iterator it = loadedSources.find(path);
delete it->second;
loadedSources.erase(it);
ofLogNotice("MediaServer") << "Source count after video removal: " << loadedSources.size() << endl;
ofNotifyEvent(onVideoUnloaded, path, this);
return;
}
@ -223,7 +240,6 @@ namespace piMapper {
}
BaseSource* MediaServer::getSourceByPath(std::string& mediaPath) {
cout << "num loaded sources: " << loadedSources.size() << endl;
if (loadedSources.count(mediaPath)) {
return loadedSources[mediaPath];
}

7
src/MediaServer/MediaServer.h

@ -28,9 +28,10 @@ class MediaServer {
int getNumVideos();
int getNumImages();
std::vector<string>& getVideoPaths();
std::vector<string>& getImagePaths();
std::vector<string> getImageNames();
std::vector<std::string>& getVideoPaths();
std::vector<std::string> getVideoNames();
std::vector<std::string>& getImagePaths();
std::vector<std::string> getImageNames();
BaseSource* loadMedia(string& path, int mediaType);
BaseSource* loadImage(string& path);

4
src/Sources/BaseSource.cpp

@ -12,6 +12,10 @@ namespace ofx {
texture = newTexture;
}
BaseSource::~BaseSource() {
cout << "BaseSource destr" << endl;
}
ofTexture* BaseSource::getTexture() {
return texture;
}

1
src/Sources/BaseSource.h

@ -10,6 +10,7 @@ namespace ofx {
public:
BaseSource();
BaseSource(ofTexture* newTexture); // Only one clean way of passing the texture
~BaseSource();
ofTexture* getTexture();
std::string& getName();
bool isLoadable(); // Maybe the loading features shoud go to a derrived class

8
src/Sources/ImageSource.cpp

@ -9,9 +9,7 @@ namespace ofx {
type = SourceType::SOURCE_TYPE_IMAGE;
}
ImageSource::~ImageSource() {
clear();
}
ImageSource::~ImageSource() {}
void ImageSource::loadImage(std::string& filePath) {
path = filePath;
@ -32,8 +30,8 @@ namespace ofx {
image->clear();
delete image;
image = NULL;
path = "";
name = "";
//path = "";
//name = "";
loaded = false;
}

14
src/Sources/VideoSource.cpp

@ -3,14 +3,14 @@
namespace ofx {
namespace piMapper {
VideoSource::VideoSource() {
cout << "VideoSource constr" << endl;
loadable = true;
loaded = false;
type = SourceType::SOURCE_TYPE_VIDEO;
videoPlayer = NULL;
}
VideoSource::~VideoSource() {
clear();
}
VideoSource::~VideoSource() {}
void VideoSource::loadVideo(std::string& filePath) {
path = filePath;
@ -47,8 +47,8 @@ namespace ofx {
delete videoPlayer;
videoPlayer = NULL;
#endif
path = "";
name = "";
//path = "";
//name = "";
loaded = false;
}
@ -59,7 +59,9 @@ namespace ofx {
// probably needs updating as well
//
#else
videoPlayer->update();
if (videoPlayer != NULL) {
videoPlayer->update();
}
#endif
}
}

141
src/SourcesEditor.cpp

@ -4,42 +4,15 @@ namespace ofx {
namespace piMapper {
SourcesEditor::SourcesEditor() {
init();
// Create new MediaServer instance,
// we will need to clear this in the deconstr
mediaServer = new MediaServer();
isMediaServerExternal = false;
cout << "numImages: " << mediaServer->getNumImages() << endl;
/*
cout << "list: " << endl;
for (int i = 0; i < mediaServer->getNumImages(); i++) {
cout << mediaServer->getImagePaths()[i] << endl;
}
*/
cout << "numVideos: " << mediaServer->getNumVideos() << endl;
/*
cout << "list: " << endl;
for (int i = 0; i < mediaServer->getNumVideos(); i++) {
cout << mediaServer->getImagePaths()[i] << endl;
}
*/
addMediaServerListeners();
// Test media server onImageLoaded event
/*
if (mediaServer->getNumImages()) {
mediaServer->loadImage(mediaServer->getImagePaths()[0]);
}
*/
}
SourcesEditor::SourcesEditor(MediaServer* externalMediaServer) {
init();
// Assign external MediaServer instance pointer
mediaServer = externalMediaServer;
isMediaServerExternal = true;
@ -48,12 +21,8 @@ namespace piMapper {
SourcesEditor::~SourcesEditor() {
unregisterAppEvents();
delete gui;
while (images.size()) {
delete images.back();
images.pop_back();
}
delete imageSelector;
delete videoSelector;
removeMediaServerListeners();
clearMediaServer();
}
@ -67,40 +36,48 @@ namespace piMapper {
}
void SourcesEditor::setup(ofEventArgs& args) {
gui = new RadioList();
imageSelector = new RadioList();
videoSelector = new RadioList();
// Get image names from media server
vector<string> vnames = mediaServer->getImageNames();
gui->setup("Images", vnames, mediaServer->getImagePaths());
gui->setPosition(20, 20);
// Add radio selected event listener so we can load sources
ofAddListener(gui->onRadioSelected, this, &SourcesEditor::handleRadioSelected);
vector<string> imageNames = mediaServer->getImageNames();
imageSelector->setup("Images", imageNames, mediaServer->getImagePaths());
imageSelector->setPosition(20, 20);
ofAddListener(imageSelector->onRadioSelected, this, &SourcesEditor::handleImageSelected);
vector<string> videoNames = mediaServer->getVideoNames();
cout << "list video names: " << endl;
for (int i = 0; i < videoNames.size(); i++) {
cout << videoNames[i] << endl;
}
videoSelector->setup("Videos", videoNames, mediaServer->getVideoPaths());
videoSelector->setPosition(250, 20);
ofAddListener(videoSelector->onRadioSelected, this, &SourcesEditor::handleVideoSelected);
}
void SourcesEditor::draw() {
// Don't draw if there is no source selected
if (surfaceManager->getSelectedSurface() == NULL) {
ofLogNotice("SourcesEditor") << "No surface selected";
return;
}
gui->draw();
imageSelector->draw();
videoSelector->draw();
}
void SourcesEditor::loadImage(string name, string path) {
images.push_back(new ofImage());
images.back()->loadImage(path);
imageNames.push_back(name);
ofSendMessage("imageLoaded");
void SourcesEditor::disable() {
imageSelector->disable();
videoSelector->disable();
}
void SourcesEditor::disable() { gui->disable(); }
void SourcesEditor::enable() {
// Don't enable if there is no surface selected
if (surfaceManager->getSelectedSurface() == NULL) {
cout << "No surface selected. Not enable()ing source list." << endl;
ofLogNotice("SourcesEditor") << "No surface selected. Not enabling and not showing source list.";
return;
}
gui->enable();
imageSelector->enable();
videoSelector->enable();
BaseSource* source = surfaceManager->getSelectedSurface()->getSource();
selectSourceRadioButton(source->getPath());
}
void SourcesEditor::setSurfaceManager(SurfaceManager* newSurfaceManager) {
@ -122,35 +99,27 @@ namespace piMapper {
isMediaServerExternal = true;
}
void SourcesEditor::selectImageSourceRadioButton(string name) {
if (name == "none") {
gui->unselectAll();
void SourcesEditor::selectSourceRadioButton(std::string& sourcePath) {
if (sourcePath == "") {
ofLogNotice("SourcesEditor") << "Path is empty";
imageSelector->unselectAll();
videoSelector->unselectAll();
return;
} else {
int i;
for (i = 0; i < gui->size(); i++) {
if (gui->getItemName(i) == name) {
gui->selectItem(i);
return;
}
// Check image selector first
bool imageRadioSelected = imageSelector->selectItemByValue(sourcePath);
bool videoRadioSelected = videoSelector->selectItemByValue(sourcePath);
if (imageRadioSelected || videoRadioSelected) {
return;
}
// Log warning if we are still here
ofLogWarning("SourcesEditor") << "Could not find option in any of the source lists";
}
}
int SourcesEditor::getLoadedTexCount() { return images.size(); }
ofTexture* SourcesEditor::getTexture(int index) {
if (index >= images.size()) {
throw std::runtime_error("Texture index out of bounds.");
}
return &images[index]->getTextureReference();
}
void SourcesEditor::init() {
mediaServer = NULL; // Pointers to NULL pointer so we can check later
isMediaServerExternal = false;
defImgDir = DEFAULT_IMAGES_DIR;
registerAppEvents();
}
@ -160,7 +129,6 @@ namespace piMapper {
ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set");
return;
}
// Add listeners to custom events of the media server
ofAddListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded);
ofAddListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved);
@ -177,7 +145,6 @@ namespace piMapper {
ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set");
return;
}
// Remove listeners to custom events of the media server
ofRemoveListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded);
ofRemoveListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved);
@ -187,16 +154,38 @@ namespace piMapper {
ofRemoveListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded);
}
void SourcesEditor::handleRadioSelected(string& sourcePath) {
void SourcesEditor::handleImageSelected(string& imagePath) {
// Unselect video item if any selected
videoSelector->unselectAll();
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
ofLogNotice("SourcesEditor") << "No surface selected";
return;
}
// Unload old media
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
}
// Load new image
surface->setSource(mediaServer->loadImage(imagePath));
}
void SourcesEditor::handleVideoSelected(string& videoPath) {
// Unselect image item if any selected
imageSelector->unselectAll();
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
ofLogNotice("SourcesEditor") << "No surface selected";
return;
}
// Unload old media
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
}
surface->setSource(mediaServer->loadImage(sourcePath));
// Load new video
surface->setSource(mediaServer->loadVideo(videoPath));
}
void SourcesEditor::clearMediaServer() {
@ -232,8 +221,8 @@ namespace piMapper {
// Test image unload
// mediaServer->unloadImage(path);
BaseSource* source = mediaServer->getSourceByPath(path);
surfaceManager->getSelectedSurface()->setSource(source);
//BaseSource* source = mediaServer->getSourceByPath(path);
//surfaceManager->getSelectedSurface()->setSource(source);
}
void SourcesEditor::handleImageUnloaded(string& path) {

12
src/SourcesEditor.h

@ -30,7 +30,8 @@ class SourcesEditor {
// Sets external MediaServer
void setMediaServer(MediaServer* newMediaServer);
void selectImageSourceRadioButton(string name);
//void selectImageSourceRadioButton(string name);
void selectSourceRadioButton(std::string& sourcePath);
int getLoadedTexCount();
ofTexture* getTexture(int index);
@ -38,10 +39,8 @@ class SourcesEditor {
private:
MediaServer* mediaServer;
SurfaceManager* surfaceManager;
RadioList* gui;
string defImgDir;
vector<ofImage*> images;
vector<string> imageNames;
RadioList* imageSelector;
RadioList* videoSelector;
// Is the media server pointer local or from somewhere else?
// We use this to determine if we are allowed to clear media server locally.
@ -55,7 +54,8 @@ class SourcesEditor {
void removeMediaServerListeners();
// Handles GUI event, whenever someone has clicked on a radio button
void handleRadioSelected(string& sourcePath);
void handleImageSelected(string& imagePath);
void handleVideoSelected(string& videoPath);
// Careful clearing of the media server,
// clears only if the media server has been initialized locally

24
src/ui/RadioList.cpp

@ -72,6 +72,30 @@ void RadioList::selectItem(int index) {
ofNotifyEvent(onRadioSelected, value, this);
storedSelectedItem = index;
}
bool RadioList::selectItemByValue(std::string itemValue) {
if (itemValue == "") {
ofLogNotice("RadioList") << "Item value empty";
return false;
}
unselectAll();
int itemIndex = -1;
for (int i = 0; i < storedValues.size(); i++) {
if (itemValue == storedValues[i]) {
itemIndex = i;
break;
}
}
if (itemIndex >= 0) {
ofxToggle* toggle = static_cast<ofxToggle*>(guiGroup.getControl(itemIndex));
toggle->removeListener(this, &RadioList::onToggleClicked);
*toggle = true; // Select the specific radio button
toggle->addListener(this, &RadioList::onToggleClicked);
return true;
}
ofLogNotice("RadioList") << "Item with value " << itemValue << " not found";
return false;
}
void RadioList::enable() {
if (guiGroup.getNumControls() >= 0) {

1
src/ui/RadioList.h

@ -21,6 +21,7 @@ class RadioList {
void setPosition(ofPoint p);
void setPosition(float x, float y);
void selectItem(int index);
bool selectItemByValue(std::string itemValue);
void enable();
void disable();
void clear();

Loading…
Cancel
Save