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

2019-01-02  本文已影响0人  Spirituality韬

接口已经封装这里只看一小部分,添加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形式来使用等待操作

上一篇下一篇

猜你喜欢

热点阅读