scuffle_transmuxer/codecs/
aac.rs1use bytes::Bytes;
2use scuffle_aac::PartialAudioSpecificConfig;
3use scuffle_flv::audio::header::legacy::{SoundSize, SoundType};
4use scuffle_mp4::DynBox;
5use scuffle_mp4::types::esds::Esds;
6use scuffle_mp4::types::esds::descriptor::header::DescriptorHeader;
7use scuffle_mp4::types::esds::descriptor::traits::DescriptorType;
8use scuffle_mp4::types::esds::descriptor::types::decoder_config::DecoderConfigDescriptor;
9use scuffle_mp4::types::esds::descriptor::types::decoder_specific_info::DecoderSpecificInfoDescriptor;
10use scuffle_mp4::types::esds::descriptor::types::es::EsDescriptor;
11use scuffle_mp4::types::mp4a::Mp4a;
12use scuffle_mp4::types::stsd::{AudioSampleEntry, SampleEntry};
13use scuffle_mp4::types::trun::{TrunSample, TrunSampleFlag};
14
15use crate::TransmuxError;
16
17pub(crate) fn stsd_entry(
18 sound_size: SoundSize,
19 sound_type: SoundType,
20 data: Bytes,
21) -> Result<(DynBox, PartialAudioSpecificConfig), TransmuxError> {
22 let aac_config = scuffle_aac::PartialAudioSpecificConfig::parse(&data)?;
23
24 Ok((
25 Mp4a::new(
26 SampleEntry::new(AudioSampleEntry::new(
27 match sound_type {
28 SoundType::Mono => 1,
29 SoundType::Stereo => 2,
30 _ => return Err(TransmuxError::InvalidAudioChannels),
31 },
32 match sound_size {
33 SoundSize::Bit8 => 8,
34 SoundSize::Bit16 => 16,
35 _ => return Err(TransmuxError::InvalidAudioSampleSize),
36 },
37 aac_config.sampling_frequency,
38 )),
39 Esds::new(EsDescriptor::new(
40 2,
41 0,
42 Some(0),
43 None,
44 Some(0),
45 Some(DecoderConfigDescriptor::new(
46 0x40, 0x05, 0, 0, Some(DecoderSpecificInfoDescriptor {
51 header: DescriptorHeader::new(DecoderSpecificInfoDescriptor::TAG),
52 data,
53 }),
54 )),
55 None,
56 )),
57 None,
58 )
59 .into(),
60 aac_config,
61 ))
62}
63
64pub(crate) fn trun_sample(data: &Bytes) -> Result<(TrunSample, u32), TransmuxError> {
65 Ok((
66 TrunSample {
67 duration: Some(1024),
68 composition_time_offset: None,
69 flags: Some(TrunSampleFlag {
70 reserved: 0,
71 is_leading: 0,
72 sample_degradation_priority: 0,
73 sample_depends_on: 2,
74 sample_has_redundancy: 0,
75 sample_is_depended_on: 0,
76 sample_is_non_sync_sample: false,
77 sample_padding_value: 0,
78 }),
79 size: Some(data.len() as u32),
80 },
81 1024,
82 ))
83}