http://wiki.linuxtoy.cn/WorkLog/oldcdr.html
可以改进的地方
设置白平衡,曝光等参数的时候,最好可以看到预览
回放预览窗口中可以加一个文件过滤的功能:
按时间过滤
按文件类型过滤
需要解决的问题
配置文件中pixels ARGB 和 ABGR的问题
优化cdr启动时间
实现回放预览窗口中的图像预览。
TODO:
处理TF卡状态发生变化时,每个窗口的响应 回放列表循环 播放状态下,调整快进与快退, 快退的效果不明显。 暂停的时候,按快退或者快进会自动播放. 回放时,长按快进, 短按音量 如果启动的时候没有找到配置文件menu.cfg, 将会采用默认的英文界面, 但是在打开子菜单,却发现是中文的. 回放预览显示 设置预览帧率, HerbCamera->setPreviewFrameRate csi和UVC录像得到的视屏时间长度不同。 低电量的提示, 10S 自动关机, 拔火牛时 提示, 10s自动关机。
done at 2014-08-05
how: (改为在record_front线程中insert database就可以避免这个问题, 和保护fron_db_info互斥访问的问题)
FIXED List:
进入子菜单后按mode键退出, 发现配置文件中current中被写入了-1. fixed
2014-08-04 Take Picture done 播放异常退出后,Alpha没有关闭 如Phtograh切换菜单后,再切换回来后状态栏图标不一致。 done
(是因为在MSG_SHOWWINDOW中没有判断current_state) fixed 2014-08-04 双路录像时duration到达时,会有一路插入数据库失败.
由于对数据库的访问没有加锁 录像时,先更换已有的预分配文件,再预分配下一次的文件。 在使用每个thread_data都需要加锁,因为有可能这个变量正被释放, 比如快速按ok键,启动和停止录像,就会出现thread_data已经被释放掉了,却还在使用这个变量. 回放 PlayBack.cpp MWM_CHANGE_FROM_WINDOW 文件路径的原因导致 不能播放移动侦测文件。 启动时先预分配好一些文件,发现pre_alloc thread只被唤醒了一次 切换到PlayBackPreview的时候,数据库中记录的总数有的时候不正确
to fix: Mainwindow.cpp(msg): line:[0206] update_database() sql is INSERT INTO CdrFile VALUES('20000101_062159A.MP4',946707719,'video',1,0), tffiles[0] is 20000101_062159A.MP4 , executeSQL() [302], code=19 errmsg=UNIQUE constraint failed: CdrFile.file
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-07-29.html
录像预览window有3种状态:
typedef enum {
Preview = 1,
Record,
PhotoGraph
}RecordPreviewStatus;
3种状态之间如何切换
在MSG_CREATE中调用init_window_data初始化:
static int init_window_data(HWND hWnd)
{
rPreviewWndData->status = Preview;
return 0;
}
在MSG_CREATE种判断是否需要上电录像,如果是,则设置status为Record
在程序运行过程中, status的状态通过按Mode键来切换。
Preview/Record --> PhotoGraph --> Playback --> Preview/Record
从其他窗口切换过来的时候,收到Mainwindow发过来的MWM_CHANGE_FROM_WINDOW, 可以知道是从哪个窗口切换过来的, 这个时候可以重新设置status
Preview/Record的状态通过按OK键切换
if(status == Preview || status == Record) {
if(Mode short press) {
if(status == Preview)
status = Record
else if (status == Record)
status = Preview
}
}
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-07-30.html
使用录像的回调函数
HerbMediaRecorder::setMaxDuration 设置最大时间
回调CedarXRecorder::dataCallbackTimestamp
if (mMaxFileDurationUs != 0 mListener->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
MEDIA_RECORDER_INFO_MAX_DURATION_REACHED 回调可以这样写 class OnInfoListener : public HerbMediaRecorder::OnInfoListener { public: OnInfoListener(需要的信息 *arg):mPriv(arg){}; bool onInfo(HerbMediaRecorder *pMr, int what, int extra) { fd = getNewFd(); pMr->setOutputFileSync(fd); } private: 需要的信息* const mPriv; };
OnInfoListener mOnInfoListener(需要的信息指针); mHMR->setOnInfoListener(&mOnInfoListener);
TODO:
修改录像流程:
之前的策略是, 使用照录像时长作为间隔,定时启动和关闭录像线程,由于需要实现碰撞加锁,所以需要录像不能停止,否则会有一个时间间隙,导致有可能丢失碰撞前后的数据 现在的流程为: 除非手动停止录像,否则录像线程应该一直运行下去,并设置录像时长的MaxDuration, 这个值即录像时长.添加录像的回调函数,通知应用程序录像已完成。
thread: pre_alloc run record_thread() { thread: record_front thread: record_rear thread: record_others } Problems: record_thread如何管理上面的多个线程:
如何控制预分配线程:
#if WITH_PRE_ALLOC
pre_alloc事先已经运行, 等待条件变量:
激活pre_alloc的方法:
pthread_mutex_lock(&pre_alloc_mutex);
pthread_cond_signal(&pre_alloc_cond);
pthread_mutex_unlock(&pre_alloc_mutex);
获取预分配文件的文件名:
ptr = get_pre_alloc_file(pre_alloc_files);
根据当前的时间,重命名预分配文件名:
bzero(filename, sizeof(filename));
now = set_video_filename(filename, CAMERA_FRONT);
sprintf(buf, "%s%s", CON_2STRING(TF_CARD_PATH, VIDEO_DIR), filename);
buf[strlen(TF_CARD_PATH) + strlen(VIDEO_DIR) + strlen(filename)] = '\0';
db_msg("buf is %s\n", buf);
rename(ptr, buf);
清空预分配buffer,pre_alloc通过判断这个buffer如果位空,那么表示文件以被取走:
pthread_mutex_lock(&pre_alloc_mutex);
bzero(ptr, CDR_FILE_LENGHT);
pthread_mutex_unlock(&pre_alloc_mutex);
打开文件预分配文件:
if((fd = open(buf, O_RDWR)) == -1) {
db_error("open %s failed: %s\n", buf, strerror(errno));
unlink(buf);
continue;
}
#else
pre_alloc事先已经运行, 等待条件变量:
激活pre_alloc的方法:
pthread_mutex_lock(&pre_alloc_mutex);
pthread_cond_signal(&pre_alloc_cond);
pthread_mutex_unlock(&pre_alloc_mutex);
获取预分配文件名:
bzero(filename, sizeof(filename));
now = set_video_filename(filename, CAMERA_FRONT);
sprintf(buf, "%s%s", CON_2STRING(TF_CARD_PATH, VIDEO_DIR), filename);
buf[strlen(TF_CARD_PATH) + strlen(VIDEO_DIR) + strlen(filename)] = '\0';
打开文件预分配文件:
if((fd = open(buf, O_RDWR | O_CREAT, 0777)) == -1) {
db_error("open %s failed: %s\n", buf, strerror(errno));
unlink(buf);
continue;
}
#endif
record_manager_thread要完成的功能:
管理多个录像线程的启动与停止(通过显示模式判断改启动或停止哪些线程)
伪代码: wait record event (know start which record, or stop which record) if(start) {
}
record_thread_xxx要完成的功能:
控制预分配线程,得到预分配文件的fd (通过录像完成的回调来通知) 重新设置outputfile fd
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-07-31.html
使用HerbMediaRecorder的回调函数,通知录像完成
如果使用了 mHMR->setMaxDuration(seconds * 1000); , 那么在listener里面会收到 MEDIA_RECORDER_INFO_MAX_DURATION_REACHED 这个消息, 然后通知录像线程继续
class OnInfoListener : public HerbMediaRecorder::OnInfoListener
{
public:
OnInfoListener(thread_data *arg):record_thread_data(arg){}
virtual ~OnInfoListener(){}
void onInfo(HerbMediaRecorder *pMr, int what, int extra)
{
switch(what)
{
case MEDIA_RECORDER_INFO_EXTRA_FILE_DONE:
{
db_msg("finish recodering extra file.\n");
// last_extra_finished = true; //fix -> atomic operation
}
break;
case MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
{
db_msg("reached max duration.\n");
pthread_mutex_lock(&record_thread_data->mutex);
pthread_cond_signal(&record_thread_data->cond);
pthread_mutex_unlock(&record_thread_data->mutex);
}
break;
default:
break;
}
}
private:
thread_data *record_thread_data;
};
注意:
SetOutFile(fd) 在prepare之前调用, 在stop之前要切换文件就使用setOutFileSync(fd)
setMexDuration(xxx);
setOutputFile(fd);
prepare();
start();
setOutputFileSync(fd);
setOutputFileSync(fd);
...
setOutputFileSync(fd);
stop();
添加碰撞加锁的支持
正常文件
/mnt/extsd/video/xxx.MP4
加锁文件
/mnt/extsd/lock/xxx_impact.MP4
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-04.html
测试碰撞之后,收不到extrafile完成的消息
初步判断,是调用 setOutputFileSync 导致的, 还不确定。
添加拍照功能
API:
void HerbCamera::takePicture(ShutterCallback *pShutter, PictureCallback *pRaw, PictureCallback *pPostview, PictureCallback *pJpeg)
拍照前设置拍照模式
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-05.html
添加 uvc摄像头 (USB video class 或USB video device class)
UVC是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,目前已成为USB org标准之一。
修改.config
要编译产生uvcvideo.ko需要修改config文件: linux-3.4/arch/arm/configs/sun7ismp_defconfig
CONFIG_USB_VIDEO_CLASS=m
同时删除linux-3.4/.config, 到camlinux目录执行mklichee会自动将sun7ismp_defconfig拷贝到.config
修改init.rc
编辑device/softwinner/pluto-common/init.rc 加入 insmod /system/vendor/modules/uvcvideo.ko
修改camera.cfg
edit camlinux/device/softwinner/pluto-cdr/configs/camera.cfg, set number_of_camera with 2
uvc的驱动位于 linux-3.4/drivers/media/video/uvc
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-06.html
添加显示模式:
typedef enum {
CSI_ONLY = 1,
UVC_ONLY,
UVC_ON_CSI,
CSI_ON_UVC,
NO_VIDEO
}pip_mode_t; /* define the Picture-in-Picture mode */
状态转移图如下:
PIP_MODE状态转移图
PIP_MODE状态转移图表格
切换显示模式的2个原则:
保证不需要显示的Layer是处于关闭状态的 保证Rect大的Layer在下面,小的在上面.
所以得到切换的代码如下:
pthread_mutex_lock(&status_mutex);
if(pip_mode == NO_VIDEO) {
pthread_mutex_unlock(&status_mutex);
break;
}
/* chang the pip_mode */
if(pip_mode == UVC_ON_CSI) {
mCD_front->exchangeSurface(hlay_front, hlay_rear, 1);
pip_mode = CSI_ON_UVC;
pthread_mutex_unlock(&status_mutex);
db_msg("-----------PIP_MODE: UVC_ON_CSI ---> CSI_ON_UVC\n");
/* do something */
} else if(pip_mode == CSI_ON_UVC) {
if(close_layer(hlay_front) < 0) {
pthread_mutex_unlock(&status_mutex);
break;
}
pip_mode = UVC_ONLY;
pthread_mutex_unlock(&status_mutex);
db_msg("-----------PIP_MODE: CSI_ON_UVC ---> UVC_ONLY\n");
} else if(pip_mode == UVC_ONLY) {
if(CSI_EXSIST) {
if(close_layer(hlay_rear) < 0) {
pthread_mutex_unlock(&status_mutex);
break;
}
if(open_layer(hlay_front) < 0) {
pthread_mutex_unlock(&status_mutex);
break;
}
mCD_front->exchangeSurface(hlay_front, hlay_rear, 1);
pip_mode = CSI_ONLY;
pthread_mutex_unlock(&status_mutex);
db_msg("-----------PIP_MODE: UVC_ONLY ---> CSI_ONLY\n");
} else {
pthread_mutex_unlock(&status_mutex);
}
}
else if(pip_mode == CSI_ONLY) {
if(UVC_EXSIST) {
if(open_layer(hlay_rear) < 0) {
pthread_mutex_unlock(&status_mutex);
break;
}
pip_mode = UVC_ON_CSI;
pthread_mutex_unlock(&status_mutex);
db_msg("-----------PIP_MODE: CSI_ONLY ---> UVC_ON_CSI\n");
} else {
pthread_mutex_unlock(&status_mutex);
}
} else {
db_error("invalid PIP MODE: %d\n", pip_mode);
pthread_mutex_unlock(&status_mutex);
}
UVC插拔的处理
UVC录像和回放的处理
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-08.html
更改current_state中STATUS_RECORD和STATUS_PREVIEW之间切换的处理
这两种状态的切换只能放在录像线程里面处理.
如果其中一个录像线程在进行中,那么current_state = STATUS_RECORD 如果两个录像线程都已经停止,那么current_state = STATUS_PREVIEW
解决从RecordPreview窗口切换到PlaybackPreview窗口时, 预览关闭和surface释放的问题:
RecordPreview ---> PlaybackPreview
1. CSI camera stop preview 2. CSI camera release surface 3. uvc camera close layer
PlaybackPreview ---> RecordPreview
1. request layer for csi 2. 根据pip_mode恢复切换之前csi layer的大小和位置 3. uvc camera open layer 4. csi camera start preview
处理插拔 UVC 摄像头时, 停止录像的问题
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-11.html
修改预分配策略:
启动时,先预分配好文件。包括normal video, impact video, motion detect video, 总共3个文件 录像过程中先更换文件,再预分配下一次的文件。
static pre_alloc_t pre_alloc_files[2][PRE_ALLOC_BUFFER_COUNT];
其中
buffer[0] -- buffer[1] is for normal video file. buffer[2] -- buffer[3] is for the impact video file buffer[4] -- buffer[5] is for the motion detect video file
so PRE_ALLOC_BUFFER_COUNT must great than 6
record 线程的流程:
首先能够进入到录像线程的前提是已经获得了预分配的文件 设置参数, listener ... start 继续为下一次预分配文件,得到文件描述符,存入data->fd.(这个时候已经在另外的线程中往之前预分配的文件中写入数据,所以不会影响本次录像) 等待duration到达(pthread_cond_wait(&rear_data->cond, &rear_data->mutex);) 如果data->fd有效,则重新设置fd 更新上一次录像的数据库信息 如果data->fd有效则替换数据库信息(例: rear_db_info = db_info_bak), 如果data->fd无效,则表示预分配失败,需要退出录像线程
在这个流程中有一个问题:
在为下一次录像预分配好文件之后并没有关闭文件描述符, 关闭文件描述符的时机是重新设置文件描述符之后,那么再duration没有到达之前之前这个文件一直处于打开状态:如果这个时候拔卡会怎样:
拔卡的时候会主动给RecordPreview窗口发消息,停止录像,所以等待的条件会立即返回,然后关闭文件描述符。
那如何避免主动停止录像后又重新设置文件描述符?
因为停止录像的方式是: 先设置data->run, 然后产生条件, 所以只需要在重新设置文件描述符之前判断data->run
代码如下:
mHMR->start();
db_msg("==================== record_rear start recording ...\n");
pthread_mutex_lock(&rear_data->run_mutex);
while(data->run == 1)
{
pthread_mutex_unlock(&rear_data->run_mutex);
pthread_mutex_lock(¤t_state_mutex);
status_record_rear = 1;
current_state = STATUS_RECORD;
pthread_mutex_unlock(¤t_state_mutex);
db_msg("======================= Recording... filename is %s\n", rear_db_info.filename);
/* now the record is going on, prepare the next file*/
retries = 5;
while(retries > 0)
{
param.camera_index = CAMERA_REAR;
param.size = SZ_1M * 100;
param.type = 0;
if((data->fd = wakeup_pre_alloc(¶m, &db_info_bak)) <= 0) {
db_msg("pre alloc file failed, retry again!\n");
retries--;
} else {
break;
}
}
pthread_cond_wait(&rear_data->cond, &rear_data->mutex);
pthread_mutex_unlock(&rear_data->mutex);
db_msg("==================== this duration reached ...\n");
/* change another file, and save the last file to db */
if(data->fd > 0 && data->run == 1) {
mHMR->setOutputFileSync(data->fd);
close(data->fd);
}
/* insert record to database */
if(dbc != NULL) {
rear_db_info.flag = 1; /* completion */
dbc->setRecord(String8("file"), (void*) rear_db_info.filename); /* filename time and type is set in the wakeup_pre_alloc */
dbc->setRecord(String8("time"), (void*) &rear_db_info.time);
dbc->setRecord(String8("type"), (void*) rear_db_info.type);
dbc->setRecord(String8("vtl"), (void*) &rear_db_info.vtl); /* be set, after call the set_duration */
dbc->setRecord(String8("flag"), (void*) &rear_db_info.flag);
dbc->insertRecord();
} else {
db_warn("========== invalid dbc, not update the database ======= \n");
}
if(data->fd > 0) {
rear_db_info = db_info_bak;
} else {
db_error("pre_alloc invalid fd\n");
break;
}
pthread_mutex_lock(&rear_data->run_mutex);
}
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-12.html
1.图像质量接口
mHMR->setVideoSize
HD:1280*720
FHD:1920*1080
2. 移动侦测
侦测到移动物体(onAWMoveDetection回调返回值为1)开始录像连续侦测到5秒以上不动(回调返回值为0),就停止录像。
预分配1min(60M)的大小
3.碰撞检测前5后10,预分配15M
发现移动侦测必须要在startpreview之后才能启动成功。
离线
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-18.html
回放预览-》mode长按出菜单,菜单选项目前就一项:删除-》按ok-》弹出是否删除对话框
secondary dc的特效:
/* 弹出式效果 */
static void effect_pop_out(HWND hDlg)
{
RECT rect;
HDC sec_dc;
GetWindowRect(hDlg, &rect);
printf("left is %d\n", rect.left);
printf("top is %d\n", rect.top);
printf("right is %d\n", rect.right);
printf("bottom is %d\n", rect.bottom);
sec_dc = GetSecondaryDC(hDlg);
StretchBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, RECTW(rect)/5, RECTH(rect)/5, 0);
usleep(50000);
StretchBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, RECTW(rect) * 2/5, RECTH(rect) * 2/5, 0);
usleep(50000);
StretchBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, RECTW(rect) * 3/5, RECTH(rect) * 3/5, 0);
usleep(50000);
StretchBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, RECTW(rect) * 4/5, RECTH(rect) * 4/5, 0);
usleep(50000);
SetMemDCAlpha(sec_dc, 0, 0);
BitBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, 0);
SetSecondaryDC(hDlg, sec_dc, ON_UPDSECDC_DEFAULT);
}
/* 淡入淡出效果 */
static void effect_fade(HWND hDlg)
{
RECT rect;
HDC sec_dc;
GetWindowRect(hDlg, &rect);
printf("left is %d\n", rect.left);
printf("top is %d\n", rect.top);
printf("right is %d\n", rect.right);
printf("bottom is %d\n", rect.bottom);
sec_dc = GetSecondaryDC(hDlg);
SetMemDCAlpha(sec_dc, MEMDC_FLAG_SRCALPHA, 64);
BitBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, 0);
usleep(100000);
SetMemDCAlpha(sec_dc, MEMDC_FLAG_SRCALPHA, 128);
BitBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, 0);
usleep(100000);
SetMemDCAlpha(sec_dc, 0, 0);
BitBlt(sec_dc, 0, 0, RECTW(rect), RECTH(rect), HDC_SCREEN, rect.left, rect.top, 0);
SetSecondaryDC(hDlg, sec_dc, ON_UPDSECDC_DEFAULT);
}
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-25.html
打补丁
work/a10t/patch/patch0825.tar.gz
git am是使用:
将 git format-patch 生成的patchy引入到自己的代码库中(里面包含了提交的日志,作者,日期等信息):
使用git-am之前, 你要首先git am –abort 一次,来放弃掉以前的am信息,这样才可以进行一次全新的am。
不然会遇到这样的错误。 .git/rebase-apply still exists but mbox given.
若发生冲突,使用下面的命令apply补丁 git apply --reject 0001.patch 查看*.rej文件修改源文件后再次git add文件 若报whitespace的警告,可以加上下面的参数 --ignore-space-change --ignore-whitespace --whitespace=nowarn
├── camlinux
│ ├── 0001-Support-capture-a-Bitmap-containing-a-representative.patch
│ ├── 0002-fix-hwdisplay-bug-screen-is-blurred-when-exchanged.patch
│ ├── 0003-modify-the-display-framerate-to-30fps.patch
│ └── 0004-add-fallocate.patch
└── lichee
├── brandy
│ ├── 0001-fix-lcd-bug.patch
│ ├── 0002-rm-uboot-some-log.patch
│ └── 0003-reduce-time-for-optimize.patch
├── linux-3.4
│ ├── 0001-fix-showlogo-issue-and-rm-some-log.patch
│ └── 0002-rm-some-driver-for-optimize.patch
└── tools
├── 0001-fix-LCD-bug.patch
├── 0002-fix-show-logo-issue.patch
├── 0003-reduce-time-for-optimize.patch
├── 0004-optimize-uboot-time-when-boot.patch
└── 0005-update-cfg.fex-for-miniGUI-cfg.patch
camlinux 0001 提供视频图像预览的接口 camlinux 0002 解决uvc和csi layer交换时屏幕闪烁的问题. camlinux 0004 将预分配的功能集成到framework里面
添加data分区
从norflash里面分出一个可读写的分区
修改分区配置:
lichee/tools/pack/chips/sun7i/configs/linux/default/sys_partition.fex
[partition] name = cfg size = 1024 downloadfile = "cfg.fex" user_type = 0x8000
分区的名称位Cfg, 分区的大小为 1024个扇区, 每个扇区的大小是512Byte, 那么cfg分区的大小就是512KB
下载的文件位cfg.fex, 是相对于image.cfg的路径, 例如: lichee/tools/pack/out
$ file cfg.fex cfg.fex: Linux jffs2 filesystem data little endian
制作cfg.fex的方法
例如新建一个data目录:
$ ls data/ 480X272.cfg menu.cfg
mkfs.jffs2 -d data -o cfg.fex
将生成的文件拷贝到 lichee/tools/pack/chips/sun7i/configs/linux/cdr
安装jffs2工具
下载 linux - mtd-snapshot 工具, 编译并安装即可
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-26.html
添加change_pip_mode的函数统一管理画中画模式的切换:
画中画模式的切换有4种触发条件,状态转移图如下:
画中画模式切换的状态转移图
从STATUS_PREVIEW 切换到 Menu菜单, 或者切换到拍照模式前, 用pip_mode_bak保存当前的pip_mode
如果是切换到拍照模式,那么统一把pip_mode切换为CSI_ONLY, 然后从其他窗口切换回录像预览窗口时,
根据pip_mode_bak恢复pip模式
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-08-29.html
解决UVC不能录像的问题:
现象:
一开始录像,UVC就停止预览。
原因: 在初始化uvc camera的时候没有设置 params.setVideoSize(1280, 720);
log: V/CameraHardware2( 967): (f:startRecording, l:1106)VideoCapture:640x480, Capture:1280x720
这两个大小不同,导致无法开始录像:
device/softwinner/common/hardware/camera/CameraHardware2.cpp
status_t CameraHardware::startRecording()
{
LOGV("(f:%s, l:%d)VideoCapture:%dx%d, Capture:%dx%d", __FUNCTION__, __LINE__, mVideoCaptureWidth, mVideoCaptureHeight, mCaptureWidth, mCaptureHeight);
if (mVideoCaptureWidth != mCaptureWidth || mVideoCaptureHeight != mCaptureHeight)
{
doStopPreview();
doStartPreview();
}
}
具体原因待查
录像过程中对文件加锁
离线
http://wiki.linuxtoy.cn/WorkLog/worklog_2014-09-01.html
log
20:51:59.872: root@android:/ # ^^^^^^^^^^^^^^^^^^^^^^^^^^ in MiniGUI main_entry time is 47 secs, 494186693 nsecs 20:52:00.888: V/Mainwindow.cpp line[1109] MiniGUIAppMain()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ start cdr, time is 47 secs, 795755109 nsecs 20:52:00.983: ^^^^^^^^^^^^^^^^^^^^^^^ init_global_data , time is 48 secs, 59881234 nsecs 20:52:01.012: V/Mainwindow.cpp line[1166] MiniGUIAppMain()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 65991859 nsecs
20:52:01.149: V/Mainwindow.cpp line[0880] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 67561859 nsecs 20:52:01.168: V/Mainwindow.cpp line[0890] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 69468943 nsecs 20:52:01.198: V/Mainwindow.cpp line[0897] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 70774193 nsecs
20:52:01.207: V/cdr line[0134] create_windows()( 1016): ^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 70916276 nsecs 20:52:02.479: V/cdr line[0154] create_windows()( 1016): ^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 777987193 nsecs 20:52:02.549: V/cdr line[0174] create_windows()( 1016): ^^^^^^^^^^^^^^^^^^^^^ time is 48 secs, 983287943 nsecs 20:52:02.582: V/cdr line[0194] create_windows()( 1016): ^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 26243985 nsecs 20:52:02.591: V/cdr line[0212] create_windows()( 1016): ^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 50553901 nsecs
20:52:02.638: V/Mainwindow.cpp line[0905] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 51580360 nsecs 20:52:02.647: V/Mainwindow.cpp line[0919] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 51739651 nsecs 20:52:02.670: V/Mainwindow.cpp line[0931] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 51973276 nsecs 20:52:02.692: V/Mainwindow.cpp line[0942] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 52151818 nsecs 20:52:02.702: V/Mainwindow.cpp line[0949] CDRWinProc()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 52279485 nsecs
20:52:02.711: V/Mainwindow.cpp line[1174] MiniGUIAppMain()( 1016): ^^^^^^^^^^^^^^^^^^^^^^^ time is 49 secs, 52306110 nsecs
==>
启动MiniGUI 花费了301ms
init_global_data 花费了 264 ms
CreateMainWindow 返回花费了 986 ms
init_window_data花费了 1.3 ms create_windows 花费了 980 ms
创建RecordPreview Window 花费了 700 ms 创建Menu Window 花费了206 ms 创建PlayBack Preview Window 花费了 42.9 ms 创建PlayBack Window花费了24 ms
需要优化的地方, init_global_data
get_db打开数据库需要花费200ms左右的时间。所以移到update_database,放到线程池里面做。
将创建窗口的create_windows分开位createRecordPreviewWindow 和 createOtherWindows.
createRecordPreviewWindow
16:10:04.430: /RecordPreview.cpp line[1218] RecordPreviewProc()( 1022): ^^^^^^^^^^^^^^^^^^^^^^^^ time is 84 secs, 112473666 nsecs 16:10:04.523: V/RecordPreview.cpp line[1230] RecordPreviewProc()( 1022): ^^^^^^^^^^^^^^^^^^^^^^^^ time is 84 secs, 119090208 nsecs 16:10:04.566: V/RecordPreview.cpp line[1240] RecordPreviewProc()( 1022): ^^^^^^^^^^^^^^^^^^^^^^^^ time is 84 secs, 126690249 nsecs 16:10:04.587: V/RecordPreview.cpp line[1265] RecordPreviewProc()( 1022): ^^^^^^^^^^^^^^^^^^^^^^^^ time is 84 secs, 127225791 nsecs 16:10:05.631: V/RecordPreview.cpp line[1287] RecordPreviewProc()( 1022): ^^^^^^^^^^^^^^^^^^^^^^^^ time is 84 secs, 635226458 nsecs
==> init_window_data 花费了 6.5ms createStatusBar 花费了 7.5ms 初始化CSI 并启动预览 花费了 510 ms
16:42:42.753: V/Mainwindow.cpp line[1090] MiniGUIAppMain()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 12 secs, 37455466 nsecs 16:42:43.543: V/Mainwindow.cpp line[1098] MiniGUIAppMain()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 12 secs, 370375466 nsecs
16:42:42.936: V/CreateWindow.cpp line[0099] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 12 secs, 38818883 nsecs 16:42:43.455: V/CreateWindow.cpp line[0130] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 12 secs, 367532591 nsecs
总共用了300ms启动 其中录像预览启动花了280 ms
启动CDR: 16:14:50.506: V/Mainwindow.cpp line[1067] main()( 969): ^^^^^^^^^^^^^^^ in MiniGUI main_entry time is 11 secs, 516866258 nsecs 16:14:50.569: V/Mainwindow.cpp line[0858] InitRecordPreviewEx()( 969): ^^^^^^^^^^InitRecordPreviewEx time is 11 secs, 518473966 nsecs 16:14:50.580: V/Mainwindow.cpp line[0865] InitRecordPreviewEx()( 969): ^^^^^^^^^^startPreview time is 11 secs, 518612341 nsecs 16:14:50.590: V/RecordPreview.cpp line[1165] startPreview()( 969): ^^^^^^^^^^^^^ time is 11 secs, 518666341 nsec 16:14:50.613: V/RecordPreview.cpp line[1192] startPreview()( 969): ^^^^^^^^^^^^^ time is 11 secs, 752963509 nsec 16:14:50.622: V/RecordPreview.cpp line[1209] startPreview()( 969): ^^^^^^^^^^^^^ time is 11 secs, 753074259 nsec 16:14:50.631: V/CDRCamera.cpp line[0049] CDRCamera()( 969): ^^^^^^^^^^^ time is 11 secs, 754967675 nsec 16:14:50.650: V/Mainwindow.cpp line[1079] MiniGUIAppMain()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ start cdr, time is 11 secs, 968260383 nsecs 16:14:50.670: V/Mainwindow.cpp line[1132] MiniGUIAppMain()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969067967 nsecs 16:14:50.776: V/Mainwindow.cpp line[0902] CDRWinProc()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969644466 nsecs 16:14:50.786: V/Mainwindow.cpp line[0248] init_window_data()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969667758 nsecs 16:14:50.795: V/Mainwindow.cpp line[0266] init_window_data()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969685841 nsecs 16:14:50.805: V/Mainwindow.cpp line[0909] CDRWinProc()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969745508 nsecs 16:14:50.814: V/CreateWindow.cpp line[0106] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969766425 nsecs 16:14:50.825: V/CreateWindow.cpp line[0120] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969788758 nsecs 16:14:50.859: V/RecordPreview.cpp line[1391] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 969964591 nsecs 16:14:50.884: V/RecordPreview.cpp line[1403] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 974361258 nsecs 16:14:50.927: V/RecordPreview.cpp line[1413] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 983591550 nsecs 16:14:50.937: V/RecordPreview.cpp line[1421] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 983785717 nsecs 16:14:51.039: V/CreateWindow.cpp line[0139] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 984154842 nsecs 16:14:51.066: V/CreateWindow.cpp line[0148] createRecordPreviewWindow()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 984207217 nsecs 16:14:51.077: V/Mainwindow.cpp line[0919] CDRWinProc()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 984226175 nsecs 16:14:51.086: V/Mainwindow.cpp line[1140] MiniGUIAppMain()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 984247383 nsecs 16:14:51.158: V/Mainwindow.cpp line[0779] LazyInit()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 985330633 nsecs 16:14:51.187: V/RecordPreview.cpp line[1432] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 985369467 nsecs 16:14:51.210: V/RecordPreview.cpp line[1465] RecordPreviewProc()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 11 secs, 985431592 nsecs 16:14:51.900: V/CDRCamera.cpp line[0060] CDRCamera()( 969): ^^^^^^^^^^^ time is 12 secs, 934134634 nsec 16:14:51.919: V/CDRCamera.cpp line[0071] CDRCamera()( 969): ^^^^^^^^^^^ time is 12 secs, 934885592 nsec 16:14:51.927: V/RecordPreview.cpp line[1216] startPreview()( 969): ^^^^^^^^^^^^^ time is 12 secs, 934938509 nsec 16:14:51.942: V/RecordPreview.cpp line[1224] startPreview()( 969): ^^^^^^^^^^^^^ time is 12 secs, 934971467 nsec 16:14:52.535: V/RecordPreview.cpp line[1231] startPreview()( 969): ^^^^^^^^^^^^^ time is 13 secs, 19691592 nsec 16:14:52.544: V/RecordPreview.cpp line[1240] startPreview()( 969): ^^^^^^^^^^^^^ time is 13 secs, 19763842 nsec 16:14:52.769: V/RecordPreview.cpp line[1248] startPreview()( 969): ^^^^^^^^^^^^^ time is 13 secs, 164646925 nsec 16:14:52.778: V/RecordPreview.cpp line[1258] startPreview()( 969): ^^^^^^^^^^^^^ time is 13 secs, 164671175 nsec 16:14:52.787: V/Mainwindow.cpp line[0872] InitRecordPreviewEx()( 969): ^^^^^^^^^^startPreview finished time is 13 secs, 164738967 nsecs 16:14:52.820: V/Mainwindow.cpp line[0786] LazyInit()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 166534759 nsecs 16:14:52.880: V/CreateWindow.cpp line[0168] createOtherWindows()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 311103259 nsecs 16:14:53.057: V/CreateWindow.cpp line[0198] createOtherWindows()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 367021509 nsecs 16:14:53.298: V/CreateWindow.cpp line[0219] createOtherWindows()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 623499050 nsecs 16:14:53.453: V/CreateWindow.cpp line[0238] createOtherWindows()( 969): ^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 696772217 nsecs 16:14:53.705: V/Mainwindow.cpp line[0846] LazyInit()( 969): ^^^^^^^^^^^^^^^^^^^^^^^ time is 13 secs, 935998092 nsecs
离线