1背景
上一篇结尾的时候只处理了一帧,这一篇继续把后续的补上。
2步骤
2.1 视频循环播放
hthread.h中取消run中while注释
virtual void run(){
while(status!= STOP){
doTask();
}
}
hframebuf.cpp 中修改pop和push如下
int HFrameBuf::push(HFrame *pFrame)
{
std::lock_guard<std::mutex> locker(this->mutex);
if(pFrame->isNull())
return -10;
if(frames.size()>=(size_t)cache_num){
HFrame frame = std::move(frames.front()); // 移动所有权
frames.pop_front(); // 先移除,避免析构冲突
free(frame.buf.len); // 安全释放内存
frame.buf = {nullptr, 0}; // 必须置空!
if (frame.userdata) {
::free(frame.userdata);
frame.userdata = nullptr;
}
}
int ret=0;
if(isNull()){
resize(pFrame->buf.len*cache_num);
ret=1;
}
HFrame frame;
frame.buf.base=alloc(pFrame->buf.len);
frame.buf.len=pFrame->buf.len;
frame.copy(*pFrame);
frames.push_back(frame);
return ret;
}
int HFrameBuf::pop(HFrame *pFrame)
{
std::lock_guard<std::mutex> locker(this->mutex);
if(isNull())
return -10;
if(frames.size()==0){
return -20;
}
HFrame frame = std::move(frames.front());
frames.pop_front();
if(frame.isNull()){
return -30;
}
pFrame->copy(frame);
free(frame.buf.len);
frame.buf={nullptr,0};
if(frame.userdata){
::free(frame.userdata);
frame.userdata=nullptr;
}
return 0;
}
2.2 循环效果
2.3 视频播放不正常的bug修复
上面换个有声音的视频重新播放
上面因为生产太快,缓存就10帧,满了会替换旧的一帧。。当然如果没播放就丢掉了。。。
hframebuf.h中添加
std::condition_variable buffer_not_full;
std::condition_variable buffer_not_empty;
hframebuf.cpp 中修改如下
int HFrameBuf::push(HFrame *pFrame)
{
std::unique_lock<std::mutex> locker(this->mutex);
if(pFrame->isNull())
return -10;
this->buffer_not_full.wait(locker,[this](){
return frames.size() < cache_num;
});
if(frames.size()>=(size_t)cache_num){
HFrame frame = std::move(frames.front()); // 移动所有权
frames.pop_front(); // 先移除,避免析构冲突
free(frame.buf.len); // 安全释放内存
frame.buf = {nullptr, 0}; // 必须置空!
if (frame.userdata) {
::free(frame.userdata);
frame.userdata = nullptr;
}
}
int ret=0;
if(isNull()){
resize(pFrame->buf.len*cache_num);
ret=1;
}
HFrame frame;
frame.buf.base=alloc(pFrame->buf.len);
frame.buf.len=pFrame->buf.len;
frame.copy(*pFrame);
frames.push_back(frame);
locker.unlock();
this->buffer_not_empty.notify_one();
return ret;
}
int HFrameBuf::pop(HFrame *pFrame)
{
std::unique_lock<std::mutex> locker(this->mutex);
if(isNull())
return -10;
if(frames.size()==0){
return -20;
}
this->buffer_not_empty.wait(locker, [this] {
return !frames.empty();
});
HFrame frame = std::move(frames.front());
frames.pop_front();
if(frame.isNull()){
return -30;
}
pFrame->copy(frame);
free(frame.buf.len);
frame.buf={nullptr,0};
if(frame.userdata){
::free(frame.userdata);
frame.userdata=nullptr;
}
locker.unlock();
this->buffer_not_full.notify_one();
return 0;
}
void HFrameBuf::clear()
{
std::unique_lock<std::mutex> locker(this->mutex);
frames.clear();
HRingBuf::clear();
}
更换锁