parent
							
								
									795fe94d56
								
							
						
					
					
						commit
						6ce7f8e6b3
					
				| @ -0,0 +1,254 @@ | ||||
| 
 | ||||
| #ifndef FFMSG_QUEUE_H | ||||
| #define FFMSG_QUEUE_H | ||||
| 
 | ||||
| #include <mutex> | ||||
| #include <libavutil/mem.h> | ||||
| 
 | ||||
| /**************** msg  define begin ***************/ | ||||
| 
 | ||||
| #define FFP_MSG_FLUSH                       0 | ||||
| #define FFP_MSG_ERROR                       100 | ||||
| #define FFP_MSG_PREPARED                    200 | ||||
| #define FFP_MSG_COMPLETED                   300 | ||||
| #define FFP_MSG_VIDEO_SIZE_CHANGED          400 | ||||
| #define FFP_MSG_SAR_CHANGED                 401 | ||||
| #define FFP_MSG_VIDEO_RENDERING_START       402 | ||||
| #define FFP_MSG_AUDIO_RENDERING_START       403 | ||||
| #define FFP_MSG_VIDEO_ROTATION_CHANGED      404 | ||||
| #define FFP_MSG_AUDIO_DECODED_START         405 | ||||
| #define FFP_MSG_VIDEO_DECODED_START         406 | ||||
| #define FFP_MSG_OPEN_INPUT                  407 | ||||
| #define FFP_MSG_FIND_STREAM_INFO            408 | ||||
| #define FFP_MSG_COMPONENT_OPEN              409 | ||||
| #define FFP_MSG_VIDEO_SEEK_RENDERING_START  410 | ||||
| #define FFP_MSG_AUDIO_SEEK_RENDERING_START  411 | ||||
| 
 | ||||
| #define FFP_MSG_BUFFERING_START             500 | ||||
| #define FFP_MSG_BUFFERING_END               501 | ||||
| #define FFP_MSG_BUFFERING_UPDATE            502 | ||||
| #define FFP_MSG_BUFFERING_BYTES_UPDATE      503 | ||||
| #define FFP_MSG_BUFFERING_TIME_UPDATE       504 | ||||
| #define FFP_MSG_SEEK_COMPLETE               600 | ||||
| #define FFP_MSG_PLAYBACK_STATE_CHANGED      700 | ||||
| #define FFP_MSG_TIMED_TEXT                  800 | ||||
| #define FFP_MSG_VIDEO_DECODER_OPEN          900 | ||||
| 
 | ||||
| #define FFP_REQ_START                       1001 | ||||
| #define FFP_REQ_PAUSE                       1002 | ||||
| #define FFP_REQ_SEEK                        1003 | ||||
| 
 | ||||
| /**************** msg  define end *****************/ | ||||
| 
 | ||||
| typedef struct AVMessage { | ||||
|     int what; | ||||
|     int arg1; | ||||
|     int arg2; | ||||
|     void *obj; | ||||
|     void (*free_l)(void *obj); | ||||
|     struct AVMessage *next; | ||||
| } AVMessage; | ||||
| 
 | ||||
| typedef struct MessageQueue { | ||||
|     AVMessage *first_msg, *last_msg; | ||||
|     int nb_messages; | ||||
|     int abort_request; | ||||
|     std::mutex mutex; | ||||
|     std::condition_variable cond; | ||||
| 
 | ||||
|     AVMessage *recycle_msg; | ||||
|     int recycle_count; | ||||
|     int alloc_count; | ||||
| } MessageQueue; | ||||
| 
 | ||||
| inline static void msg_free(AVMessage *msg) { | ||||
|     if (!msg || !msg->obj) | ||||
|         return; | ||||
|     assert(msg->free_l); | ||||
|     msg->free_l(msg->obj); | ||||
|     msg->obj = nullptr; | ||||
| } | ||||
| 
 | ||||
| inline static int msg_queue_put_private(MessageQueue *q, AVMessage *msg) { | ||||
|     AVMessage *msg1; | ||||
| 
 | ||||
|     if (q->abort_request) | ||||
|         return -1; | ||||
| 
 | ||||
|     msg1 = q->recycle_msg; | ||||
|     if (msg1) { | ||||
|         q->recycle_msg = msg1->next; | ||||
|         q->recycle_count++; | ||||
|     } else { | ||||
|         q->alloc_count++; | ||||
|         msg1 = static_cast<AVMessage *>(av_malloc(sizeof(AVMessage))); | ||||
|     } | ||||
| 
 | ||||
|     if (!msg1) | ||||
|         return -1; | ||||
| 
 | ||||
|     *msg1 = *msg; | ||||
|     msg1->next = nullptr; | ||||
| 
 | ||||
|     if (!q->last_msg) | ||||
|         q->first_msg = msg1; | ||||
|     else | ||||
|         q->last_msg->next = msg1; | ||||
|     q->last_msg = msg1; | ||||
|     q->nb_messages++; | ||||
|     q->cond.notify_all(); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| inline static int msg_queue_put(MessageQueue *q, AVMessage *msg) { | ||||
|     int ret; | ||||
| 
 | ||||
|     std::lock_guard<std::mutex> lock(q->mutex); | ||||
|     ret = msg_queue_put_private(q, msg); | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| inline static void msg_init_msg(AVMessage *msg) { | ||||
|     memset(msg, 0, sizeof(AVMessage)); | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_put_notify1(MessageQueue *q, int what) { | ||||
|     AVMessage msg; | ||||
|     msg_init_msg(&msg); | ||||
|     msg.what = what; | ||||
|     msg_queue_put(q, &msg); | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_put_notify2(MessageQueue *q, int what, int arg1) { | ||||
|     AVMessage msg; | ||||
|     msg_init_msg(&msg); | ||||
|     msg.what = what; | ||||
|     msg.arg1 = arg1; | ||||
|     msg_queue_put(q, &msg); | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_put_notify3(MessageQueue *q, int what, int arg1, int arg2) { | ||||
|     AVMessage msg; | ||||
|     msg_init_msg(&msg); | ||||
|     msg.what = what; | ||||
|     msg.arg1 = arg1; | ||||
|     msg.arg2 = arg2; | ||||
|     msg_queue_put(q, &msg); | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_init(MessageQueue *q) { | ||||
|     memset(q, 0, sizeof(MessageQueue)); | ||||
|     q->abort_request = 1; | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_flush(MessageQueue *q) { | ||||
|     AVMessage *msg, *msg1; | ||||
|     std::lock_guard<std::mutex> lock(q->mutex); | ||||
| 
 | ||||
|     for (msg = q->first_msg; msg != NULL; msg = msg1) { | ||||
|         msg1 = msg->next; | ||||
|         msg->next = q->recycle_msg; | ||||
|         q->recycle_msg = msg; | ||||
|     } | ||||
|     q->last_msg = nullptr; | ||||
|     q->first_msg = nullptr; | ||||
|     q->nb_messages = 0; | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_abort(MessageQueue *q) { | ||||
|     std::unique_lock<std::mutex> lock(q->mutex); | ||||
|     q->abort_request = 1; | ||||
|     q->cond.notify_all(); | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_start(MessageQueue *q) { | ||||
|     std::lock_guard<std::mutex> lock(q->mutex); | ||||
|     q->abort_request = 0; | ||||
| 
 | ||||
|     AVMessage msg; | ||||
|     msg_init_msg(&msg); | ||||
|     msg.what = FFP_MSG_FLUSH; | ||||
|     msg_queue_put_private(q, &msg); | ||||
| } | ||||
| 
 | ||||
| inline static int msg_queue_get(MessageQueue *q, AVMessage *msg, int block) { | ||||
|     AVMessage *msg1; | ||||
|     int ret; | ||||
| 
 | ||||
|     std::unique_lock<std::mutex> lock(q->mutex); | ||||
| 
 | ||||
|     for (;;) { | ||||
|         if (q->abort_request) { | ||||
|             ret = -1; | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         msg1 = q->first_msg; | ||||
|         if (msg1) { | ||||
|             q->first_msg = msg1->next; | ||||
|             if (!q->first_msg) | ||||
|                 q->last_msg = nullptr; | ||||
|             q->nb_messages--; | ||||
|             *msg = *msg1; | ||||
|             msg1->obj = nullptr; | ||||
|             msg1->next = q->recycle_msg; | ||||
|             q->recycle_msg = msg1; | ||||
|             ret = 1; | ||||
|             break; | ||||
|         } else if (!block) { | ||||
|             ret = 0; | ||||
|             break; | ||||
|         } else { | ||||
|             q->cond.wait(lock); | ||||
|         } | ||||
|     } | ||||
|     lock.unlock(); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_remove(MessageQueue *q, int what) { | ||||
|     AVMessage **p_msg, *msg, *last_msg; | ||||
|     std::lock_guard<std::mutex> lock(q->mutex); | ||||
| 
 | ||||
|     last_msg = q->first_msg; | ||||
| 
 | ||||
|     if (!q->abort_request && q->first_msg) { | ||||
|         p_msg = &q->first_msg; | ||||
|         while (*p_msg) { | ||||
|             msg = *p_msg; | ||||
| 
 | ||||
|             if (msg->what == what) { | ||||
|                 *p_msg = msg->next; | ||||
|                 msg_free(msg); | ||||
|                 msg->next = q->recycle_msg; | ||||
|                 q->recycle_msg = msg; | ||||
|                 q->nb_messages--; | ||||
|             } else { | ||||
|                 last_msg = msg; | ||||
|                 p_msg = &msg->next; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (q->first_msg) { | ||||
|             q->last_msg = last_msg; | ||||
|         } else { | ||||
|             q->last_msg = nullptr; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline static void msg_queue_destroy(MessageQueue *q) { | ||||
|     msg_queue_flush(q); | ||||
|     std::lock_guard<std::mutex> lock(q->mutex); | ||||
| 
 | ||||
|     while(q->recycle_msg) { | ||||
|         AVMessage *msg = q->recycle_msg; | ||||
|         if (msg) | ||||
|             q->recycle_msg = msg->next; | ||||
|         msg_free(msg); | ||||
|         av_freep(&msg); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif // FFMSG_QUEUE_H
 | ||||
					Loading…
					
					
				
		Reference in new issue