一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 7670|回复: 2
收起左侧

基于FPGA的JPEG解码器设计与实现

[复制链接]
发表于 2009-3-23 22:41 | 显示全部楼层 |阅读模式
基于FPGA的JPEG解码器设计与实现; p8 A, c* Z% _) u
. \% \) h6 _. `# Q# h
刘小卫,周剑扬,黄云鹰,刘旻焘
4 P+ f" \: o5 D: Q/ Z( K4 n; Q2 j厦门大学 电子工程系,福建 厦门3610053 u# N* g( p; Q" x
2008-07-28 8 }( K# Y3 e# r9 o, o7 s9 K2 V. v$ c) t
    摘 要: 为满足SoC中JPEG静止图像实时解压缩要求,在完成JPEG解码器C语言建模的基础上,采用自顶向下的设计方法,完成了JPEG Baseline解码器设计,并在FPGA开发板上验证了设计结果。该设计与ACTEL、4I2I等公司的IP核相比具有相近的解压缩速度,能满足实时解码要求。" u' c2 z0 P8 c4 |4 M) O0 q! a
    关键词: JPEG;FPGA;解码器;IDCT
! V& X: ?% @& N6 P; w! n: b! A
  x$ T8 I# p) y$ \
    随着多媒体技术的蓬勃发展,视频编解码技术得到了长足的进步,人们先后制定了多个数字图像视频编解码标准。其中JPEG仍然是目前最流行的静止图像压缩格式,在手持设备和网络中有广泛的应用。
& P! \9 P1 r2 C8 p3 C* H3 @  q2 i    本论文工作是无线投影机控制器设计中的一部分,见图1。该控制器以开放源代码处理器LEON3为核心,具有以太网、VGA、PCI等接口,PCI接口用来连接无线网卡,VGA接口用来连接投影机,这样构成一个无线投影系统。PC机通过有线网络或无线网络向控制器传输JPEG压缩图像数据,经过解码器解码后显示在投影仪上,从而实现多台电脑共享一台投影机,并且避免了连线的麻烦,具有一定的市场前景。考虑到系统的灵活性,本控制器选用Altera FPGA作为实现平台,设计可以无缝地转移到Altera Hardcopy技术,从而实现低成本。
8 h: W& U( o) k" ]
                           1 B$ h+ ]/ x6 H9 O
: j3 K- \  v' f9 r0 o' z
    本设计利用硬件描述语言(VHDL)设计了JPEG Baseline的解码系统。; {) a: n0 f3 o# G
1 JPEG解码器原理( F8 c" w- T- ~4 S
    JPEG解码器主要由四部分组成:图像头信息的读取、熵解码、反量化、IDCT(反离散余弦变换),其数据流图见图2。1 d" b; r2 D, u; O) A0 C
( T! V9 J4 X' d$ k' [
    从图中可以看出,解码器首先从JPEG图像数据中读取Header信息,得到与解码相关的如哈夫曼表、量化表以及图像大小等信息,并且将这些信息存储在RAM或者寄存器中,供后面的步骤调用。3 y! s. U) e, h+ j& P2 k+ t; i7 v
    在图像头信息读取完成后,解码器进一步读取压缩编码的数据并对其进行熵解码。压缩编码的数据采用哈夫曼(Huffman)编码。哈夫曼编码是一种常用的压缩编码方法,是Huffman于1952年为压缩文本文件建立的。它的基本原理是:将频繁使用的数据用较短的代码代替,而较少使用的数据用较长的代码代替,每个数据的代码各不相同。这些代码都是二进制码,且码的长度可变,因此哈夫曼编码是可变长编码的一种。在JPEG中采用游程编码与范式huffman编码进行数据的压缩存储,并且直流系数(DC)与交流系数(AC)分开编码,提高了压缩效率。因而在熵解码过程中需要分别对直流系数和交流系数分别解码。当前直流系数为上一个直流系数加上当前熵解码数据(即残差)。
7 D* K' Y* T, e9 s    当解码完一个MCU(Minimal Coded Unit)后,接下来就是进行反量化的操作,即将解码出来的数据乘以一个量化系数。2 f# A) N) e; i
    最后是IDCT(反离散余弦变换)操作,即DCT(离散余弦变换)的反变换。离散余弦变换(DCT)是N.Ahmed等人在1974年提出的正交变换方法,它常被认为是对语音和图像信号进行变换的最佳方法。通过DCT变换,将数据从一个域变换到另外一个域,其大多数高频分量的系数变为0。人眼对低频分量比较敏感,对高频分量则不太敏感;因而量化的结果是去掉了不太重要的高频分量,降低了码率。在JPEG解码过程中需要通过IDCT还原图像原始数据。IDCT部分是计算量最大的单元,对此单元设计的好坏将直接影响到解码速度。0 b% N( W3 f5 G& i3 T
2 JPEG解码器设计与实现0 ]- e3 L0 N8 P, k
    针对JPEG解码流程特点,本JPEG解码器硬件总体设计如图3所示。JPEG CONTROLLER负责调度各个模块的执行;Src_ram存储着JPEG原始图像数据;Addr_gen模块产生下一个需要读取字节的地址;Read_markers模块读取JPEG图像的图像头信息,并且将头信息保存在Register files中,相应的量化表信息及huffman表将存储在Dqt rams和Dht rams中;Huff_derived_tbl是由huffman表生成的用于熵解码的表格;Decode MCU 模块从Src_ram读取JPEG图像数据并解码,解码出来的数据将逆zig-zag顺序存储在Block ram中;IDCT模块读取Block ram中的哈夫曼解码数据进行反量化和IDCT变换,之后将数据输出到Ram。下面将对各个模块的设计作详细的介绍。. }4 M1 h! H8 G2 M) d+ U
2.1 Addr_gen模块设计
3 t  u  u3 g  k8 c# E6 c+ u    此模块用于产生读取Src_ram的地址并生成下一个要读取字节的地址。其硬件实现如图4虚线右边部分所示。在非跳转情况下,当RD信号有效时,Addr_gen计数器每次递增1个单位。( i- ?. K$ K0 V1 ~1 D4 q9 `0 L
    跳转情况下,即skip有效时,其计数器工作如图4虚线左边部分所示,当读入地址为Addr_n的数据后需要跳转k个单位的字节(Skip_num=k),因为在读取地址为Addr_n的数据Data_n后地址计数已经增加了一个单位,因而在第三个时钟周期能跳转到地址为Addr_n+1+k的数据,而这第三个时钟周期读出来的数据Data_n+1将会被忽略。从第四个时钟起此模块将恢复正常的读取数据功能。
# l! m9 o1 e2 [3 l2 ?7 Y- I& L; c3 w' U" H6 j" G
2.2 Read_markers模块设计
9 H4 _* Q$ R9 {; e, r# k3 r9 G
    Read_markers读取JPEG文件头信息并且解释,由以下子模块组成,见图5虚线左边部分。
$ J9 f! `. D) h( A    (1)First_marker:判断文件是否为JPEG文件,即判断开始的2B是否为FF D8;
$ ~# [& D% [' l# W    (2)Next_marker:查找下一个标志;0 X% m3 G1 l. m+ G( P- b- U. B
    (3)Get_sos:读取sos(start of scan);% @  |* E, c: O$ U$ o. m
    (4)Skip_var:跳过一些信息时被调用,给Addr_gen模块传送跳过信息标志;, l3 ~3 C" F4 _  D) H1 e% l
    (5)Get_sof:读取sof(start of frame);
% m  X+ T# \& `8 o! m    (6)Get_dht:读取huffman表信息,存储在Dht rams(见图1);( g0 ?1 ?3 ]( u! [
    (7)Get_dqt:读取量化表信息,并存储在Dqt rams(见图1);
/ X# E6 f' D% ^( k' |, t    (8)Get_dri:读取重起间隔,以MCU(Minimum Coded Unit)为单位。
) g6 K- z" R+ l) j    硬件实现利用FSM(有限状态机)来进行控制。其模块调度示意图见图5虚线右边部分。  Z& N2 L3 Z+ Y
5 X0 S2 ^  S( P- w

9 o; j" i$ E- B2.3 Decode_MCU模块设计: i. v% ^+ H% e7 n! r9 _& X
    Decode_MCU是jpeg解码器设计中一个非常重要的单元,也是正式解码的开始。本设计中此模块的设计见图6虚线框中设计,主要由四个子模块组成:Fill_buffer、Decode_block&IZZ、Process_restart和Controller。
7 Y0 D( K4 D- z% v5 Q$ J- w& j  B    (1)Fill_buffer:当32BITS_REG中的比特数不够时控制器将启动此模块读取Src_ram中的数据并且加载到32bits_reg中,并且去掉码流中的填充数据。
7 N' H/ a9 @& E0 J    (2)Decode_block&IZZ:huffman解码,并且将解码数据逆zig_zag顺序输出。/ z, H+ s! P/ M4 e
    (3)Process_restart:当JPEG图像中有restart interval(Get_dri)标志,在解码完由Get_dri规定的n个MCU后,控制器首先调用此模块来进行同步(在网络传输中非常重要)。; |8 D9 x- b3 B; J4 V
    (4)Controller:控制协调各模块的执行。
% a" u& ]. t0 k+ _1 r8 @, `9 Z# Z    核心模块Decode_block硬件实现如图6,虚线右边是EXTEND[1]部分,采用查找表实现。Get_buffer即图6中的32BITS_REG, Bits_left记录32BITS_REG中剩余的比特数。Huff_D模块每启动一次解码一个熵编码数据。由于DC编码采用DPCM编码,解码直流(DC)时需要增加一个时钟周期来加上上一个DC的值,从而得出如图6所示的output,解码交流系数(AC)时则在EXTEND后直接输出。Sel_s_input为”00”时,选通huffman解码数据;为”01”时,选通EXTEND后的数据;为”10”时,选通加上了last_dc_val的数据。
" v( T( J3 i3 J( f6 s+ K5 s* B: j6 l/ Z4 z' Y

. E) F- _, G" H7 @- X' o2.4 IDCT模块设计2 W9 Z$ Y/ R6 w- d
    IDCT(Inverse Discrete Consine Transform)是JPEG解码器中最耗资源和计算量最大的单元。本设计为减少内存读取,提高解码速度,将反量化也放在IDCT模块中实现。
3 f/ ?+ C% J) {, y8 c    离散余弦变换的公式和离散余弦逆变换的公式如下:
0 A- ~. P9 L9 l; ~# {/ `/ @   http://www.chinaaet.com/uploadfiles/jishu/jslw/20080728043215890_small.gif+ s9 s, s1 C6 G( W- q0 n( `  E+ }
5 S+ b0 q$ S+ N  ], T6 \+ k
    经分析公式(1)可以做如下等效变换:
( L2 Z3 P: M2 S8 o) R! R8 w" J4 p) n    http://www.chinaaet.com/uploadfiles/jishu/jslw/20080728043253984.gif- s; N/ |  ?! S9 h1 ~$ X4 |% B2 D- h& H* ?
3 E/ r) o2 x/ Y4 p, p' N8 t
    即通过两次一维的IDCT变换即可实现二维的IDCT。考虑到数据的读取,本设计IDCT模块的设计如图7虚线框中所示。3 p5 S  o7 [$ w/ m5 D/ b  R" w
    实现过程:首先读取Block ram的一列,相应的反量化数据从Dqt ram中读取,经过IQ(反量化单元,即乘法器)后的8个数据存储在regs中,之后控制器启动一维IDCT变换,并将反变换后的数据存储在REG FILES的一列中。当一个Block ram中的8列数据全部反量化和IDCT变换后,控制器将切换成对REG FILES中一行的数据进行一维IDCT变换,变换后的数据存储在REG FILES中的一行中,之后再进行下一行变换,直到8行数据全部IDCT 变换完。基于参考文献[2]的一维IDCT实现具有资源比较小和实现简单的特点,通过对IDCT反变换矩阵系数分析,一维IDCT奇偶数据变换具有不同的结构化特点,在此可以进行单独的设计,最后将两部分的结果数据进行碟形加减操作,得到一维IDCT的运算结果(见图7)。这样变换完的数据即可进行输出,送到显示单元进行色彩变换和其它后续处理后显示。* P! s4 f7 x; w# y1 N

" W; f9 E+ _, g5 Y: j2.5 测试与结果
0 x( R5 E9 x. k0 T. y% O3 u7 M      本设计采用的硬件开发平台为ALTERA DE2,FPGA为EP2C35F672C6,在quartusii 5.0中进行综合,所耗资源和最大时钟频率见表1。2005年ACTEL[3]公司推出的JPEG-D IP的速度针对不同的平台其速度变化从31M~69M,同年4I2I[4]公司推出的JPEG-D的最大速率为40M,从速度可以看出本设计达到了实时解码的要求。
: V% [) ^- A2 J( t5 H& k: L% A5 W8 J+ g- T; H# \, J' ]3 h
/ r- S8 F* l5 M
    将VHDL与C语言实现的JPEG解码器对图像解码产生的结果进行对比,从而可以判断解码正确与错误。通过结果对比,本设计结果完全正确。
4 I9 T7 w9 }. s* ^    本设计严格按照VLSI自顶向下设计的一般流程,首先进行C语言级建模[5],从而得到测试矢量和JPEG硬件解码器的总体架构;之后完成了各个顶层模块和子模块的接口定义;最后进行各个模块的VHDL实现。从结果可知达到了实时解码要求,并且节约了资源。
+ {# {, Z, {. {) ?6 Z( b; Z
, [2 E7 L/ d3 C& W
参考文献  C# O+ d/ K# j+ t$ Q* [) E0 w
[1] CCITT Rec.T.81(1992 E)104-105.
8 _0 j2 s2 E" J[2] Chris.tophLoeffler,Adriaan.Ligtenberg.Practical  fast 1-D DCT algorithms with 11 multiplication.[J]IEEE 1989.988-990.& S0 y) c. I2 z- P& W; g' ~# O0 P# z
[3] http://www.cast-inc.com.
# W0 K* w- g2 U4 o9 n3 S[4] http://www.4i42.com.8 m4 F7 ?0 A, u
[5] http://www.smalleranimals.com/.' R9 X, I) X3 ^
 楼主| 发表于 2009-3-23 22:52 | 显示全部楼层
JPEG2000编解码芯片ADV202的原理及应用
" E  X* a! s7 D+ ~7 L0 Q4 Z
# O2 `8 q$ G9 T/ R5 K) Y2 J: q4 Y6 b! Z6 [. u2 v
  ADV202是AD公司最新推出的一款单片JPEG2000(ISO/IEC15444-1图像压缩标准)编解码芯片,是当今市场上少有的具有实时压缩和解压缩标准(SD)视频信号和高清晰度(HDTV)视频信号功能的芯片。该芯片带有一个灵活接口,适用于多种视频和静止图像格式。8 l+ p  o; e& c) N# ]: j" }
http://img.ddvip.com/2008_08/1218277391_ddvip_1555.gif
0 J5 ]1 Q/ C- N% E  1 主要特点" ?3 {+ m) q4 ^/ q7 @3 k
  ·视频和静止图像的完全单片JPEG2000压缩和解压解决方案;
: P; N7 r( v* ?5 i2 m  ·专利的空间超效率回归滤波(SURF)技术使之具有低功耗和低成本的小波压缩;: [% j, z3 K: ?1 R& i
  ·支持最高6级的9/7和5/3小波变换;
/ X+ D1 d, n' v8 z  ·可编程图块/图像尺寸,在3分量4:2:2隔行扫描中的宽度可达2048像素,单分量模式中的宽度可达4096像素;. e. P. B0 ~9 M; B# J5 h0 K! X6 T
  ·最大图块/图像高度:4096像素;' V0 Z: s# |; R) I% k
  ·视频接口可直接支持ITU.R-BT656、SMPTE125M PAL/NTSC、SMPTE274M、SMPTE293M(525p)、ITU.R-BT1358(625p),以及不可逆模式最大输入速度为65Msps、可逆模式最大输入速度为40Msps的任何视频格式;: `$ N% S2 M+ `$ Q+ _
  ·两个或多个ADV202能组合满帧SMPTE274M HDTV(1080i)或SMPTE296M(720p);
, n9 s, X, i( X9 l  ·灵活异步SRAM类型主机接口能无缝连接到大多数16/32位微控制器和ASIC;
. d* [# b7 b. u0 e; N1 z  ·速率为115MHz的产品采用12mm×12mm121引脚CSPBGA封装,速率为150MHz产品采用13mm×13mm 144引脚CSPBGA封装。6 Q" u# ]  i' l0 D5 A1 A
  根据特殊的应用需求,ADV202可提供JPEG2000压缩所支持的不同标准,可提供原始的编码模块和特征数据输出,而JPEG2000编码流的产生和其它诸如位速率控制等的压缩过程则完全由主机软件来控制。另外,它也可以制作完整的、完全兼容的JPEG2000码流(j2c)以及jp2、jpx和mj2(运动JPEG2000)增强型格式的文件。
" E* E7 p+ a# C, lhttp://img.ddvip.com/2008_08/1218277392_ddvip_2119.gif3 t8 o3 Y' \' {: K1 `7 l$ H
  2 工作原理. }  M# X- A* T/ H8 X- Z
  ADV202的内部功能框图如图所示,该芯片主要由像素接口、小波变换引擎、熵编解码器、嵌入式处理器、存储器系统和内部DMA引擎等组成。输入图像和像素数据输入像素接口,采样值则经过隔行扫描传输到小波变换引擎中。在小波引擎中,每个图块或帧将通过5/3或9/7滤波器分解成许多子带。生成的小波系数写入内部寄存器中。熵编解码器将图像数据编码为符合JPEG2000标准的数据。内部DMA引擎提供存储器之间的高带宽传输及各模块和存储器之间的高性能传输。
6 P5 l! G, q1 k4 Z+ q6 a0 U5 d3 H1 ^  2.1 小波变换引擎& F0 I$ l2 N3 a2 K" I
  由于ADV202内含基于AD专利SURF技术的专用小波变换处理器。因此,它可以对一个图块进行高达6级的小波分解。在编码方式中,小波变换处理器将对未压缩的采样值进行小波变换和量化,然后将所有频率子带的小波系数写到内部存储器中。这些子带进一步分解成大小由用户定义的编码块,在将小波系数写入内部存储器时,通常由小波变换处理器来组织小波系数。在解码方式中,小波系数从内部存储器中读出,以用来重新生成未压缩时的采样值。% C, i3 m. V9 b$ V
  2.2 熵编解码器$ T  E/ L4 G+ s- h& ]
  熵编解码器用来对小波系数的编码块进行背景建模和算术编码,同时可在压缩过程中计算最佳速率和失真性能所必需的失真度。由于熵编码过程在JPEG2000压缩工程中对计算要求最高,因此,ADV202内部提供了三个专用的硬件熵编解码器。" g3 g7 Y/ x3 o' N1 I- O
  2.3 嵌入式处理器! y* }9 _; L3 {0 z" R" u: B6 g4 Q
  ADV202内嵌入了一个32位的RISC处理器,可用来配置、控制和管理其它专用硬件模块以及分解和产生JPEG2000视频流。RISC处理器具有每一个程序和数据存储器、中断控制器、标准总线接口及定时器计数器所对应的ROM和RAM。
2 ]' l  C. W, A! N$ h9 G! q% B  2.4 存储器系统: ]$ I0 L' Q: {
  存储器系统的主要功能是管理小波变换的系数数据、暂时存放编码块的特征数据以及给JPEG2000码流提供临时的存储空间。另外还可用作嵌入式处理器的程序和数据存储器。/ Z. s2 v* m" {: G
http://img.ddvip.com/2008_08/1218277393_ddvip_8736.gif
: ]# i* R* Z' a3 z& {+ A  2.5 内部DMA引擎   内部DMA引擎可提供存储器之间的高带宽传输及各模块和存储器之间的高性能传输。这对于码流的分解和高速率数据的产生万为重要。, q. P# B8 P0 k: r
  2.6 可配置FIFO模块
( K$ i8 ^9 f: q( J  T. U  内部FIFO用来给像素数据、编码流、特征数据或者其他辅助数据提供存储空间。它可以由主机接口在通常地址的读写周期中直接访问,也可以由外部主机DMA利用DREQ/DACK协议或专用硬件的握手机制来访问。每个FIFO都有一个可编程的门限值用来产生中断。
/ X, v0 E$ Z) }/ Y# q+ h  n  2.7 视频和主机接口
5 s, V, o  T: r/ _3 X8 v  有多种模式可以用来配置ADV202的接口。设计人员可以同时使用VDATA总线和HDATA总线,也可以单独使用HDATA总线。# z4 c% O" A8 l4 @+ o7 i
  (1)视频接口(VDATA总线)# h" M$ j, _* W' U- p6 C
  视频接口主要应用于未压缩像素数据和压缩数据分离的场合。例如用VDATA总线输入未压缩的数据,而通过HDATA总线输出压缩后的数据等。8 K8 V& g5 ^! m1 u
  视频接口支持8、10、12位单一或多元格式,也支持双通道8、10、12位格式的视频和静止图像数据,还支持单通道输入模式下YcrCb格式的数字视频和双通道输入模式下Y和CrCb格式的数字视频信号,但YcrCb数据必须是4:2:2格式。VDATA总线可支持多种格式视频数据的输入输出,表1所列是其可支持的视频输入输出格式。$ Q) t) W8 M3 |, f0 @2 ~
  表1 视频输入输出模式
, O( U0 y( }$ V$ s! e$ ]
视频模式描  述
EAV/SAV模式包含EAV/SAV编码的视频,YCrCb在单总线上隔行扫描
HVF模式H,V,F独立的视频信号,YCrCb在单总线上的隔行扫描
双通道模式包含EAV/SAV编码的视频,Y和YCrCb在独立的总线
原始视频模式用于静止图征和非标准视频
HDTV模式用于高于27MHz时钟信号的视频数据
  (2)主机接口(HDATA总线): o6 Z5 X' B. Y- c* P+ n0 o
  ADV202可以通过异步SRAM方式、DMA访问方式或码流方式直接和大多数主机处理器及ASIC相连接。ADV202提供有16位和32位控制总线及8、16和32位数据传输总线。主机接口用于配置、控制制控制功能以及传输压缩后的数据流,在某些格式中还可用作未压缩数据流的传输。主机接口要吧由并发的四个数据流及控制和状态通信所共享。输入主机接口的像素数据支持8、10、12、14和16位原始像素数据。它既可用作静止图像的输入输出,也可用作压缩后视频数据的输出。9 a- s* {# m( @
  3 典型应用
+ M. R) h1 F! Z% G5 e  Z  3.1 多片编码模式& ^( Y' y+ S( ^; [
  由于输入数据速率的限制,一个1080i视频信号的应用系统至少需要两片ADV202,来对完全分辨率为1080i的视频信号进行编码或解码。图2所示为它的编码模式,Y数据和CbCr数据通过不同的总线输入到ADV202,其中AD202_1处理1080i视频信号的亮度数据,而ADV202_2则用于处理1080i视频信号的色度数据。为了对此应用模式下对应的输出数据进行同步,其输入数据必须是EAV/SAV编码格式。此模式通常应用于ADV202的视频输出直接连到需要亮度和色度数据同步的接收设备中。
1 Q5 _8 I5 _$ s1 c# P  多片模式也可以应用于主/从或从/从配置中的解码模式。而在编码模式中,ADV202通常用作从设备。为了使获取的1080i视频信号具有更好的特性(如无损压缩),建议选用三片或三片以上的ADV202来处理信号。! P$ D5 ]: K& Y( B+ K# B
  3.2 HPII(主机接口-像素接口)解码模式
, C7 [# `8 `7 a- f! a  ADV202允许通过HDATA总线来输入输出视频和静止图像,而不用VDATA总线提供的专用视频接口,这种模式称为HIPI模式。
) q& M8 G0 ]4 o. ^0 x( e  图3所示为ADV202用于HIPI解码模式的电路连接,像素数据由HDATA1[31:1]输出。DMA通道1用来输入压缩数据,而DMA通道0则用于将像素数据写到像素FIFO中。DREQ0/DACK0用来控制通道0的读写过程,而DREQ1/DACK1用来控制通道1的读写过程
 楼主| 发表于 2009-3-23 23:05 | 显示全部楼层
用verilog  写的JPGE的代码

fpga-jpeg.rar

101.38 KB, 下载次数: 465, 下载积分: 一乐金币 -1

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-18 18:24 , Processed in 0.056859 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表