Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33216
  • 博文数量: 11
  • 博客积分: 1420
  • 博客等级: 上尉
  • 技术积分: 65
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-04 11:38
文章分类
文章存档

2010年(11)

我的朋友
最近访客

分类: 嵌入式

2010-06-04 13:29:28

上次写到吃中午饭,匆匆收笔,后来调wifi,竟然忘了。

趁周末,把这个坑填上。

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;

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