美文网首页
C代码线程锁结合工作Bookmark功能的实现

C代码线程锁结合工作Bookmark功能的实现

作者: Spirituality韬 | 来源:发表于2019-01-02 15:18 被阅读0次
    • 需求如下:播放刻录文件时退出时要求保留offset,下次在播放时seek。客户需求很简单,但是领导要求拓展功能,防止中途突然断电的这种情况,要求播放过程中每隔30s保存bookmark。

    接口已经封装这里只看一小部分,添加Bookmark代码

    JT_StatusCode_t JTAPIBOOKMARK_AddBookMark(PST_JTAPIBOOKMARK_Data pstData)
    {
    #ifdef ANDROID_PLATFORM
        JT_S8 path[128] = {0};
        JT_S8 *tmp = strrchr(pstData->file, '/');
        int size = tmp - pstData->file;
        memcpy(path, pstData->file, size);
        JTHDIVFS_ChangeCurrentDir(path);
    #else
        JTHDIVFS_ChangeCurrentDir("/");
    #endif
        JT_StatusCode_t status_code = JT_SUCCESS;
        JT_U8 msg[128];
        FILE * fd;
        system("mv Bookmark.xml bookmark.xml");
        fd = fopen("Bookmark.xml","a+");
        fputs("<Bookmark>\n",fd);
        memset(msg ,0 ,128);
        sprintf(msg ,"<filename>%s</filename>\n",pstData->file);
        fputs(msg ,fd);
        memset(msg ,0 ,128);
        sprintf(msg ,"<offset>%d</offset>\n", pstData->u64seekoffset);
        fputs(msg ,fd);
        fputs("</Bookmark>\n",fd);
        if (fclose(fd) != 0)
        {
            status_code = JT_FAILED;
        }
        system("cat bookmark.xml >> Bookmark.xml");
        system("rm -f bookmark.xml");
        JTHDIVFS_ChangeCurrentDir("/");
        return status_code;
    }
    

    代码很简单,因为之前都是在Linux平台上面使用,这里自己修改用Android 宏隔开,Bookmark.xml要求保存在同刻录文件目录下,BookMark结构体由filename(路径/文件名)和offset构成十分简单。

    整体逻辑也很容易实现,在播放时查询有没有Bookmark,如果有,seek offset,然后删除Bookmark(防止有多个Bookmark),退出时,保存Bookmark。

    现在就是拓展需求,要求每隔30s去添加Bookmark。开启个线程来做此操作,但是C代码来实现线程并没有什么经验,于是去网上查找的部分解决方案。

    static pthread_mutex_t mutex;
    static pthread_cond_t cond;
    static int flag = 0;
    //static char cur_play_name[256]; 
        
    void srpthread_init()
    {
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);
    }
     
    void srpthread_suspend()
    {
        pthread_mutex_lock(&mutex);
        flag--;
        pthread_mutex_unlock(&mutex);
    }
     
     
    void srpthread_resume()
    {
        pthread_mutex_lock(&mutex);
        flag++;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }
    
    static void StartBookMark(void *args)
    {
        PST_JTAPIBOOKMARK_Data pstData;
        JTAPIMedia_PlayStatusParams_t play_status ;
        pstData = (PST_JTAPIBOOKMARK_Data)JTOS_MemMalloc(sizeof(ST_JTAPIBOOKMARK_Data));
        while(1)
        {
            pthread_mutex_lock(&mutex);
            while(flag<=0)
            {
                pthread_cond_wait(&cond,&mutex);
            }
            pthread_mutex_unlock(&mutex);
            sleep(30);
            ....
        }
    }
    
    StartBookMark是线程执行函数,利用锁来控制线程的执行,逻辑大致是播放开始时resume 释放锁,将会开始执行sleep之后的代码(添加Bookmark)然后循环,stop时调用suspend,然后在pthread_cond_wait(&cond,&mutex)处等待下一次的resume
    

    感觉一切完美,没有什么毛病,自己也测试了一下功能OK吗,但是领导review一下代码,代码不够规范(什么可能编译不能通过,反正不太懂),要改用海思的接口来实现这个方案。

    莫名其妙地自己又去看海思的接口,然后看看在接口在其他部分是怎么调用的,最后找嵌入式同事帮忙。

    static JTOS_QueueId_t g_bookmark_queue = JT_INVALID_ID;
    static JTOS_TaskId_t g_bookmark_task = JT_INVALID_ID;
    static JTOS_MutexId_t bookmark_mutex_id = JT_INVALID_ID;
    
    static int flag = 0;
    
    #define mutex_Lock() \
    do { \
        if(JT_INVALID_ID == bookmark_mutex_id) \
        { \
             (void)JTOS_MutexCreate(&bookmark_mutex_id); \
        } \
         \
        if((JT_INVALID_ID == bookmark_mutex_id) || (JT_SUCCESS != JTOS_MutexLock(bookmark_mutex_id, JTOS_TIMEOUT_INFINITY))) \
        { \
            JT_ERROR(("JTOS_MutexCreate or JTOS_MutexLock ird_mutex_id Failed\n")); \
        } \
    }while(0)
    
    #define mutex_Unlock() \
    do { \
        if(JT_INVALID_ID == bookmark_mutex_id) \
        { \
            (void)JTOS_MutexCreate(&bookmark_mutex_id); \
        } \
             \
        if((JT_INVALID_ID == bookmark_mutex_id) || (JT_SUCCESS != JTOS_MutexUnlock(bookmark_mutex_id))) \
        { \
            JT_ERROR(("JTOS_MutexCreate or JTOS_MutexUnlock ird_mutex_id Failed\n")); \
        } \
    }while(0)   
    
     
    void srpthread_suspend()
    {
        mutex_Lock();
        flag--;
        mutex_Unlock();
    }
     
     
    void srpthread_resume()
    {
        JT_U32 au32Msg[4] = {0};
        mutex_Lock();
        flag++;
        JTOS_QueueSend(g_bookmark_queue, au32Msg, JTOS_TIMEOUT_IMMEDIATE);
        mutex_Unlock();
    }
    
    static void StartBookMark(void *args)
    {
        JT_StatusCode_t enStatusCode = JT_SUCCESS;
        JT_U32 au32Msg[4] = {0};
        PST_JTAPIBOOKMARK_Data pstData;
        JTAPIMedia_PlayStatusParams_t play_status ;
        pstData = (PST_JTAPIBOOKMARK_Data)JTOS_MemMalloc(sizeof(ST_JTAPIBOOKMARK_Data));
        while(1)
        {
            while(flag <= 0)
            {
                enStatusCode = JTOS_QueueReceive(g_bookmark_queue, au32Msg, JTOS_TIMEOUT_INFINITY);
            }
            ...
        }
    }
    

    逻辑和之前差不多只是,换用了海思的接口,利用Send 、Receive形式来使用等待操作

    相关文章

      网友评论

          本文标题:C代码线程锁结合工作Bookmark功能的实现

          本文链接:https://www.haomeiwen.com/subject/lapzlqtx.html