This describe GM8126 ioctl functions: update-record-setting.c

GM8126 DVR

update-record-setting.c

/**
 * this sample code implement main bitstream + sub1 bitstream + sub2 bitstream update record function  
 * after record 10 seconds, update main bitstream record.
 * after record 15 seconds, update sub1 bitstream record.
 * after record 25 seconds, finish record.
 * 
 * (1)  for H264 record, file format please indicate xxx.h264
 *      for MPEG record, file format please indicate xxx.m4v
 *      for MOTION JPEG record, file format please indicate xxx.jpg
 * (2)  for H264 record, max_quant < 51, 1 < min_quant 
 *      for MPEG record, max_quant < 31, 1 < min_quant 
 * (3)  for example, if you only updat "frame_rate", 
 *      paramter "bit_rate" don't need to update, 
 *      please assign enc_parm.update_parm.bit_rate = GMVAL_DO_NOT_CARE;
 *      and so on.
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include "dvr_common_api.h"
#include "dvr_enc_api.h"
#include "gmavi_api.h"

int dvr_fd = 0;
int enc_fd = 0;

//test record
unsigned char *bs_buf;
HANDLE  rec_file;
int enc_buf_size;
int sub1_bs_buf_offset;
int sub2_bs_buf_offset;
int bs_buf_snap_offset;
struct pollfd rec_fds;
char file_name[128];

//sub record
char sub_rec_filename[DVR_ENC_REPD_BT_NUM - 1][64];
int multi_bitstream = 0;
HANDLE  rec_sub_bs_file[DVR_ENC_REPD_BT_NUM - 1];

/**
 * @brief main function
 * @return 0 on success, !0 on error
 */
int main(int argc, char *argv[])
{
    int ret = 0, ch_num = 0, sub1_num = 1, sub2_num = 2;    
    dvr_enc_channel_param   ch_param;    
    ReproduceBitStream sub1_param; 
    ReproduceBitStream sub2_param; 
    EncParam_Ext3 enc_param_ext = {0};     
    EncParam_Ext3 enc_param_ext1 = {0};    
    EncParam_Ext3 enc_param_ext2 = {0};        
    dvr_enc_control  enc_ctrl;
    dvr_enc_control  enc_update;
    dvr_enc_control  sub_update;
    dvr_enc_queue_get   data;
    unsigned char *buf;
    int buf_size;      
    FuncTag tag;        
    struct timeval t1,t2;  
    char tmp_str[128];
    int flag = 0, sub_flag = 0;                 

    dvr_fd = open("/dev/dvr_common", O_RDWR);   //open_dvr_common
    
    enc_fd = open("/dev/dvr_enc", O_RDWR);      //open_dvr_encode
            
    //set dvr encode source parameter
    ch_param.src.input_system = MCP_VIDEO_NTSC;
    ch_param.src.channel = ch_num;
    ch_param.src.enc_src_type = ENC_TYPE_FROM_CAPTURE;
    
    ch_param.src.dim.width = 1280;
    ch_param.src.dim.height = 720;
    
    ch_param.src.di_mode = LVFRAME_EVEN_ODD;
    ch_param.src.mode = LVFRAME_FRAME_MODE;
    ch_param.src.dma_order = DMAORDER_PACKET;
    ch_param.src.scale_indep = CAPSCALER_NOT_KEEP_RATIO;
    ch_param.src.input_system = MCP_VIDEO_NTSC;
    ch_param.src.color_mode = CAPCOLOR_YUV422;
    
    ch_param.src.vp_param.is_3DI = FALSE;
    ch_param.src.vp_param.is_denoise = FALSE;
    ch_param.src.vp_param.denoise_mode = GM3DI_FIELD;
    ///////////////////////////////////////////////////////////////
    //set dvr encode main bitstream parameter
    ch_param.main_bs.enabled = DVR_ENC_EBST_ENABLE;
    ch_param.main_bs.out_bs = 0;
    ch_param.main_bs.enc_type = ENC_TYPE_H264;    
    ch_param.main_bs.is_blocked = FALSE;
    ch_param.main_bs.en_snapshot = DVR_ENC_EBST_DISABLE;
    
    ch_param.main_bs.dim.width = 1280;
    ch_param.main_bs.dim.height = 720;
    
    //set main bitstream encode parameter
    ch_param.main_bs.enc.input_type = ENC_INPUT_H2642D;
    ch_param.main_bs.enc.frame_rate = 15;
    ch_param.main_bs.enc.bit_rate = 1048576;
    ch_param.main_bs.enc.ip_interval = 60;
    ch_param.main_bs.enc.init_quant = 25;
    ch_param.main_bs.enc.max_quant = 51;
    ch_param.main_bs.enc.min_quant = 1;
    ch_param.main_bs.enc.is_use_ROI = FALSE;
    ch_param.main_bs.enc.ROI_win.x = 0;
    ch_param.main_bs.enc.ROI_win.y = 0;
    ch_param.main_bs.enc.ROI_win.width = 320;
    ch_param.main_bs.enc.ROI_win.height = 240;
    
    //set main bitstream scalar parameter
    ch_param.main_bs.scl.src_fmt = SCALE_YUV422;
    ch_param.main_bs.scl.dst_fmt = SCALE_YUV422;
    ch_param.main_bs.scl.scale_mode = SCALE_LINEAR;
    ch_param.main_bs.scl.is_dither = FALSE;
    ch_param.main_bs.scl.is_correction = FALSE;
    ch_param.main_bs.scl.is_album = TRUE;
    ch_param.main_bs.scl.des_level = 0;
    
    //set main bitstream snapshot parameter
    ch_param.main_bs.snap.sample = JCS_yuv420;   
    ch_param.main_bs.snap.RestartInterval = 0;   
    ch_param.main_bs.snap.u82D = JENC_INPUT_MP42D;   
    ch_param.main_bs.snap.quality = 70;   
    
    //associate the ext. structure                      
    ch_param.main_bs.enc.ext_size = DVR_ENC_MAGIC_ADD_VAL(sizeof(enc_param_ext));
    ch_param.main_bs.enc.pext_data = &enc_param_ext;
    
    enc_param_ext.feature_enable = 0;      //CBR

    ////////////////////////////////////////////////////////////////
    //sub1 bitstream    
    memset(&sub1_param, 0x0, sizeof(ReproduceBitStream));    

    sub1_param.enabled = DVR_ENC_EBST_ENABLE;
    sub1_param.out_bs = 1;
    sub1_param.enc_type = ENC_TYPE_H264;    
    sub1_param.is_blocked = FALSE;
    sub1_param.en_snapshot = DVR_ENC_EBST_DISABLE;
    
    sub1_param.dim.width = 1280;
    sub1_param.dim.height = 720;
    
    sub1_param.enc.input_type = ENC_INPUT_H2642D;
    sub1_param.enc.frame_rate = 15;
    sub1_param.enc.bit_rate = 200000;
    sub1_param.enc.ip_interval = 30;
    sub1_param.enc.init_quant = 30;
    sub1_param.enc.max_quant = 51;
    sub1_param.enc.min_quant = 1;
    sub1_param.enc.is_use_ROI = FALSE;
    sub1_param.enc.ROI_win.x = 0;
    sub1_param.enc.ROI_win.y = 0;
    sub1_param.enc.ROI_win.width = 320;
    sub1_param.enc.ROI_win.height = 240;
    
    //set sub1 bitstream scalar parameter
    sub1_param.scl.src_fmt = SCALE_YUV422;
    sub1_param.scl.dst_fmt = SCALE_YUV422;
    sub1_param.scl.scale_mode = SCALE_LINEAR;
    sub1_param.scl.is_dither = FALSE;
    sub1_param.scl.is_correction = FALSE;
    sub1_param.scl.is_album = TRUE;
    sub1_param.scl.des_level = 0;
    
    //set sub1 bitstream snapshot parameter
    sub1_param.snap.sample = JCS_yuv420;   
    sub1_param.snap.RestartInterval = 0;   
    sub1_param.snap.u82D = JENC_INPUT_MP42D;   
    sub1_param.snap.quality = 70;   
    //associate the ext. structure                      
    sub1_param.enc.ext_size = DVR_ENC_MAGIC_ADD_VAL(sizeof(enc_param_ext1));
    sub1_param.enc.pext_data = &enc_param_ext1;            
        
    enc_param_ext1.feature_enable &= ~DVR_ENC_MJPEG_FUNCTION;
            
    //////////////////////////////////////////////////////////////////////
    //sub2 bitstream
    memset(&sub2_param, 0x0, sizeof(ReproduceBitStream));    

    sub2_param.enabled = DVR_ENC_EBST_ENABLE;
    sub2_param.out_bs = 2;
    sub2_param.enc_type = ENC_TYPE_H264;    
    sub2_param.is_blocked = FALSE;
    sub2_param.en_snapshot = DVR_ENC_EBST_DISABLE;
    
    sub2_param.dim.width = 1280;
    sub2_param.dim.height = 720;
    
    sub2_param.enc.input_type = ENC_INPUT_H2642D;
    sub2_param.enc.frame_rate = 15;
    sub2_param.enc.bit_rate = 131072;
    sub2_param.enc.ip_interval = 30;
    sub2_param.enc.init_quant = 25;
    sub2_param.enc.max_quant = 51;
    sub2_param.enc.min_quant = 1;
    sub2_param.enc.is_use_ROI = FALSE;
    sub2_param.enc.ROI_win.x = 0;
    sub2_param.enc.ROI_win.y = 0;
    sub2_param.enc.ROI_win.width = 160;
    sub2_param.enc.ROI_win.height = 128;
    
    //set sub2 bitstream scalar parameter
    sub2_param.scl.src_fmt = SCALE_YUV422;
    sub2_param.scl.dst_fmt = SCALE_YUV422;
    sub2_param.scl.scale_mode = SCALE_LINEAR;
    sub2_param.scl.is_dither = FALSE;
    sub2_param.scl.is_correction = FALSE;
    sub2_param.scl.is_album = TRUE;
    sub2_param.scl.des_level = 0;
    
    //set sub2 bitstream snapshot parameter
    sub2_param.snap.sample = JCS_yuv420;   
    sub2_param.snap.RestartInterval = 0;   
    sub2_param.snap.u82D = JENC_INPUT_MP42D;   
    sub2_param.snap.quality = 70;   
    //associate the ext. structure                      
    sub2_param.enc.ext_size = DVR_ENC_MAGIC_ADD_VAL(sizeof(enc_param_ext2));
    sub2_param.enc.pext_data = &enc_param_ext2;
    
    enc_param_ext2.feature_enable &= ~DVR_ENC_MJPEG_FUNCTION;
    
    //////////////////////////////////////////////////////////////////////    
    //set update recode parameter   
    memset(&enc_update, 0x0, sizeof(dvr_enc_control));    
    enc_update.stream = 0;
    enc_update.update_parm.stream_enable = 1;
    enc_update.update_parm.frame_rate = 30;
    enc_update.update_parm.bit_rate = 262144;
    enc_update.update_parm.ip_interval = 60;
    enc_update.update_parm.dim.width = 1280;  
    enc_update.update_parm.dim.height = 720;
    enc_update.update_parm.src.di_mode = LVFRAME_EVEN_ODD;
    enc_update.update_parm.src.mode = LVFRAME_FRAME_MODE;
    enc_update.update_parm.src.scale_indep = CAPSCALER_NOT_KEEP_RATIO;
    enc_update.update_parm.src.is_3DI = FALSE;
    enc_update.update_parm.src.is_denoise = FALSE;
    enc_update.update_parm.init_quant = 25;
    enc_update.update_parm.max_quant = 51;
    enc_update.update_parm.min_quant = 1;
    
    //////////////////////////////////////////////////////////////////////    
    //set sub update recode parameter   
    memset(&sub_update, 0x0, sizeof(dvr_enc_control));    
    sub_update.stream = 1;
    sub_update.update_parm.stream_enable = 1;
    sub_update.update_parm.frame_rate = 30;
    sub_update.update_parm.bit_rate = 131072;
    sub_update.update_parm.ip_interval = 60;
    sub_update.update_parm.dim.width = 1280;  
    sub_update.update_parm.dim.height = 720;
    sub_update.update_parm.src.di_mode = LVFRAME_EVEN_ODD;
    sub_update.update_parm.src.mode = LVFRAME_FRAME_MODE;
    sub_update.update_parm.src.scale_indep = CAPSCALER_NOT_KEEP_RATIO;
    sub_update.update_parm.src.is_3DI = FALSE;
    sub_update.update_parm.src.is_denoise = FALSE;
    sub_update.update_parm.init_quant = 25;
    sub_update.update_parm.max_quant = 51;
    sub_update.update_parm.min_quant = 1;
    //////////////////////////////////////////////////////////////////////    
    ioctl(enc_fd, DVR_ENC_SET_CHANNEL_PARAM, &ch_param);
    
    ioctl(enc_fd, DVR_ENC_QUERY_OUTPUT_BUFFER_SIZE, &enc_buf_size);
    
    ioctl(enc_fd, DVR_ENC_QUERY_OUTPUT_BUFFER_SUB1_BS_OFFSET, &sub1_bs_buf_offset);
    
    ioctl(enc_fd, DVR_ENC_QUERY_OUTPUT_BUFFER_SUB2_BS_OFFSET, &sub2_bs_buf_offset);
    
    ioctl(enc_fd, DVR_ENC_QUERY_OUTPUT_BUFFER_SNAP_OFFSET, &bs_buf_snap_offset);
        
    bs_buf = (unsigned char*) mmap(NULL, enc_buf_size, PROT_READ|PROT_WRITE, 
                                          MAP_SHARED, enc_fd, 0);
    
    ioctl(enc_fd, DVR_ENC_SET_SUB_BS_PARAM, &sub1_param);        
    
    ioctl(enc_fd, DVR_ENC_SET_SUB_BS_PARAM, &sub2_param);        
    /////////////////////////////////////////////////////////////////            
    //main bitstream record start
    memset(&enc_ctrl, 0x0, sizeof(dvr_enc_control));                    
    enc_ctrl.command = ENC_START;
    enc_ctrl.stream = 0;    
    ret = ioctl(enc_fd, DVR_ENC_CONTROL, &enc_ctrl);
    
    // set function tag paremeter to dvr graph level
    FN_RESET_TAG(&tag);
    FN_SET_REC_CH(&tag, ch_num);
    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);    
    ///////////////////////////////////////////////////////////////    
    multi_bitstream = DVR_ENC_EBST_ENABLE;    
    //sub1 bitstream record start
    memset(&enc_ctrl, 0x0, sizeof(dvr_enc_control));                    
    enc_ctrl.command = ENC_START;
    enc_ctrl.stream = 1;    
    ret = ioctl(enc_fd, DVR_ENC_CONTROL, &enc_ctrl);
    
    // set function tag paremeter to dvr graph level
    FN_RESET_TAG(&tag);    
    FN_SET_SUB1_REC_CH(&tag, ch_num);
    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);
    ///////////////////////////////////////////////////////////////         
    //sub2 bitstream record start
    memset(&enc_ctrl, 0x0, sizeof(dvr_enc_control));                    
    enc_ctrl.command = ENC_START;
    enc_ctrl.stream = 2;    
    ret = ioctl(enc_fd, DVR_ENC_CONTROL, &enc_ctrl);
    
    // set function tag paremeter to dvr graph level
    FN_RESET_TAG(&tag);    
    FN_SET_SUB2_REC_CH(&tag, ch_num);
    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);
    ///////////////////////////////////////////////////////////////         
    //main bitstream    
    sprintf(file_name, "CH%d_video_%d", 0, 0);      
    sprintf(tmp_str, "%s.h264", file_name);
    rec_file = fopen ( tmp_str , "wb+" );
    ///////////////////////////////////////////////////////////////
    //sub1 bitstream    
    sprintf(sub_rec_filename[sub1_num - 1], "CH%d_Sub%d_Video_%03d", ch_num, sub1_num, 001);        
    sprintf(tmp_str, "%s.h264", sub_rec_filename[sub1_num - 1]);
    rec_sub_bs_file[sub1_num - 1] = fopen ( tmp_str , "wb+" );
    ///////////////////////////////////////////////////////////////
    //sub2 bitstream
    sprintf(sub_rec_filename[sub2_num - 1], "CH%d_Sub%d_Video_%03d", ch_num, sub2_num, 001);        
    sprintf(tmp_str, "%s.h264", sub_rec_filename[sub2_num - 1]);
    rec_sub_bs_file[sub2_num - 1] = fopen ( tmp_str , "wb+" );
    ///////////////////////////////////////////////////////////////
    gettimeofday(&t1, NULL);        
    
    while(1) {          
            // prepare to select(or poll)
            rec_fds.fd = enc_fd;      
            rec_fds.revents = 0;
            rec_fds.events = POLLIN_MAIN_BS;
            
            if (multi_bitstream == DVR_ENC_EBST_ENABLE)
                rec_fds.events |= (POLLIN_SUB1_BS | POLLIN_SUB2_BS);
            
            poll(&rec_fds, 1, 500);     
            
            if (rec_fds.revents & POLLIN_SUB1_BS) {                
                ret = ioctl(enc_fd, DVR_ENC_QUEUE_GET_SUB1_BS, &data); 
                if(ret < 0)    
                    continue;
                
                if(data.new_bs) {
                    printf("Change file2\n");
                    fclose(rec_sub_bs_file[sub1_num - 1]);
                    sprintf(sub_rec_filename[sub1_num - 1], "CH%d_Sub%d_Video_%03d_update", ch_num, sub1_num, 001);
                    sprintf(tmp_str, "%s.h264", sub_rec_filename[sub1_num - 1]);
                    rec_sub_bs_file[sub1_num - 1] = fopen ( tmp_str , "wb+" );      
                }
                   
                buf = bs_buf + sub1_bs_buf_offset + data.bs.offset;         
                buf_size = data.bs.length;
    
                fwrite (buf , 1 , buf_size , rec_sub_bs_file[sub1_num - 1]);
                fflush(rec_sub_bs_file[sub1_num - 1]);  
                ioctl(enc_fd, DVR_ENC_QUEUE_PUT, &data);   
            }    
            
            if (rec_fds.revents & POLLIN_SUB2_BS) {                
                ret = ioctl(enc_fd, DVR_ENC_QUEUE_GET_SUB2_BS, &data); 
                if(ret < 0)    
                    continue;
                   
                buf = bs_buf + sub2_bs_buf_offset + data.bs.offset;         
                buf_size = data.bs.length;
    
                fwrite (buf , 1 , buf_size , rec_sub_bs_file[sub2_num - 1]);
                fflush(rec_sub_bs_file[sub2_num - 1]);  
                ioctl(enc_fd, DVR_ENC_QUEUE_PUT, &data);   
            }
            
            if (!(rec_fds.revents & POLLIN_MAIN_BS)) 
                continue;
    
            // get dataout buffer   
            ret = ioctl(enc_fd, DVR_ENC_QUEUE_GET, &data);
            if(ret < 0)    
                continue;
            
            if(data.new_bs) {
                printf("Change file\n");
                fclose(rec_file);
                sprintf(file_name, "CH%d_video_%d_update", ch_num, ch_num);                
                sprintf(tmp_str, "%s.h264", file_name);
                rec_file = fopen ( tmp_str , "wb+" );       
            }
                    
            buf = bs_buf + data.bs.offset;
            buf_size = data.bs.length;
    
            ret = fwrite (buf , 1 , buf_size , rec_file);
            fflush(rec_file);  
            ioctl(enc_fd, DVR_ENC_QUEUE_PUT, &data);   
                
            gettimeofday(&t2, NULL);
        
            if ((t2.tv_sec - t1.tv_sec) == 10) {    //<record for 10 seconds. then update record setting
                if(flag == 0){
                   flag = 1;
                    enc_update.command = ENC_UPDATE;
                    ioctl(enc_fd, DVR_ENC_CONTROL, &enc_update);
    
                    FN_RESET_TAG(&tag);
                    FN_SET_REC_CH(&tag, ch_num);    
                    //FN_SET_SUB1_REC_CH(&tag, ch_num);
                    //FN_SET_SUB2_REC_CH(&tag, ch_num);   

                    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);                          
                }
            }
            
            if ((t2.tv_sec - t1.tv_sec) == 15) {    //<record for 15 seconds. then update sub bitstream record setting
                if(sub_flag == 0){
                    sub_flag = 1;                    
                    sub_update.command = ENC_UPDATE;
                    ioctl(enc_fd, DVR_ENC_CONTROL, &sub_update);
    
                    FN_RESET_TAG(&tag);                    
                    FN_SET_SUB1_REC_CH(&tag, ch_num);                    

                    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);                          
                }
            }
            
            if ((t2.tv_sec - t1.tv_sec) == 25) {    //<record for 25 seconds. then finish record.
                fclose(rec_file);      
                fclose(rec_sub_bs_file[sub1_num - 1]);       
                fclose(rec_sub_bs_file[sub2_num - 1]);       
                break;               
            }       
    }
        
    //record stop
    memset(&enc_ctrl, 0x0, sizeof(dvr_enc_control));    
    enc_ctrl.stream = 0;    // for all main and sub 
    enc_ctrl.command = ENC_STOP;
    ioctl(enc_fd, DVR_ENC_CONTROL, &enc_ctrl);
    
    FN_RESET_TAG(&tag);
    FN_SET_REC_CH(&tag, ch_num);
    FN_SET_SUB1_REC_CH(&tag, ch_num);
    FN_SET_SUB2_REC_CH(&tag, ch_num);
    ioctl(dvr_fd, DVR_COMMON_APPLY, &tag);    
    munmap((void*)bs_buf, enc_buf_size);      
    
    printf("----------------------------------\n");
    printf(" Record finish\n");
    printf("----------------------------------\n");    
    
    close(enc_fd);      //close_dvr_encode    
    close(dvr_fd);      //close_dvr_common

    return 0;
}











Generated on Wed Jun 15 2011 15:51:00 for This describe GM8126 ioctl functions by  doxygen 1.7.1