Skip to main content

mediadecode_ffmpeg/
adapter.rs

1//! `Ffmpeg` adapter — implements [`mediadecode::VideoAdapter`],
2//! [`mediadecode::AudioAdapter`], and [`mediadecode::SubtitleAdapter`]
3//! for this crate.
4//!
5//! The adapter is a zero-sized type whose sole purpose is to bind the
6//! associated types together so the rest of the API (Packet / Frame /
7//! Decoder) reads cleanly: `VideoPacket<Ffmpeg, FfmpegBuffer>` etc.
8
9use mediadecode::{
10  PixelFormat,
11  adapter::{AudioAdapter, SubtitleAdapter, VideoAdapter},
12  channel::AudioChannelLayout,
13};
14
15use crate::{
16  codec_id::CodecId,
17  extras::{
18    AudioFrameExtra, AudioPacketExtra, SubtitleFrameExtra, SubtitlePacketExtra, VideoFrameExtra,
19    VideoPacketExtra,
20  },
21  sample_format::SampleFormat,
22};
23
24/// Zero-sized type carrying the FFmpeg adapter's vocabulary.
25///
26/// Used as the `A` parameter on `mediadecode::VideoPacket<A, B>` /
27/// `Frame<A, B>` (and audio / subtitle counterparts) when this crate's
28/// decoders are in play. Construction is `Ffmpeg` (unit struct);
29/// nothing about the adapter is stateful.
30#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
31pub struct Ffmpeg;
32
33impl VideoAdapter for Ffmpeg {
34  type CodecId = CodecId;
35  type PixelFormat = PixelFormat;
36  type PacketExtra = VideoPacketExtra;
37  type FrameExtra = VideoFrameExtra;
38}
39
40impl AudioAdapter for Ffmpeg {
41  type CodecId = CodecId;
42  type SampleFormat = SampleFormat;
43  type ChannelLayout = AudioChannelLayout;
44  type PacketExtra = AudioPacketExtra;
45  type FrameExtra = AudioFrameExtra;
46}
47
48impl SubtitleAdapter for Ffmpeg {
49  type CodecId = CodecId;
50  type PacketExtra = SubtitlePacketExtra;
51  type FrameExtra = SubtitleFrameExtra;
52}
53
54#[cfg(test)]
55mod tests {
56  use super::*;
57
58  /// Compile-time proof that the three trait impls' associated types
59  /// resolve correctly when the `Ffmpeg` adapter parameterizes
60  /// mediadecode's generic types.
61  #[test]
62  fn adapter_parameterizes_mediadecode_types() {
63    use crate::buffer::FfmpegBuffer;
64    use mediadecode::{
65      adapter::{AudioAdapter, SubtitleAdapter, VideoAdapter},
66      packet::{AudioPacket, SubtitlePacket, VideoPacket},
67    };
68
69    fn _video_packet_resolves(
70      _: &VideoPacket<Ffmpeg, FfmpegBuffer>,
71      _: <Ffmpeg as VideoAdapter>::CodecId,
72      _: <Ffmpeg as VideoAdapter>::PixelFormat,
73      _: &<Ffmpeg as VideoAdapter>::PacketExtra,
74      _: &<Ffmpeg as VideoAdapter>::FrameExtra,
75    ) {
76    }
77
78    fn _audio_packet_resolves(
79      _: &AudioPacket<Ffmpeg, FfmpegBuffer>,
80      _: <Ffmpeg as AudioAdapter>::CodecId,
81      _: <Ffmpeg as AudioAdapter>::SampleFormat,
82      _: &<Ffmpeg as AudioAdapter>::ChannelLayout,
83      _: &<Ffmpeg as AudioAdapter>::PacketExtra,
84      _: &<Ffmpeg as AudioAdapter>::FrameExtra,
85    ) {
86    }
87
88    fn _subtitle_packet_resolves(
89      _: &SubtitlePacket<Ffmpeg, FfmpegBuffer>,
90      _: <Ffmpeg as SubtitleAdapter>::CodecId,
91      _: &<Ffmpeg as SubtitleAdapter>::PacketExtra,
92      _: &<Ffmpeg as SubtitleAdapter>::FrameExtra,
93    ) {
94    }
95  }
96
97  #[test]
98  fn ffmpeg_is_zero_sized() {
99    use core::mem::size_of;
100    assert_eq!(size_of::<Ffmpeg>(), 0);
101  }
102}