From 7fe46306ac577db11ba8a8bbf20653861fcb1a1a Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期二, 22 十月 2019 15:31:29 +0800
Subject: [PATCH] rec bug fix
---
csrc/buz/recorder.hpp | 36 ++--
csrc/buz/recorder.cpp | 224 +++++++++++++++++----------
csrc/ffmpeg/format/FormatIn.cpp | 2
csrc/wrapper.cpp | 38 +++-
csrc/worker/rec.cpp | 96 +++++++++--
csrc/worker/stream.cpp | 11
csrc/worker/decoder.cpp | 8
csrc/wrapper.hpp | 4
csrc/ffmpeg/format/FormatOut.cpp | 2
csrc/worker/rec.hpp | 8
csrc/worker/stream.hpp | 2
csrc/worker/decoder.hpp | 6
csrc/common.hpp | 7
13 files changed, 292 insertions(+), 152 deletions(-)
diff --git a/csrc/buz/recorder.cpp b/csrc/buz/recorder.cpp
index d3d9a98..4eb454c 100644
--- a/csrc/buz/recorder.cpp
+++ b/csrc/buz/recorder.cpp
@@ -24,19 +24,20 @@
,out_(NULL)
,maxduration(30 * 25)
,minduration(10 * 25)
- ,end_frame(minduration)
- ,cur_frame(0)
+ ,fp_(NULL)
,stop_recorder_(false)
,id_(id)
- ,id_frame_(-1)
- ,id_frame_in_file_(-1)
+ ,id_frame_(0)
+ ,id_frame_in_file_(0)
,file_path_("")
,func_rec_info_(nullptr)
,thrd_(nullptr)
- ,error_occured_(false)
,audio_(false)
- ,cur_frame_a(0)
- ,fp_(NULL)
+ ,end_frame_(0)
+ ,v_cur_frame_(0)
+ ,a_cur_frame_(0)
+ ,error_occured_(false)
+ ,last_rec_id_(-1)
{
if (in){
maxduration = 30 * in->getFPS();
@@ -91,14 +92,14 @@
}
bool ret = out_->JustWriter(v, a, file_path_.c_str());
if (ret){
- logIt("start record file: %s", file_path_.c_str());
+ logIt("start record h264 file: %s", file_path_.c_str());
return 0;
}else{
file_path_ = "./" + filename;
ret = out_->JustWriter(v, a, file_path_.c_str());
logIt("failed in dir %s, try file %s to start record file", dir_.c_str(), file_path_.c_str());
if (ret){
- logIt("start record file: %s", file_path_.c_str());
+ logIt("start record h264 file: %s", file_path_.c_str());
return 0;
}
}
@@ -114,7 +115,7 @@
}
int pid = getpid();
- std::string filename(sole::uuid4().base62() + "-" + std::to_string(pid) + ".mp4");
+ std::string filename(sole::uuid4().base62() + "-" + std::to_string(pid) + ".hevc");
file_path_ = dir_ + "/" + filename;
fp_ = fopen(file_path_.c_str(), "wb");
@@ -127,7 +128,7 @@
return -1;
}
}
- logIt("start record file: %s", file_path_.c_str());
+ logIt("start record hevc file: %s", file_path_.c_str());
return 0;
}
@@ -149,27 +150,33 @@
////////////////////////
int Recorder::write_h264(const CPacket &pkt){
//reader failed, break stream
- if(pkt.id == -1 && !pkt.data){
+ if(!pkt.data){
return -1;
}
- if (cur_frame == end_frame){
+ if (v_cur_frame_ == end_frame_){
return 1;
}
AVPacket &op = pkt.data->getAVPacket();
+
+ if (!audio_ && in_->isAudioPkt(&op)) {
+ return 0;
+ }
+
AVPacket np(op);
av_copy_packet(&np, &op);
- int64_t cur = cur_frame;
+ int64_t cur = v_cur_frame_;
if (in_->isVideoPkt(&np)){
- if(pkt.id == id_frame_){
- id_frame_in_file_ = cur_frame;
+ if(pkt.v_id == id_frame_){
+ id_frame_in_file_ = v_cur_frame_;
}
- cur_frame++;
+ v_cur_frame_++;
+
}else if (in_->isAudioPkt(&np)) {
- cur = cur_frame_a++;
+ cur = a_cur_frame_++;
}
auto ret = out_->writeFrame(&np, cur);
@@ -187,21 +194,31 @@
logIt("write hevc packet error, file not open");
return -1;
}
- if (cur_frame == end_frame){
+ if (v_cur_frame_ == end_frame_){
return 1;
}
AVPacket &op = pkt.data->getAVPacket();
- int64_t cur = cur_frame;
- if (in_->isVideoPkt(&op)){
-
- if(pkt.id == id_frame_){
- id_frame_in_file_ = cur_frame;
- }
- cur_frame++;
+
+ if (in_->isAudioPkt(&op)) {
+ return 0;
+ }
+ if (op.data == NULL){
+ logIt("hevc avpacket data null");
+ return 0;
}
+ if (in_->isVideoPkt(&op)){
+
+ if(pkt.v_id == id_frame_){
+ id_frame_in_file_ = v_cur_frame_;
+ }
+ v_cur_frame_++;
+ }
fwrite(op.data, op.size, 1, fp_);
+ logIt("hevc write data len: %d frame id: %d key %d",
+ op.size, v_cur_frame_, op.flags & AV_PKT_FLAG_KEY);
+
return 0;
}
@@ -265,22 +282,27 @@
}
int Recorder::mux_hevc(FILE *fp, const char *outfile){
- std::unique_ptr<FormatIn> in(new FormatIn(false));
if (!fp) {
logIt("mux hevc file handle is null");
return -1;
}
+ std::unique_ptr<FormatIn> in(nullptr);
int tryTime = 0;
- while (in->openWithCustomIO(fp, read_buffer) < 0) {
- usleep(10000);
- if (tryTime++ < 100){
- logIt("mux hevc mux: %d failed open custom io %s, try again", tryTime, outfile);
- continue;
+
+ while(true){
+ std::unique_ptr<FormatIn> tmp(new FormatIn(false));
+ auto ret = tmp->openWithCustomIO(fp, read_buffer);
+ if (ret == 0){
+ in = std::move(tmp);
+ break;
}
- logIt("mux hevc try %d time to open custom io, failed", tryTime);
- return -2;
+ usleep(10000);
+ if (tryTime++ > 100){
+ logIt("mux hevc try %d time to open custom io %s, failed", tryTime, outfile);
+ return -2;
+ }
}
if (in->open(NULL, NULL) < 0){
logIt("mux hevc open stream error");
@@ -298,7 +320,7 @@
return -5;
}
if (out->JustWriter(v, NULL, outfile)){
- logIt("mux hevc start record file: %s", outfile);
+ logIt("mux hevc start record file: %s", outfile);
}
int64_t id = 0;
@@ -327,13 +349,12 @@
end_write_h264();
}
- logIt("finished record : %s frames: %d", file_path_.c_str(), cur_frame);
+ logIt("finished record : %s frames: %d, frame in file id: %d",
+ file_path_.c_str(), end_frame_, id_frame_in_file_);
{
std::lock_guard<std::mutex> l(mutex_pkt_);
list_pkt_.clear();
}
- // logIt("INDEX %d, REAL-FRAME-ID %d, FILE %s, CURFrame %d, ENDFrame %d\n",
- // id_frame_in_file_, id_frame_, file_path_.c_str(), cur_frame, end_frame);
if(func_rec_info_){
func_rec_info_(id_,id_frame_in_file_, file_path_);
@@ -347,14 +368,17 @@
std::list<CPacket> pkts;
{
std::unique_lock<std::mutex> locker(mutex_pkt_);
- auto status = cv_.wait_for(locker, std::chrono::seconds(3), [&]{
+ int sec = minduration/50;
+ if (in_) sec = minduration/in_->getFPS()/2;
+ auto status = cv_.wait_for(locker, std::chrono::seconds(sec), [&]{
return !list_pkt_.empty() || stop_recorder_.load();
});
-
+
if (!status || stop_recorder_.load()){
error_occured_ = !status;
break;
}
+
list_pkt_.swap(pkts);
}
@@ -373,6 +397,7 @@
stop_recorder_.store(true);
end_writer();
+ list_pkt_.clear();
}
int Recorder::Run(const char* output, const int mind, const int maxd, const bool audio){
@@ -391,12 +416,12 @@
if(fps > 1.0){
maxduration = fps * maxd;
minduration = fps * mind;
- end_frame = minduration;
+ end_frame_ = minduration;
}
audio_ = a;
- logIt("minduration %d maxduration %d curduration %d", minduration, maxduration, end_frame);
+ logIt("minduration %d maxduration %d", minduration, maxduration);
thrd_.reset(new std::thread([&]{
run_thread();
@@ -409,76 +434,111 @@
int Recorder::FireRecorder(const int64_t &id){
if (stop_recorder_.load()) return -1;
- if(id_frame_ == -1){
+ if(id_frame_ == 0){
id_frame_ = id;
-
+
std::lock_guard<std::mutex> locker(mutex_pkt_);
- if (list_pkt_.size() > end_frame){
- end_frame = list_pkt_.size() + minduration/2;
- if (end_frame > maxduration)
- end_frame = maxduration;
+ if (list_pkt_.size() > end_frame_){
+ end_frame_ = list_pkt_.size() + minduration/2;
+ if (end_frame_ > maxduration)
+ end_frame_ = maxduration;
}
+
+ }else if(v_cur_frame_ > minduration/2 && end_frame_ < maxduration){
+ logIt("cur frame: %d, end frame: %d, duration: [%d-%d]",
+ v_cur_frame_, end_frame_, minduration, maxduration);
- // logIt("FIRST FIRE RECORD ID: %lld, cur_frame: %d, end_frame: %d", id, cur_frame, end_frame);
-
- }else if(cur_frame > minduration/2 && end_frame < maxduration){
- end_frame = end_frame + minduration / 2;
- if(end_frame > maxduration){
- end_frame = maxduration;
+ end_frame_ = end_frame_ + minduration / 2;
+ if(end_frame_ > maxduration){
+ end_frame_ = maxduration;
}
- // logIt("PROLONG REC, cur_frame: %d, end_frame: %d", cur_frame, end_frame);
}
- // logIt("FIRE REC FRAME ID: %lld", id);
+
return 0;
}
- int Recorder::PushPacket(const CPacket &pkt){
+ int Recorder::PushPacket(std::list<CPacket> &lst){
if (stop_recorder_.load()) return 0;
std::lock_guard<std::mutex> locker(mutex_pkt_);
-
- if(id_frame_ == -1){
- //wait I
- if (!audio_ && in_->isAudioPkt(&pkt.data->getAVPacket())){
- return 0;
+ // 娌℃湁寮�濮嬪綍鍒�
+ if (last_rec_id_ < 0){
+ logIt("last rec id is 0 cache size: %ld", lst.size());
+ for (auto &i : lst){
+ // 浠庣涓�涓潪闊抽鍏抽敭甯у紑濮�
+ if (last_rec_id_ < 0){
+ if (!in_->isVideoPkt(&i.data->getAVPacket())){
+ continue;
+ }
+ if (!(i.data->getAVPacket().flags & AV_PKT_FLAG_KEY)){
+ continue;
+ }
+ }
+ last_rec_id_ = i.id;
+ list_pkt_.push_back(i);
}
-
- maybe_dump_gop();
-
- list_pkt_.push_back(pkt);
- // cv_.notify_one();
-
}else{
- list_pkt_.push_back(pkt);
- cv_.notify_one();
+ for(auto &i : lst){
+ if (i.id > last_rec_id_){
+ list_pkt_.push_back(i);
+ last_rec_id_++;
+ }
+ }
}
+
+
+ cv_.notify_one();
return list_pkt_.size();
}
- int Recorder::PushPackets(std::list<CPacket> &lst){
-
+ int Recorder::StartWritePacket(std::list<CPacket> &lst, const int64_t &id, const int start, const int end){
+
if (stop_recorder_.load()) return 0;
+ // 绗竴娆″綍鍍�,璁剧疆瑙﹀彂甯d
+ id_frame_ = id;
+
+
+ if (start < 0) {
+ logIt("start write packet [%d-%d] in pkt size: %d, frame id: %lld, "
+ "cur frame: %d, end frame: %d, duration: [%d-%d], last rec id: %lld",
+ start, end, lst.size(), id_frame_,
+ v_cur_frame_, end_frame_, minduration, maxduration, last_rec_id_);
+ return -1;
+ }
+
std::lock_guard<std::mutex> locker(mutex_pkt_);
- bool i = false;
+ // 灏嗕紶鍏ョ殑鎵�鏈塸ackets淇濆瓨濡傜紦瀛�
+ int index = -1;
for (auto &p : lst){
- if (!audio_ && in_->isAudioPkt(&p.data->getAVPacket())){
- continue;
- }
+ index++;
+ if (index < start) continue;
list_pkt_.push_back(p);
+
+ if (index == end){
+ last_rec_id_ = p.id;
+ break;
+ }
}
- maybe_dump_gop();
+
+
+ logIt("start write packet [%d-%d] in pkt size: %d, frame id: %lld, "
+ "cur frame: %d, end frame: %d, duration: [%d-%d], last rec id: %lld",
+ start, end, lst.size(), id_frame_,
+ v_cur_frame_, end_frame_, minduration, maxduration, last_rec_id_);
+
+
+ // maybe_dump_gop();
cv_.notify_one();
- // logIt("CACHE PACKET : %d", list_pkt_.size());
return list_pkt_.size();
}
void Recorder::maybe_dump_gop(){
- //瓒呰繃min/2,涓㈠純gop
- while (list_pkt_.size() > minduration) {
+
+ while (list_pkt_.size() > maxduration) {
list_pkt_.pop_front();
while(!list_pkt_.empty()){
auto &i = list_pkt_.front();
@@ -490,5 +550,5 @@
}
}
}
- }
-}
+ }// end clase
+}// end namespace
diff --git a/csrc/buz/recorder.hpp b/csrc/buz/recorder.hpp
index 9c88bbb..9cb557a 100644
--- a/csrc/buz/recorder.hpp
+++ b/csrc/buz/recorder.hpp
@@ -32,8 +32,8 @@
public:
int Run(const char* output, const int mind, const int maxd, const bool audio);
- int PushPacket(const CPacket &pkt);
- int PushPackets(std::list<CPacket> &lst);
+ int PushPacket(std::list<CPacket> &lst);
+ int StartWritePacket(std::list<CPacket> &lst, const int64_t &id, const int start, const int end);
int FireRecorder(const int64_t &id);
void SetCallback(FUNC_REC_INFO cb){
@@ -63,33 +63,33 @@
ffwrapper::FormatIn *in_;
ffwrapper::FormatOut *out_;
- int maxduration;
- int minduration;
- int end_frame;
- int cur_frame;
- int cur_frame_a;
-
- std::list<CPacket> list_pkt_;
-
+ std::list<CPacket> list_pkt_;
std::atomic_bool stop_recorder_;
std::mutex mutex_pkt_;
std::condition_variable cv_;
-
- std::unique_ptr<std::thread> thrd_;
-
std::string dir_;
std::string id_;
-
int64_t id_frame_;
int id_frame_in_file_;
+
std::string file_path_;
FUNC_REC_INFO func_rec_info_;
-
- bool error_occured_;
-
+ FILE *fp_;
bool audio_;
- FILE *fp_;
+ std::unique_ptr<std::thread> thrd_;
+
+
+ int end_frame_;
+ int v_cur_frame_;
+ int a_cur_frame_;
+
+ int64_t last_rec_id_;
+
+ int maxduration;
+ int minduration;
+
+ bool error_occured_;
};
}
}
diff --git a/csrc/common.hpp b/csrc/common.hpp
index e2a6064..2495bd5 100644
--- a/csrc/common.hpp
+++ b/csrc/common.hpp
@@ -8,9 +8,12 @@
class CodedData;
}
// 缂撳瓨鐨勮棰戝抚
-typedef struct _cache_pkt{
+class CPacket{
+public:
std::shared_ptr<ffwrapper::CodedData> data;
+ int64_t v_id;
+ int64_t a_id;
int64_t id;
-}CPacket;
+};
#endif
\ No newline at end of file
diff --git a/csrc/ffmpeg/format/FormatIn.cpp b/csrc/ffmpeg/format/FormatIn.cpp
index 9f743f8..f130419 100644
--- a/csrc/ffmpeg/format/FormatIn.cpp
+++ b/csrc/ffmpeg/format/FormatIn.cpp
@@ -84,7 +84,7 @@
}
ctx_->pb = io_ctx_;
- auto err = av_probe_input_buffer(ctx_->pb, &ctx_->iformat, NULL, NULL, 0, read_io_buff_size_);
+ auto err = av_probe_input_buffer(ctx_->pb, &ctx_->iformat, NULL, NULL, 0, 0);
if(err != 0){
logIt("open with custom io prob input buffer error:%d err: %s\n", err, getAVErrorDesc(err).c_str());
return -1;
diff --git a/csrc/ffmpeg/format/FormatOut.cpp b/csrc/ffmpeg/format/FormatOut.cpp
index 60efd59..e832bfe 100644
--- a/csrc/ffmpeg/format/FormatOut.cpp
+++ b/csrc/ffmpeg/format/FormatOut.cpp
@@ -399,7 +399,7 @@
int out_idx = -1;
std::vector<AVStream*> in_streams{in_v_stream_, in_a_stream_};
for (auto i : in_streams){
- if (i->index == pkt->stream_index){
+ if (i && (i->index == pkt->stream_index)){
if (i->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){
out_idx = v_idx_;
in_stream = i;
diff --git a/csrc/worker/decoder.cpp b/csrc/worker/decoder.cpp
index f5e95b5..558d871 100644
--- a/csrc/worker/decoder.cpp
+++ b/csrc/worker/decoder.cpp
@@ -4,6 +4,7 @@
#include "../ffmpeg/format/FormatIn.hpp"
#include "../ffmpeg/data/CodedData.hpp"
#include "../ffmpeg/log/log.hpp"
+#include "../common.hpp"
extern "C"{
#include <libavformat/avformat.h>
@@ -46,7 +47,7 @@
return 0;
}
- int decoder::saveFrame(AVFrame *frame, int64_t &id){
+ int decoder::saveFrame(AVFrame *frame, const int64_t &id){
FRM frm;
frm.width = frame->width;
frm.height = frame->height;
@@ -67,7 +68,8 @@
return list_frm_.size();
}
- int decoder::SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){
+ int decoder::SetFrame(const CPacket &pkt){
+ auto data = pkt.data;
if (!data) return -10;
if (!decRef_->isVideoPkt(&data->getAVPacket())) return -20;
@@ -83,7 +85,7 @@
av_packet_unref(&np);
if (ret == 0){
- saveFrame(frame, id);
+ saveFrame(frame, pkt.v_id);
}
av_frame_free(&frame);
return ret;
diff --git a/csrc/worker/decoder.hpp b/csrc/worker/decoder.hpp
index d157d25..a1946bd 100644
--- a/csrc/worker/decoder.hpp
+++ b/csrc/worker/decoder.hpp
@@ -12,6 +12,8 @@
struct AVFrame;
struct AVCodecContext;
+class CPacket;
+
namespace ffwrapper
{
class FormatIn;
@@ -40,10 +42,10 @@
private:
int initDecoder();
- int saveFrame(AVFrame *frame, int64_t &id);
+ int saveFrame(AVFrame *frame, const int64_t &id);
public:
void Start();
- int SetFrame(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id);
+ int SetFrame(const CPacket &pkt);
void GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id);
public:
diff --git a/csrc/worker/rec.cpp b/csrc/worker/rec.cpp
index 36d837c..abb8da6 100644
--- a/csrc/worker/rec.cpp
+++ b/csrc/worker/rec.cpp
@@ -16,11 +16,13 @@
using namespace ffwrapper;
using namespace cffmpeg_wrap::buz;
+static const int cache_time = 30 * 60;
+
namespace cffmpeg_wrap
{
rec::rec()
:recRef_(NULL)
- ,min_cache_len_(10 * 60 * 25) // 鏈�灏忕紦瀛�?鍒嗛挓鐨勮棰�,鍥犱负鏁翠釜娴佺▼浼氭湁寤惰繜,鏆傚畾?鍒嗛挓
+ ,min_cache_len_(cache_time * 25) // 鏈�灏忕紦瀛�?鍒嗛挓鐨勮棰�,鍥犱负鏁翠釜娴佺▼浼氭湁寤惰繜,鏆傚畾?鍒嗛挓
{}
rec::~rec()
@@ -43,6 +45,48 @@
list_recInfo_.emplace_back(info);
}
+ void rec::findRecFramesIndex(const int64_t &fired_id, const int duration, int &start, int &end){
+
+ start = end = -1;
+
+ if (list_pkt_.empty()){
+ return;
+ }
+
+ // 褰曞儚寮�濮媔d鍦ㄨЕ鍙慽d涔嬪墠1/2鏃堕暱,淇濊瘉鍦ㄤ腑闂�
+ int64_t start_id = fired_id - duration/2;
+ // 瀵绘壘鍏抽敭甯т綔涓哄綍鍍忓紑濮媔d
+ int offset = recRef_ ? recRef_->getFPS() : 25;
+
+ int64_t index = -1;
+
+ for(auto &i : list_pkt_){
+ index++;
+ // 璺宠繃闊抽
+ if(!recRef_->isVideoPkt(&i.data->getAVPacket())){
+ continue;
+ }
+ // 瀵绘壘鍏抽敭甯т綔涓鸿捣濮�
+ if (start < 0){
+ if (i.data->getAVPacket().flags & AV_PKT_FLAG_KEY){
+ // 褰撳墠甯d > 寮�濮媔d鎴栧紑濮媔d鍦╫ffset鍐�,浣滀负璧峰褰曞儚甯�
+ if (i.v_id >= start_id || start_id - i.v_id < offset){
+ start = index;
+ start_id = i.v_id;
+ }
+ }
+ }else if (recRef_->isVideoPkt(&i.data->getAVPacket())){
+ // 瑙嗛甯�,鐪嬫槸鍚︾紦瀛樹腑鏈夋墍鏈夌殑duration鏁版嵁
+ if (i.v_id - start_id == duration){
+ end = index;
+ }
+ }
+
+ }
+
+ if (end < 0) end = index;
+ }
+
std::unique_ptr<buz::Recorder> rec::startRec(std::string id, std::string dir, const int64_t &frameID, const int mind, const int maxd, const bool audio){
if(!recRef_){
logIt("Init wrapper first");
@@ -63,8 +107,15 @@
}
if (trycnt < 100){
+ int duration = mind * recRef_->getFPS();
+ int start=0, end=0;
+
std::lock_guard<std::mutex> locker(mtx_pkt_);
- rec->PushPackets(list_pkt_);
+ logIt("cache size: %ld", list_pkt_.size());
+ // 棣栨鑾峰彇褰曞儚淇℃伅,鍏堝瓨涓�涓渶鐭椂闀�
+ findRecFramesIndex(frameID, duration, start, end);
+ rec->StartWritePacket(list_pkt_, frameID, start, end);
+
return rec;
}
@@ -126,6 +177,9 @@
void rec::Load(ffwrapper::FormatIn *in){
recRef_ = in;
+ if (in){
+ min_cache_len_ = in->getFPS() * cache_time;
+ }
}
void rec::Unload(){
@@ -165,30 +219,35 @@
// logIt("recorders count: %d", map_rec_.size());
}
- void rec::SetPacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){
- if (!data) return;
+ void rec::SetPacket(const CPacket &pkt){
+ if (!pkt.data) return;
+ cachePacket(pkt);
std::lock_guard<std::mutex> l(mtx_rec_);
for(auto &i : map_rec_){
if (i.second){
- i.second->PushPacket({data, id});
+ std::lock_guard<std::mutex> pl(mtx_pkt_);
+ i.second->PushPacket(list_pkt_);
}
}
- cachePacket(data, id);
}
- void rec::cachePacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){
+ void rec::cachePacket(const CPacket &pkt){
+
std::lock_guard<std::mutex> l(mtx_pkt_);
//wait I
if (list_pkt_.empty()) {
+ if (!recRef_->isVideoPkt(&pkt.data->getAVPacket())){
+ return;
+ }
- if (!(data->getAVPacket().flags & AV_PKT_FLAG_KEY)){
+ if (!(pkt.data->getAVPacket().flags & AV_PKT_FLAG_KEY)){
return;
}
}
- list_pkt_.push_back({data, id});
+ list_pkt_.push_back(pkt);
// 瓒呰繃缂撳瓨鏈�澶ч暱搴�,鍒犻櫎涓�涓猤op
shrinkCache();
@@ -204,20 +263,17 @@
}
int rec::shrinkCache(){
- //瓒呰繃鏈�澶х紦瀛�,涓㈠純gop
- //缂撳瓨鏈�灏忛暱搴︾殑,鐢ㄤ簬璁板綍
- int fps = 25;
- if (recRef_){
- fps = recRef_->getFPS();
- }
- // 鏈�灏�5绉掗暱搴�
- int mincache = fps * 5;
- int md = min_cache_len_ < mincache ? mincache : min_cache_len_;
- while (list_pkt_.size() > md) {
+ //瓒呰繃鏈�澶х紦瀛�,涓㈠純gop
+
+ while (list_pkt_.size() > min_cache_len_) {
list_pkt_.pop_front();
while(!list_pkt_.empty()){
auto &i = list_pkt_.front();
- if (!(i.data->getAVPacket().flags & AV_PKT_FLAG_KEY)){
+ // 闊抽涓㈠純
+ if (!recRef_->isVideoPkt(&i.data->getAVPacket())){
+ list_pkt_.pop_front();
+ }else if (!(i.data->getAVPacket().flags & AV_PKT_FLAG_KEY)){
+ // 闈炲叧閿抚涓㈠純
list_pkt_.pop_front();
}else{
break;
diff --git a/csrc/worker/rec.hpp b/csrc/worker/rec.hpp
index e79e332..fc6ba0d 100644
--- a/csrc/worker/rec.hpp
+++ b/csrc/worker/rec.hpp
@@ -9,6 +9,7 @@
#include "../buz/recorder.hpp"
struct AVPacket;
+class CPacket;
namespace ffwrapper
{
@@ -45,10 +46,13 @@
std::mutex mtx_pkt_;
private:
+ // 鏌ユ壘缂撳瓨涓殑褰曞埗甯�
+ void findRecFramesIndex(const int64_t &fired_id, const int duration, int &start, int &end);
+
// 褰曞儚瀹炰緥鐨勫洖璋冨嚱鏁�,褰曞儚瀹屾垚鍚庤缃綍鍍忔枃浠惰矾寰�,id鍜屽抚id
void setRecInfo(std::string &id, int &index, std::string &path);
// 缂撳瓨瑙嗛鍖�
- void cachePacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id);
+ void cachePacket(const CPacket &pkt);
// 涓㈠純缂撳瓨
int shrinkCache();
// 鍒涘缓褰曞儚瀹炰緥寮�濮嬪綍鍍�
@@ -63,7 +67,7 @@
void Unload();
const bool Loaded() const;
// 缂撳瓨褰曞儚鐨勮棰戝寘,绛夊緟瑙﹀彂褰曞儚,鎴栫洿鎺ユ斁鍒板綍鍍忕紦瀛�
- void SetPacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id);
+ void SetPacket(const CPacket &pkt);
// 瑙﹀彂褰曞儚
void FireRecSignal(const char* sid,const int64_t &id);
// 鑾峰彇褰曞儚鏂囦欢璺緞鍜屽抚id
diff --git a/csrc/worker/stream.cpp b/csrc/worker/stream.cpp
index 9fe11da..94e5ac3 100644
--- a/csrc/worker/stream.cpp
+++ b/csrc/worker/stream.cpp
@@ -6,6 +6,8 @@
#include "../ffmpeg/format/FormatIn.hpp"
#include "../ffmpeg/data/CodedData.hpp"
+#include "../ffmpeg/log/log.hpp"
+using namespace logif;
namespace cffmpeg_wrap{
stream::stream(ffwrapper::FormatIn *in, const int maxSize)
@@ -19,16 +21,15 @@
list_pkt_.clear();
}
- int stream::SetPacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){
- if (data){
-
+ int stream::SetPacket(const CPacket &pkt){
+ if (pkt.data){
// 濡傛灉鍖呮槸闊抽鍖�,浣嗘槸涓嶄娇鐢ㄩ煶棰�,鐩存帴杩斿洖
- if (!audio_ && streamRef_->isAudioPkt(&data->getAVPacket())){
+ if (!audio_ && streamRef_->isAudioPkt(&pkt.data->getAVPacket())){
return 0;
}
std::lock_guard<std::mutex> locker(mutex_avpkt_);
- list_pkt_.push_back({data, id});
+ list_pkt_.push_back(pkt);
while(list_pkt_.size() > max_size_/2*3){
list_pkt_.pop_front();
diff --git a/csrc/worker/stream.hpp b/csrc/worker/stream.hpp
index 5c75d26..8a0feec 100644
--- a/csrc/worker/stream.hpp
+++ b/csrc/worker/stream.hpp
@@ -24,7 +24,7 @@
stream(ffwrapper::FormatIn *in, const int maxSize);
~stream();
- int SetPacket(std::shared_ptr<ffwrapper::CodedData> data, int64_t &id);
+ int SetPacket(const CPacket &pkt);
void GetPacket(unsigned char **pktData, int *size, int *key);
void AudioSwitch(const bool a){audio_ = a;}
};
diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp
index 9d0c679..721d366 100644
--- a/csrc/wrapper.cpp
+++ b/csrc/wrapper.cpp
@@ -24,6 +24,7 @@
#include "worker/stream.hpp"
#include "worker/decoder.hpp"
#include "worker/rec.hpp"
+#include "common.hpp"
using namespace logif;
using namespace ffwrapper;
@@ -158,15 +159,15 @@
}
}
- int Wrapper::run_worker(ffwrapper::FormatIn *in, std::shared_ptr<ffwrapper::CodedData> data, int64_t &id){
+ int Wrapper::run_worker(ffwrapper::FormatIn *in, const CPacket &pkt){
if (gb_){
- AVPacket &pkt = data->getAVPacket();
- pkt.pts = pkt.dts = AV_NOPTS_VALUE;
+ AVPacket &p = pkt.data->getAVPacket();
+ p.pts = p.dts = AV_NOPTS_VALUE;
}
int flag = 0;
- if (stream_) stream_->SetPacket(data, id);
- if (decoder_ && run_dec_) flag = decoder_->SetFrame(data, id);
- if (rec_->Loaded()) rec_->SetPacket(data, id);
+ if (stream_) stream_->SetPacket(pkt);
+ if (decoder_ && run_dec_) flag = decoder_->SetFrame(pkt);
+ if (rec_->Loaded()) rec_->SetPacket(pkt);
return flag;
}
@@ -195,7 +196,9 @@
init_worker(in.get());
int64_t id = gb_ ? 0 : -1;
-
+ int64_t v_id = id;
+ int64_t a_id = id;
+
bool exist = access(input_url_.c_str(), 0) == 0 ? true : false;
while(!stop_stream_.load()){
@@ -204,25 +207,34 @@
logIt("read packet error, id: %lld", id);
break;
}
+ // 闈為煶瑙嗛
if (in->notVideoAudio(&data->getAVPacket())){
continue;
}
-
+ // 闈炲浗鏍囪烦杩囩涓�甯�,娴嬭瘯绗竴甯ф湁闂
if (!gb_ && id < 0){
- id++;
+ id++; v_id++; a_id++;
continue;
}
-
+ CPacket pkt{data, v_id, a_id, id};
// decode error
- if (run_worker(in.get(), data, id) == -1){
+ if (run_worker(in.get(), pkt) == -1){
break;
}
+ if (in->isVideoPkt(&data->getAVPacket())){
+ v_id++;
+ }else{
+ a_id++;
+ }
+
+ id++;
+
+ //鏈湴鏂囦欢澶揩sleep涓�涓�
if (exist){
usleep(wTime);
}
- id++;
}
deinit_worker();
@@ -236,7 +248,7 @@
void Wrapper::BuildRecorder(const char* id, const char *output, const int64_t &fid, const int mindur, const int maxdur, const bool audio){
bool a = audio;
if (gb_) a = false;
-
+
if (rec_->Loaded()){
rec_->NewRec(id, output, fid, mindur, maxdur, a);
}else{
diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp
index 3e68b46..5677ad0 100644
--- a/csrc/wrapper.hpp
+++ b/csrc/wrapper.hpp
@@ -11,7 +11,7 @@
#include <memory>
#include "common/callback.hpp"
-
+class CPacket;
namespace ffwrapper{
class FormatIn;
@@ -34,7 +34,7 @@
std::unique_ptr<ffwrapper::FormatIn> init_reader(const char* input);
void init_worker(ffwrapper::FormatIn *in);
- int run_worker(ffwrapper::FormatIn *in, std::shared_ptr<ffwrapper::CodedData> data, int64_t &id);
+ int run_worker(ffwrapper::FormatIn *in, const CPacket &pkt);
void deinit_worker();
public:
int RunStream(const char* input);
--
Gitblit v1.8.0