今天用三星的测试程序跑了一下H.264,发现颜色正常,打印出的信息有所不同。
covia android解码时的ioctrl命令为
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800011
测试程序解码为
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800013
前面分析过s3c_mfc_ioctl: cmd = 800011是将YUV数据返回用户
而s3c_mfc_ioctl: cmd = 800013和前者不一样的地方在于:
1)databuf_paddr = (unsigned int)S3C_MFC_BASEADDR_DATA_BUF;
//直接用寄存器(Physical Base Address for the MFC Data Buffer )地址填充
2)args.get_buf_addr.out_buf_addr = databuf_paddr + offset;
//输出地址用paddr填充,databuf_paddr
分析:
MFC转换出的数据格式是YUV的。
三星的测试程序使用了Post Processor驱动,800013命令返回物理地址给pp使用,直接刷到fb上。
推测covia的驱动可能没有使用pp,而是手动做的YUV2RGB再刷到fb,仅仅是推测,因为q5的内核也含有pp驱动。
附录:一些代码及调试信息
case S3C_MFC_IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR:
mutex_lock(s3c_mfc_mutex);
out = copy_from_user(&args.get_buf_addr,
(s3c_mfc_get_buf_addr_arg_t *)arg,
sizeof(s3c_mfc_get_buf_addr_arg_t));
yuv_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1;
args.get_buf_addr.out_buf_size = yuv_size;
yuv_buffer = (unsigned int)pMfcInst->yuv_buffer;
run_index = pMfcInst->run_index;
out_buf_size = args.get_buf_addr.out_buf_size;
databuf_vaddr = (unsigned int)s3c_mfc_get_databuf_virt_addr();
databuf_paddr = (unsigned int)S3C_MFC_BASEADDR_DATA_BUF;
offset = yuv_buffer + run_index * out_buf_size - databuf_vaddr;
args.get_buf_addr.out_buf_addr = databuf_paddr + offset;
args.get_buf_addr.ret_code = S3C_MFC_INST_RET_OK;
out = copy_to_user((s3c_mfc_get_buf_addr_arg_t *)arg,
&args.get_buf_addr, sizeof(s3c_mfc_get_buf_addr_arg_t));
mutex_unlock(s3c_mfc_mutex);
break;
========= S3C6400/6410 Demo Application ==========
= =
= 1. H.264 display =
= 2. MPEG4 display =
= 3. H.263 display =
= 4. VC-1 display =
= 5. 4-windows display =
= 6. Display using local path =
= 7. Display using double buffering =
= 8. Camera preview & MFC encoding =
= 9. MFC decoding & Camera preview =
= 10. Camera preview & MFC encoding/decoding =
= 11. Camera input and JPEG encoding =
= 12. JPEG decoding and display =
= 13. Exit =
= =
==================================================
Select number --> 1
s3c_mfc_yuv_buffer_mgr_final
address of segment_info=c141c400, address of commit_info =c1426040
s3c_mfc_init_hw: downloading firmware into bitprocessor
s3c_mfc_get_firmware_ver: GET_FW_VER command was issued
s3c_mfc_get_firmware_ver: GET_FW_VER => 0xf202, 0x130e
s3c_mfc_get_firmware_ver: BUSY_FLAG => 0
s3c_mfc_get_stream_buffer_addr: ctx->stream_buffer address 0xc0f46000
s3c_mfc_get_stream_buffer_addr: ctx->phys_addr_stream_buffer address 0x50f46000
s3c_mfc_inst_create: state = 10
s3c_mfc_open: mfc open success
s3c_mfc_ioctl: cmd = 80000f
s3c_mfc_ioctl: cmd = 800005
s3c_mfc_inst_init_dec: strm_leng = 7956
s3c_mfc_inst_init_dec: ctx->inst_no = 0
s3c_mfc_inst_init_dec: ctx->codec_mode = 2
s3c_mfc_inst_init_dec: sequece bit buffer size = 500 (kb)
s3c_mfc_inst_init_dec: RET_DEC_SEQ_SRC_SIZE = 327920
s3c_mfc_inst_init_dec: RET_DEC_SEQ_SRC_FRAME_RATE = 0
s3c_mfc_inst_init_dec: RET_DEC_SEQ_FRAME_NEED_COUNT = 4
s3c_mfc_inst_init_dec: RET_DEC_SEQ_FRAME_DELAY = 0
s3c_mfc_inst_init_dec: width = 320, height = 240, buf_width = 320, buf_height = 240
s3c_mfc_print_commit_yuv_buffer_info: commit index = 000, base segment index = 0
s3c_mfc_print_commit_yuv_buffer_info: commit index = 000, number of segment = 509
s3c_mfc_get_yuv_buffer_addr: ctx->inst_no : 0
s3c_mfc_get_yuv_buffer_addr: ctx->yuv_buffer : 0xc1040000
s3c_mfc_get_yuv_buffer_addr: ctx->phys_addr_yuv_buffer : 0x51040000
s3c_mfc_ioctl: cmd = 800007
######## width=320 height=240.
s3c_mfc_ioctl: cmd = 800013
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800013
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800013
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800013
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800013