创建线程解析packet并存入队列
This commit is contained in:
		@@ -6,23 +6,15 @@ extern "C" {
 | 
			
		||||
#include "libavutil/imgutils.h"
 | 
			
		||||
}
 | 
			
		||||
#include <queue>
 | 
			
		||||
#include <thread>
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
struct VideoParam
 | 
			
		||||
{
 | 
			
		||||
	AVFormatContext* fmtCtx;
 | 
			
		||||
	AVCodecContext* codecCtx;
 | 
			
		||||
	int width;
 | 
			
		||||
	int height;
 | 
			
		||||
	int videoStreamIndex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
	requires std::is_same_v<T, AVPacket> || std::is_same_v<T, AVFrame>
 | 
			
		||||
struct MediaQueue 
 | 
			
		||||
{
 | 
			
		||||
	static constexpr int MAX_SIZE = 500;
 | 
			
		||||
	bool full = false;
 | 
			
		||||
	std::queue<T> queue;
 | 
			
		||||
	std::condition_variable cv;
 | 
			
		||||
	std::mutex mut;
 | 
			
		||||
@@ -31,6 +23,7 @@ struct MediaQueue
 | 
			
		||||
	uint32_t count;
 | 
			
		||||
 | 
			
		||||
	MediaQueue() = default;
 | 
			
		||||
	bool isFill() const { return full; }
 | 
			
		||||
	bool push(const T* item);
 | 
			
		||||
	bool pop(T* item, bool block = false, bool quit = false);
 | 
			
		||||
};
 | 
			
		||||
@@ -38,18 +31,22 @@ struct MediaQueue
 | 
			
		||||
template <typename T> requires std::is_same_v<T, AVPacket> || std::is_same_v<T, AVFrame>
 | 
			
		||||
bool MediaQueue<T>::push(const T* item) {
 | 
			
		||||
	if (item == nullptr) return false;
 | 
			
		||||
	if (count >= MAX_SIZE)
 | 
			
		||||
		return false;
 | 
			
		||||
	std::unique_lock lock(mut);
 | 
			
		||||
	if constexpr (std::is_same_v<T, AVPacket>) {
 | 
			
		||||
		auto temp = av_packet_alloc();
 | 
			
		||||
		av_packet_ref(temp, item);
 | 
			
		||||
		queue.push(*temp);
 | 
			
		||||
		size += temp->size;
 | 
			
		||||
		count++;
 | 
			
		||||
		queue.push(*temp);
 | 
			
		||||
	}else if(std::is_same_v<T, AVFrame>) {
 | 
			
		||||
		auto temp = av_frame_alloc();
 | 
			
		||||
		av_frame_ref(temp, item);
 | 
			
		||||
		queue.push(*temp);
 | 
			
		||||
		count++;
 | 
			
		||||
	}
 | 
			
		||||
	count++;
 | 
			
		||||
	if(count >= MAX_SIZE) {
 | 
			
		||||
		full = true;
 | 
			
		||||
	}
 | 
			
		||||
	cv.notify_all();
 | 
			
		||||
	return true;
 | 
			
		||||
@@ -75,6 +72,7 @@ bool MediaQueue<T>::pop(T* item, bool block, bool quit) {
 | 
			
		||||
			}
 | 
			
		||||
			queue.pop();
 | 
			
		||||
			count--;
 | 
			
		||||
			full = false;
 | 
			
		||||
			return true; 
 | 
			
		||||
		}
 | 
			
		||||
		else if (block) {
 | 
			
		||||
@@ -88,8 +86,22 @@ bool MediaQueue<T>::pop(T* item, bool block, bool quit) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct VideoParam
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	MediaQueue<AVPacket> queue;
 | 
			
		||||
	AVFormatContext* fmtCtx;
 | 
			
		||||
	AVCodecContext* codecCtx;
 | 
			
		||||
	int width;
 | 
			
		||||
	int height;
 | 
			
		||||
	int videoStreamIndex;
 | 
			
		||||
 | 
			
		||||
	bool eof = false;
 | 
			
		||||
	bool pause = false;
 | 
			
		||||
	bool quit = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void InitDecoder(const char* filepath, VideoParam& param);
 | 
			
		||||
void RequestPacket(VideoParam& param);
 | 
			
		||||
AVFrame* RequestFrame(VideoParam& param);
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user