@@ -70,6 +70,32 @@ struct Frame
70
70
int64_t duration = 0 ;
71
71
};
72
72
73
+ AVPixelFormat get_pix_fmt_with_alpha (AVPixelFormat fmt)
74
+ {
75
+ switch (fmt) {
76
+ case AV_PIX_FMT_YUV420P:
77
+ return AV_PIX_FMT_YUVA420P;
78
+ case AV_PIX_FMT_YUV422P:
79
+ return AV_PIX_FMT_YUVA422P;
80
+ case AV_PIX_FMT_YUV444P:
81
+ return AV_PIX_FMT_YUVA444P;
82
+ default :
83
+ break ;
84
+ }
85
+ return fmt;
86
+ }
87
+
88
+ const AVCodec* get_decoder (AVCodecID codec_id)
89
+ {
90
+ // enforce use of libvpx for vp8 and vp9 codecs to be able
91
+ // to decode webm files with alpha channel
92
+ if (codec_id == AV_CODEC_ID_VP9)
93
+ return avcodec_find_decoder_by_name (" libvpx-vp9" );
94
+ else if (codec_id == AV_CODEC_ID_VP8)
95
+ return avcodec_find_decoder_by_name (" libvpx" );
96
+ return avcodec_find_decoder (codec_id);
97
+ }
98
+
73
99
// TODO (fix) Handle ts discontinuities.
74
100
// TODO (feat) Forward options.
75
101
@@ -102,7 +128,8 @@ class Decoder
102
128
explicit Decoder (AVStream* stream)
103
129
: st(stream)
104
130
{
105
- const auto codec = avcodec_find_decoder (stream->codecpar ->codec_id );
131
+ const auto codec = get_decoder (stream->codecpar ->codec_id );
132
+
106
133
if (!codec) {
107
134
FF_RET (AVERROR_DECODER_NOT_FOUND, " avcodec_find_decoder" );
108
135
}
@@ -116,6 +143,12 @@ class Decoder
116
143
117
144
FF (avcodec_parameters_to_context (ctx.get (), stream->codecpar ));
118
145
146
+ if (stream->metadata != NULL ) {
147
+ auto entry = av_dict_get (stream->metadata , " alpha_mode" , NULL , AV_DICT_MATCH_CASE);
148
+ if (entry != NULL && entry->value != NULL && *entry->value == ' 1' )
149
+ ctx->pix_fmt = get_pix_fmt_with_alpha (ctx->pix_fmt );
150
+ }
151
+
119
152
int thread_count = env::properties ().get (L" configuration.ffmpeg.producer.threads" , 0 );
120
153
FF (av_opt_set_int (ctx.get (), " threads" , thread_count, 0 ));
121
154
0 commit comments