解決三星ARM11開發板攝像頭採集程序源碼出現的Bug

市面上比較流行的飛凌OK6410A/飛凌OK6410B或者是友善之臂的arm11開發板亦或是華天正的arm11開發板使用的都是三星公司的32位CPU。
前陣子發現了這些開發板視頻採集方面存在的共同Bug:當用MFC壓縮攝像頭採集的H264視頻的時候,由於這些開發板用的是三星公司提供的攝像頭壓縮源碼,這個源碼存在一個Bug,在採集視頻的時候輸入“e”採集視頻,輸入“x”退出採集,可是連續採集視頻的時候,也就是連續輸入“e”時出現錯誤“segment…”。
首先三星的源碼是:

while (1) {

        key = getchar();

        if(key == 'e')
            encoding_flag = TRUE;
        else if(key == 'x') {
            finished = 1;
            pthread_exit(0);
        }

        if (encoding_flag == TRUE) {

            pthread_mutex_lock(&mutex);

            handle = mfc_encoder_init(LCD_WIDTH, LCD_HEIGHT, 30, 1000, 30);

            sprintf(&file_name[0], "Cam_encoding_%dx%d-%d.264", LCD_WIDTH, LCD_HEIGHT, ++film_cnt);
            printf("Name of encoded file : Cam_encoding_%dx%d-%d.264\n", LCD_WIDTH, LCD_HEIGHT, film_cnt);
            fflush(stdout);

            /* file create/open, note to "wb" */
            encoded_fp = fopen(&file_name[0], "wb");
            if (!encoded_fp) {
                perror(&file_name[0]);
            }

            /* Codec start */
            start = 1;
            ret = ioctl(cam_c_fp, VIDIOC_STREAMON, &start);
            if (ret < 0) {
                printf("V4L2 : ioctl on VIDIOC_STREAMON failed\n");
                exit(1);
            }

            for(yuv_cnt=0; yuv_cnt < frame_num; yuv_cnt++){
                frame_count++;

                /* read from camera device */
                if (read(cam_c_fp, g_yuv, YUV_FRAME_BUFFER_SIZE) < 0) {
                    perror("read()");
                }


                if(frame_count == 1)
                    encoded_buf = mfc_encoder_exe(handle, g_yuv, YUV_FRAME_BUFFER_SIZE, 1, &encoded_size);
                else
                    encoded_buf = mfc_encoder_exe(handle, g_yuv, YUV_FRAME_BUFFER_SIZE, 0, &encoded_size);          

                fwrite(encoded_buf, 1, encoded_size, encoded_fp);
            }

            frame_count = 0;

            /* Codec stop */
            start = 0;
            ret = ioctl(cam_c_fp, VIDIOC_STREAMOFF, &start);
            if (ret < 0) {
                printf("V4L2 : ioctl on VIDIOC_STREAMOFF failed\n");
                exit(1);
            }

            printf("100 frames were encoded\n");
            printf("\nSelect ==> ");

            mfc_encoder_free(handle);

            fclose(encoded_fp);

            encoding_flag= FALSE;

            pthread_mutex_unlock(&mutex);
        }
    }

上述源碼將壓縮好的數據寫入文件,每次輸入”e“則重新生成一個新文件,從中不難看出每次生成一個文件之後執行了:

ret = ioctl(cam_c_fp, VIDIOC_STREAMOFF, &start);
            if (ret < 0) {
                printf("V4L2 : ioctl on VIDIOC_STREAMOFF failed\n");
                exit(1);
            }

這段代碼的作用是關閉視頻流,這兒關閉了視頻流之後實際上是關閉了攝像頭,所以如果要再次輸入”e“之後重新壓縮視頻成H264文件需要重新初始化攝像頭。
因此,如果要重複壓縮視頻只需簡單地將這句刪除即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章