From d602f6b1d9bbe2e166a7eb1b45bacbccd4101418 Mon Sep 17 00:00:00 2001 From: "[CST] Focus" Date: Wed, 21 May 2014 14:45:53 +0400 Subject: [PATCH] gui/upnpbrowser.cpp: avoid crash, if TotalMatches is wrong; try to fix ogg mime type, add audio/x-wav for wav --- src/gui/upnpbrowser.cpp | 119 ++++++++++++++++++++++------------------ src/gui/upnpbrowser.h | 9 ++- 2 files changed, 71 insertions(+), 57 deletions(-) diff --git a/src/gui/upnpbrowser.cpp b/src/gui/upnpbrowser.cpp index 71e7e8ea9..6b0189494 100644 --- a/src/gui/upnpbrowser.cpp +++ b/src/gui/upnpbrowser.cpp @@ -291,7 +291,7 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) 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); } if (!strcmp(node->GetType(), "item")) @@ -299,6 +299,7 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) std::vector resources; int preferred = -1; std::string protocol, prot, network, mime, additional; + CFile::FileType ftype = CFile::FILE_UNKNOWN; isdir=false; for (snode=node->GetChild(); snode; snode=snode->GetNext()) { @@ -385,9 +386,11 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) { preferred=i; 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; pref=4; } @@ -395,22 +398,29 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) { preferred=i; pref=5; + ftype = CFile::FILE_FLAC; } - if (mime.substr(0,6) == "video/" && pref < 6) + if (mime == "audio/x-wav" && pref < 6) { preferred=i; pref=6; + ftype = CFile::FILE_WAV; } - if (mime == "video/x-flv" && pref < 7) + if (mime.substr(0,6) == "video/" && pref < 7) { preferred=i; pref=7; } - if (mime == "video/mp4" && pref < 8) + if (mime == "video/x-flv" && pref < 8) { preferred=i; pref=8; } + if (mime == "video/mp4" && pref < 9) + { + preferred=i; + pref=9; + } } } p = node->GetAttributeValue("id"); @@ -423,7 +433,7 @@ std::vector *CUpnpBrowserGui::decodeResult(std::string result) 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); } } @@ -586,13 +596,11 @@ void CUpnpBrowserGui::playnext(void) int preferred=(*entries)[0].preferred; if (preferred != -1) { - std::string protocol, prot, network, mime, additional; - protocol=(*entries)[0].resources[preferred].protocol; - splitProtocol(protocol, prot, network, mime, additional); - if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac") { + std::string &mime = (*entries)[0].mime; + if (mime.substr(0,6) == "audio/") { m_playing_entry = (*entries)[0]; 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/") { 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); } else if (!timeout && (msg == CRCInput::RC_ok || msg == CRCInput::RC_right)) { + if ((selected - liststart) >= (*entries).size()) + continue; if ((*entries)[selected - liststart].isdir) { endall=selectItem((*entries)[selected - liststart].id); if (endall) @@ -758,14 +768,12 @@ bool CUpnpBrowserGui::selectItem(std::string id) int preferred=(*entries)[selected - liststart].preferred; if (preferred != -1) { - std::string protocol, prot, network, mime, additional; - protocol=(*entries)[selected - liststart].resources[preferred].protocol; - splitProtocol(protocol, prot, network, mime, additional); - if (mime == "audio/mpeg" || mime == "audio/x-vorbis+ogg" || mime == "audio/x-flac") + std::string &mime = (*entries)[selected - liststart].mime; + if (mime.substr(0,6) == "audio/") { m_playing_entry = (*entries)[selected - liststart]; 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/") { @@ -807,6 +815,8 @@ bool CUpnpBrowserGui::selectItem(std::string id) } } else if (msg == CRCInput::RC_play) { + if ((selected - liststart) >= (*entries).size()) + continue; m_folderplay = true; m_playfolder = (*entries)[selected - liststart].id; m_playid = 0; @@ -982,7 +992,7 @@ void CUpnpBrowserGui::paintDevices() paintItem2DetailsLine (-1); // clear it } -void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, unsigned int selected) +void CUpnpBrowserGui::paintItem(std::vector *entries, unsigned int pos, unsigned int selected) { int ypos = m_y + m_title_height + m_theight + pos*m_fheight; fb_pixel_t color; @@ -992,12 +1002,6 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, { color = COL_MENUCONTENT_TEXT_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 { @@ -1006,13 +1010,25 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, } m_frameBuffer->paintBoxRel(m_x, ypos, m_width - 15, m_fheight, bgcolor); - if (pos >= entry->size()) + if (pos >= (*entries).size()) 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 fileicon; - if ((*entry)[pos].isdir) + if (entry->isdir) { info = ""; fileicon = NEUTRINO_ICON_FOLDER; @@ -1021,7 +1037,7 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, { if (preferred != -1) { - info = (*entry)[pos].resources[preferred].duration; + info = entry->resources[preferred].duration; fileicon = NEUTRINO_ICON_MP3; } else @@ -1031,7 +1047,7 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, } } - std::string name = (*entry)[pos].title; + std::string name = entry->title; char tmp_time[] = "00:00:00.0"; int w = g_Font[SNeutrinoSettings::FONT_TYPE_FILEBROWSER_ITEM]->getRenderWidth(tmp_time); @@ -1042,26 +1058,26 @@ void CUpnpBrowserGui::paintItem(std::vector *entry, unsigned int pos, name, color, m_fheight, true); // UTF-8 } -void CUpnpBrowserGui::paintItemInfo(std::vector *entry, unsigned int selected) +void CUpnpBrowserGui::paintItemInfo(UPnPEntry *entry) { std::string tmp; std::stringstream ts; int w, xstart; - int preferred=(*entry)[selected].preferred; + int preferred=entry->preferred; // LCD - CVFD::getInstance()->showMenuText(0, (*entry)[selected].title.c_str(), -1, true); + CVFD::getInstance()->showMenuText(0, entry->title.c_str(), -1, true); // 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 + 2, m_y + 2, m_width - 4, m_title_height - 14, COL_MENUCONTENTSELECTED_PLUS_0, RADIUS_MID); // first line - ts << "Resources: " << (*entry)[selected].resources.size() << " Selected: " << preferred+1 << " "; + ts << "Resources: " << entry->resources.size() << " Selected: " << preferred+1 << " "; tmp = ts.str(); if (preferred != -1) - tmp = tmp + "Duration: " + (*entry)[selected].resources[preferred].duration; + tmp = tmp + "Duration: " + entry->resources[preferred].duration; else tmp = tmp + "No resource for Item"; @@ -1072,17 +1088,13 @@ void CUpnpBrowserGui::paintItemInfo(std::vector *entry, unsigned int tmp, COL_MENUCONTENTSELECTED_TEXT, 0, true); // UTF-8 // second line - if ((*entry)[selected].isdir) + if (entry->isdir) tmp = "Directory"; else { tmp = ""; if (preferred != -1) - { - std::string proto, network, mime, info; - splitProtocol((*entry)[selected].resources[preferred].protocol, proto, network, mime, info); - tmp = "Protocol: " + proto + ", MIME-Type: " + mime; - } + tmp = "Protocol: " + entry->proto + ", MIME-Type: " + entry->mime; } w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 w = std::min(w, m_width - 20); @@ -1092,8 +1104,8 @@ void CUpnpBrowserGui::paintItemInfo(std::vector *entry, unsigned int //third line tmp = ""; - if (!(*entry)[selected].isdir && preferred != -1) - tmp = "URL: " + (*entry)[selected].resources[preferred].url; + if (!entry->isdir && preferred != -1) + tmp = "URL: " + entry->resources[preferred].url; w = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getRenderWidth(tmp, true); // UTF-8 w = std::min(w, m_width - 20); @@ -1101,10 +1113,10 @@ void CUpnpBrowserGui::paintItemInfo(std::vector *entry, unsigned int 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 static std::string lastname = "", tmpname = ""; - if(!(*entry)[selected].albumArtURI.empty()){ + if(!entry->albumArtURI.empty()){ static int flogo_w = 0, flogo_h = 0; - if(lastname != (*entry)[selected].albumArtURI){ - tmpname = lastname = (*entry)[selected].albumArtURI.c_str(); + if(lastname != entry->albumArtURI){ + tmpname = lastname = entry->albumArtURI.c_str(); tmpname = g_PicViewer->DownloadImage(tmpname ); flogo_w = 0, flogo_h = 0; 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); } -void CUpnpBrowserGui::paintDetails(std::vector *entry, unsigned int index, bool use_playing) +void CUpnpBrowserGui::paintDetails(UPnPEntry *entry, bool use_playing) { // Foot info int top = m_y + (m_height - m_info_height - 1 * m_buttonHeight) + 2; int text_start = m_x + 10; -printf("paintDetails: index %d use_playing %d shown %d\n", index, use_playing, m_playing_entry_is_shown); - if ((!use_playing) && ((*entry)[index].isdir)) +printf("paintDetails: use_playing %d shown %d\n", use_playing, m_playing_entry_is_shown); + if ((!use_playing) && entry->isdir) { m_frameBuffer->paintBackgroundBoxRel(m_x+2, top + 2, m_width-4, 2 * m_buttonHeight+8); 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_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, - top + 1 * m_buttonHeight + 4, m_x + m_width - 8, (*entry)[index].title + " - " + - (*entry)[index].artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 + top + 1 * m_buttonHeight + 4, m_x + m_width - 8, entry->title + " - " + + entry->artist, COL_MENUCONTENTDARK_TEXT, 0, true); // UTF-8 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) { - paintDetails(NULL, 0, true); + paintDetails(NULL, true); 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); 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, type); + CAudiofile mp3(name, (CFile::FileType) type); CAudioPlayer::getInstance()->play(&mp3, g_settings.audioplayer_highprio == 1); } diff --git a/src/gui/upnpbrowser.h b/src/gui/upnpbrowser.h index ae7dba0f4..1e7f78051 100644 --- a/src/gui/upnpbrowser.h +++ b/src/gui/upnpbrowser.h @@ -59,8 +59,11 @@ struct UPnPEntry std::string album; std::string albumArtURI; std::string children; + std::string proto; + std::string mime; std::vector resources; int preferred; + int type; }; class CUpnpBrowserGui : public CMenuTarget @@ -116,12 +119,12 @@ class CUpnpBrowserGui : public CMenuTarget bool selectItem(std::string); void paintItems(std::vector *entry, unsigned int selected, unsigned int max, unsigned int offset); void paintItem (std::vector *entry, unsigned int pos, unsigned int selected); - void paintItemInfo(std::vector *entry, unsigned int selected); - void paintDetails(std::vector *entry, unsigned int index, bool use_playing = false); + void paintItemInfo(UPnPEntry *entry); + void paintDetails(UPnPEntry *entry, bool use_playing = false); void paintItem2DetailsLine (int pos); 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 playVideo(std::string name, std::string url); };