1 /*****************************************************************************
2 * extradata.c: Muxing extradata builder/gatherer
3 *****************************************************************************
4 * Copyright (C) 2018 VideoLabs, VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
24 #include <vlc_common.h>
25 #include <vlc_codec.h>
27 #include "extradata.h"
28 #include "../packetizer/av1_obu.h"
29 #include "../packetizer/a52.h"
31 struct mux_extradata_builder_cb
33 int (*pf_init
)(mux_extradata_builder_t
*);
34 void (*pf_feed
)(mux_extradata_builder_t
*, const uint8_t *, size_t);
35 void (*pf_deinit
)(mux_extradata_builder_t
*);
38 struct mux_extradata_builder_t
40 struct mux_extradata_builder_cb cb
;
47 static void ac3_extradata_builder_Feed(mux_extradata_builder_t
*m
,
48 const uint8_t *p_data
, size_t i_data
)
50 if(m
->i_extra
|| i_data
< VLC_A52_MIN_HEADER_SIZE
||
51 p_data
[0] != 0x0B || p_data
[1] != 0x77)
54 struct vlc_a52_bitstream_info bsi
;
55 if(vlc_a52_ParseAc3BitstreamInfo(&bsi
, &p_data
[4], /* start code + CRC */
56 VLC_A52_MIN_HEADER_SIZE
- 4 ) != VLC_SUCCESS
)
59 m
->p_extra
= malloc(3);
65 bs_write_init(&s
, m
->p_extra
, m
->i_extra
);
66 bs_write(&s
, 2, bsi
.i_fscod
);
67 bs_write(&s
, 5, bsi
.i_bsid
);
68 bs_write(&s
, 3, bsi
.i_bsmod
);
69 bs_write(&s
, 3, bsi
.i_acmod
);
70 bs_write(&s
, 1, bsi
.i_lfeon
);
71 bs_write(&s
, 5, bsi
.i_frmsizcod
>> 1); // bit_rate_code
72 bs_write(&s
, 5, 0); // reserved
75 const struct mux_extradata_builder_cb ac3_cb
=
78 ac3_extradata_builder_Feed
,
82 static void eac3_extradata_builder_Feed(mux_extradata_builder_t
*m
,
83 const uint8_t *p_data
, size_t i_data
)
85 if(m
->i_extra
|| i_data
< VLC_A52_MIN_HEADER_SIZE
||
86 p_data
[0] != 0x0B || p_data
[1] != 0x77)
89 struct vlc_a52_bitstream_info bsi
;
90 if(vlc_a52_ParseEac3BitstreamInfo(&bsi
, &p_data
[2], /* start code */
91 i_data
- 2) != VLC_SUCCESS
)
94 m
->p_extra
= malloc(5);
100 bs_write_init(&s
, m
->p_extra
, m
->i_extra
);
101 const unsigned rgi_fscod_samplerates
[] = { 48000, 44100, 32000 };
102 unsigned fs
= rgi_fscod_samplerates
[bsi
.i_fscod
];
103 unsigned numblks
= bsi
.eac3
.i_numblkscod
+ 1;
106 unsigned data_rate
= (bsi
.eac3
.i_frmsiz
+ 1) * fs
/ (numblks
<< 4); /* F.6.2.2 */
107 bs_write(&s
, 13, data_rate
);
108 bs_write(&s
, 3, 0); // num_ind_sub - 1
109 bs_write(&s
, 2, bsi
.i_fscod
);
110 bs_write(&s
, 5, bsi
.i_bsid
);
111 bs_write(&s
, 5, bsi
.i_bsmod
);
112 bs_write(&s
, 3, bsi
.i_acmod
);
113 bs_write(&s
, 1, bsi
.i_lfeon
);
114 bs_write(&s
, 3, 0); // reserved
115 bs_write(&s
, 4, 0); // num_dep_sub
116 bs_write(&s
, 1, 0); // reserved
119 const struct mux_extradata_builder_cb eac3_cb
=
122 eac3_extradata_builder_Feed
,
126 static void av1_extradata_builder_Feed(mux_extradata_builder_t
*m
,
127 const uint8_t *p_data
, size_t i_data
)
132 AV1_OBU_iterator_ctx_t ctx
;
133 AV1_OBU_iterator_init(&ctx
, p_data
, i_data
);
134 const uint8_t *p_obu
; size_t i_obu
;
135 while(AV1_OBU_iterate_next(&ctx
, &p_obu
, &i_obu
))
137 enum av1_obu_type_e OBUtype
= AV1_OBUGetType(p_obu
);
138 if(OBUtype
!= AV1_OBU_SEQUENCE_HEADER
)
140 av1_OBU_sequence_header_t
*p_sh
= AV1_OBU_parse_sequence_header(p_obu
, i_obu
);
143 m
->i_extra
= AV1_create_DecoderConfigurationRecord(&m
->p_extra
, p_sh
,
144 1, (const uint8_t **)&p_obu
, &i_obu
);
145 AV1_release_sequence_header(p_sh
);
151 const struct mux_extradata_builder_cb av1_cb
=
154 av1_extradata_builder_Feed
,
158 void mux_extradata_builder_Delete(mux_extradata_builder_t
*m
)
166 mux_extradata_builder_t
* mux_extradata_builder_New(vlc_fourcc_t fcc
)
168 const struct mux_extradata_builder_cb
*cb
;
184 mux_extradata_builder_t
*m
= calloc(1, sizeof(*m
));
189 if(m
->cb
.pf_init
&& m
->cb
.pf_init(m
) != 0)
198 size_t mux_extradata_builder_Get(mux_extradata_builder_t
*m
, const uint8_t **a
)
204 void mux_extradata_builder_Feed(mux_extradata_builder_t
*m
,
205 const uint8_t *p_data
, size_t i_data
)
207 m
->cb
.pf_feed(m
, p_data
, i_data
);