realarm6410的multimedia_test_real6410測試中的“通過TV 輸出的 MFC 解碼與攝像頭預覽”黑屏問題,是地址傳送的問題。
我現在用的方法是在內核裏面定義了一塊內存,然後通過copy_from_user讀到內核的這段內存裏面,再把內核這段內存的物理地址送給tvout的scaler。
下面是我在s3c-tvenc.c 驅動中的修改,添加了copy_from_user函數
//add by thl 20120213 V is the class of video devices 100 is the 100th io control ,struct cpFrame is the arg structure(is it so strict?,next time to try)
static char rgb_for_preview[720 * 480 * 2];
struct cpFrame
{
int addr;
int n;
};
#define VIDIOC_CPY_FRM _IOWR('V', 100,struct cpFrame)
static int s3c_tvenc_do_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,void *arg)
{
............
case VIDIOC_CPY_FRM:
{
struct cpFrame *copyframe=arg;
ret=copy_from_user(rgb_for_preview, copyframe->addr, copyframe->n);
if (ret)
{
printk("TV-OUT: copy__frame_from_usr_error :%d \n",ret);
/return -EINVAL;
}
return 0;
}
.......................
}
//copy_from_user函數的第二個參數必須是用戶空間的地址,如果使用arg=buf將用戶空間的buf傳入驅動,驅動ioctl函數的參數void *arg傳進來後就不是用戶空間地址了。
static int s3c_tvenc_v4l2_control(struct v4l2_control *ctrl)
{
switch(ctrl->id) {
// peter added for MFC related op.
case V4L2_CID_MPEG_STREAM_PID_VIDEO:
{
//tv_param.sp.SrcFrmSt = ctrl->value; //removed by thl 2012 2
//add by thl 2012 2
if(ctrl->value==0)
{
tv_param.sp.SrcFrmSt = __pa(rgb_for_preview);
}
else
{
tv_param.sp.SrcFrmSt = ctrl->value;
}
///////////////////////////////////////end
return 0;
}
...............................
}
最後要得到rgb_for_preview的真正物理地址也需要用__pa(x) 宏來轉換
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)