MT#65420 initial support for video transcoding

Change-Id: I6fbf6dae7370860523abdb56ee3106e9fb3f0915
pull/2169/head
Richard Fuchs 1 week ago
parent 2ad9d9b9f0
commit 0534e3d8ed

@ -916,7 +916,7 @@ struct codec_handler *codec_handler_make_playback(const rtp_payload_type *src_pt
handler->ssrc_handler->h.ssrc = ssrc;
while (handler->ssrc_handler->csch.first_ts == 0)
handler->ssrc_handler->csch.first_ts = ssl_random();
handler->ssrc_handler->rtp_mark = true;
handler->ssrc_handler->rtp_mark = true; // relevant for audio
ilogs(codec, LOG_DEBUG, "Created media playback context for " STR_FORMAT "/" STR_FORMAT
" -> " STR_FORMAT "/" STR_FORMAT "/%d",
@ -4458,11 +4458,13 @@ static struct ssrc_entry *__ssrc_handler_transcode_new(void *p) {
.time_base = h->dest_pt.time_base,
};
// see if there's a complete codec chain usable for this
if (!h->pcm_dtmf_detect)
ch->chain = codec_cc_new(h->source_pt.codec_def, &dec_format,
h->dest_pt.codec_def, &enc_format,
ch->bitrate, ch->ptime, async_chain_start, async_chain_finish);
if (h->dest_pt.codec_def->media_type == MT_AUDIO) {
// see if there's a complete codec chain usable for this
if (!h->pcm_dtmf_detect)
ch->chain = codec_cc_new(h->source_pt.codec_def, &dec_format,
h->dest_pt.codec_def, &enc_format,
ch->bitrate, ch->ptime, async_chain_start, async_chain_finish);
}
if (ch->chain) {
ilogs(codec, LOG_DEBUG, "Using codec chain to transcode from " STR_FORMAT "/" STR_FORMAT
@ -6434,12 +6436,14 @@ out:
void codec_store_synthesise_basic(struct codec_store *dst, const char *reason) {
if (!dst->codec_prefs.length) {
// no codecs given: add defaults
static const str PCMU_str = STR_CONST("PCMU");
static const str PCMA_str = STR_CONST("PCMA");
codec_store_add_raw_order(dst, codec_make_payload_type(&PCMU_str, MT_AUDIO));
codec_store_add_raw_order(dst, codec_make_payload_type(&PCMA_str, MT_AUDIO));
if (dst->media->type_id == MT_AUDIO) {
static const str PCMU_str = STR_CONST("PCMU");
static const str PCMA_str = STR_CONST("PCMA");
codec_store_add_raw_order(dst, codec_make_payload_type(&PCMU_str, MT_AUDIO));
codec_store_add_raw_order(dst, codec_make_payload_type(&PCMA_str, MT_AUDIO));
ilogs(codec, LOG_DEBUG, "Using default codecs PCMU and PCMA for %s", reason);
ilogs(codec, LOG_DEBUG, "Using default codecs PCMU and PCMA for %s", reason);
}
}
else {
// we already have a list of codecs - make sure they're all supported by us

@ -263,7 +263,9 @@ void config_load_ext(int *argc, char ***argv, GOptionEntry *app_entries, const c
{ "io-uring", 0,0, G_OPTION_ARG_NONE, &rtpe_common_config_ptr->io_uring, "Use io_uring", NULL },
{ "io-uring-buffers", 0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->io_uring_buffers,"Number of io_uring entries per thread","INT" },
#endif
#ifdef WITH_TRANSCODING
{ "evs-lib-path", 0,0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->evs_lib_path, "Location of .so for 3GPP EVS codec", "FILE" },
{ "video-packet-size", 0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->video_pkt_size,"Target maximum size of video RTP packets","INT" },
#ifdef HAVE_CODEC_CHAIN
{ "codec-chain-lib-path",0,0, G_OPTION_ARG_FILENAME, &rtpe_common_config_ptr->codec_chain_lib_path,"Location of libcodec-chain.so", "FILE" },
{ "codec-chain-runners",0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->codec_chain_runners,"Number of chain runners per codec","INT" },
@ -273,6 +275,7 @@ void config_load_ext(int *argc, char ***argv, GOptionEntry *app_entries, const c
{ "codec-chain-interval",0,0, G_OPTION_ARG_INT, &rtpe_common_config_ptr->codec_chain_interval,"Microseconds between runs", "INT" },
{ "codec-chain-opus-application",0,0,G_OPTION_ARG_STRING,&opus_application, "Opus application", "default|VoIP|audio|low-delay" },
{ "codec-chain-opus-complexity",0,0,G_OPTION_ARG_INT, &rtpe_common_config_ptr->codec_chain_opus_complexity,"Opus encoding complexity (0..10)","INT" },
#endif
#endif
};
@ -525,6 +528,9 @@ out:
die("Invalid value for --io-uring-buffers");
#endif
if (rtpe_common_config_ptr->video_pkt_size <= 0)
rtpe_common_config_ptr->video_pkt_size = 1300;
return;
err:

@ -40,6 +40,7 @@ struct rtpengine_common_config {
int max_log_line_length;
int mos_type; // enum in codec_def_t
char *evs_lib_path;
int video_pkt_size;
char *codec_chain_lib_path;
int codec_chain_runners;
int codec_chain_concurrency;

@ -283,28 +283,47 @@ static int __decoder_input_data(decoder_t *dec, const str *data, unsigned long t
else
dec->dtx.do_dtx(dec, &frames, *ptime);
AVFrame *frame;
int ret = 0;
unsigned long samples = 0;
while ((frame = t_queue_pop_head(&frames))) {
samples += frame->nb_samples;
dec->dec_out_format.format = frame->format;
AVFrame *rsmp_frame = resample_frame(&dec->resampler, frame, &dec->dest_format);
if (!rsmp_frame) {
ilog(LOG_ERR | LOG_FLAG_LIMIT, "Resampling failed");
ret = -1;
if (dec->def->media_type == MT_AUDIO) {
AVFrame *frame;
unsigned long samples = 0;
while ((frame = t_queue_pop_head(&frames))) {
samples += frame->nb_samples;
dec->dec_out_format.format = frame->format;
AVFrame *rsmp_frame = resample_frame(&dec->resampler, frame, &dec->dest_format);
if (!rsmp_frame) {
ilog(LOG_ERR | LOG_FLAG_LIMIT, "Resampling failed");
ret = -1;
}
else {
if (callback(dec, rsmp_frame, u1, u2))
ret = -1;
}
if (rsmp_frame != frame)
av_frame_free(&frame);
}
else {
if (callback(dec, rsmp_frame, u1, u2))
if (ptime)
*ptime = samples * 1000L / dec->in_format.clockrate;
}
else { // MT_VIDEO
AVFrame *frame;
while ((frame = t_queue_pop_head(&frames))) {
AVFrame *rsmp_frame = rescale_frame(&dec->rescaler, frame, &dec->dest_format);
if (!rsmp_frame) {
ilog(LOG_ERR | LOG_FLAG_LIMIT, "Rescaling failed");
ret = -1;
}
else {
if (callback(dec, rsmp_frame, u1, u2))
ret = -1;
}
if (rsmp_frame != frame)
av_frame_free(&frame);
}
if (rsmp_frame != frame)
av_frame_free(&frame);
}
if (ptime)
*ptime = samples * 1000L / dec->in_format.clockrate;
return ret;
}
int decoder_input_data(decoder_t *dec, const str *data, unsigned long ts,
@ -416,10 +435,18 @@ void codeclib_init(int print) {
def->default_clockrate_fact.div = 1;
if (!def->default_ptime)
def->default_ptime = -1;
if (!def->default_clockrate)
def->default_clockrate = -1;
if (!def->default_channels)
def->default_channels = -1;
if (!def->default_clockrate) {
if (def->media_type == MT_VIDEO)
def->default_clockrate = 90000;
else
def->default_clockrate = -1;
}
if (!def->default_channels) {
if (def->media_type == MT_VIDEO)
def->default_channels = 1;
else
def->default_channels = -1;
}
if (!def->default_fps && def->media_type == MT_VIDEO)
def->default_fps = 30;
@ -445,8 +472,10 @@ void codeclib_init(int print) {
if (print) {
if (def->support_encoding && def->support_decoding) {
if (def->default_channels > 0 && def->default_clockrate >= 0)
printf("%20s: fully supported\n", def->rtpname);
if (def->media_type == MT_AUDIO && def->default_channels > 0 && def->default_clockrate >= 0)
printf("%20s: fully supported (audio)\n", def->rtpname);
else if (def->media_type == MT_VIDEO && def->default_width > 0 && def->default_height >= 0)
printf("%20s: fully supported (video)\n", def->rtpname);
else
printf("%20s: codec supported but lacks RTP definition\n", def->rtpname);
}
@ -711,7 +740,7 @@ int encoder_config_fmtp(encoder_t *enc, codec_def_t *def, int bitrate, int ptime
enc->input_fn = encoder_input_direct;
if (enc->actual_format.format != -1 && enc->actual_format.clockrate > 0) {
if (def->media_type == MT_AUDIO && enc->actual_format.format != -1 && enc->actual_format.clockrate > 0) {
enc->frame->nb_samples = enc->samples_per_frame ? : 256;
enc->frame->format = enc->actual_format.format;
enc->frame->sample_rate = enc->actual_format.clockrate;

Loading…
Cancel
Save