OSDN Git Service

stagefright-plugins: prevent deadlock
authorKeith Mok <kmok@cyngn.com>
Wed, 17 Feb 2016 00:50:34 +0000 (16:50 -0800)
committerKeith Mok <kmok@cyngn.com>
Wed, 17 Feb 2016 00:56:46 +0000 (16:56 -0800)
If video/audio data offset too large,
it will create a deadlock, since there is only one
thread in consuming the video/audio data.
The video can be full, but with all audio data
consumed, causing read function to wait foreve for
new audio data.

CYNGNOS-2061

Change-Id: I0d366311463d5ae25c1d18a584d51d1deae7dfea

extractor/FFmpegExtractor.cpp
utils/ffmpeg_utils.cpp
utils/ffmpeg_utils.h

index dd2dcde..26034ea 100644 (file)
@@ -1201,6 +1201,15 @@ void FFmpegExtractor::readerEntry() {
             ALOGV("readerEntry, full(wtf!!!), mVideoQ.size: %d, mVideoQ.nb_packets: %d, mAudioQ.size: %d, mAudioQ.nb_packets: %d",
                     mVideoQ.size, mVideoQ.nb_packets, mAudioQ.size, mAudioQ.nb_packets);
 #endif
+            // avoid deadlock, the audio and video data in the video is offset too large.
+            if ((mAudioQ.size == 0) && mAudioQ.wait_for_data) {
+                ALOGE("abort audio queue, since offset to video data too large");
+                packet_queue_abort(&mAudioQ);
+            }
+            if ((mVideoQ.size == 0) && mVideoQ.wait_for_data) {
+                ALOGE("abort video queue, since offset to audio data too large");
+                packet_queue_abort(&mVideoQ);
+            }
             /* wait 10 ms */
             mExtractorMutex.lock();
             mCondition.waitRelative(mExtractorMutex, milliseconds(10));
index d02ea61..c9eb25c 100644 (file)
@@ -432,6 +432,12 @@ int packet_queue_put(PacketQueue *q, AVPacket *pkt)
     return ret;
 }
 
+int packet_queue_is_wait_for_data(PacketQueue *q)
+{
+    Mutex::Autolock autoLock(q->lock);
+    return q->wait_for_data;
+}
+
 int packet_queue_put_nullpacket(PacketQueue *q, int stream_index)
 {
     AVPacket pkt1, *pkt = &pkt1;
@@ -468,9 +474,11 @@ int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
             ret = 0;
             break;
         } else {
+            q->wait_for_data = 1;
             q->cond.waitRelative(q->lock, 10000000LL);
         }
     }
+    q->wait_for_data = 0;
     return ret;
 }
 
index 23439ef..83be7fa 100644 (file)
@@ -90,6 +90,7 @@ typedef struct PacketQueue {
     AVPacketList *first_pkt, *last_pkt;
     int nb_packets;
     int size;
+    int wait_for_data;
     int abort_request;
     Mutex lock;
     Condition cond;
@@ -100,6 +101,7 @@ void packet_queue_destroy(PacketQueue *q);
 void packet_queue_flush(PacketQueue *q);
 void packet_queue_start(PacketQueue *q);
 void packet_queue_abort(PacketQueue *q);
+int packet_queue_is_wait_for_data(PacketQueue *q);
 int packet_queue_put(PacketQueue *q, AVPacket *pkt);
 int packet_queue_put_nullpacket(PacketQueue *q, int stream_index);
 int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block);