diff --git a/ffmpeg.c b/ffmpeg.c index 9f29eac7b1..46ea57b933 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2270,16 +2270,34 @@ static void print_sdp(void) { char sdp[16384]; int i; + int j; + AVIOContext *sdp_pb; AVFormatContext **avc = av_malloc_array(nb_output_files, sizeof(*avc)); if (!avc) exit_program(1); - for (i = 0; i < nb_output_files; i++) - avc[i] = output_files[i]->ctx; + for (i = 0, j = 0; i < nb_output_files; i++) { + if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) { + avc[j] = output_files[i]->ctx; + j++; + } + } + + av_sdp_create(avc, j, sdp, sizeof(sdp)); + + if (!sdp_filename) { + printf("SDP:\n%s\n", sdp); + fflush(stdout); + } else { + if (avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL) < 0) { + av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename); + } else { + avio_printf(sdp_pb, "SDP:\n%s", sdp); + avio_close(sdp_pb); + av_free(sdp_filename); + } + } - av_sdp_create(avc, nb_output_files, sdp, sizeof(sdp)); - printf("SDP:\n%s\n", sdp); - fflush(stdout); av_freep(&avc); } @@ -3122,7 +3140,7 @@ static int transcode_init(void) return ret; } - if (want_sdp) { + if (sdp_filename || want_sdp) { print_sdp(); } diff --git a/ffmpeg.h b/ffmpeg.h index 117a35ce87..0ad1e37267 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -470,6 +470,7 @@ extern FilterGraph **filtergraphs; extern int nb_filtergraphs; extern char *vstats_filename; +extern char *sdp_filename; extern float audio_drift_threshold; extern float dts_delta_threshold; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index ae05bf0571..ac93eb50f6 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -77,6 +77,7 @@ const HWAccel hwaccels[] = { }; char *vstats_filename; +char *sdp_filename; float audio_drift_threshold = 0.1; float dts_delta_threshold = 10; @@ -381,6 +382,13 @@ static int opt_map_channel(void *optctx, const char *opt, const char *arg) return 0; } +static int opt_sdp_file(void *optctx, const char *opt, const char *arg) +{ + av_free(sdp_filename); + sdp_filename = av_strdup(arg); + return 0; +} + /** * Parse a metadata specifier passed as 'arg' parameter. * @param arg metadata string to parse @@ -3070,6 +3078,8 @@ const OptionDef options[] = { "set the initial demux-decode delay", "seconds" }, { "override_ffserver", OPT_BOOL | OPT_EXPERT | OPT_OUTPUT, { &override_ffserver }, "override the options from ffserver", "" }, + { "sdp_file", HAS_ARG | OPT_EXPERT | OPT_OUTPUT, { opt_sdp_file }, + "specify a file in which to print sdp information", "file" }, { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) }, "A comma-separated list of bitstream filters", "bitstream_filters" },