Bug 1376967 - Fix defects in GeckoHlsRendererBase found from Coverity Scan. draft
authorKilik Kuo <kikuo@mozilla.com>
Fri, 30 Jun 2017 14:38:21 -0700
changeset 602891 03a3a4364944bbb80638b84cf4f59587f0272455
parent 602051 f3483af8ecf997453064201c49c48a682c7f3c29
child 635761 075decb65544ac26eca8c0f74d16639d6ba669e8
push id66600
push userbmo:kikuo@mozilla.com
push dateFri, 30 Jun 2017 21:42:30 +0000
bugs1376967
milestone56.0a1
Bug 1376967 - Fix defects in GeckoHlsRendererBase found from Coverity Scan. MozReview-Commit-ID: Gu7iySeCa8h
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsRendererBase.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsVideoRenderer.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsRendererBase.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsRendererBase.java
@@ -45,16 +45,20 @@ public abstract class GeckoHlsRendererBa
     protected abstract void handleReconfiguration(DecoderInputBuffer bufferForRead);
     protected abstract void handleFormatRead(DecoderInputBuffer bufferForRead);
     protected abstract void handleEndOfStream(DecoderInputBuffer bufferForRead);
     protected abstract void handleSamplePreparation(DecoderInputBuffer bufferForRead);
     protected abstract void resetRenderer();
     protected abstract boolean clearInputSamplesQueue();
     protected abstract void notifyPlayerInputFormatChanged(Format newFormat);
 
+    private DecoderInputBuffer mBufferForRead =
+        new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
+    private final DecoderInputBuffer mflagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
+
     protected void assertTrue(boolean condition) {
         if (DEBUG && !condition) {
             throw new AssertionError("Expected condition to be true");
         }
     }
 
     public GeckoHlsRendererBase(int trackType, GeckoHlsPlayer.ComponentEventDispatcher eventDispatcher) {
         super(trackType);
@@ -82,35 +86,38 @@ public abstract class GeckoHlsRendererBa
 
     public Format getFormat(int index) {
         assertTrue(index >= 0);
         Format fmt = index < mFormats.size() ? mFormats.get(index) : null;
         if (DEBUG) { Log.d(LOGTAG, "getFormat : index = " + index + ", format : " + fmt); }
         return fmt;
     }
 
-    public long getFirstSamplePTS() { return mFirstSampleStartTime; }
+    public synchronized long getFirstSamplePTS() { return mFirstSampleStartTime; }
 
     public synchronized ConcurrentLinkedQueue<GeckoHLSSample> getQueuedSamples(int number) {
         ConcurrentLinkedQueue<GeckoHLSSample> samples =
             new ConcurrentLinkedQueue<GeckoHLSSample>();
 
+        GeckoHLSSample sample = null;
         int queuedSize = mDemuxedInputSamples.size();
         for (int i = 0; i < queuedSize; i++) {
             if (i >= number) {
                 break;
             }
-            GeckoHLSSample sample = mDemuxedInputSamples.poll();
+            sample = mDemuxedInputSamples.poll();
             samples.offer(sample);
         }
-        if (samples.isEmpty()) {
+
+        sample = samples.isEmpty() ? null : samples.peek();
+        if (sample == null) {
             if (DEBUG) { Log.d(LOGTAG, "getQueuedSamples isEmpty, mWaitingForData = true !"); }
             mWaitingForData = true;
         } else if (mFirstSampleStartTime == Long.MIN_VALUE) {
-            mFirstSampleStartTime = samples.peek().info.presentationTimeUs;
+            mFirstSampleStartTime = sample.info.presentationTimeUs;
             if (DEBUG) { Log.d(LOGTAG, "mFirstSampleStartTime = " + mFirstSampleStartTime); }
         }
         return samples;
     }
 
     protected void handleDrmInitChanged(Format oldFormat, Format newFormat) {
         Object oldDrmInit = oldFormat == null ? null : oldFormat.drmInitData;
         Object newDrnInit = newFormat.drmInitData;
@@ -184,68 +191,67 @@ public abstract class GeckoHlsRendererBa
      */
     protected synchronized boolean feedInputBuffersQueue() {
         if (!mInitialized || mInputStreamEnded || isQueuedEnoughData()) {
             // Need to reinitialize the renderer or the input stream has ended
             // or we just reached the maximum queue size.
             return false;
         }
 
-        DecoderInputBuffer bufferForRead =
-            new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
-        bufferForRead.data = mInputBuffer;
-        if (bufferForRead.data != null) {
-            bufferForRead.clear();
+        mBufferForRead.data = mInputBuffer;
+        if (mBufferForRead.data != null) {
+            mBufferForRead.clear();
         }
 
-        handleReconfiguration(bufferForRead);
+        handleReconfiguration(mBufferForRead);
 
         // Read data from HlsMediaSource
         int result = C.RESULT_NOTHING_READ;
         try {
-            result = readSource(mFormatHolder, bufferForRead, false);
+            result = readSource(mFormatHolder, mBufferForRead, false);
         } catch (Exception e) {
             Log.e(LOGTAG, "[feedInput] Exception when readSource :", e);
             return false;
         }
 
         if (result == C.RESULT_NOTHING_READ) {
             return false;
         }
 
         if (result == C.RESULT_FORMAT_READ) {
-            handleFormatRead(bufferForRead);
+            handleFormatRead(mBufferForRead);
             return true;
         }
 
         // We've read a buffer.
-        if (bufferForRead.isEndOfStream()) {
+        if (mBufferForRead.isEndOfStream()) {
             if (DEBUG) { Log.d(LOGTAG, "Now we're at the End Of Stream."); }
-            handleEndOfStream(bufferForRead);
+            handleEndOfStream(mBufferForRead);
             return false;
         }
 
-        bufferForRead.flip();
+        mBufferForRead.flip();
 
-        handleSamplePreparation(bufferForRead);
+        handleSamplePreparation(mBufferForRead);
 
         maybeNotifyDataArrived();
         return true;
     }
 
     private void maybeNotifyDataArrived() {
         if (mWaitingForData && isQueuedEnoughData()) {
             if (DEBUG) { Log.d(LOGTAG, "onDataArrived"); }
             mPlayerEventDispatcher.onDataArrived(getTrackType());
             mWaitingForData = false;
         }
     }
 
     private void readFormat() {
-        int result = readSource(mFormatHolder, null, true);
+        mflagsOnlyBuffer.clear();
+        int result = readSource(mFormatHolder, mflagsOnlyBuffer, true);
         if (result == C.RESULT_FORMAT_READ) {
             onInputFormatChanged(mFormatHolder.format);
         }
     }
 
     @Override
     protected void onEnabled(boolean joining) {
         // Do nothing.
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsVideoRenderer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsVideoRenderer.java
@@ -162,16 +162,20 @@ public class GeckoHlsVideoRenderer exten
 
     @Override
     protected void handleReconfiguration(DecoderInputBuffer bufferForRead) {
         // For adaptive reconfiguration OMX decoders expect all reconfiguration
         // data to be supplied at the start of the buffer that also contains
         // the first frame in the new format.
         assertTrue(mFormats.size() > 0);
         if (mRendererReconfigurationState == RECONFIGURATION_STATE.WRITE_PENDING) {
+            if (bufferForRead.data == null) {
+                if (DEBUG) { Log.d(LOGTAG, "[feedInput][WRITE_PENDING] bufferForRead.data is not initialized."); }
+                return;
+            }
             if (DEBUG) { Log.d(LOGTAG, "[feedInput][WRITE_PENDING] put initialization data"); }
             Format currentFormat = mFormats.get(mFormats.size() - 1);
             for (int i = 0; i < currentFormat.initializationData.size(); i++) {
                 byte[] data = currentFormat.initializationData.get(i);
                 bufferForRead.data.put(data);
             }
             mRendererReconfigurationState = RECONFIGURATION_STATE.QUEUE_PENDING;
         }