Skip to content

Commit 48bfd05

Browse files
committed
Add RFC: Codec Identifiers
1 parent da063de commit 48bfd05

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

text/0000-codec-identifiers.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Summary
2+
3+
This RFC intends to faciliatet discussion to find a way to move away from storing codec identifiers as strings. This is to avoid string comparisons and remove some redundancies such as outputs defining their own codec enumerations.
4+
5+
# Motivation
6+
7+
String comparisons are slow, error prone (case sensitivity, typos, etc.), and generally ugly. Most outputs convert from strings to internal enumerations anyway which could be made redundant by providing them in the first place.
8+
9+
# Overview
10+
11+
There are two components to this RFC: Codec Identifier and Codec Tags.
12+
The former specifies a codec family such as H.264/AVC, while the latter specifies a specific variant used for the encoded bitstream.
13+
14+
## Codec Tags
15+
16+
Codec "tags" or FourCC codes (`uint32_t`) are used by containers such as MOV/MP4 or Enhanced FLV, and are used by some codecs to identify specific flavours or variants.
17+
For example, ProRes uses several different ones depending on the specific feature set used (ProRes LT/HQ/XQ/etc.).
18+
Currently support for this is hacked in by passing a value through `obs_data` objects, but this should be implemented natively.
19+
20+
### Proposed API
21+
22+
Codec tags can change depending on encoder configuration, and cannot be a static value in the `obs_encoder_info` struct, thus there needs to be a function that can be called to ask the encoder for the appropiate tag for its current configuration.
23+
24+
- New API function: `uint32_t obs_encoder_get_codec_tag(obs_encoder_t *encoder)`
25+
- New `obs_encoder_info` struct member: `uint32_t (*codec_tag)(void *data)`
26+
27+
For most codecs the implementation of the `codec_tag´ function may be ommited and a default value is provided by libobs. This default tag could be obtained from libavcodec via `av_codec_get_tag()` or hardcoded to the ones we currently use (i.e. `avc1` for H.264, `hvc1` for HEVC, `av01` for AV1).
28+
29+
**Note:** FFmpeg currently has two separate codec tag lists, one for ISO-BMFF/QuickTime (MP4/MOV) and one for RIFF (e.g. AVI), this proposal would only implement the MOV/MP4 tags as the RIFF ones are not relevant to OBS outside of possibly DirectShow.
30+
We may elect to remove ambiguities by having a second paramter specifying a codec tag namespace, or explicitly naming the function to indicate that it returns ISO format tags.
31+
32+
## Codec Identifier
33+
34+
This RFC proposes there different methods, one of which should be agreed upon:
35+
36+
### FFmpeg AVCodecID
37+
38+
This approach would simply use `AVCodecID` enum defined in libavcodec.
39+
40+
#### Advantages
41+
42+
- libobs already links against libav* libraries so IDs can be used without many changes
43+
- Easy to use in FFmpeg muxer and FFmpeg-based outputs (e.g. SRT/RIST)
44+
- libav* functions available for converting from current string-based names to FFmpeg IDs
45+
46+
#### Drawbacks
47+
48+
- Not all modules that interface with video data or implement encoders currently depend on ffmpeg (e.g. obs-outputs, VideoToolbox)
49+
- While unlikely, it could happen that FFmpeg does not support a codec we want to support, or support is missing from an older version, e.g. on LTS releases
50+
51+
### Codec Tags / FourCC
52+
53+
In this case we define the aforementioned codec tag as the new identifier.
54+
55+
#### Advantages
56+
57+
- Avoids a secondary API for codec identifiers
58+
- FFmpeg's ISO/QuickTime tag list should support all codecs upstream OBS supports
59+
60+
#### Drawbacks
61+
62+
- Many codecs have more than one tag, which could require large if clauses and may still require mapping to an internal enumeration value
63+
- Codec support for ISO and QuickTime formats is limited
64+
- Tags are mostly intended to be opaque values that are relevant to the muxer, and probably shouldn't be used as a unqiue identifier for a codec family
65+
66+
### OBS-specific IDs
67+
68+
In this case we would define our own enumeration, for example:
69+
```c
70+
enum OBSCodecID {
71+
OBS_CODEC_INVALID = 0,
72+
OBS_CODEC_H264,
73+
OBS_CODEC_HEVC,
74+
OBS_CODEC_AV1,
75+
OBS_CODEC_PRORES,
76+
}
77+
```
78+
79+
#### Advantages
80+
81+
- Simple enum in libobs
82+
- No external dependencies
83+
84+
#### Drawbacks
85+
86+
- Requires libobs API changes to add new codecs
87+
- Would prevent third-party plugins from adding codecs not supported by upstream OBS
88+
89+
A potential workaround is to still have a fallback such as `OBS_CODEC_CUSTOM` which still allows passing a string to the muxer, which would need special support for handling codec string names which is probably undesireable.
90+
91+
# Additional Information
92+
93+
- FFmpeg Codec Defintions: https://github.com/FFmpeg/FFmpeg/blob/0ae157b3603f27d8057febd8f2680ac1030722ee/libavcodec/codec_id.h#L49
94+
- RFC 6381, specifying the common use of ISO codec identifiers for MIME types: https://datatracker.ietf.org/doc/html/rfc6381

0 commit comments

Comments
 (0)