//initialize the x264 encoder void init_encoder(struct camera *cam) { h264_encoder = NULL; //get memory for the encoder if (NULL == (h264_encoder = (struct encoder *)malloc(sizeof(struct encoder)))) { printf("can't get memory for X264 encoder struct\n"); exit(EXIT_FAILURE); } compress_begin(FRAME_WIDTH, FRAME_HEIGHT); h264_buf = NULL; //get memory for h264 buffer field if (NULL == ( h264_buf = (uint8 *)malloc(sizeof(uint8) * cam->width * cam->height * 3))) { printf("out of memory\n"); exit(EXIT_FAILURE); } }
/* This little puppy handles the calls which vfw programs send out to the codec */ LRESULT WINAPI DriverProc( DWORD dwDriverId, HDRVR hDriver, UINT uMsg, LPARAM lParam1, LPARAM lParam2 ) { CODEC *codec = (CODEC *)dwDriverId; switch( uMsg ) { case DRV_LOAD: case DRV_FREE: return DRV_OK; case DRV_OPEN: { ICOPEN *icopen = (ICOPEN *)lParam2; if( icopen != NULL && icopen->fccType != ICTYPE_VIDEO ) return DRV_CANCEL; if( ( codec = malloc( sizeof( CODEC ) ) ) == NULL ) { if( icopen != NULL ) icopen->dwError = ICERR_MEMORY; return 0; } memset( codec, 0, sizeof( CODEC ) ); config_reg_load( &codec->config ); codec->h = NULL; if( icopen != NULL ) icopen->dwError = ICERR_OK; return (LRESULT)codec; } case DRV_CLOSE: /* From xvid: compress_end/decompress_end don't always get called */ compress_end(codec); free( codec ); return DRV_OK; case DRV_DISABLE: case DRV_ENABLE: return DRV_OK; case DRV_INSTALL: case DRV_REMOVE: return DRV_OK; case DRV_QUERYCONFIGURE: case DRV_CONFIGURE: return DRV_CANCEL; /* info */ case ICM_GETINFO: { ICINFO *icinfo = (ICINFO *)lParam1; /* return a description */ icinfo->fccType = ICTYPE_VIDEO; icinfo->fccHandler = FOURCC_X264; icinfo->dwFlags = VIDCF_COMPRESSFRAMES | VIDCF_FASTTEMPORALC; icinfo->dwVersion = 0; icinfo->dwVersionICM = ICVERSION; wcscpy( icinfo->szName, X264_NAME_L); wcscpy( icinfo->szDescription, X264_DESC_L); return lParam2; /* size of struct */ } case ICM_ABOUT: if( lParam1 != -1 ) { DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), (HWND)lParam1, callback_about, 0 ); } return ICERR_OK; case ICM_CONFIGURE: if( lParam1 != -1 ) { CONFIG temp; codec->config.b_save = FALSE; memcpy( &temp, &codec->config, sizeof(CONFIG) ); DialogBoxParam( g_hInst, MAKEINTRESOURCE(IDD_MAINCONFIG), (HWND)lParam1, callback_main, (LPARAM)&temp ); if( temp.b_save ) { memcpy( &codec->config, &temp, sizeof(CONFIG) ); config_reg_save( &codec->config ); } } return ICERR_OK; case ICM_GETSTATE: if( (void*)lParam1 == NULL ) { return sizeof( CONFIG ); } memcpy( (void*)lParam1, &codec->config, sizeof( CONFIG ) ); return ICERR_OK; case ICM_SETSTATE: if( (void*)lParam1 == NULL ) { config_reg_load( &codec->config ); return 0; } memcpy( &codec->config, (void*)lParam1, sizeof( CONFIG ) ); return 0; /* not sure the difference, private/public data? */ case ICM_GET: case ICM_SET: return ICERR_OK; /* older-stype config */ case ICM_GETDEFAULTQUALITY: case ICM_GETQUALITY: case ICM_SETQUALITY: case ICM_GETBUFFERSWANTED: case ICM_GETDEFAULTKEYFRAMERATE: return ICERR_UNSUPPORTED; /* compressor */ case ICM_COMPRESS_QUERY: return compress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_FORMAT: return compress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_SIZE: return compress_get_size(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_FRAMES_INFO: return compress_frames_info(codec, (ICCOMPRESSFRAMES *)lParam1); case ICM_COMPRESS_BEGIN: return compress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_END: return compress_end(codec); case ICM_COMPRESS: return compress(codec, (ICCOMPRESS *)lParam1); /* decompressor : not implemented */ case ICM_DECOMPRESS_QUERY: case ICM_DECOMPRESS_GET_FORMAT: case ICM_DECOMPRESS_BEGIN: case ICM_DECOMPRESS_END: case ICM_DECOMPRESS: case ICM_DECOMPRESS_GET_PALETTE: case ICM_DECOMPRESS_SET_PALETTE: case ICM_DECOMPRESSEX_QUERY: case ICM_DECOMPRESSEX_BEGIN: case ICM_DECOMPRESSEX_END: case ICM_DECOMPRESSEX: return ICERR_UNSUPPORTED; default: if (uMsg < DRV_USER) return DefDriverProc(dwDriverId, hDriver, uMsg, lParam1, lParam2); else return ICERR_UNSUPPORTED; } }
/* __declspec(dllexport) */ LRESULT WINAPI DriverProc( DWORD_PTR dwDriverId, HDRVR hDriver, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { CODEC * codec = (CODEC *)dwDriverId; switch(uMsg) { /* driver primitives */ case DRV_LOAD : case DRV_FREE : return DRVCNF_OK; case DRV_OPEN : DPRINTF("DRV_OPEN"); { ICOPEN * icopen = (ICOPEN *)lParam2; if (icopen != NULL && icopen->fccType != ICTYPE_VIDEO) { return DRVCNF_CANCEL; } codec = malloc(sizeof(CODEC)); if (codec == NULL) { if (icopen != NULL) { icopen->dwError = ICERR_MEMORY; } return 0; } memset(codec, 0, sizeof(CODEC)); codec->status.hDlg = NULL; codec->config.ci_valid = 0; codec->ehandle = codec->dhandle = NULL; codec->fbase = 25; codec->fincr = 1; config_reg_get(&codec->config); #if 0 /* bad things happen if this piece of code is activated */ if (lstrcmp(XVID_BUILD, codec->config.build)) { config_reg_default(&codec->config); } #endif if (icopen != NULL) { icopen->dwError = ICERR_OK; } return (LRESULT)codec; } case DRV_CLOSE : DPRINTF("DRV_CLOSE"); /* compress_end/decompress_end don't always get called */ compress_end(codec); decompress_end(codec); clean_dll_bindings(codec); status_destroy_always(&codec->status); free(codec); return DRVCNF_OK; case DRV_DISABLE : case DRV_ENABLE : return DRVCNF_OK; case DRV_INSTALL : case DRV_REMOVE : return DRVCNF_OK; case DRV_QUERYCONFIGURE : case DRV_CONFIGURE : return DRVCNF_CANCEL; /* info */ case ICM_GETINFO : DPRINTF("ICM_GETINFO"); if (lParam1 && lParam2 >= sizeof(ICINFO)) { ICINFO *icinfo = (ICINFO *)lParam1; icinfo->fccType = ICTYPE_VIDEO; icinfo->fccHandler = FOURCC_XVID; icinfo->dwFlags = VIDCF_FASTTEMPORALC | VIDCF_FASTTEMPORALD | VIDCF_COMPRESSFRAMES; icinfo->dwVersion = 0; #if !defined(ICVERSION) #define ICVERSION 0x0104 #endif icinfo->dwVersionICM = ICVERSION; wcscpy(icinfo->szName, XVID_NAME_L); wcscpy(icinfo->szDescription, XVID_DESC_L); return lParam2; /* size of struct */ } return 0; /* error */ /* state control */ case ICM_ABOUT : DPRINTF("ICM_ABOUT"); DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_ABOUT), (HWND)lParam1, about_proc, 0); return ICERR_OK; case ICM_CONFIGURE : DPRINTF("ICM_CONFIGURE"); if (lParam1 != -1) { CONFIG temp; codec->config.save = FALSE; memcpy(&temp, &codec->config, sizeof(CONFIG)); DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_MAIN), (HWND)lParam1, main_proc, (LPARAM)&temp); if (temp.save) { memcpy(&codec->config, &temp, sizeof(CONFIG)); config_reg_set(&codec->config); } } return ICERR_OK; case ICM_GETSTATE : DPRINTF("ICM_GETSTATE"); if ((void*)lParam1 == NULL) { return sizeof(CONFIG); } memcpy((void*)lParam1, &codec->config, sizeof(CONFIG)); return ICERR_OK; case ICM_SETSTATE : DPRINTF("ICM_SETSTATE"); if ((void*)lParam1 == NULL) { DPRINTF("ICM_SETSTATE : DEFAULT"); config_reg_get(&codec->config); return 0; } memcpy(&codec->config,(void*)lParam1, sizeof(CONFIG)); return 0; /* sizeof(CONFIG); */ /* not sure the difference, private/public data? */ case ICM_GET : case ICM_SET : return ICERR_OK; /* older-stype config */ case ICM_GETDEFAULTQUALITY : case ICM_GETQUALITY : case ICM_SETQUALITY : case ICM_GETBUFFERSWANTED : case ICM_GETDEFAULTKEYFRAMERATE : return ICERR_UNSUPPORTED; /* compressor */ case ICM_COMPRESS_QUERY : DPRINTF("ICM_COMPRESS_QUERY"); return compress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_FORMAT : DPRINTF("ICM_COMPRESS_GET_FORMAT"); return compress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_GET_SIZE : DPRINTF("ICM_COMPRESS_GET_SIZE"); return compress_get_size(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_FRAMES_INFO : DPRINTF("ICM_COMPRESS_FRAMES_INFO"); return compress_frames_info(codec, (ICCOMPRESSFRAMES *)lParam1); case ICM_COMPRESS_BEGIN : DPRINTF("ICM_COMPRESS_BEGIN"); return compress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_COMPRESS_END : DPRINTF("ICM_COMPRESS_END"); return compress_end(codec); case ICM_COMPRESS : DPRINTF("ICM_COMPRESS"); return compress(codec, (ICCOMPRESS *)lParam1); /* decompressor */ case ICM_DECOMPRESS_QUERY : DPRINTF("ICM_DECOMPRESS_QUERY"); return decompress_query(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_GET_FORMAT : DPRINTF("ICM_DECOMPRESS_GET_FORMAT"); return decompress_get_format(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_BEGIN : DPRINTF("ICM_DECOMPRESS_BEGIN"); return decompress_begin(codec, (BITMAPINFO *)lParam1, (BITMAPINFO *)lParam2); case ICM_DECOMPRESS_END : DPRINTF("ICM_DECOMPRESS_END"); return decompress_end(codec); case ICM_DECOMPRESS : DPRINTF("ICM_DECOMPRESS"); return decompress(codec, (ICDECOMPRESS *)lParam1); case ICM_DECOMPRESS_GET_PALETTE : case ICM_DECOMPRESS_SET_PALETTE : case ICM_DECOMPRESSEX_QUERY: case ICM_DECOMPRESSEX_BEGIN: case ICM_DECOMPRESSEX_END: case ICM_DECOMPRESSEX: return ICERR_UNSUPPORTED; /* VFWEXT entry point */ case ICM_USER+0x0fff : if (lParam1 == VFWEXT_CONFIGURE_INFO) { VFWEXT_CONFIGURE_INFO_T * info = (VFWEXT_CONFIGURE_INFO_T*)lParam2; DPRINTF("%i %i %i %i %i %i", info->ciWidth, info->ciHeight, info->ciRate, info->ciScale, info->ciActiveFrame, info->ciFrameCount); codec->config.ci_valid = 1; memcpy(&codec->config.ci, (void*)lParam2, sizeof(VFWEXT_CONFIGURE_INFO_T)); return ICERR_OK; } return ICERR_UNSUPPORTED; default: if (uMsg < DRV_USER) return DefDriverProc(dwDriverId, hDriver, uMsg, lParam1, lParam2); else return ICERR_UNSUPPORTED; } }
void init_encoder(struct camera *cam) { compress_begin(&en, cam->width, cam->height); h264_buf = (uint8_t *) malloc( sizeof(uint8_t) * cam->width * cam->height * 3); // 设置缓冲区 }
void *video_Capture_Thread(void *arg) { compress_begin(&en, cam->width, cam->height);//初始化编码器 int i=0; //unsigned char *data; int len=framelength; struct timeval now; struct timespec outtime; while(1) { usleep(DelayTime); gettimeofday(&now, NULL); outtime.tv_sec =now.tv_sec; outtime.tv_nsec =DelayTime * 1000; pthread_mutex_lock(&(Buff[i].lock)); /*获取互斥锁,锁定当前缓冲区*/ if(i) printf("----video_Capture_Thread Buff 1\n"); if(!i) printf("----video_Capture_Thread Buff 0\n"); while((Buff[i].wpos + len)%BUF_SIZE==Buff[i].rpos && Buff[i].rpos != 0) /*等待缓存区处理操作完成*/ { printf("***********video_Capture_Thread ************阻塞\n"); //pthread_cond_wait(&(Buff[i].encodeOK),&(Buff[i].lock)); pthread_cond_timedwait(&(Buff[i].encodeOK),&(Buff[i].lock),&outtime); } if(buffOneFrame(&Buff[i] , cam))//采集一帧数据 { pthread_cond_signal(&(Buff[i].captureOK)); /*设置状态信号*/ pthread_mutex_unlock(&(Buff[i].lock)); /*释放互斥锁*/ //convert_yuv_to_rgb_buffer(); flag[i]=1;//缓冲区i已满 Buff[i].rpos=0; i=!i; //切换到另一个缓冲区 Buff[i].wpos=0; flag[i]=0;//缓冲区i为空 } pthread_cond_signal(&(Buff[i].captureOK)); /*设置状态信号*/ pthread_mutex_unlock(&(Buff[i].lock)); /*释放互斥锁*/ } }