播放器缓存队列bug解决方案

背景

我在开发一个播放器的缓存队列时,遇到一个bug,导致包和帧无法被下一个模块读取

找了半天,原来是队列中的包和帧数据要进行内容的刷新暂存

包数据和帧数据不能直接放入队列

cpp 复制代码
//入队,包进队列
int AVPacketQueue::Push(AVPacket *val,int timeout)
{
    //加作用域互斥锁:资源同一时间只能有一个线程访问,作用域结束自动释放锁
    //std::lock_guard<std::mutex> lock(mutex_);

    std::unique_lock<std::mutex> lock(mutex_);//这里必须要加手动作用域互斥锁,因为wait_for需要作用域


    //因为是包队列-双链表
    //如果队满了,等待timeout时间
    if(duration_cur>=duration_MAX) {
        // 等待pop或者超时唤醒
        cond_.wait_for(lock, std::chrono::milliseconds(timeout), [this] {
            return duration_cur<duration_MAX;
        });
    }

    //如果依然队满,就直接返回-1
    if(duration_cur>=duration_MAX){
        return -1;
    }

    //入队:出现问题的代码,这里是直接把包指针存放到队列中了,但是在ffmpeg中不能直接存放,必须要先搞一个新包,然后刷新暂存数据
    queue_.push(val);

    //增加队列缓存时间,强转成ms
    long ms = static_cast<long>(av_rescale(val->duration, 1000, AV_TIME_BASE));

    this->duration_cur+=ms;

    cond_.notify_one();//条件变量:通知其他线程可以继续执行
    return 0;
}

解决方案

cpp 复制代码
//入队,包进队列
int AVPacketQueue::Push(AVPacket *val,int timeout)
{
    //加作用域互斥锁:资源同一时间只能有一个线程访问,作用域结束自动释放锁
    //std::lock_guard<std::mutex> lock(mutex_);

    std::unique_lock<std::mutex> lock(mutex_);//这里必须要加手动作用域互斥锁,因为wait_for需要作用域


    //因为是包队列-双链表
    //如果队满了,等待timeout时间
    if(duration_cur>=duration_MAX) {
        // 等待pop或者超时唤醒
        cond_.wait_for(lock, std::chrono::milliseconds(timeout), [this] {
            return duration_cur<duration_MAX;
        });
    }

    //如果依然队满,就直接返回-1
    if(duration_cur>=duration_MAX){
        return -1;
    }

    //入队:一定注意,必须要重新申请空间,不然会指向同一段地址,而且后面要释放对应的数据包av_packet_free
    AVPacket *tmp_packet = av_packet_alloc();
    av_packet_move_ref(tmp_packet, val);
    queue_.push(tmp_packet);

    //增加队列缓存时间,强转成ms
    long ms = static_cast<long>(av_rescale(val->duration, 1000, AV_TIME_BASE));

    this->duration_cur+=ms;

    cond_.notify_one();//条件变量:通知其他线程可以继续执行
    return 0;
}
相关推荐
JanelSirry5 小时前
缓存击穿,缓存穿透,缓存雪崩的原因和解决方案(或者说使用缓存的过程中有没有遇到什么问题,怎么解决的)
缓存
我命由我1234513 小时前
Java 并发编程 - Delay(Delayed 概述、Delayed 实现、Delayed 使用、Delay 缓存实现、Delayed 延迟获取数据实现)
java·开发语言·后端·缓存·java-ee·intellij-idea·intellij idea
北城以北888813 小时前
SSM--MyBatis框架之缓存
java·缓存·intellij-idea·mybatis
JH307316 小时前
Redis 中被忽视的“键过期策略”与内存回收机制
数据库·redis·缓存
Microsoft Word16 小时前
Redis常见面试题
数据库·redis·缓存
dudke16 小时前
c#实现redis的调用与基础类
数据库·redis·缓存
小马爱打代码18 小时前
MyBatis:进阶 - 动态 SQL、关联查询与缓存
sql·缓存·mybatis
tuokuac1 天前
ps -ef | grep redis
数据库·redis·缓存
⑩-1 天前
如何保证Redis和Mysql数据缓存一致性?
java·数据库·redis·mysql·spring·缓存·java-ee
刘一说1 天前
深入理解 Spring Boot 中的 Redis 缓存集成:从基础配置到高可用实践
spring boot·redis·缓存