gui/upnpbrowser.cpp: avoid crash, if TotalMatches is wrong;

try to fix ogg mime type, add audio/x-wav for wav
This commit is contained in:
[CST] Focus
2014-05-21 14:45:53 +04:00
parent 9d916ba8d7
commit d602f6b1d9
2 changed files with 71 additions and 57 deletions

View File

@@ -291,7 +291,7 @@ std::vector<UPnPEntry> *CUpnpBrowserGui::decodeResult(std::string result)
p = ""; p = "";
children=std::string(p); children=std::string(p);
UPnPEntry entry={id, isdir, title, artist, album, albumArtURI, children, resources, -1}; UPnPEntry entry={id, isdir, title, artist, album, albumArtURI, children, "", "", resources, -1, CFile::FILE_DIR};
entries->push_back(entry); entries->push_back(entry);
} }
if (!strcmp(node->GetType(), "item")) if (!strcmp(node->GetType(), "item"))
@@ -299,6 +299,7 @@ std::vector<UPnPEntry> *CUpnpBrowserGui::decodeResult(std::string result)
std::vector<UPnPResource> resources; std::vector<UPnPResource> resources;
int preferred = -1; int preferred = -1;
std::string protocol, prot, network, mime, additional; std::string protocol, prot, network, mime, additional;
CFile::FileType ftype = CFile::FILE_UNKNOWN;
isdir=false; isdir=false;
for (snode=node->GetChild(); snode; snode=snode->GetNext()) for (snode=node->GetChild(); snode; snode=snode->GetNext())
{ {
@@ -385,9 +386,11 @@ std::vector<UPnPEntry> *CUpnpBrowserGui::decodeResult(std::string result)
{ {
preferred=i; preferred=i;
pref=3; pref=3;
ftype = CFile::FILE_MP3;
} }
if (mime == "audio/x-vorbis+ogg" && pref < 4) if ((mime == "audio/ogg" || mime == "audio/x-ogg") && pref < 4)
{ {
ftype = CFile::FILE_OGG;
preferred=i; preferred=i;
pref=4; pref=4;
} }
@@ -395,22 +398,29 @@ std::vector<UPnPEntry> *CUpnpBrowserGui::decodeResult(std::string result)
{ {
preferred=i; preferred=i;
pref=5; pref=5;
ftype = CFile::FILE_FLAC;
} }
if (mime.substr(0,6) == "video/" && pref < 6) if (mime == "audio/x-wav" && pref < 6)
{ {
preferred=i; preferred=i;
pref=6; pref=6;
ftype = CFile::FILE_WAV;
} }
if (mime == "video/x-flv" && pref < 7) if (mime.substr(0,6) == "video/" && pref < 7)
{ {
preferred=i; preferred=i;
pref=7; pref=7;
} }
if (mime == "video/mp4" && pref < 8) if (mime == "video/x-flv" && pref < 8)
{ {
preferred=i; preferred=i;
pref=8; pref=8;
} }
if (mime == "video/mp4" && pref < 9)
{
preferred=i;
pref=9;
}
} }
} }
p = node->GetAttributeValue("id"); p = node->GetAttributeValue("id");
@@ -423,7 +433,7 @@ std::vector<UPnPEntry> *CUpnpBrowserGui::decodeResult(std::string result)
p = ""; p = "";
children=std::string(p); children=std::string(p);
UPnPEntry entry={id, isdir, title, artist, album, albumArtURI, children, resources, preferred}; UPnPEntry entry={id, isdir, title, artist, album, albumArtURI, children, prot, mime, resources, preferred, ftype};
entries->push_back(entry); entries->push_back(entry);
} }
} }
@@ -586,13 +596,11 @@ void CUpnpBrowserGui::playnext(void)
int preferred=(*entries)[0].preferred; int preferred=(*entries)[0].preferred;
if (preferred != -1) if (preferred != -1)
{ {
std::string protocol, prot, network, mime, additional; std::string &mime = (*entries)[0].mime;
protocol=(*entries)[0].resources[preferred].protocol; if (mime.substr(0,6) == "audio/") {
splitProtocol(protocol, prot, network, mime, additional);
if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac") {
m_playing_entry = (*entries)[0]; m_playing_entry = (*entries)[0];
m_playing_entry_is_shown = false; m_playing_entry_is_shown = false;
playAudio((*entries)[0].resources[preferred].url, mime); playAudio((*entries)[0].resources[preferred].url, (*entries)[0].type);
} }
else if (mime.substr(0,6) == "video/") { else if (mime.substr(0,6) == "video/") {
playVideo((*entries)[0].title, (*entries)[0].resources[preferred].url); playVideo((*entries)[0].title, (*entries)[0].resources[preferred].url);
@@ -748,6 +756,8 @@ bool CUpnpBrowserGui::selectItem(std::string id)
updateItemSelection(id, entries, new_selected, selected, liststart); updateItemSelection(id, entries, new_selected, selected, liststart);
} }
else if (!timeout && (msg == CRCInput::RC_ok || msg == CRCInput::RC_right)) { else if (!timeout && (msg == CRCInput::RC_ok || msg == CRCInput::RC_right)) {
if ((selected - liststart) >= (*entries).size())
continue;
if ((*entries)[selected - liststart].isdir) { if ((*entries)[selected - liststart].isdir) {
endall=selectItem((*entries)[selected - liststart].id); endall=selectItem((*entries)[selected - liststart].id);
if (endall) if (endall)
@@ -758,14 +768,12 @@ bool CUpnpBrowserGui::selectItem(std::string id)
int preferred=(*entries)[selected - liststart].preferred; int preferred=(*entries)[selected - liststart].preferred;
if (preferred != -1) if (preferred != -1)
{ {
std::string protocol, prot, network, mime, additional; std::string &mime = (*entries)[selected - liststart].mime;
protocol=(*entries)[selected - liststart].resources[preferred].protocol; if (mime.substr(0,6) == "audio/")
splitProtocol(protocol, prot, network, mime, additional);
if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac")
{ {
m_playing_entry = (*entries)[selected - liststart]; m_playing_entry = (*entries)[selected - liststart];
m_playing_entry_is_shown = false; m_playing_entry_is_shown = false;
playAudio((*entries)[selected - liststart].resources[preferred].url, mime); playAudio((*entries)[selected - liststart].resources[preferred].url, (*entries)[selected - liststart].type);
} }
else if (mime.substr(0,6) == "video/") else if (mime.substr(0,6) == "video/")
{ {
@@ -807,6 +815,8 @@ bool CUpnpBrowserGui::selectItem(std::string id)
} }
} }
else if (msg == CRCInput::RC_play) { else if (msg == CRCInput::RC_play) {
if ((selected - liststart) >= (*entries).size())
continue;
m_folderplay = true; m_folderplay = true;
m_playfolder = (*entries)[selected - liststart].id; m_playfolder = (*entries)[selected - liststart].id;
m_playid = 0; m_playid = 0;
@@ -982,7 +992,7 @@ void CUpnpBrowserGui::paintDevices()
paintItem2DetailsLine (-1); // clear it paintItem2DetailsLine (-1); // clear it
} }
void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos, unsigned int selected) void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entries, unsigned int pos, unsigned int selected)
{ {
int ypos = m_y + m_title_height + m_theight + pos*m_fheight; int ypos = m_y + m_title_height + m_theight + pos*m_fheight;
fb_pixel_t color; fb_pixel_t color;
@@ -992,12 +1002,6 @@ void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos,
{ {
color = COL_MENUCONTENT_TEXT_PLUS_2; color = COL_MENUCONTENT_TEXT_PLUS_2;
bgcolor = COL_MENUCONTENT_PLUS_2; bgcolor = COL_MENUCONTENT_PLUS_2;
paintItemInfo(entry, selected);
paintDetails(entry, pos);
if ((*entry)[pos].isdir)
paintItem2DetailsLine (-1); // clear it
else
paintItem2DetailsLine (pos);
} }
else else
{ {
@@ -1006,13 +1010,25 @@ void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos,
} }
m_frameBuffer->paintBoxRel(m_x, ypos, m_width - 15, m_fheight, bgcolor); m_frameBuffer->paintBoxRel(m_x, ypos, m_width - 15, m_fheight, bgcolor);
if (pos >= entry->size()) if (pos >= (*entries).size())
return; return;
int preferred=(*entry)[pos].preferred; UPnPEntry *entry = &(*entries)[pos];
if (pos == selected)
{
paintItemInfo(entry);
paintDetails(entry);
if (entry->isdir)
paintItem2DetailsLine (-1); // clear it
else
paintItem2DetailsLine (pos);
}
int preferred=entry->preferred;
std::string info; std::string info;
std::string fileicon; std::string fileicon;
if ((*entry)[pos].isdir) if (entry->isdir)
{ {
info = "<DIR>"; info = "<DIR>";
fileicon = NEUTRINO_ICON_FOLDER; fileicon = NEUTRINO_ICON_FOLDER;
@@ -1021,7 +1037,7 @@ void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos,
{ {
if (preferred != -1) if (preferred != -1)
{ {
info = (*entry)[pos].resources[preferred].duration; info = entry->resources[preferred].duration;
fileicon = NEUTRINO_ICON_MP3; fileicon = NEUTRINO_ICON_MP3;
} }
else else
@@ -1031,7 +1047,7 @@ void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos,
} }
} }
std::string name = (*entry)[pos].title; std::string name = entry->title;
char tmp_time[] = "00:00:00.0"; char tmp_time[] = "00:00:00.0";
int w = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getRenderWidth(tmp_time); int w = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getRenderWidth(tmp_time);
@@ -1042,26 +1058,26 @@ void CUpnpBrowserGui::paintItem(std::vector<UPnPEntry> *entry, unsigned int pos,
name, color, m_fheight, true); // UTF-8 name, color, m_fheight, true); // UTF-8
} }
void CUpnpBrowserGui::paintItemInfo(std::vector<UPnPEntry> *entry, unsigned int selected) void CUpnpBrowserGui::paintItemInfo(UPnPEntry *entry)
{ {
std::string tmp; std::string tmp;
std::stringstream ts; std::stringstream ts;
int w, xstart; int w, xstart;
int preferred=(*entry)[selected].preferred; int preferred=entry->preferred;
// LCD // LCD
CVFD::getInstance()->showMenuText(0, (*entry)[selected].title.c_str(), -1, true); CVFD::getInstance()->showMenuText(0, entry->title.c_str(), -1, true);
// Info // Info
m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6, RADIUS_MID); m_frameBuffer->paintBoxRel(m_x, m_y, m_width, m_title_height - 10, COL_MENUCONTENT_PLUS_6, RADIUS_MID);
m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, RADIUS_MID); m_frameBuffer->paintBoxRel(m_x + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, RADIUS_MID);
// first line // first line
ts << "Resources: " << (*entry)[selected].resources.size() << " Selected: " << preferred+1 << " "; ts << "Resources: " << entry->resources.size() << " Selected: " << preferred+1 << " ";
tmp = ts.str(); tmp = ts.str();
if (preferred != -1) if (preferred != -1)
tmp = tmp + "Duration: " + (*entry)[selected].resources[preferred].duration; tmp = tmp + "Duration: " + entry->resources[preferred].duration;
else else
tmp = tmp + "No resource for Item"; tmp = tmp + "No resource for Item";
@@ -1072,17 +1088,13 @@ void CUpnpBrowserGui::paintItemInfo(std::vector<UPnPEntry> *entry, unsigned int
tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8
// second line // second line
if ((*entry)[selected].isdir) if (entry->isdir)
tmp = "Directory"; tmp = "Directory";
else else
{ {
tmp = ""; tmp = "";
if (preferred != -1) if (preferred != -1)
{ tmp = "Protocol: " + entry->proto + ", MIME-Type: " + entry->mime;
std::string proto, network, mime, info;
splitProtocol((*entry)[selected].resources[preferred].protocol, proto, network, mime, info);
tmp = "Protocol: " + proto + ", MIME-Type: " + mime;
}
} }
w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8
w = std::min(w, m_width - 20); w = std::min(w, m_width - 20);
@@ -1092,8 +1104,8 @@ void CUpnpBrowserGui::paintItemInfo(std::vector<UPnPEntry> *entry, unsigned int
//third line //third line
tmp = ""; tmp = "";
if (!(*entry)[selected].isdir && preferred != -1) if (!entry->isdir && preferred != -1)
tmp = "URL: " + (*entry)[selected].resources[preferred].url; tmp = "URL: " + entry->resources[preferred].url;
w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8
w = std::min(w, m_width - 20); w = std::min(w, m_width - 20);
@@ -1101,10 +1113,10 @@ void CUpnpBrowserGui::paintItemInfo(std::vector<UPnPEntry> *entry, unsigned int
g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 3*m_mheight, m_width - 20, g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(m_x + xstart, m_y + 4 + 3*m_mheight, m_width - 20,
tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8
static std::string lastname = "", tmpname = ""; static std::string lastname = "", tmpname = "";
if(!(*entry)[selected].albumArtURI.empty()){ if(!entry->albumArtURI.empty()){
static int flogo_w = 0, flogo_h = 0; static int flogo_w = 0, flogo_h = 0;
if(lastname != (*entry)[selected].albumArtURI){ if(lastname != entry->albumArtURI){
tmpname = lastname = (*entry)[selected].albumArtURI.c_str(); tmpname = lastname = entry->albumArtURI.c_str();
tmpname = g_PicViewer->DownloadImage(tmpname ); tmpname = g_PicViewer->DownloadImage(tmpname );
flogo_w = 0, flogo_h = 0; flogo_w = 0, flogo_h = 0;
g_PicViewer->getSize(tmpname.c_str(), &flogo_w, &flogo_h); g_PicViewer->getSize(tmpname.c_str(), &flogo_w, &flogo_h);
@@ -1155,13 +1167,13 @@ printf("CUpnpBrowserGui::paintItem:s selected %d max %d offset %d\n", selected,
::paintButtons(m_x, top, 0, 4, BrowseButtons, m_width, m_buttonHeight); ::paintButtons(m_x, top, 0, 4, BrowseButtons, m_width, m_buttonHeight);
} }
void CUpnpBrowserGui::paintDetails(std::vector<UPnPEntry> *entry, unsigned int index, bool use_playing) void CUpnpBrowserGui::paintDetails(UPnPEntry *entry, bool use_playing)
{ {
// Foot info // Foot info
int top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2; int top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2;
int text_start = m_x + 10; int text_start = m_x + 10;
printf("paintDetails: index %d use_playing %d shown %d\n", index, use_playing, m_playing_entry_is_shown); printf("paintDetails: use_playing %d shown %d\n", use_playing, m_playing_entry_is_shown);
if ((!use_playing) && ((*entry)[index].isdir)) if ((!use_playing) && entry->isdir)
{ {
m_frameBuffer->paintBackgroundBoxRel(m_x+2, top + 2, m_width-4, 2 * m_buttonHeight+8); m_frameBuffer->paintBackgroundBoxRel(m_x+2, top + 2, m_width-4, 2 * m_buttonHeight+8);
m_playing_entry_is_shown = false; m_playing_entry_is_shown = false;
@@ -1189,10 +1201,10 @@ printf("paintDetails: index %d use_playing %d shown %d\n", index, use_playing, m
m_playing_entry_is_shown = false; m_playing_entry_is_shown = false;
m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE); m_frameBuffer->paintBoxRel(m_x, top + 2, m_width-2, 2 * ih, COL_MENUCONTENTDARK_PLUS_0, RADIUS_LARGE);
g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start,
top + 1 * m_buttonHeight + 4, m_x + m_width - 8, (*entry)[index].title + " - " + top + 1 * m_buttonHeight + 4, m_x + m_width - 8, entry->title + " - " +
(*entry)[index].artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 entry->artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8
g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start, g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->RenderString(text_start,
top + 2 * m_buttonHeight + 4, m_x + m_width - 8, (*entry)[index].album, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 top + 2 * m_buttonHeight + 4, m_x + m_width - 8, entry->album, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8
} }
} }
} }
@@ -1240,7 +1252,7 @@ printf("updateTimes: force %d updatePlayed %d\n", force, updatePlayed);
if (updatePlayed) if (updatePlayed)
{ {
paintDetails(NULL, 0, true); paintDetails(NULL, true);
top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + m_buttonHeight + 4; top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + m_buttonHeight + 4;
m_frameBuffer->paintBoxRel(m_x + m_width - w - 15, top + 1, w + 4, m_buttonHeight, COL_MENUCONTENTDARK_PLUS_0); m_frameBuffer->paintBoxRel(m_x + m_width - w - 15, top + 1, w + 4, m_buttonHeight, COL_MENUCONTENTDARK_PLUS_0);
g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString(m_x + m_width - w - 11, top + 1 + m_buttonHeight, w, play_time, COL_MENUCONTENTDARK_TEXT); g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString(m_x + m_width - w - 11, top + 1 + m_buttonHeight, w, play_time, COL_MENUCONTENTDARK_TEXT);
@@ -1248,10 +1260,9 @@ printf("updateTimes: force %d updatePlayed %d\n", force, updatePlayed);
} }
} }
void CUpnpBrowserGui::playAudio(std::string name, std::string mime) void CUpnpBrowserGui::playAudio(std::string name, int type)
{ {
CFile::FileType type = mime == "audio/mpeg" ? CFile::FILE_MP3 : mime == "audio/x-vorbis+ogg" ? CFile::FILE_OGG : CFile::FILE_FLAC; CAudiofile mp3(name, (CFile::FileType) type);
CAudiofile mp3(name, type);
CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1);
} }

View File

@@ -59,8 +59,11 @@ struct UPnPEntry
std::string album; std::string album;
std::string albumArtURI; std::string albumArtURI;
std::string children; std::string children;
std::string proto;
std::string mime;
std::vector<UPnPResource> resources; std::vector<UPnPResource> resources;
int preferred; int preferred;
int type;
}; };
class CUpnpBrowserGui : public CMenuTarget class CUpnpBrowserGui : public CMenuTarget
@@ -116,12 +119,12 @@ class CUpnpBrowserGui : public CMenuTarget
bool selectItem(std::string); bool selectItem(std::string);
void paintItems(std::vector<UPnPEntry> *entry, unsigned int selected, unsigned int max, unsigned int offset); void paintItems(std::vector<UPnPEntry> *entry, unsigned int selected, unsigned int max, unsigned int offset);
void paintItem (std::vector<UPnPEntry> *entry, unsigned int pos, unsigned int selected); void paintItem (std::vector<UPnPEntry> *entry, unsigned int pos, unsigned int selected);
void paintItemInfo(std::vector<UPnPEntry> *entry, unsigned int selected); void paintItemInfo(UPnPEntry *entry);
void paintDetails(std::vector<UPnPEntry> *entry, unsigned int index, bool use_playing = false); void paintDetails(UPnPEntry *entry, bool use_playing = false);
void paintItem2DetailsLine (int pos); void paintItem2DetailsLine (int pos);
void updateTimes(const bool force = false); void updateTimes(const bool force = false);
void playAudio(std::string name, std::string mime); void playAudio(std::string name, int type);
void showPicture(std::string name); void showPicture(std::string name);
void playVideo(std::string name, std::string url); void playVideo(std::string name, std::string url);
}; };