DM365上运行jpegdec程序全记录

DM365上运行jpegdec程序记录
 

1.   说明
DVSDK版本:dvsdk_2_10_00_17

路径:ROOTDIR = /opt/dvsdk_2_10_00_17/dm365_codecs_01_00_06/packages/ti/sdo/codecs/jpegdec/

源代码:$(ROOTDIR)/apps/Client/Test/Src

头文件:$(ROOTDIR)/apps/Client/Test/Inc

2.   源代码部分
关于源代码可以简单看一下jpgdTestApp.c

而头文件需要注意定义内存大小的地方,如:testFramework.h

其中一段:

#define MAX_WIDTH 1280

#define MAX_HEIGHT 960

 

#define JPEG_MAX_NUM_JPEG_BYTES          (3*MAX_WIDTH*MAX_HEIGHT)    // Max stream size 1M byte

#define RINGBUF_SIZE                    (1024*4096)       // (20*4096)         // Ring buffer size

#define JPEG_MAX_NUM_YCC_BYTES          (3*MAX_WIDTH*MAX_HEIGHT)

#define AIM_START_ADDRESS                   (0x10000)

#define INTERNAL_DATA_MEM_SIZE        (4096)

#define EXTERNAL_DATA_MEM_SIZE       (16*1024)

#define JPEG_MAX_NUM_RGB_BUFFER_LINES     (16)

#define JPEG_MAX_NUM_SAMPLES_PER_LINE     (5000+32)                  // Width

#define STRING_SIZE                    256      //!< Size of strings used for filenames
 

 

应用在jpgdTestApp.c中,如:

CMEM_init();

ExternalGlobalMemPool = ExternalGlobalMemPoolBase =          CMEM_alloc(EXTERNAL_DATA_MEM_SIZE,&memParams);

ringbuf = CMEM_alloc(RINGBUF_SIZE,&memParams);

bJpegStream = CMEM_alloc(JPEG_MAX_NUM_JPEG_BYTES,&memParams);

bDecodedYCC = CMEM_alloc(JPEG_MAX_NUM_YCC_BYTES,&memParams);
 

 

从上面代码可以看出:

需要4块连续内存,即CMEM,如下:

EXTERNAL_DATA_MEM_SIZE:                  16*1024 = 16384

RINGBUF_SIZE:                                    1024*4096 = 4194304

JPEG_MAX_NUM_JPEG_BYTES:     3*1280*960 = 3686400

JPEG_MAX_NUM_YCC_BYTES:       3*1280*960 = 3686400

3.   写loadmodules.sh脚本
#!/bin/sh

rmmod cmemk 2>/dev/null

rmmod irqk 2>/dev/null

rmmod edmak 2>/dev/null

rmmod dm365mmap 2>/dev/null

 

# Pools configuration

#insmod cmemk.ko phys_start=0x85000000 phys_end=0x88000000 pools=6x4096,2x8192,1x11908,2x13184,1x2697152,6x4096,1x30720,3x81920, 1x3185664,64x56,1x320,1x640,1x81920,1x6650880,2x608,1x296,1x28,2x24,23x1548288,1x154288,2x3686400 allowOverlap=1 phys_start_1=0x00001000 phys_end_1=0x00008000 pools_1=1x28672

 

#上面注释的是demo演示程序中的配置,下面是根据分析写的3个pool,虽然物理地址不需要那么多,先写着。
insmod cmemk.ko phys_start=0x85000000 phys_end=0x88000000 pools=1x16384,1x4194304,2x3686400

 

insmod irqk.ko

insmod edmak.ko

insmod dm365mmap.ko
 

 

4.   准备运行
4.1.  修改Testvecs.cfg文件
2

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/frida_720x480.jpeg

./TestVecs/Input/frida_720x480_dec.yuv
 

 

而Testparams.cfg文件中的宽度和长度分别是720x480,所以不用修改。

4.2.  修改源代码并进行编译
修改jpgdTestApp.c的第261行代码如下:

Int8 *fileCfgName = "./TestVecs/Config/Testvecs.cfg";

Int8 *fileLogName = "./TestVecs/Config/log.txt";
 

 

先执行make clean

再make

注:直接make不行,因为有几个c文件的时间戳是未来的,就不编译了。

最后会生成jpgdec-r可执行文件。

4.3.  所需文件
如果在ARM端运行,则需要的文件如下:

Testparams.cfg  Testvecs.cfg  JPG文件

下面是本人的文件结构:

myJpgDec

|-jpgdec-r

|-TestVecs

|       |-Config

|       |       |-Testparams.cfg

|       |       |-Testvecs.cfg

|       |-Input

|       |       |-frida_720x480.jpeg

|       |-Output

|       |-module

|       |       |-cmemk.ko

|       |       |-dm365mmap.ko

|       |       |-edmak.ko

|       |       |-irqk.ko

|       |       |-loadmodules.sh

 

注:如果你找不到cmemk.ko、dm365mmap.ko、edmak.ko、irqk.ko等4个文件,启动365板子,在demo演示程序中就有,直接拿来用就可以了。但是loadmodules.sh文件需修改过,见第3章。

 

5.   开始运行
如何在365板子上运行,有几种方法:

1.         把myJpgDec打包,通过网络(tftp)下载下去,在板子上解压,然后运行。

2.         考虑到nandflash的大小只有128MB,启动板子,然后用df -h命令查看,可用的也就37MB左右,所以不建议在flash上运行。那么有两种方法:

1)         在U盘或SD卡上运行

2)         挂载nfs

 

下面分别介绍两种方式的挂载:

1.         挂载U盘

插入U盘,默认的Linux内核中有驱动,所以能自动识别出来。但是会一直停在那里,用(CTRL+C)退出。

然后使用下面命令进行查看:

# fdisk -l /dev/sda

本人2G的朗科U盘,显示如下:

Disk /dev/sda: 2003 MB, 2003828736 bytes

...

注:试过有些U盘显示的是Disk /dev/sda1:

下面根据上面的显示,进行挂载:

# mount -t msdos /dev/sda /mnt/usb               (fat16格式)

# mount -t vfat /dev/sda /mnt/usb                  (fat32格式)

# mount -t ext2 /dev/sda /mnt/usb                   (ext2格式)

2.         挂载NFS

命令如下:

# mount -t nfs 192.168.1.109:/opt/nfs /nfsclient/

如果出现下列错误:

mount: RPC: Program not registered

请重启Linux服务器端的nfsserver:

# /etc/init.d/nfsserver restart

关于Linux服务器端的NFSServer建立,这里不讲。

 

运行比较简单:(如挂载U盘)

# mount -t vfat /dev/sda /mnt/usb

# cd /mnt/usb/myJpgDec/

# cd module

# ./loadmodules.sh

# cd ../

# ./jpgdec-r

6.   进行200万像素的JPEG图片解码
因工作需要,需要对200万像素和500万像素的JPG图片进行编解码。

200万像素的图片大小为1600x1200。

500万像素的图片大小为2448x2048。

6.1.  单张200万像素的JPG图片解码
1.         修改Testvecs.cfg文件,如下:

2

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic2m_001.jpg

./TestVecs/Input/pic2m_001_dec.yuv
 

2.         修改Testparams.cfg文件,如下:

Resize                            = 0            # 0: No resizing, 1: resize by 1/8, 2: resize by 2/8, etc

DisplayWidth                = 0          # 0: display width = image output width

rotation                           = 0

areaDecode                      = 0

maxWidth                          = 1600

maxHeight                         = 1200

# forceChromaFormat    = 4             # 4: 422

forceChromaFormat       = 9             # 9: 420

dataEndianness               = 1

subRegionUpLeftY                    = 0

subRegionUpLeftX                    = 0

subRegionDownRightX = 0

subRegionDownRightY = 0
 

 

3.         在Input目录下添加JPG文件。

4.         开始运行:(为调试方便,以下测试都是挂载NFS的方式)

# mount -t nfs 192.168.1.109:/opt/nfs /nfsclient/

# cd /nfsclient/myJpgDec/

# cd module

# ./loadmodules.sh

# cd ../

# ./jpgdec-r

解码成功。

 

6.2.  多张200万像素JPG图片的解码
1.         修改Testvecs.cfg文件,如下:

2

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic2m_001.jpg

./TestVecs/Input/pic2m_001_dec.yuv

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic2m_002.jpg

./TestVecs/Input/pic2m_002_dec.yuv

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic2m_003.jpg

./TestVecs/Input/pic2m_003_dec.yuv

 

...

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic2m_017.jpg

./TestVecs/Input/pic2m_017_dec.yuv
 

 

2.         在Input目录中添加JPG图片。

3.         运行

 

惊喜,17张图片解码成功。

7.   进行500万像素的JPEG图片解码
500万像素的图片大小为2448x2048。

7.1.  单张500万像素的JPG图片解码
1.         修改Testvecs.cfg文件,如下:

2

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic5m_001.jpg

./TestVecs/Input/pic5m_001_dec.yuv

 
 

 

 

2.         修改Testparams.cfg文件,如下:

Resize                            = 0            # 0: No resizing, 1: resize by 1/8, 2: resize by 2/8, etc

DisplayWidth                = 0          # 0: display width = image output width

rotation                           = 0

areaDecode                      = 0

maxWidth                          = 2448

maxHeight                         = 2048

# forceChromaFormat    = 4             # 4: 422

forceChromaFormat       = 9             # 9: 420

dataEndianness               = 1

subRegionUpLeftY                    = 0

subRegionUpLeftX                    = 0

subRegionDownRightX = 0

subRegionDownRightY = 0
 

 

3.         在Input目录下添加JPG文件。

4.         开始运行,出现错误,如下:

*******************************************

Read Configuration Set 1

*******************************************

Opened file ./TestVecs/Input/pic5m_001.jpg

 

FileSize = 502832, Reading file ...done

CMEMK Error: get_phys: Unable to find phys addr for 0x40f97000

CMEMK Error: get_phys: get_user_pages() failed: -14

CMEMK Error: GETPHYS: Failed to convert virtual 0x40f97000 to physical.

CMEMK Error: get_phys: Unable to find phys addr for 0x40f97000

CMEM Error: getPCMEMK Error: get_phys: get_user_pages() failed: -14

hys: Failed to gCMEMK Error: GETPHYS: Failed to convert virtual 0x40f97000 to physical.

et physical address of 0x40f97000

CMEM Error: getPhys: Failed to get physical address of 0x40f97000

!!!! Error during jpeg decode !!!!

End of test
 

 

突然出现这么个问题,一点头绪都没有,google了一阵,确实有很多人遇到过此类问题,但是真正给出解答的却没有几个。

没办法,自己折腾。

下面是折腾以后运行正确的修改:

1.         修改testFramework.h:

#define MAX_WIDTH 1920      //1280

#define MAX_HEIGHT 1440    //960
 

 

重新make clean和make,生成jpgdec-r

注:其中改这个大小的时候比较奇怪,随便改的大一点好像也不行的。我搜索过源代码(不包括库),没有用到这两个宏定义的。

2.         改了大小,就要重新修改pools了(loadmodules.sh),如下:

insmod cmemk.ko phys_start=0x85000000 phys_end=0x88000000 pools=1x16384,1x4194304,2x8294400
 

 

重新运行,就成功了。

 

7.2.  多张500万像素JPG图片的解码
1.         修改Testvecs.cfg文件,如下:

2

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic5m_001.jpg

./TestVecs/Input/pic5m_001_dec.yuv

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic5m_002.jpg

./TestVecs/Input/pic5m_002_dec.yuv

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic5m_003.jpg

./TestVecs/Input/pic5m_003_dec.yuv

 

...

 

./TestVecs/Config/Testparams.cfg

./TestVecs/Input/pic5m_017.jpg

./TestVecs/Input/pic5m_017_dec.yuv
 

 

2.         在Input目录中添加JPG图片。

3.         运行,运行到第10张的时候报错如下(前面几张都是正确解码的):

*******************************************

Read Configuration Set 10

*******************************************

Opened file ../jpg_source/jpg5m/pic5m_010.jpg

 

FileSize = 990000, Reading file ...done

989997 bytes     2448 x 2048     10.13:1

================Test Summary======================

Total bytes consumed 989997

status.imageWidth = 2448...

status.imageHeight = 2048...

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

Segmentation fault
 

又是一个头疼的问题,就连怎么去google都不知道。

只能自己折腾。

注:出现上面的错误之后,不能继续运行任何应用程序了,都会报这个错,只能重启板子。

 

下面是折腾以后运行正确的修改:

1.         分析loadmodules.sh:

insmod cmemk.ko phys_start=0x85000000 phys_end=0x88000000 pools=1x16384,1x4194304,2x8294400
 

 

pools的大小为:16364 + 4194304 + 8294400*2 = 20799468 (19.8MB左右,算20MB)

而实际分配的物理地址是从0x85000000到0x88000000,有48MB

修改如下:

insmod cmemk.ko phys_start=0x86C00000 phys_end=0x88000000 pools=1x16384,1x4194304,2x8294400
 

 

2.         修改uboot中的启动参数bootargs

> setenv bootargs mem=108M console=ttyS0,115200n8 noinitrd rw ip=192.168.1.144:255.255.255.0:192.168.1.254 root=/dev/mtdblock3 rootfstype=yaffs video=davincifb:osd0=720x576x16,4050K dm365_imp.oper_mode=0 davinci_capture.device_type=4

> saveenv

> boot
 

 

重新运行,17张图片解码成功。

 

8.   小结
另外,如果解码的图片数量再往上增加,还是会出错的,如下错误信息:

oom-killer: gfp_mask=0x200d2, order=0

Mem-info:

DMA per-cpu:

cpu 0 hot: high 42, batch 7 used:6

cpu 0 cold: high 14, batch 3 used:11

DMA32 per-cpu: empty

Normal per-cpu: empty

HighMem per-cpu: empty

Free pages:        1364kB (0kB HighMem)

Active:13185 inactive:41 dirty:0 writeback:0 unstable:0 free:341 slab:684 mapped:1 pagetables:57

DMA free:1364kB min:1328kB low:1660kB high:1992kB active:52740kB inactive:164kB present:110592kB pages_scanned:16452 all_unreclaimable? no

lowmem_reserve[]: 0 0 0 0

DMA32 free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no

lowmem_reserve[]: 0 0 0 0

Normal free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no

lowmem_reserve[]: 0 0 0 0

HighMem free:0kB min:128kB low:128kB high:128kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no

lowmem_reserve[]: 0 0 0 0

DMA: 9*4kB 10*8kB 2*16kB 0*32kB 3*64kB 0*128kB 0*256kB 0*512kB 1*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 1364kB

DMA32: empty

Normal: empty

HighMem: empty

Swap cache: add 0, delete 0, find 0/0, race 0+0

Free swap  = 0kB

Total swap = 0kB

Free swap:            0kB

27648 pages of RAM

416 free pages

13081 reserved pages

683 slab pages

0 pages shared

0 pages swap cached

Out of Memory: Kill process 708 (sh) score 652 and children.

Out of memory: Killed process 732 (jpgdec-r).

Killed
 

 

所以我有理由怀疑,这个应用程序没有写好,至少在内存这一块没有处理好。

不然再多的图片进行解码,只要一张处理好以后释放内存,再进行下一张解码。对吧?

 

还有,通过NFS读写数据是,一直报下面这个错,但是数据还是读写正确的。

ERROR: davinci_emac: WARN: emac_dev_tx: Out of TX BD's

EMAC: TX Complete: Starting queue
 

 

不知道,上面的错误是不是由这里引起的?

 

对于嵌入式写软件的人来说,内存管理是很现实和很重要的问题。但是对于DAVINCI的这一块却很生疏,想找资料也不容易,以下是一个CMEM的介绍,用处不大。

http://processors.wiki.ti.com/index.php/CMEM_Overview

希望大家多多帮助,多介绍一下资料或网站,这里先谢过了。

 

本人也是刚开始接触DAVINCI系列的DSP,很多东西都不懂,写文章只是为了记录一下,肯定有不少错误的地方。

另外,对于最后两个问题,如果有高手看到,望赐教,本人不胜感激。

 

你可能感兴趣的:(File,buffer,input,output,linux内核,filenames)