ijkplayer 升级 FFmpeg 到 6 代
ijkplayer 升级 FFmpeg 到 6 代
ijkplayer 的编译工具链得到了全面升级,但是 FFmpeg 仍旧使用 ff4.0–ijk0.8.8–20210426–001 版本,很多新特性无法使用。所以决定升级到 6 代版本,下面记录的是遇到的一些问题:
找不到 av_frame_get_pkt_pos
在 6 代里这个方法已经被移除了,所以我打开 4 代的源码,想通过看实现逻辑中找到适配的灵感。但当我打开 4 代的源码时却发现有方法声明,但没有方法定义。怎么可能呢,我对 C 语言很了解的,没有定义意味着根本无法成功编译啊。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#if FF_API_FRAME_GET_SET
/**
* Accessors for some AVFrame fields. These used to be provided for ABI
* compatibility, and do not need to be used anymore.
*/
attribute_deprecated
int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame);
attribute_deprecated
void av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val);
attribute_deprecated
int64_t av_frame_get_pkt_duration (const AVFrame *frame);
attribute_deprecated
void av_frame_set_pkt_duration (AVFrame *frame, int64_t val);
attribute_deprecated
int64_t av_frame_get_pkt_pos (const AVFrame *frame);
attribute_deprecated
void av_frame_set_pkt_pos (AVFrame *frame, int64_t val);
attribute_deprecated
int64_t av_frame_get_channel_layout (const AVFrame *frame);
attribute_deprecated
void av_frame_set_channel_layout (AVFrame *frame, int64_t val);
attribute_deprecated
int av_frame_get_channels (const AVFrame *frame);
attribute_deprecated
void av_frame_set_channels (AVFrame *frame, int val);
attribute_deprecated
int av_frame_get_sample_rate (const AVFrame *frame);
attribute_deprecated
void av_frame_set_sample_rate (AVFrame *frame, int val);
attribute_deprecated
AVDictionary *av_frame_get_metadata (const AVFrame *frame);
attribute_deprecated
void av_frame_set_metadata (AVFrame *frame, AVDictionary *val);
attribute_deprecated
int av_frame_get_decode_error_flags (const AVFrame *frame);
attribute_deprecated
void av_frame_set_decode_error_flags (AVFrame *frame, int val);
attribute_deprecated
int av_frame_get_pkt_size(const AVFrame *frame);
attribute_deprecated
void av_frame_set_pkt_size(AVFrame *frame, int val);
#if FF_API_FRAME_QP
attribute_deprecated
int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type);
attribute_deprecated
int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int type);
#endif
attribute_deprecated
enum AVColorSpace av_frame_get_colorspace(const AVFrame *frame);
attribute_deprecated
void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val);
attribute_deprecated
enum AVColorRange av_frame_get_color_range(const AVFrame *frame);
attribute_deprecated
void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val);
#endif
仔细一看,发现了这些方法被 FF_API_FRAME_GET_SET 宏包裹着,这是什么鬼东西,搜索这个宏之后,发现了新大陆:
1
2
3
4
5
6
7
8
9
10
11
12
13
#if FF_API_FRAME_GET_SET
MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp)
MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration)
MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos)
MAKE_ACCESSORS(AVFrame, frame, int64_t, channel_layout)
MAKE_ACCESSORS(AVFrame, frame, int, channels)
MAKE_ACCESSORS(AVFrame, frame, int, sample_rate)
MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
MAKE_ACCESSORS(AVFrame, frame, int, decode_error_flags)
MAKE_ACCESSORS(AVFrame, frame, int, pkt_size)
MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace)
MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range)
#endif
原来在 frame.c 里通过宏进行定义的,难怪直接搜方法,搜不到呢。又是 FFmpeg 的一个黑科技。实际上就是访问结构体的属性,没干啥事,模拟下面向对象的 getter 和 setter 方法。
那对于 av_frame_get_pkt_pos 方法,直接改成 frame->pkt_pos 就行了,其他属性也是如此。
本文由作者按照 CC BY 4.0 进行授权