OSDN Git Service

Fix deadlock when showing subtitles MediaPlayer
authorRobert Shih <robertshih@google.com>
Thu, 26 May 2016 21:02:51 +0000 (14:02 -0700)
committerRobert Shih <robertshih@google.com>
Fri, 27 May 2016 22:16:47 +0000 (15:16 -0700)
Move all SubtitleTrack operations to TimeProvider's event handler thread.

Bug: 28784397
Change-Id: Iff848635390e99ffb19add03277a9d62feece4cc

media/java/android/media/MediaPlayer.java

index cee7d60..3f6081b 100644 (file)
@@ -2276,6 +2276,8 @@ public class MediaPlayer extends PlayerBase
             Log.w(TAG, "addSubtitleSource called with null InputStream");
         }
 
+        getMediaTimeProvider();
+
         // process each subtitle in its own thread
         final HandlerThread thread = new HandlerThread("SubtitleReadThread",
               Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
@@ -2302,7 +2304,12 @@ public class MediaPlayer extends PlayerBase
                 synchronized (mIndexTrackPairs) {
                     mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
                 }
-                track.onData(contents.getBytes(), true /* eos */, ~0 /* runID: keep forever */);
+                Handler h = mTimeProvider.mEventHandler;
+                int what = TimeProvider.NOTIFY;
+                int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes());
+                Message m = h.obtainMessage(what, arg1, 0, trackData);
+                h.sendMessage(m);
                 return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
             }
 
@@ -2501,6 +2508,8 @@ public class MediaPlayer extends PlayerBase
             mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
         }
 
+        getMediaTimeProvider();
+
         final FileDescriptor fd3 = fd2;
         final long offset2 = offset;
         final long length2 = length;
@@ -2526,7 +2535,12 @@ public class MediaPlayer extends PlayerBase
                             total += bytes;
                         }
                     }
-                    track.onData(bos.toByteArray(), true /* eos */, ~0 /* runID: keep forever */);
+                    Handler h = mTimeProvider.mEventHandler;
+                    int what = TimeProvider.NOTIFY;
+                    int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                    Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
+                    Message m = h.obtainMessage(what, arg1, 0, trackData);
+                    h.sendMessage(m);
                     return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
                 } catch (Exception e) {
                     Log.e(TAG, e.getMessage(), e);
@@ -3528,6 +3542,7 @@ public class MediaPlayer extends PlayerBase
         private static final int REFRESH_AND_NOTIFY_TIME = 1;
         private static final int NOTIFY_STOP = 2;
         private static final int NOTIFY_SEEK = 3;
+        private static final int NOTIFY_TRACK_DATA = 4;
         private HandlerThread mHandlerThread;
 
         /** @hide */
@@ -3667,6 +3682,12 @@ public class MediaPlayer extends PlayerBase
             }
         }
 
+        private synchronized void notifyTrackData(Pair<SubtitleTrack, byte[]> trackData) {
+            SubtitleTrack track = trackData.first;
+            byte[] data = trackData.second;
+            track.onData(data, true /* eos */, ~0 /* runID: keep forever */);
+        }
+
         private synchronized void notifyStop() {
             for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
                 if (listener == null) {
@@ -3899,6 +3920,9 @@ public class MediaPlayer extends PlayerBase
                     case NOTIFY_SEEK:
                         notifySeek();
                         break;
+                    case NOTIFY_TRACK_DATA:
+                        notifyTrackData((Pair<SubtitleTrack, byte[]>)msg.obj);
+                        break;
                     }
                 }
             }