[FFmpeg-devel] [RFC][PATCH 18/18] avcodec/avpacket: make the AVPacketList API thread safe

James Almer jamrial at gmail.com
Wed Nov 18 18:52:47 EET 2020


Signed-off-by: James Almer <jamrial at gmail.com>
---
I don't know if this is necessary, so i'm sending it as an RFC.

 libavcodec/avpacket.c        | 34 +++++++++++++++++++++++++++++++---
 libavcodec/packet_internal.h |  2 ++
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 0db47c1d62..a8e934913e 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -807,6 +807,8 @@ AVPacketList *av_packet_list_alloc(void)
     if (!pktl)
         return NULL;
 
+    ff_mutex_init(&pktl->mutex, NULL);
+
     return (AVPacketList *)pktl;
 }
 
@@ -840,6 +842,7 @@ int av_packet_list_put(AVPacketList *list, AVPacket *pkt,
         av_packet_move_ref(&pktle->pkt, pkt);
     }
 
+    ff_mutex_lock(&pktl->mutex);
     if (pktl->head)
         pktl->tail->next = pktle;
     else
@@ -847,6 +850,7 @@ int av_packet_list_put(AVPacketList *list, AVPacket *pkt,
 
     /* Add the packet in the buffered packet list. */
     pktl->tail = pktle;
+    ff_mutex_unlock(&pktl->mutex);
 
     return 0;
 }
@@ -861,8 +865,11 @@ int av_packet_list_get(AVPacketList *list, AVPacket *pkt,
     AVPacketList *pktl = list;
 #endif
 
-    if (!pktl->head)
+    ff_mutex_lock(&pktl->mutex);
+    if (!pktl->head) {
+        ff_mutex_unlock(&pktl->mutex);
         return AVERROR(EAGAIN);
+    }
 
     pktle      = pktl->head;
     if (pkt)
@@ -873,6 +880,7 @@ int av_packet_list_get(AVPacketList *list, AVPacket *pkt,
 
     if (!pktle->next)
         pktl->tail = NULL;
+    ff_mutex_unlock(&pktl->mutex);
 
     av_freep(&pktle);
 
@@ -891,14 +899,20 @@ int av_packet_list_peek(AVPacketList *list, AVPacket *pkt,
     AVPacket tmp = { 0 };
     int ret;
 
-    if (!pktl->head)
+    ff_mutex_lock(&pktl->mutex);
+    if (!pktl->head) {
+        ff_mutex_unlock(&pktl->mutex);
         return AVERROR(EAGAIN);
+    }
 
-    if (!pkt)
+    if (!pkt) {
+       ff_mutex_unlock(&pktl->mutex);
        return 0;
+    }
 
     pktle = pktl->head;
     ret = av_packet_ref(&tmp, &pktle->pkt);
+    ff_mutex_unlock(&pktl->mutex);
     if (ret < 0)
         return ret;
 
@@ -915,6 +929,7 @@ void av_packet_list_flush(AVPacketList *list)
     AVPacketList *pktl = list;
 #endif
 
+    ff_mutex_lock(&pktl->mutex);
     while (pktl->head) {
         PacketListEntry *pktle = pktl->head;
         pktl->head = pktle->next;
@@ -923,16 +938,29 @@ void av_packet_list_flush(AVPacketList *list)
     }
 
     pktl->tail = NULL;
+    ff_mutex_unlock(&pktl->mutex);
 }
 
 void av_packet_list_free(AVPacketList **plist)
 {
     AVPacketList *list = *plist;
+#if FF_API_PACKET_LIST
+    struct PacketList *pktl;
+#else
+    AVPacketList *pktl;
+#endif
 
     if (!list)
         return;
 
+#if FF_API_PACKET_LIST
+    pktl = (struct PacketList *)list;
+#else
+    pktl = list;
+#endif
+
     av_packet_list_flush(list);
+    ff_mutex_destroy(&pktl->mutex);
     av_freep(plist);
 }
 
diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h
index fd9637bc44..4cb3fb4bbd 100644
--- a/libavcodec/packet_internal.h
+++ b/libavcodec/packet_internal.h
@@ -21,6 +21,7 @@
 
 #include <stdint.h>
 
+#include "libavutil/thread.h"
 #include "packet.h"
 
 typedef struct PacketListEntry {
@@ -36,6 +37,7 @@ struct AVPacketList {
 #endif
     PacketListEntry *head;
     PacketListEntry *tail;
+    AVMutex mutex;
 };
 
 #if LIBAVCODEC_VERSION_MAJOR < 59
-- 
2.29.2



More information about the ffmpeg-devel mailing list