亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 852 | 回復(fù): 0
打印 上一主題 下一主題

硬解 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-02-27 00:59 |只看該作者 |倒序瀏覽
S3C6410 MFC decode H.264流程(1)
2009-12-15 12:45

郁悶的,用MFC放出來的H.264視屏竟然是黑白的,無奈跟蹤下MFC的調(diào)用流程:

內(nèi)核啟動初始化:
1)執(zhí)行s3c_mfc_init(),打印“S3C6400 MFC Driver, (c) 2007 Samsung Electronics”;
2)注冊平臺設(shè)備platform_driver_register(&s3c_mfc_driver);
3)進入s3c_mfc_probe();
4)獲取時鐘、打開時鐘,映射寄存器物理地址,獲取中斷、注冊中斷;
5)調(diào)用s3c_get_media_memory(S3C_MDEV_MFC),獲取顯存空間;
6)調(diào)用s3c_mfc_setup_memory(),設(shè)置Bitprocessor buffer, Data buffer;
7)調(diào)用s3c_mfc_memmap_databuf,打印以下信息“s3c_mfc_memmap_databuf: virtual address of data buffer = 0xc0700000”;
8)調(diào)用s3c_mfc_init_yuvbuf_mgr(),This function initializes the MfcFramBufMgr(Buffer Segment Manager);
最后打印“address of segment_info=c0bd6400, address of commit_info =c0be0040”
9)調(diào)用s3c_mfc_init_hw(),初始化硬件;
1. Reset the MFC IP
2. Download Firmware code into MFC
輸出:“s3c_mfc_init_hw: downloading firmware into bitprocessor”;
3. Start Bit Processor
4. Set the Base Address Registers for the following 3 buffers(CODE_BUF, WORKING_BUF, PARAMETER_BUF)
5. Set the Control Registers
輸出:
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

10)最后再次輸出banner:S3C6400 MFC Driver, (c) 2007 Samsung Electronics。


H.264 decode時:
0)上層調(diào)用s3c_mfc_open();
1)調(diào)用s3c_mfc_init_yuvbuf_mgr();
2)調(diào)用s3c_mfc_yuv_buffer_mgr_final(),表示不需要重新分配yuv buffer;
3)調(diào)用s3c_mfc_init_hw(),重新初始化硬件;
4)調(diào)用s3c_mfc_inst_create創(chuàng)建一個實例->s3c_mfc_get_stream_buffer_addr()獲取流地址;
輸出:
s3c_mfc_get_stream_buffer_addr: ctx->stream_buffer address 0xc0700000
s3c_mfc_get_stream_buffer_addr: ctx->phys_addr_stream_buffer address 0x50700000
s3c_mfc_inst_create: state = 10 /* instance is created but not initialized */
5)輸出s3c_mfc_open: mfc open success,open結(jié)束。

6)調(diào)用s3c_mfc_ioctl,發(fā)送命令: cmd = 80000f,S3C_MFC_IOCTL_MFC_GET_LINE_BUF_ADDR
copy_from_user
處理XXXXXX
copy_to_user
7)調(diào)用s3c_mfc_ioctl,發(fā)送命令: cmd = 800005,S3C_MFC_IOCTL_MFC_H264_DEC_INIT
copy_from_user
codec_mode = AVC_DEC;
Initialize MFC Instance
——>s3c_mfc_inst_init_dec
(1)checking state
(2)codec_mode
(3)stream size checking
(4)判斷instance序列號
(5)s3c_mfc_set_eos(0);
(6)s3c_mfc_issue_command();
(7)s3c_mfc_stream_end();
(8)獲取視屏參數(shù)
(9)s3c_mfc_get_yuv_buffer_addr——>s3c_mfc_print_commit_yuv_buffer_info();
(10)s3c_mfc_get_param_buff_virt_addr();
/*
* set the parameters in the parameters buffer for SET_FRAME_BUF command. 
* buffer address of y, cb, cr will be set in parameters buffer before issuing SET_FRAME_BUF command
*/
(11)s3c_mfc_issue_command(ctx->inst_no, ctx->codec_mode, SET_FRAME_BUF);
(12)changing state to 20;
輸出信息:
s3c_mfc_inst_init_dec: strm_leng = 7767
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 = 737680
s3c_mfc_inst_init_dec: RET_DEC_SEQ_SRC_FRAME_RATE   = 0
s3c_mfc_inst_init_dec: RET_DEC_SEQ_FRAME_NEED_COUNT = 3
s3c_mfc_inst_init_dec: RET_DEC_SEQ_FRAME_DELAY = 0
s3c_mfc_inst_init_dec: width = 720, height = 400, buf_width = 720, buf_height = 400
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 = 1325
s3c_mfc_get_yuv_buffer_addr: ctx->inst_no : 0
s3c_mfc_get_yuv_buffer_addr: ctx->yuv_buffer : 0xc07fa000
s3c_mfc_get_yuv_buffer_addr: ctx->phys_addr_yuv_buffer : 0x507fa000

回到ioctrl
將初始化信息copy_to_user

8)視屏播放過程中,反復(fù)調(diào)用
s3c_mfc_ioctl: cmd = 800007
s3c_mfc_ioctl: cmd = 800011

9)cmd = 800007,S3C_MFC_IOCTL_MFC_H264_DEC_EXE
copy_from_user從用戶態(tài)獲取數(shù)據(jù),sizeof(s3c_mfc_enc_exe_arg_t)
s3c_mfc_inst_dec 對數(shù)據(jù)進行decode,真正decode函數(shù),此函數(shù)需要重點關(guān)注
copy_to_user將數(shù)據(jù)返回用戶態(tài)
難道直接將YUV數(shù)據(jù)返回用戶?然后用戶態(tài)再操作Framebuffer???

10)cmd = 800011,S3C_MFC_IOCTL_MFC_GET_YUV_BUF_ADDR
copy_from_user,sizeof(s3c_mfc_enc_exe_arg_t)
    yuv_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1;
    args.get_buf_addr.out_buf_size = yuv_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;
copy_to_user

11)解碼完畢,調(diào)用s3c_mfc_release釋放instance
s3c_mfc_release: deleting instance number = 0

僅僅分析了調(diào)用過程,下一步需要研究解碼過程這兩個操作究竟是干什么的,有什么區(qū)別
cmd = 800007,S3C_MFC_IOCTL_MFC_H264_DEC_EXE
cmd = 800011,S3C_MFC_IOCTL_MFC_GET_YUV_BUF_ADDR

阿虛(Rockie Cheng)


上次寫到吃中午飯,匆匆收筆,后來調(diào)wifi,竟然忘了。

趁周末,把這個坑填上。

cmd = 800007,S3C_MFC_IOCTL_MFC_H264_DEC_EXE

s3c_mfc_inst_dec 對數(shù)據(jù)進行decode

s3c_mfc_inst_dec函數(shù)分析
簡介: this function decodes the input stream and put the decoded frame into the yuv buffer 
輸入?yún)?shù)
s3c_mfc_inst_context_t *ctx 結(jié)構(gòu)體包含instance number,stream buffer和yuv buffer
unsigned long strm_leng stream長度
1) checking state(忽略所有涉及到旋轉(zhuǎn)的代碼)
2)大部分情況下,根據(jù)inst_no選擇對應(yīng)的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);
這段代碼中的寄存器我的數(shù)據(jù)手冊里面竟然沒有,看來應(yīng)該更新了

5)將stream物理地址寫入CMD_DEC_PIC_BB_START (0x1AC)
需要4byte對齊
4-byte aligned byte address of the decoder input picture stream buffer

6)不對齊的數(shù)據(jù)寫入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)
啟動解碼函數(shù)
根據(jù)S3C_MFC_IOCTL_MFC_H264_DEC_INIT的配置,codec_mode應(yīng)該為2

將inst_no寫入RunIndex (0x168)
將codec_mode = 2寫入RunCodStd (0x16C)
將run命令寫入RunCommand (0x164),啟動解碼
掛起interruptible_sleep_on_timeout(&s3c_mfc_wait_queue, 500)

9)讀取命令執(zhí)行結(jié)果狀態(tài)寄存器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.
并判斷幀情況,是否結(jié)尾,是否失敗等等

11)轉(zhuǎn)換inst_no的狀態(tài)
//* 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;

阿虛(Rockie Cheng)


今天用三星的測試程序跑了一下H.264,發(fā)現(xiàn)顏色正常,打印出的信息有所不同。
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數(shù)據(jù)返回用戶
而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轉(zhuǎn)換出的數(shù)據(jù)格式是YUV的。
三星的測試程序使用了Post Processor驅(qū)動,800013命令返回物理地址給pp使用,直接刷到fb上。
推測covia的驅(qū)動可能沒有使用pp,而是手動做的YUV2RGB再刷到fb,僅僅是推測,因為q5的內(nèi)核也含有pp驅(qū)動。


附錄:一些代碼及調(diào)試信息
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
        ########<STREAMINFO> 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



您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP