summaryrefslogtreecommitdiff
blob: 7c006b8506ae64974a7990e534606f2ed788283d (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
commit dcfde2934dd7b5401b29d6a604fa3eca1b867d5c
Author: wm4 <wm4@nowhere>
Date:   Sun Jul 24 19:31:47 2016 +0200

audio: use idiotic FFmpeg ABI rules for public-except-not-public fields

The FFmpeg API is incredibly weird and inconsistent about this. This is
also a FFmpeg-only issue and nothing like this is in Libav - which
doesn't really show FFmpeg in a very positive light.

(To make it even worse: this is a full-blown Libav API incompatibility,
even though this crap was added for Libav ABI-compatibility. It's
absurd.)

Quoting the FFmpeg header for the AVFrame.channels field:

    /**
     * number of audio channels, only used for audio.
     * Code outside libavutil should access this field using:
     * av_frame_get_channels(frame)
     * - encoding: unused
     * - decoding: Read by user.
     */
    int channels;

It says "should" not must, and it doesn't even mention
av_frame_set_channels(). It's also in the section for public fields (not
below a marker that indicates private fields in a public struct, like
it's done e.g. in AVCodecContext).

But not using the accessor will cause silent failures on ABI changes.
The failure that happened due to this code didn't even make it apparent
what was wrong. So just use the idiotic accessor.

Also harmonize the FFmpeg-cursing in the code. (It's fully justified.)

Fixes #3295.

Note that mpv will still check the exact library version numbers, and
reject mismatches - to protect itself from such issues in the future.

diff --git a/audio/audio.c b/audio/audio.c
index 710cc03..4c67a9a 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -347,9 +347,9 @@ struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe)
     mp_chmap_from_lavc(&lavc_chmap, avframe->channel_layout);

 #if LIBAVUTIL_VERSION_MICRO >= 100
-    // FFmpeg being special again
-    if (lavc_chmap.num != avframe->channels)
-        mp_chmap_from_channels(&lavc_chmap, avframe->channels);
+    // FFmpeg being stupid POS again
+    if (lavc_chmap.num != av_frame_get_channels(avframe))
+        mp_chmap_from_channels(&lavc_chmap, av_frame_get_channels(avframe));
 #endif

     new->rate = avframe->sample_rate;
@@ -407,8 +407,8 @@ int mp_audio_to_avframe(struct mp_audio *frame, struct AVFrame *avframe)
     if (!avframe->channel_layout)
         goto fail;
 #if LIBAVUTIL_VERSION_MICRO >= 100
-    // FFmpeg being a stupid POS (but I respect it)
-    avframe->channels = frame->channels.num;
+    // FFmpeg being a stupid POS again
+    av_frame_set_channels(avframe, frame->channels.num);
 #endif
     avframe->sample_rate = frame->rate;