ffmpeg的mpeg2编码I帧代码解读(续)

1.MpegEncContext这个struct类型,一定要吃透,虽然代码是用C写得,但是写得很C++,这个MpegEncContext其实可以看做一个C++的类,里面定义了很多指针,这些指针指又指向了一些strcut,而这个struct其实相当于C++的成员函数,成员函数的初始化,一般是在XX_init函数里面初始化的。这一点,可以在后面的叙述中体现出来。

2.再说一下编码的过程,encode_mb_internal函数,做了MarcoBlock的编码,在1629行,开始做DCT&quant,1686行,开始做霍夫曼编码,而霍夫曼编码,对不同的标准来说,码表是不一样的,因此在1687行做了一个switch的选择,mpeg1和mpeg2,都是用的相同的mpeg1_encode_mb函数进行block的编码,而block内的编码,在以前的笔记中已经提到,过程这里不重复。

3.现在说DCT&quant,其中,1635行s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);,就是做DCT&quant。正如第1点中说的,dct_quantize本来只是MpegEncContext中的一个元素,类型为指针,指向一个struct,而这个struct就相当于C++里面的成员函数。现在,我们知道了在这个地方,相当于调用了一个成员函数,做了DCT&quant这件事情,接下来,讨论这个成员函数在哪里初始化的。

4.在Mpegvideo.c的MPV_encode_init函数里面,对编码所需要的一些“成员函数”进行了初始化。前面一堆东西,是做编码器的选择。在第656行,dct_quant这成员函数被初始化为dct_quant_c这个函数。于是,接下去找dct_quant_c这个函数的定义。发现,3649行,又调用了dsp.fdct这个成员函数,做离散余弦变换。接下来找dsp.fdct这个成员函数的初始化地方。
这个非常费劲,我找了半天才找到——在函数dsputil_init里面做了fdct的初始化,一步一步的跟踪调用关系,可以发现过程是这样的:
MPV_encode_init调用MPV_common_init,再调用dsputil_init,在dsputil_init里面初始化了fdct,而MPV_encode_init紧接着,执行前面提到的dct_quantize的初始化。
至此,整个初始化完成。

posted on 2009-09-10 16:40  vincenzo.lai  阅读(2751)  评论(3编辑  收藏  举报

导航