From 63365de7f4420543b3b07f504d6ca9a949f962d4 Mon Sep 17 00:00:00 2001 From: Alan Smillie Date: Tue, 26 Jan 2016 17:55:27 +0000 Subject: [PATCH 1/3] Win32 - Fix playback on Windows 8 and Windows 10 This commit fixes playback on the Windows 8 and 10 platforms. The behaviour of these platforms differs from the development (Windows 7) platform in that if the ByteStream supplied to the SourceReader does not have the MFBYTESTREAM_IS_SEEKABLE capability the stream recognition will fail without even reading any data. On Windows 7 the stream recognition phase executed seeks regardless of the capability setting. Highlights ---------- 1. Enable the MFBYTESTREAM_IS_SEEKABLE capability in the OpenHomeByteStream. This allows stream recognition to succeed. It does not enable stream seeking from a control point. 2. When OpenHomeByteStream receives a seek request outside of the initial recognition cache, during recognition, it updates iStreamPos to the requested position and passes the seek. The subsequent read request will execute an out of band read of the requested size from the 'seeked' location storing it at the start of the existing recognition cache. The required data will then be returned from the updated cache. NB. The out of bound read requires the IWriter interface be implemented. 3. Standardise on TBOOL to avoid passing pointers to TBOOL and casting to BOOL. I suspect this was causing some subtle data corruption. 4. In Process() check for stream start/end exception after all calls to ReadSample() so that can be passed back to the CodecController in a timely manner. Also avoid calling FlushPCM() on stream exceptions as it was seen to cause crashes. --- Win32/IMFCodec.cpp | 34 ++--- Win32/OHPlayerByteStream.cpp | 245 +++++++++++++++++++++-------------- Win32/OHPlayerByteStream.h | 33 +++-- Win32/OptionalFeatures.h | 19 ++- 4 files changed, 199 insertions(+), 132 deletions(-) diff --git a/Win32/IMFCodec.cpp b/Win32/IMFCodec.cpp index 4aa27a1..fd7717a 100644 --- a/Win32/IMFCodec.cpp +++ b/Win32/IMFCodec.cpp @@ -31,7 +31,7 @@ #include #define DBUG_F(...) \ - Log::Print("[CodecIMF] [%llu] ", \ + Log::Print("[%llu] [CodecIMF] ", \ std::chrono::high_resolution_clock::now().time_since_epoch().count()); \ Log::Print(__VA_ARGS__) #else @@ -90,7 +90,6 @@ class CodecIMF : public CodecBase const TChar *iStreamFormat; TBool iStreamStart; TBool iStreamEnded; - TUint64 iByteTotal; OHPlayerByteStream *iByteStream; IMFSourceReader *iSourceReader; @@ -190,7 +189,6 @@ CodecIMF::CodecIMF(IMimeTypeList& aMimeTypeList) , iStreamFormat(NULL) , iStreamStart(false) , iStreamEnded(false) - , iByteTotal(0) , iByteStream(NULL) , iSourceReader(NULL) { @@ -292,7 +290,7 @@ TBool CodecIMF::VerifyStreamType(IMFSourceReader *aSourceReader) { HRESULT hr = S_OK; IMFMediaType *mediaType = NULL; - TBool retVal = FALSE; + TBool retVal = false; hr = aSourceReader->GetNativeMediaType( (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, @@ -481,12 +479,13 @@ TBool CodecIMF::ConfigureAudioStream(IMFSourceReader *aSourceReader) SafeRelease(&uncompressedAudioType); SafeRelease(&partialType); - return FALSE; + return false; } TBool CodecIMF::Recognise(const EncodedStreamInfo& aStreamInfo) { HRESULT hr; + TBool retVal = false; #ifdef _DEBUG DBUG_F("Recognise\n"); @@ -494,13 +493,13 @@ TBool CodecIMF::Recognise(const EncodedStreamInfo& aStreamInfo) if (aStreamInfo.RawPcm()) { - return false; + return retVal; } // Initialise the byte stream. iByteStream = new OHPlayerByteStream(iController, - (BOOL *)&iStreamStart, - (BOOL *)&iStreamEnded); + (TBool *)&iStreamStart, + (TBool *)&iStreamEnded); // Create the SourceReader #ifdef _DEBUG @@ -562,7 +561,7 @@ void CodecIMF::StreamInitialise() // Remove the recognition cache and start operating on the actual stream. if (iStreamFormat == kFmtMp3) { - // Move the stream postition to that reached in Recognise(). + // Move the stream position to that reached in Recognise(). iByteStream->DisableRecogCache(true); } else @@ -758,22 +757,17 @@ void CodecIMF::Process() NULL, &sampleBuf); - if (FAILED(hr)) - { - DBUG_F("ReadSample Failed\n"); - } - if (iStreamStart) { DBUG_F("SourceReader ReadSample CodecStreamStart\n"); - FlushPCM(); + THROW(CodecStreamStart); } if (iStreamEnded) { DBUG_F("SourceReader ReadSample CodecStreamEnded\n"); - FlushPCM(); + THROW(CodecStreamEnded); } @@ -793,6 +787,14 @@ void CodecIMF::Process() THROW(CodecStreamEnded); } + if (FAILED(hr)) + { + DBUG_F("ReadSample Failed\n"); + + DBUG_F("SourceReader ReadSample CatchAll\n"); + THROW(CodecStreamEnded); + } + if (sampleBuf == NULL) { DBUG_F("No sample read\n"); diff --git a/Win32/OHPlayerByteStream.cpp b/Win32/OHPlayerByteStream.cpp index a171704..3f8e831 100644 --- a/Win32/OHPlayerByteStream.cpp +++ b/Win32/OHPlayerByteStream.cpp @@ -111,14 +111,14 @@ STDMETHODIMP ReadRequest::QueryInterface(REFIID aIId, void **aInterface) } OHPlayerByteStream::OHPlayerByteStream(ICodecController *controller, - BOOL *streamStart, - BOOL *streamEnded) : + TBool *streamStart, + TBool *streamEnded) : iStreamLength(0), iStreamPos(0), - iInAsyncRead(FALSE), - iIsRecogPhase(TRUE), - iRecogSeekOutwithCache(FALSE), - iSeekExpected(FALSE), + iInAsyncRead(false), + iIsRecogPhase(true), + iRecogCachePos(0), + iSeekExpected(false), iController(controller), iStreamStart(streamStart), iStreamEnded(streamEnded) @@ -132,7 +132,20 @@ OHPlayerByteStream::OHPlayerByteStream(ICodecController *controller, // Use a cache during stream format recognition to minimise seeking about // the physical stream. - iController->Read(iRecogCache, iRecogCache.MaxBytes()); + iRecogCache.SetBytes(0); + try + { + iController->Read(iRecogCache, iRecogCache.MaxBytes()); + +#ifdef _DEBUG + DBUG_F("OHPlayerByteStream: Recognition Cache [%lu]\n", + iRecogCache.Bytes()); +#endif + } + catch (...) + { + DBUG_F("OHPlayerByteStream: Unexpected recognition cache error\n"); + } } OHPlayerByteStream::~OHPlayerByteStream() @@ -144,7 +157,7 @@ OHPlayerByteStream::~OHPlayerByteStream() _aligned_free(iRefCount); } -// Note the stream fomat recognition phase is complete. +// Note the stream format recognition phase is complete. // // This effects how Seek() requests are processed. void OHPlayerByteStream::RecognitionComplete() @@ -153,13 +166,13 @@ void OHPlayerByteStream::RecognitionComplete() DBUG_F("RecognitionComplete\n"); #endif - iIsRecogPhase = FALSE; + iIsRecogPhase = false; } // Release the recognition cache. // // Future operations will be performed on the physical stream. -void OHPlayerByteStream::DisableRecogCache(BOOL revertStreamPos) +void OHPlayerByteStream::DisableRecogCache(TBool revertStreamPos) { #ifdef _DEBUG DBUG_F("DisableRecogCache\n"); @@ -203,6 +216,11 @@ void OHPlayerByteStream::DisableRecogCache(BOOL revertStreamPos) break; } } + +#ifdef _DEBUG + DBUG_F("DisableRecogCache - Stream Advanced To [%llu]\n", + iController->StreamPos()); +#endif } else { @@ -211,6 +229,7 @@ void OHPlayerByteStream::DisableRecogCache(BOOL revertStreamPos) // Disable the recognition cache iRecogCache.SetBytes(0); + iRecogCachePos = -1; } // Not that a stream seek is expected and should not be ignored. @@ -220,7 +239,7 @@ void OHPlayerByteStream::ExpectExternalSeek() DBUG_F("ExpectExternalSeek\n"); #endif - iSeekExpected = TRUE; + iSeekExpected = true; } // IUnknown Methods. @@ -293,10 +312,10 @@ STDMETHODIMP OHPlayerByteStream::BeginRead(BYTE *aBuffer, IMFAsyncResult *result; ReadRequest *requestState; - iInAsyncRead = TRUE; + iInAsyncRead = true; // Execute a synchronous read - hr = Read(aBuffer, aLength, &bytesRead); + Read(aBuffer, aLength, &bytesRead); // Create the result object to pass to EndRead() requestState = new ReadRequest(bytesRead); @@ -308,16 +327,16 @@ STDMETHODIMP OHPlayerByteStream::BeginRead(BYTE *aBuffer, SafeRelease(&requestState); - // Set async operation status to the result of the read. - result->SetStatus(S_OK); - if (SUCCEEDED(hr)) { + // Set async operation status to the result of the read. + result->SetStatus(S_OK); + // Invoke the async callback to instigate the EndRead() call. hr = MFInvokeCallback(result); } - return S_OK; + return hr; } STDMETHODIMP OHPlayerByteStream::Read(BYTE *aBuffer, @@ -329,23 +348,50 @@ STDMETHODIMP OHPlayerByteStream::Read(BYTE *aBuffer, // If we have a cache and the current stream position resides // within it return data from the cache. - if (iStreamPos < (LONGLONG)iRecogCache.Bytes()) + if (iIsRecogPhase) { - ULONG available = (ULONG)(iRecogCache.Bytes() - iStreamPos); + if ((iStreamPos < iRecogCachePos) || + (iStreamPos >= iRecogCachePos + iRecogCache.Bytes())) + { + // To fulfill this request we need to reallocate the cache. + iRecogCache.SetBytes(0); + try + { + // Perform an out of band read on the stream. + iController->Read(*this, iStreamPos, aLength); + + iRecogCachePos = iStreamPos; + +#ifdef _DEBUG + DBUG_F("Read: iRecogCachePos [%lld] Size [%lu]\n", + iRecogCachePos, iRecogCache.Bytes()); +#endif + } + catch (...) + { + DBUG_F("Read: Unexpected error reallocating recognition " + "cache\n"); + } + } + + LONGLONG streamPos = iStreamPos; + + ULONG cacheByteOffset = (ULONG)(streamPos - iRecogCachePos); + ULONG available = (ULONG)(iRecogCache.Bytes() - cacheByteOffset); + +#ifdef _DEBUG + DBUG_F("Read: Cache Req [%lu] Avail [%lu]\n", aLength, available); +#endif if (aLength > available) { aLength = available; } - memcpy(aBuffer, (char *)(iRecogCache.Ptr() + iStreamPos), aLength); + memcpy(aBuffer, (char *)(iRecogCache.Ptr() + cacheByteOffset), aLength); *aBytesRead = aLength; iStreamPos += *aBytesRead; - -#ifdef _DEBUG - DBUG_F("Read: Cache [%lu]\n", *aBytesRead); -#endif } else { @@ -355,8 +401,18 @@ STDMETHODIMP OHPlayerByteStream::Read(BYTE *aBuffer, inputBuffer.SetBytes(0); - // Read the requested amount of data from the physical stream. - iController->Read(inputBuffer, inputBuffer.MaxBytes()); + if (*iStreamEnded || *iStreamStart) + { +#ifdef _DEBUG + DBUG_F("Read: Pre-existing exception [%d] [%d]\n", + *iStreamStart, *iStreamEnded); +#endif + } + else + { + // Read the requested amount of data from the physical stream. + iController->Read(inputBuffer, inputBuffer.MaxBytes()); + } *aBytesRead = (ULONG)inputBuffer.Bytes(); iStreamPos += *aBytesRead; @@ -364,31 +420,36 @@ STDMETHODIMP OHPlayerByteStream::Read(BYTE *aBuffer, catch(CodecStreamStart&) { #ifdef _DEBUG - DBUG_F("Read: CodecStreamStart Exception Caught\n"); + DBUG_F("Read: CodecStreamStart Exception Caught. Bytes[%lu]\n", + *aBytesRead); #endif // _DEBUG - *iStreamStart = TRUE; + *iStreamStart = true; return S_OK; } catch(CodecStreamEnded&) { #ifdef _DEBUG - DBUG_F("Read: CodecStreamEnded Exception Caught\n"); + DBUG_F("Read: CodecStreamEnded Exception Caught. Bytes[%lu]\n", + *aBytesRead); #endif // _DEBUG - *iStreamEnded = TRUE; + *iStreamEnded = true; return S_OK; } catch(CodecStreamStopped&) { #ifdef _DEBUG - DBUG_F("Read: CodecStreamStopped Exception Caught\n"); + DBUG_F("Read: CodecStreamStopped Exception Caught. Bytes[%lu]\n", + *aBytesRead); #endif // _DEBUG - *iStreamEnded = TRUE; + *iStreamEnded = true; return S_OK; } } +#ifdef _DEBUG DBUG_F("Read: Req[%lu] Got[%lu] Pos[%llu]\n", aLength, *aBytesRead, iStreamPos); +#endif return S_OK; } @@ -414,12 +475,17 @@ STDMETHODIMP OHPlayerByteStream::EndRead(IMFAsyncResult *aResult, SafeRelease(&requestState); - iInAsyncRead = FALSE; + iInAsyncRead = false; hr = aResult->GetStatus(); SafeRelease(&aResult); + if (FAILED(hr)) + { + DBUG_F("EndRead Returning Fail\n"); + } + return hr; } @@ -440,73 +506,30 @@ STDMETHODIMP OHPlayerByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin, switch (aSeekOrigin) { case msoBegin: - DBUG_F("Seek Origin: Offset [%llu]\n", aSeekOffset); + DBUG_F("Seek Origin: Offset [%lld]\n", aSeekOffset); break; case msoCurrent: - DBUG_F("Seek Curent: Offset [%llu]\n", aSeekOffset); + DBUG_F("Seek Current: Offset [%lld]\n", aSeekOffset); aSeekOffset += iStreamPos; break; } - if (aSeekOffset >= iRecogCache.Bytes()) + if (aSeekOffset < iRecogCachePos || + aSeekOffset >= iRecogCachePos + iRecogCache.Bytes()) { // A seek on the physical stream is required. - // - // Unfortunately the SourceReader has the propensity to, on occasion, - // execute seeks backwards from the current stream position then - // forwards again to the current position when decoding the stream. - // - // For ease of integration the seeks are ignored. - if (iIsRecogPhase || iRecogSeekOutwithCache || iSeekExpected) + if (iIsRecogPhase) { -#if 0 - infile.clear(); - - if (infile.seekg(aSeekOffset, way)) - { - // If the recognition cache is active note that we have - // seek'd outwith it. - // - // A physical seek will be required to prior to decoding to - // get back to the start of the stream. - // - // This will not be required in LitePipe as we are automatically - // returned to the start of the stream after recognition - // is complete. - if (iRecogCache.Bytes() > 0) - { - iRecogSeekOutwithCache = TRUE; - } - - *aCurrentPosition = aSeekOffset; - - DBUG_F("[%llu]:", *aCurrentPosition); - DBUG_F("Success [Physical]\n"); - - // We don't track physical seeks after recognition. - // - // Not required in LitePipe. - if (!iIsRecogPhase) - { - iRecogSeekOutwithCache = FALSE; - } - - // This seek was instigated via LitePipe and thus allowed. - // - // Reset things so seeks will be ignored, during decoding, - // until the next LitePipe instigated seek. - if (iSeekExpected) - { - iSeekExpected = FALSE; - } - } - else - { - DBUG_F("Failure\n"); - hr = E_FAIL; - } + // During the recognition phase we fake any attempted seeks out with + // the cache. The resulting 'read' will reallocate the cache with + // data being returned from the new cache. +#ifdef _DEBUG + DBUG_F("Seek: Recognition Phase Seek Faked [%lld]\n", aSeekOffset); #endif + + *aCurrentPosition = aSeekOffset; + iStreamPos = aSeekOffset; } else { @@ -518,7 +541,9 @@ STDMETHODIMP OHPlayerByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin, // correct position for the next read. *aCurrentPosition = aSeekOffset; - DBUG_F("Seek: Codec instigated seek skipped\n"); +#ifdef _DEBUG + DBUG_F("Seek: Codec instigated seek skipped [%lld]\n", aSeekOffset); +#endif } } else @@ -528,7 +553,9 @@ STDMETHODIMP OHPlayerByteStream::Seek(MFBYTESTREAM_SEEK_ORIGIN aSeekOrigin, // Update the position to the required offset. *aCurrentPosition = aSeekOffset; - DBUG_F("Seek Success [From Cache]\n"); +#ifdef _DEBUG + DBUG_F("Seek Success [From Cache] [%lld]\n", aSeekOffset); +#endif } iStreamPos = *aCurrentPosition; @@ -563,7 +590,11 @@ STDMETHODIMP OHPlayerByteStream::SetCurrentPosition(QWORD aPosition) STDMETHODIMP OHPlayerByteStream::GetCapabilities(DWORD *aCapabilities) { // Seeking disabled initially. - *aCapabilities = MFBYTESTREAM_IS_READABLE /*| MFBYTESTREAM_IS_SEEKABLE*/; + *aCapabilities = MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE; + +#ifdef _DEBUG + DBUG_F("GetCapabilities %d\n", *aCapabilities); +#endif return S_OK; } @@ -603,20 +634,20 @@ STDMETHODIMP OHPlayerByteStream::IsEndOfStream(BOOL *aIsEndOfStream) if (iStreamPos >= iStreamLength) { #ifdef _DEBUG - DBUG_F("IsEndOfStream [%llu] [%llu] [TRUE]\n", + DBUG_F("IsEndOfStream [%lld] [%lld] [TRUE]\n", iStreamPos, iStreamLength); #endif - *aIsEndOfStream = TRUE; + *aIsEndOfStream = true; } else { #ifdef _DEBUG - DBUG_F("IsEndOfStream [%llu] [%llu] [FALSE]\n", + DBUG_F("IsEndOfStream [%lld] [%lld] [false]\n", iStreamPos, iStreamLength); #endif - *aIsEndOfStream = FALSE; + *aIsEndOfStream = false; } return S_OK; @@ -681,4 +712,26 @@ STDMETHODIMP OHPlayerByteStream::Flush() return S_OK; } +// IWriter functions +void OHPlayerByteStream::Write(TByte aValue) +{ + if (! iRecogCache.TryAppend(aValue)) + { + DBUG_F("Write TByte: Failed to add to iRecogCache\n"); + } +} + +void OHPlayerByteStream::Write(const Brx& aBuffer) +{ + if (! iRecogCache.TryAppend(aBuffer)) + { + DBUG_F("Write Brx: Failed to add to iRecogCache\n"); + } +} + +void OHPlayerByteStream::WriteFlush() +{ + DBUG_F("WriteFlush\n"); +} + #endif USE_IMFCODEC diff --git a/Win32/OHPlayerByteStream.h b/Win32/OHPlayerByteStream.h index 733ab2a..294b14f 100644 --- a/Win32/OHPlayerByteStream.h +++ b/Win32/OHPlayerByteStream.h @@ -8,12 +8,13 @@ namespace OpenHome { namespace Media { namespace Codec { -class OHPlayerByteStream : public IMFByteStream +class OHPlayerByteStream : public IMFByteStream, public IWriter { +// From IMFByteStream public: OHPlayerByteStream(ICodecController *controller, - BOOL *streamStart, - BOOL *streamEnded); + TBool *streamStart, + TBool *streamEnded); ~OHPlayerByteStream(); // IUnknown Methods. @@ -64,10 +65,17 @@ class OHPlayerByteStream : public IMFByteStream STDMETHODIMP Flush(); - // Integration Extras +// From IWriter +public: + void Write(TByte aValue) override; + void Write(const Brx& aBuffer) override; + void WriteFlush() override; + +// Integration Extras +public: // Disable the stream format recognition cache. - void DisableRecogCache(BOOL revertStreamPos); + void DisableRecogCache(TBool revertStreamPos); void RecognitionComplete(); // Note the completion of format recognition. void ExpectExternalSeek(); // Act on the next seek request. @@ -80,17 +88,16 @@ class OHPlayerByteStream : public IMFByteStream ULONG *iRefCount; // Object reference count. LONGLONG iStreamLength; // Stream length LONGLONG iStreamPos; // Current stream position. - BOOL iInAsyncRead; // Currently in begin/end read + TBool iInAsyncRead; // Currently in begin/end read // sequence. - BOOL iIsRecogPhase; // Recognising stream format. - Bws iRecogCache; // Recognition cache. - BOOL iRecogSeekOutwithCache; // Seeked out with cache during - // recognition. - BOOL iSeekExpected; // Honour the next seek request. + TBool iIsRecogPhase; // Recognising stream format. + Bws iRecogCache; // Recognition cache + LONGLONG iRecogCachePos; // Stream position of recog cache. + TBool iSeekExpected; // Honour the next seek request. ICodecController *iController; // Codec Controller. - BOOL *iStreamStart; - BOOL *iStreamEnded; + TBool *iStreamStart; + TBool *iStreamEnded; }; } // namespace Codec diff --git a/Win32/OptionalFeatures.h b/Win32/OptionalFeatures.h index 6860614..50bd70c 100644 --- a/Win32/OptionalFeatures.h +++ b/Win32/OptionalFeatures.h @@ -1,3 +1,8 @@ +#define ENABLE_AAC +#define ENABLE_MP3 +#define ENABLE_TIDAL +#define ENABLE_QOBUZ +#define ENABLE_RADIO // Optional Features // Uncomment this line to enable MP3 support @@ -8,16 +13,16 @@ // Uncomment this line to enable the Radio source //#define ENABLE_RADIO -#define TUNEIN_PARTNER_ID TUNEIN_PARTNER_ID_STRING +#define TUNEIN_PARTNER_ID "ah2rjr68" // Uncomment this line to enable Tidal service support //#define ENABLE_TIDAL -// Replace TIDAL_TOKEN_STRING with a valid Tidal token -#define TIDAL_TOKEN TIDAL_TOKEN_STRING +// Replace "dvmPAFPZbSv19FUp" with a valid Tidal token +#define TIDAL_TOKEN "dvmPAFPZbSv19FUp" // Uncomment this line to enable Qobuz service support //#define ENABLE_QOBUZ -// Replace QOBUZ_APPID_STRING with a valid Qobuz Application ID -#define QOBUZ_APPID QOBUZ_APPID_STRING -// Replace QOBUZ_SECRET_STRING with a valid Qobuz secret -#define QOBUZ_SECRET QOBUZ_SECRET_STRING +// Replace "854233864" with a valid Qobuz Application ID +#define QOBUZ_APPID "854233864" +// Replace "68ee8040d64ec825c5393396ca1cea1e" with a valid Qobuz secret +#define QOBUZ_SECRET "68ee8040d64ec825c5393396ca1cea1e" From 4fc0c26d93ec3b4bd0917c81f22a68752ce3e73b Mon Sep 17 00:00:00 2001 From: Kyle Gordon Date: Wed, 27 Jan 2016 14:02:26 +0000 Subject: [PATCH 2/3] Linux: Use sudo for make install --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index e13438b..91aec2d 100644 --- a/README +++ b/README @@ -48,9 +48,9 @@ DEBUG=1 make ubuntu // debug build or DEBUG=1 make raspbian // debug build or -make ubuntu-install // build and install locally +sudo make ubuntu-install // build and install locally or -make raspbian-install // build and install locally +sudo make raspbian-install // build and install locally # generate a debian package for distribution ./GeneratePkg.pl --platform=raspbian --application=openhome-player --version=0.1.2.3 From dc48b4e646109ecda31aa7a5144913f87d627815 Mon Sep 17 00:00:00 2001 From: Kyle Gordon Date: Wed, 27 Jan 2016 14:03:34 +0000 Subject: [PATCH 3/3] Linux: Use gcc 4.8 in Makefile rather than changing global preferences --- README | 7 ------- linux/Makefile.ubuntu | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/README b/README index 91aec2d..edf8741 100644 --- a/README +++ b/README @@ -23,13 +23,6 @@ Linux (Ubuntu 12.x onward, Raspbian) sudo apt-get update sudo apt-get install gcc-4.8 g++-4.8 -# set up gcc alternates; we need gcc4.8 - -sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20 -sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50 -sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20 -sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50 - # install audio and UI dependencies sudo apt-get install gtk+-3-dev libnotify-dev notify-osd libasound2-dev diff --git a/linux/Makefile.ubuntu b/linux/Makefile.ubuntu index 385f885..e7196a6 100644 --- a/linux/Makefile.ubuntu +++ b/linux/Makefile.ubuntu @@ -22,11 +22,11 @@ GTK_LIBS := $(shell pkg-config --libs gtk+-3.0) # indicate to build that we have selected a valid target HWPLATFORM=$(shell uname -i) ifeq ($(HWPLATFORM),i686) - CC = g++ + CC = g++-4.8 TARG_ARCH = Linux-x86 else ifeq ($(HWPLATFORM),x86_64) - CC = g++ + CC = g++-4.8 TARG_ARCH = Linux-x64 else $(error please build on an x86/x64 Ubunutu machine)