From b73029149580370e62dd6c14a270aea902f85cf2 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期三, 18 九月 2019 09:52:30 +0800
Subject: [PATCH] fix rec bug

---
 csrc/buz/recorder.cpp |  235 +++++++++++++++++++++++++++++-----------------------------
 1 files changed, 117 insertions(+), 118 deletions(-)

diff --git a/csrc/buz/recorder.cpp b/csrc/buz/recorder.cpp
index a7086fe..af5a1fc 100644
--- a/csrc/buz/recorder.cpp
+++ b/csrc/buz/recorder.cpp
@@ -25,11 +25,11 @@
         ,maxduration(30 * 25)
         ,minduration(10 * 25)
         ,end_frame(minduration)
-        ,cur_frame(-1)
+        ,cur_frame(0)
         ,stop_recorder_(false)
         ,id_(id)
-        ,id_frame_(0)
-        ,file_frame_index_(-1)
+        ,id_frame_(-1)
+        ,id_frame_in_file_(-1)
         ,file_path_("")
         ,func_rec_info_(nullptr)
         ,thrd_(nullptr)
@@ -43,13 +43,13 @@
             try
             {
                 if (thrd_){
-                    {
-                        std::unique_lock<std::mutex> locker(mutex_pkt_);
+                    if (!stop_recorder_.load()){
                         stop_recorder_.store(true);
                         cv_.notify_one();
                     }
+
                     thrd_->join();
-                    logIt("REC THREAD JOINED, QUIT!!!");
+                    // logIt("REC THREAD JOINED, QUIT!!!, %s", id_.c_str());
                 }
             }
             catch(const std::exception& e)
@@ -71,121 +71,95 @@
 
             out_ = new FormatOut(in_->getStream(), "mp4");
 
-            return 0;
-        }
-
-        void Recorder::start_writer(){
-            if (cur_frame == 0) {
-                
-                sole::uuid u4 = sole::uuid4();
-                file_path_ = dir_ + "/" + u4.base62() + ".mp4";
-                out_->JustWriter(in_->getStream(), file_path_.c_str());
-                logIt("START RECORD %s", file_path_.c_str());
+            file_path_ = dir_ + "/" + sole::uuid4().base62() + ".mp4";
+            auto ret = out_->JustWriter(in_->getStream(), file_path_.c_str());
+            if (ret){
+                return 0;
             }
+
+            return -1;
         }
 
-        int Recorder::write_correctly(const avpacket &pkt){
+        int Recorder::write_correctly(const CPacket &pkt){
             //reader failed, break stream
             if(pkt.id == -1 && !pkt.data){
-                end_writer();
+                return -1;
+            }
+
+            if (cur_frame == end_frame){
                 return 1;
             }
-            // writer error, reinit writer
+
             int64_t cur = cur_frame++;
             AVPacket &op = pkt.data->getAVPacket();
             AVPacket np(op);
             av_copy_packet(&np, &op);
-            if(!out_->writeFrame(np, cur)){
-                av_packet_unref(&np);
-                end_writer();
-                return -1;
-            }
+            auto ret = out_->writeFrame(np, cur);
             av_packet_unref(&np);
+            if (!ret) return -1;
+            
             if(pkt.id == id_frame_){
-                file_frame_index_ = cur_frame-1;
+                id_frame_in_file_ = cur_frame-1;
             }
+            
             // logIt("WRITE FRAME ID: %d, RECORD ID: %d", pkt.id, id_frame_);
             return 0;
         }
 
         void Recorder::end_writer(){
-            if(cur_frame == -1) return;
+
             out_->endWriter();
-            logIt("INDEX %d, REAL-FRAME-ID %d, FILE %s, CURFrame %d, ENDFrame %d\n",
-                 file_frame_index_, id_frame_, file_path_.c_str(), cur_frame, end_frame);
-
-            //reinit cur_frame clear list pkt
-            {
-                std::lock_guard<std::mutex> locker(mutex_pkt_);
-                cur_frame = -1;
-                end_frame = minduration;
-                list_pkt_.clear();
-            }
-
-            //callback to frame index and path
-            if(func_rec_info_){
-                func_rec_info_(id_, file_frame_index_, file_path_);
-            }
-        }
-
-        void Recorder::run_thread(){
-            bool reinit_writer = false;
-            while(!stop_recorder_.load()){
-                if (reinit_writer) {
-                    while(!stop_recorder_.load()){
-                        if(init_writer() == 0)
-                            break;
-                        usleep(300000);
-                    }
-                    if(stop_recorder_.load()) break;
-                }
-
-                std::list<avpacket> pkts;
-                {
-                    std::unique_lock<std::mutex> locker(mutex_pkt_);
-                    auto status = cv_.wait_for(locker, std::chrono::seconds(10), [&]{
-                        return !list_pkt_.empty() || stop_recorder_.load();
-                    });
-
-                    if (!status){
-                        end_writer();
-                        error_occured_ = true;
-                        break;
-                    }
-                    if(stop_recorder_.load()){
-                        end_writer();
-                        break;
-                    }
-                    if(cur_frame == -1){
-                        continue;
-                    }
-                    list_pkt_.swap(pkts);
-                }
-
-                if (cur_frame == 0) {
-                    start_writer();
-                }
-
-                for(auto &i : pkts){
-                    if (cur_frame < end_frame){
-                        if(write_correctly(i) != 0){
-                            stop_recorder_.store(true);
-                            break;
-                        }
-                    }else{
-                        end_writer();
-                        stop_recorder_.store(true);
-                        break;
-                    }
-                }
-                
-            }
-
             if (out_){
                 delete out_;
                 out_ = NULL;
             }
-            // stop_recorder_.store(false);
+            {
+                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);
+
+            //callback to frame index and path
+            if(func_rec_info_){
+                func_rec_info_(id_,id_frame_in_file_, file_path_);
+            }
+
+        }
+
+        void Recorder::run_thread(){
+
+            while(!stop_recorder_.load()){
+
+                std::list<CPacket> pkts;
+                {
+                    std::unique_lock<std::mutex> locker(mutex_pkt_);
+                    auto status = cv_.wait_for(locker, std::chrono::seconds(3), [&]{
+                        return !list_pkt_.empty() || stop_recorder_.load();
+                    });
+
+                    if (!status || stop_recorder_.load()){
+                        error_occured_ = !status;
+                        break;
+                    }
+                    list_pkt_.swap(pkts);
+                }
+                
+                int ret = 0;
+                for(auto &i : pkts){
+                    ret = write_correctly(i);
+                    if (ret != 0){
+                        break;
+                    }
+                }
+
+                if (ret != 0){
+                    break;
+                }
+            }
+
+            stop_recorder_.store(true);
+            end_writer();
         }
 
         int Recorder::Run(const char* output, const int mind, const int maxd){
@@ -204,7 +178,7 @@
                 end_frame = minduration;
             }
 
-            logIt("minduration %d maxduration %d curduration %d", minduration, maxduration, end_frame);    
+            // logIt("minduration %d maxduration %d curduration %d", minduration, maxduration, end_frame);    
 
             thrd_.reset(new std::thread([&]{
                 run_thread();
@@ -215,38 +189,37 @@
         }
 
         int Recorder::FireRecorder(const int64_t &id){
-            if(cur_frame == -1){
+            if (stop_recorder_.load()) return -1;
+
+            if(id_frame_ == -1){
                 id_frame_ = id;
-                logIt("FIRST FIRE RECORD ID: %lld", id);
-                {
-                    std::lock_guard<std::mutex> locker(mutex_pkt_);
-                    cur_frame = 0;
-                    if (list_pkt_.size() > end_frame){
-                        end_frame = list_pkt_.size() + minduration/2;
-                        if (end_frame > maxduration)
-                            end_frame = maxduration;
-                    }
+
+                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;
                 }
-            }else if(end_frame - cur_frame > minduration/2 && end_frame < 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;
                 }
+                // logIt("PROLONG REC, cur_frame: %d, end_frame: %d", cur_frame, end_frame);
             }
             // logIt("FIRE REC FRAME ID: %lld", id);
             return 0;
         }
 
-        int Recorder::CachePacket(const avpacket &pkt){
+        int Recorder::PushPacket(const CPacket &pkt){
+            if (stop_recorder_.load()) return 0;
 
             std::lock_guard<std::mutex> locker(mutex_pkt_);
 
-            if(cur_frame == -1){
-                //error occur, stream break
-                if(pkt.id == -1 && pkt.data == nullptr){
-                    list_pkt_.clear();
-                    return -1;
-                }
+            if(id_frame_ == -1){
                 //wait I 
                 if (list_pkt_.empty()) {
                     AVPacket &avpkt = pkt.data->getAVPacket();
@@ -258,17 +231,43 @@
                 maybe_dump_gop();
 
                 list_pkt_.push_back(pkt);
+                // cv_.notify_one();
+
             }else{
                 list_pkt_.push_back(pkt);
                 cv_.notify_one();
             }
 
-            return 0;
+            return list_pkt_.size();
+        }
+
+        int Recorder::PushPackets(std::list<CPacket> &lst){
+            
+            if (stop_recorder_.load()) return 0;
+
+            std::lock_guard<std::mutex> locker(mutex_pkt_);
+            bool i = false;
+            for (auto &p : lst){
+                if (!i){
+                    AVPacket &avpkt = p.data->getAVPacket();
+                    if (!(avpkt.flags & AV_PKT_FLAG_KEY)){
+                        continue;
+                    }
+                    i = true;
+                }
+                
+                list_pkt_.push_back(p);
+            }
+            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() > maxduration) {
+            while (list_pkt_.size() > minduration) {
                 list_pkt_.pop_front();
                 while(!list_pkt_.empty()){
                     auto &cache = list_pkt_.front();

--
Gitblit v1.8.0