Skip to content

Commit

Permalink
feat: #353 enhanced rtmp v2 audio(don't support mutli-channel)
Browse files Browse the repository at this point in the history
  • Loading branch information
ireader committed Sep 7, 2024
1 parent e03136e commit 4bc6457
Show file tree
Hide file tree
Showing 10 changed files with 439 additions and 12 deletions.
5 changes: 5 additions & 0 deletions libflv/include/flv-header.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ struct flv_audio_tag_header_t
uint8_t bits; /// audio sample bits: 0-8 bit samples, 1-16-bit samples
uint8_t channels; /// audio channel count: 0-Mono sound, 1-Stereo sound
uint8_t avpacket; /// AAC only:FLV_SEQUENCE_HEADER/FLV_AVPACKET

uint8_t multitrack; /// enhanced rtmp v2, e.g. FLV_AUDIO_MULTI_TRACK_MANY_CODECS
uint8_t channelorder; /// enhanced rtmp v2, valid on FLV_AUDIO_PACKET_TYPE_MULTICHANNEL_CONFIG
uint32_t channelflags; /// enhanced rtmp v2, valid on FLV_AUDIO_PACKET_TYPE_MULTICHANNEL_CONFIG
uint8_t channelmapping[8]; /// enhanced rtmp v2, valid on FLV_AUDIO_PACKET_TYPE_MULTICHANNEL_CONFIG
};

struct flv_video_tag_header_t
Expand Down
3 changes: 3 additions & 0 deletions libflv/include/flv-muxer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ int flv_muxer_g711u(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t
/// @param[in] data opus stream, first opus head, then opus samples
int flv_muxer_opus(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t pts, uint32_t dts);

int flv_muxer_ac3(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t pts, uint32_t dts);
int flv_muxer_eac3(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t pts, uint32_t dts);

/// @param[in] data h.264 annexb bitstream: H.264 start code + H.264 NALU, 0x0000000168...
int flv_muxer_avc(flv_muxer_t* muxer, const void* data, size_t bytes, uint32_t pts, uint32_t dts);

Expand Down
39 changes: 35 additions & 4 deletions libflv/include/flv-proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@
#define FLV_AUDIO_ADPCM (1 << 4)
#define FLV_AUDIO_MP3 (2 << 4)
#define FLV_AUDIO_LLPCM (3 << 4) // Linear PCM, little endian
#define FLV_AUDIO_FLAC (4 << 4) // Nellymoser16KMono -> FLAC(enhanced rtmp v2)
#define FLV_AUDIO_EAC3 (5 << 4) // Nellymoser8KMono -> EAC3(enhanced rtmp v2)
#define FLV_AUDIO_Nelly (6 << 4) // Nellymoser
#define FLV_AUDIO_G711A (7 << 4) // G711 A-law
#define FLV_AUDIO_G711U (8 << 4) // G711 mu-law
#define FLV_AUDIO_FOURCC (9 << 4) // enhanced rtmp v2
#define FLV_AUDIO_AAC (10 << 4)
#define FLV_AUDIO_SPEEX (11 << 4)
#define FLV_AUDIO_AC3 (12 << 4) // enhanced rtmp v2
#define FLV_AUDIO_OPUS (13 << 4)
#define FLV_AUDIO_MP3_8K (14 << 4) // MP3 8 kHz
#define FLV_AUDIO_DEVIDE (15 << 4) // Device-specific sound
#define FLV_AUDIO_ASC (0x1000 | FLV_AUDIO_AAC) // AudioSpecificConfig(ISO-14496-3)
#define FLV_AUDIO_OPUS_HEAD (0x1100 | FLV_AUDIO_OPUS)// opus-codec.org
#define FLV_AUDIO_OPUS_HEAD (0x1100 | FLV_AUDIO_OPUS) // opus-codec.org
#define FLV_AUDIO_FLAC_HEAD (0x1200 | FLV_AUDIO_FLAC) // xiph.org/flac

// FLV Video Type
#define FLV_VIDEO_H263 2 // Sorenson H.263
Expand Down Expand Up @@ -64,6 +70,13 @@ enum
// note: PacketTypeSequenceStart and PacketTypeMPEG2TSSequenceStart
// are mutually exclusive
FLV_PACKET_TYPE_MPEG2TS_SEQUENCE_START = 5,

// Turns on video multitrack mode
FLV_PACKET_TYPE_MULTITRACK = 6,

// audio
FLV_AUDIO_PACKET_TYPE_MULTICHANNEL_CONFIG = 4,
FLV_AUDIO_PACKET_TYPE_MULTITRACK = 5, // Turns on audio multitrack mode
};

enum
Expand Down Expand Up @@ -95,11 +108,29 @@ enum
FLV_SOUND_CHANNEL_STEREO = 1, // 2-channels
};

// AvMultitrackType
enum flv_audio_multi_track_e
{
FLV_AUDIO_MULTI_TRACK_ONE = 0, // OneTrack
FLV_AUDIO_MULTI_TRACK_MANY = 1, // ManyTracks
FLV_AUDIO_MULTI_TRACK_MANY_CODECS = 2, // ManyTracksManyCodecs

FLV_AUDIO_MULTI_TRACK_NONE = 255,
};

#define FLV_VIDEO_FOURCC(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))

#define FLV_VIDEO_FOURCC_AV1 FLV_VIDEO_FOURCC('a', 'v', '0', '1')
#define FLV_VIDEO_FOURCC_VP9 FLV_VIDEO_FOURCC('v', 'p', '0', '9')
#define FLV_VIDEO_FOURCC_HEVC FLV_VIDEO_FOURCC('h', 'v', 'c', '1')
#define FLV_VIDEO_FOURCC_VVC FLV_VIDEO_FOURCC('v', 'v', 'c', '1')
#define FLV_VIDEO_FOURCC_AV1 FLV_VIDEO_FOURCC('a', 'v', '0', '1')
#define FLV_VIDEO_FOURCC_AVC FLV_VIDEO_FOURCC('a', 'v', 'c', '1') // H.264
#define FLV_VIDEO_FOURCC_HEVC FLV_VIDEO_FOURCC('h', 'v', 'c', '1') // H.265
#define FLV_VIDEO_FOURCC_VVC FLV_VIDEO_FOURCC('v', 'v', 'c', '1') // H.266

#define FLV_AUDIO_FOURCC_AC3 FLV_VIDEO_FOURCC('a', 'c', '-', '3') // AC-3/E-AC-3 - <https://en.wikipedia.org/wiki/Dolby_Digital>
#define FLV_AUDIO_FOURCC_EAC3 FLV_VIDEO_FOURCC('e', 'c', '-', '3')
#define FLV_AUDIO_FOURCC_OPUS FLV_VIDEO_FOURCC('O', 'p', 'u', 's') // Opus audio - <https://opus-codec.org/>
#define FLV_AUDIO_FOURCC_MP3 FLV_VIDEO_FOURCC('.', 'm', 'p', '3') // Mp3 audio - <https://en.wikipedia.org/wiki/MP3>
#define FLV_AUDIO_FOURCC_FLAC FLV_VIDEO_FOURCC('f', 'L', 'a', 'C') // Free Lossless Audio Codec - <https://xiph.org/flac/format.html>
#define FLV_AUDIO_FOURCC_AAC FLV_VIDEO_FOURCC('m', 'p', '4', 'a') // Advanced Audio Coding - <https://en.wikipedia.org/wiki/Advanced_Audio_Coding>

#endif /* !_flv_proto_h_ */
32 changes: 32 additions & 0 deletions libflv/include/xiph-flac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef _xiph_flac_h_
#define _xiph_flac_h_

#include <stddef.h>
#include <stdint.h>

#if defined(__cplusplus)
extern "C" {
#endif

struct flac_streaminfo_t
{
uint16_t min_block_size; // in samples
uint16_t max_block_size;
uint32_t min_frame_size; // 24-bits, in bytes
uint32_t max_frame_size;
uint64_t sample_rate : 20; // 20-bits, [0, 655350Hz]
uint64_t channels : 3; // (number of channels)-1, 3-bits, [1, 8]
uint64_t bits_per_sample : 5; // (bits per sample)-1, 5-bits, [4, 32]
uint64_t samples : 36; // total samples in stream
uint8_t signature[16]; // MD5 signature of the unencoded audio data
};

/// @return >0-ok, <=0-error
int flac_streaminfo_save(const struct flac_streaminfo_t* flac, uint8_t* data, size_t bytes);
/// @return >0-ok, <=0-error
int flac_streaminfo_load(const uint8_t* data, size_t bytes, struct flac_streaminfo_t* flac);

#if defined(__cplusplus)
}
#endif
#endif /* !_xiph_flac_h_ */
2 changes: 2 additions & 0 deletions libflv/libflv.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<ClInclude Include="include\opus-head.h" />
<ClInclude Include="include\riff-acm.h" />
<ClInclude Include="include\webm-vpx.h" />
<ClInclude Include="include\xiph-flac.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\amf0.c" />
Expand Down Expand Up @@ -67,6 +68,7 @@
<ClCompile Include="source\vvc-annexbtomp4.c" />
<ClCompile Include="source\vvc-mp4toannexb.c" />
<ClCompile Include="source\webm-vpx.c" />
<ClCompile Include="source\xiph-flac.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D5BA0BB6-0D84-48CB-8630-F617CB6DE375}</ProjectGuid>
Expand Down
6 changes: 6 additions & 0 deletions libflv/libflv.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
<ClInclude Include="include\avswg-avs3.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\xiph-flac.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\flv-demuxer.c">
Expand Down Expand Up @@ -155,5 +158,8 @@
<ClCompile Include="source\avswg-avs3.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="source\xiph-flac.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
25 changes: 19 additions & 6 deletions libflv/source/flv-demuxer.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "mpeg4-hevc.h"
#include "mpeg4-vvc.h"
#include "opus-head.h"
#include "xiph-flac.h"
#include "aom-av1.h"
#include "avswg-avs3.h"
#include "amf0.h"
Expand All @@ -20,6 +21,7 @@ struct flv_demuxer_t
{
struct mpeg4_aac_t aac;
struct opus_head_t opus;
struct flac_streaminfo_t flac;
} a;

union
Expand Down Expand Up @@ -101,7 +103,7 @@ static int flv_demuxer_audio(struct flv_demuxer_t* flv, const uint8_t* data, int
mpeg4_aac_audio_specific_config_load(data + n, bytes - n, &flv->a.aac);
return flv->handler(flv->param, FLV_AUDIO_ASC, data + n, bytes - n, timestamp, timestamp, 0);
}
else
else if (FLV_AVPACKET == audio.avpacket)
{
if (0 != flv_demuxer_check_and_alloc(flv, bytes + 7 + 1 + flv->a.aac.npce))
return -ENOMEM;
Expand All @@ -123,20 +125,31 @@ static int flv_demuxer_audio(struct flv_demuxer_t* flv, const uint8_t* data, int
opus_head_load(data + n, bytes - n, &flv->a.opus);
return flv->handler(flv->param, FLV_AUDIO_OPUS_HEAD, data + n, bytes - n, timestamp, timestamp, 0);
}
else
else if (FLV_AVPACKET == audio.avpacket)
{
return flv->handler(flv->param, audio.codecid, data + n, bytes - n, timestamp, timestamp, 0);
}
}
else if (FLV_AUDIO_MP3 == audio.codecid || FLV_AUDIO_MP3_8K == audio.codecid)
else if (FLV_AUDIO_FLAC == audio.codecid)
{
return flv->handler(flv->param, audio.codecid, data + n, bytes - n, timestamp, timestamp, 0);
if (FLV_SEQUENCE_HEADER == audio.avpacket)
{
flac_streaminfo_load(data + n, bytes - n, &flv->a.flac);
return flv->handler(flv->param, FLV_AUDIO_FLAC_HEAD, data + n, bytes - n, timestamp, timestamp, 0);
}
else if (FLV_AVPACKET == audio.avpacket)
{
return flv->handler(flv->param, audio.codecid, data + n, bytes - n, timestamp, timestamp, 0);
}
}
else
{
// Audio frame data
return flv->handler(flv->param, audio.codecid, data + n, bytes - n, timestamp, timestamp, 0);
// Audio frame data: mp3/ac-3/eac-3
if (FLV_AVPACKET == audio.avpacket)
return flv->handler(flv->param, audio.codecid, data + n, bytes - n, timestamp, timestamp, 0);
}

return 0;
}

static int flv_demuxer_video(struct flv_demuxer_t* flv, const uint8_t* data, int bytes, uint32_t timestamp)
Expand Down
Loading

0 comments on commit 4bc6457

Please sign in to comment.