Skip to content

Commit 26d4cea

Browse files
committed
WHIP: Only support h264+opus codec.
1. Input stream codec should be h264 or opus. 2. For video codec profile, should be h264 baseline or constrained baseline. 3. For audio, should be 48000HZ and stereo. 4. Only support one video and audio stream.
1 parent 9587390 commit 26d4cea

File tree

1 file changed

+91
-7
lines changed

1 file changed

+91
-7
lines changed

libavformat/rtcenc.c

+91-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* FLV muxer
3-
* Copyright (c) 2003 The FFmpeg Project
2+
* WebRTC muxer
3+
* Copyright (c) 2023 The FFmpeg Project
44
*
55
* This file is part of FFmpeg.
66
*
@@ -28,32 +28,116 @@
2828
#include "internal.h"
2929
#include "mux.h"
3030
#include "libavutil/opt.h"
31+
#include "libavcodec/avcodec.h"
3132

3233
typedef struct RTCContext {
3334
AVClass *av_class;
35+
36+
/* Input audio and video codec parameters */
37+
AVCodecParameters *audio_par;
38+
AVCodecParameters *video_par;
3439
} RTCContext;
3540

36-
static int rtc_init(struct AVFormatContext *s)
41+
/**
42+
* Only support video(h264) and audio(opus) for now. Note that only baseline
43+
* and constrained baseline of h264 are supported.
44+
*/
45+
static int check_codec(AVFormatContext *s)
46+
{
47+
int i;
48+
RTCContext *rtc = s->priv_data;
49+
50+
for (i = 0; i < s->nb_streams; i++) {
51+
AVCodecParameters *par = s->streams[i]->codecpar;
52+
const AVCodecDescriptor *desc = avcodec_descriptor_get(par->codec_id);
53+
switch (par->codec_type) {
54+
case AVMEDIA_TYPE_VIDEO:
55+
if (rtc->video_par) {
56+
av_log(s, AV_LOG_ERROR,
57+
"Only one video stream is supported by RTC\n");
58+
return AVERROR(EINVAL);
59+
}
60+
rtc->video_par = par;
61+
62+
if (par->codec_id != AV_CODEC_ID_H264) {
63+
av_log(s, AV_LOG_ERROR,
64+
"Unsupported video codec %s by RTC, choose h264\n",
65+
desc ? desc->name : "unknown");
66+
return AVERROR(EINVAL);
67+
}
68+
if ((par->profile & ~FF_PROFILE_H264_CONSTRAINED) != FF_PROFILE_H264_BASELINE) {
69+
av_log(s, AV_LOG_ERROR,
70+
"Profile %d of stream %d is not baseline, currently unsupported by RTC\n",
71+
par->profile, i);
72+
return AVERROR(EINVAL);
73+
}
74+
break;
75+
case AVMEDIA_TYPE_AUDIO:
76+
if (rtc->audio_par) {
77+
av_log(s, AV_LOG_ERROR,
78+
"Only one audio stream is supported by RTC\n");
79+
return AVERROR(EINVAL);
80+
}
81+
rtc->audio_par = par;
82+
83+
if (par->codec_id != AV_CODEC_ID_OPUS) {
84+
av_log(s, AV_LOG_ERROR,
85+
"Unsupported audio codec %s by RTC, choose opus\n",
86+
desc ? desc->name : "unknown");
87+
return AVERROR(EINVAL);
88+
}
89+
90+
if (par->ch_layout.nb_channels != 2) {
91+
av_log(s, AV_LOG_ERROR,
92+
"Unsupported audio channels %d by RTC, choose stereo\n",
93+
par->ch_layout.nb_channels);
94+
return AVERROR(EINVAL);
95+
}
96+
97+
if (par->sample_rate != 48000) {
98+
av_log(s, AV_LOG_ERROR,
99+
"Unsupported audio sample rate %d by RTC, choose 48000\n",
100+
par->sample_rate);
101+
return AVERROR(EINVAL);
102+
}
103+
break;
104+
default:
105+
av_log(s, AV_LOG_ERROR,
106+
"Codec type '%s' for stream %d is not supported by RTC\n",
107+
av_get_media_type_string(par->codec_type), i);
108+
return AVERROR(EINVAL);
109+
}
110+
}
111+
112+
return 0;
113+
}
114+
115+
static int rtc_init(AVFormatContext *s)
37116
{
117+
int ret;
118+
119+
if ((ret = check_codec(s)) < 0)
120+
return ret;
121+
38122
return 0;
39123
}
40124

41-
static int rtc_write_header(struct AVFormatContext *s)
125+
static int rtc_write_header(AVFormatContext *s)
42126
{
43127
return 0;
44128
}
45129

46-
static int rtc_write_packet(struct AVFormatContext *s, AVPacket *pkt)
130+
static int rtc_write_packet(AVFormatContext *s, AVPacket *pkt)
47131
{
48132
return 0;
49133
}
50134

51-
static int rtc_write_trailer(struct AVFormatContext *s)
135+
static int rtc_write_trailer(AVFormatContext *s)
52136
{
53137
return 0;
54138
}
55139

56-
static void rtc_deinit(struct AVFormatContext *s)
140+
static void rtc_deinit(AVFormatContext *s)
57141
{
58142
}
59143

0 commit comments

Comments
 (0)