Chinaunix首页 | 论坛 | 博客
  • 博客访问: 278237
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-14 19:50:14

S3C6410 MFC decode H.264流程(续)

cmd = 800007,S3C_MFC_IOCTL_MFC_H264_DEC_EXE

s3c_mfc_inst_dec 对数据进行decode



s3c_mfc_inst_dec函数分析
简介: this function decodes the input stream and put the decoded frame into the yuv buffer 
输入参数
s3c_mfc_inst_context_t *ctx 结构体包含instance number,stream buffer和yuv buffer
unsigned long strm_leng stream长度
1) checking state(忽略所有涉及到旋转的代码)
2)大部分情况下,根据inst_no选择对应的MFC物理端口(8个)
3)计算size:frm_size = ctx->buf_width * ctx->buf_height;
4)
/* DEC_PIC_OPTION was newly added for MP4ASP */
writel(0x7, s3c_mfc_sfr_base_virt_addr + S3C_MFC_PARAM_DEC_PIC_OPTION);
writel(ctx->mv_mbyte_addr, s3c_mfc_sfr_base_virt_addr + S3C_MFC_PARAM_DEC_PIC_MV_ADDR);
writel(ctx->mv_mbyte_addr + 25920, s3c_mfc_sfr_base_virt_addr + S3C_MFC_PARAM_DEC_PIC_MBTYPE_ADDR);
这段代码中的寄存器我的数据手册里面竟然没有,看来应该更新了

5)将stream物理地址写入CMD_DEC_PIC_BB_START (0x1AC)
需要4byte对齐
4-byte aligned byte address of the decoder input picture stream buffer

6)不对齐的数据写入CMD_DEC_PIC_START_BYTE (0x1B0)
Byte Address of valid bitstream in input picture stream buffer

7)将stream length写入CMD_DEC_PIC_CHUNK_SIZE (0x1A8)
Byte size of picture stream data

8)s3c_mfc_issue_command(ctx->inst_no, ctx->codec_mode, PIC_RUN)
启动解码函数
根据S3C_MFC_IOCTL_MFC_H264_DEC_INIT的配置,codec_mode应该为2

将inst_no写入RunIndex (0x168)
将codec_mode = 2写入RunCodStd (0x16C)
将run命令写入RunCommand (0x164),启动解码
挂起interruptible_sleep_on_timeout(&s3c_mfc_wait_queue, 500)

9)读取命令执行结果状态寄存器RET_DEC_PIC_SUCCESS (0x1D8)

10)读取RET_DEC_PIC_IDX (0x1C4)
Display frame index
After BIT decodes one frame, BIT return display frame index to this register.
并判断帧情况,是否结尾,是否失败等等

11)转换inst_no的状态
//* changing state 
//* state change to S3C_MFC_INST_STATE_DEC_PIC_RUN_LINE_BUF
S3C_MFC_INST_STATE_TRANSITION(ctx, S3C_MFC_INST_STATE_DEC_PIC_RUN_LINE_BUF);

12)返回OK


===========================================================================

IOCTRL:cmd = 800011,S3C_MFC_IOCTL_MFC_GET_YUV_BUF_ADDR        

DEC部分分析,这一段并没有设计到解码,解码主要在上面完成


out = copy_from_user(&args.get_buf_addr, 
(s3c_mfc_get_buf_addr_arg_t *)arg, 
sizeof(s3c_mfc_get_buf_addr_arg_t));

if (pMfcInst->yuv_buffer == NULL) {
mfc_err("mfc frame buffer is not internally allocated yet\n");
mutex_unlock(s3c_mfc_mutex);
return -EFAULT;
}

/* FRAM_BUF address is calculated differently for Encoder and Decoder. */
switch (pMfcInst->codec_mode) {
case MP4_DEC:
case AVC_DEC:
case VC1_DEC:
case H263_DEC:
/* Decoder case */
yuv_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; //计算YUV的大小
args.get_buf_addr.out_buf_size = yuv_size;//填充out_buf_size尺寸

in_usr_data = (unsigned int)args.get_buf_addr.in_usr_data;
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();
offset = yuv_buffer + run_index * out_buf_size - databuf_vaddr;//计算偏移量
args.get_buf_addr.out_buf_addr = in_usr_data + offset;//填充out_buf地址
break;

} /* end of switch (codec_mode) */

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));

break;
阅读(819) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~