1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * The Opus specification is part of IETF RFC 6716:
19  * http://tools.ietf.org/html/rfc6716
20  */
21 
22 #ifndef OPUS_HEADER_H_
23 #define OPUS_HEADER_H_
24 
25 namespace android {
26 
27 /* Constants used for delimiting Opus CSD */
28 #define AOPUS_CSD_MARKER_PREFIX "AOPUS"
29 #define AOPUS_CSD_MARKER_PREFIX_SIZE (sizeof(AOPUS_CSD_MARKER_PREFIX) - 1)
30 #define AOPUS_CSD_OPUS_HEADER_MARKER AOPUS_CSD_MARKER_PREFIX "HDR"
31 #define AOPUS_CSD_CODEC_DELAY_MARKER AOPUS_CSD_MARKER_PREFIX "DLY"
32 #define AOPUS_CSD_SEEK_PREROLL_MARKER AOPUS_CSD_MARKER_PREFIX "PRL"
33 #define AOPUS_MARKER_SIZE 8
34 #define AOPUS_LENGTH_SIZE sizeof(uint64_t)
35 #define AOPUS_CSD_CODEC_DELAY_SIZE \
36      (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + sizeof(uint64_t)
37 #define AOPUS_CSD_SEEK_PREROLL_SIZE \
38      (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + sizeof(uint64_t)
39 
40 /* OpusHead csd minimum size is 19 */
41 #define AOPUS_OPUSHEAD_MINSIZE 19
42 #define AOPUS_CSD_OPUSHEAD_MINSIZE \
43     (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + (AOPUS_OPUSHEAD_MINSIZE)
44 
45 #define AOPUS_UNIFIED_CSD_MINSIZE \
46     ((AOPUS_CSD_OPUSHEAD_MINSIZE) + \
47      (AOPUS_CSD_CODEC_DELAY_SIZE) + \
48      (AOPUS_CSD_SEEK_PREROLL_SIZE))
49 
50 /* OpusHead csd at max can be AOPUS_CSD_OPUSHEAD_MINSIZE + 2 + max number of channels (255) */
51 #define AOPUS_OPUSHEAD_MAXSIZE ((AOPUS_OPUSHEAD_MINSIZE) + 2 + 255)
52 #define AOPUS_CSD_OPUSHEAD_MAXSIZE \
53     (AOPUS_MARKER_SIZE) + (AOPUS_LENGTH_SIZE) + (AOPUS_OPUSHEAD_MAXSIZE)
54 
55 #define AOPUS_UNIFIED_CSD_MAXSIZE \
56     ((AOPUS_CSD_OPUSHEAD_MAXSIZE) + \
57      (AOPUS_CSD_CODEC_DELAY_SIZE) + \
58      (AOPUS_CSD_SEEK_PREROLL_SIZE))
59 
60 struct OpusHeader {
61     int channels;
62     int channel_mapping;
63     int num_streams;
64     int num_coupled;
65     int16_t gain_db;
66     int skip_samples;
67     uint8_t stream_map[8];
68 };
69 
70 bool ParseOpusHeader(const uint8_t* data, size_t data_size, OpusHeader* header);
71 int WriteOpusHeader(const OpusHeader &header, int input_sample_rate, uint8_t* output, size_t output_size);
72 bool GetOpusHeaderBuffers(const uint8_t *data, size_t data_size,
73                           void **opusHeadBuf, size_t *opusHeadSize,
74                           void **codecDelayBuf, size_t *codecDelaySize,
75                           void **seekPreRollBuf, size_t *seekPreRollSize);
76 int WriteOpusHeaders(const OpusHeader &header, int inputSampleRate,
77                      uint8_t* output, size_t outputSize, uint64_t codecDelay,
78                      uint64_t seekPreRoll);
79 bool IsOpusHeader(const uint8_t *data, size_t data_size);
80 }  // namespace android
81 
82 #endif  // OPUS_HEADER_H_
83