Bläddra i källkod

Merge pull request #3188 from jpark37/more-ffmpeg-cleanup

More FFmpeg cleanup
Jim 5 år sedan
förälder
incheckning
a7ad0087ec

+ 0 - 4
deps/libff/libff/ff-util.c

@@ -291,7 +291,6 @@ static inline bool is_output_device(const AVClass *avclass)
 	if (!avclass)
 		return 0;
 
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(52, 66, 101)
 	switch (avclass->category) {
 	case AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT:
 	case AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT:
@@ -300,9 +299,6 @@ static inline bool is_output_device(const AVClass *avclass)
 	default:
 		return false;
 	}
-#else
-	return (avclass->category == AV_CLASS_CATEGORY_OUTPUT);
-#endif
 }
 
 const struct ff_format_desc *ff_format_supported()

+ 0 - 6
deps/media-playback/media-playback/decode.h

@@ -44,12 +44,6 @@ extern "C" {
 #define CODEC_FLAG_TRUNC CODEC_FLAG_TRUNCATED
 #endif
 
-#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(54, 31, 100)
-#define AV_PIX_FMT_VDTOOL AV_PIX_FMT_VIDEOTOOLBOX
-#else
-#define AV_PIX_FMT_VDTOOL AV_PIX_FMT_VDA_VLD
-#endif
-
 struct mp_media;
 
 struct mp_decode {

+ 3 - 1
libobs/media-io/media-remux.c

@@ -111,8 +111,10 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename)
 
 		av_dict_copy(&out_stream->metadata, in_stream->metadata, 0);
 
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+		out_stream->codecpar->codec_tag = 0;
+#else
 		out_stream->codec->codec_tag = 0;
-#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
 		out_stream->time_base = out_stream->codec->time_base;
 		if (job->ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
 			out_stream->codec->flags |= CODEC_FLAG_GLOBAL_H;

+ 56 - 32
plugins/obs-ffmpeg/obs-ffmpeg-output.c

@@ -135,7 +135,7 @@ static bool parse_params(AVCodecContext *context, char **opts)
 
 static bool open_video_codec(struct ffmpeg_data *data)
 {
-	AVCodecContext *context = data->video->codec;
+	AVCodecContext *const context = data->video_ctx;
 	char **opts = strlist_split(data->config.video_settings, ' ', false);
 	int ret;
 
@@ -180,6 +180,10 @@ static bool open_video_codec(struct ffmpeg_data *data)
 		return false;
 	}
 
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+	avcodec_parameters_from_context(data->video->codecpar, context);
+#endif
+
 	return true;
 }
 
@@ -218,7 +222,11 @@ static bool create_video_stream(struct ffmpeg_data *data)
 	closest_format = avcodec_find_best_pix_fmt_of_list(
 		data->vcodec->pix_fmts, data->config.format, 0, NULL);
 
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+	context = avcodec_alloc_context3(data->vcodec);
+#else
 	context = data->video->codec;
+#endif
 	context->bit_rate = (int64_t)data->config.video_bitrate * 1000;
 	context->width = data->config.scale_width;
 	context->height = data->config.scale_height;
@@ -234,6 +242,8 @@ static bool create_video_stream(struct ffmpeg_data *data)
 	if (data->output->oformat->flags & AVFMT_GLOBALHEADER)
 		context->flags |= CODEC_FLAG_GLOBAL_H;
 
+	data->video_ctx = context;
+
 	if (!open_video_codec(data))
 		return false;
 
@@ -250,7 +260,7 @@ static bool create_video_stream(struct ffmpeg_data *data)
 
 static bool open_audio_codec(struct ffmpeg_data *data, int idx)
 {
-	AVCodecContext *context = data->audio_streams[idx]->codec;
+	AVCodecContext *const context = data->audio_infos[idx].ctx;
 	char **opts = strlist_split(data->config.audio_settings, ' ', false);
 	int ret;
 
@@ -292,6 +302,11 @@ static bool open_audio_codec(struct ffmpeg_data *data, int idx)
 		return false;
 	}
 
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+	avcodec_parameters_from_context(data->audio_infos[idx].stream->codecpar,
+					context);
+#endif
+
 	return true;
 }
 
@@ -311,8 +326,11 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
 			data->config.audio_encoder))
 		return false;
 
-	data->audio_streams[idx] = stream;
-	context = data->audio_streams[idx]->codec;
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+	context = avcodec_alloc_context3(data->acodec);
+#else
+	context = stream->codec;
+#endif
 	context->bit_rate = (int64_t)data->config.audio_bitrate * 1000;
 	context->time_base = (AVRational){1, aoi.samples_per_sec};
 	context->channels = get_audio_channels(aoi.speakers);
@@ -328,7 +346,7 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
 				      ? data->acodec->sample_fmts[0]
 				      : AV_SAMPLE_FMT_FLTP;
 
-	data->audio_streams[idx]->time_base = context->time_base;
+	stream->time_base = context->time_base;
 
 	data->audio_samplerate = aoi.samples_per_sec;
 	data->audio_format = convert_ffmpeg_sample_format(context->sample_fmt);
@@ -338,6 +356,9 @@ static bool create_audio_stream(struct ffmpeg_data *data, int idx)
 	if (data->output->oformat->flags & AVFMT_GLOBALHEADER)
 		context->flags |= CODEC_FLAG_GLOBAL_H;
 
+	data->audio_infos[idx].stream = stream;
+	data->audio_infos[idx].ctx = context;
+
 	return open_audio_codec(data, idx);
 }
 
@@ -351,8 +372,8 @@ static inline bool init_streams(struct ffmpeg_data *data)
 
 	if (format->audio_codec != AV_CODEC_ID_NONE &&
 	    data->num_audio_streams) {
-		data->audio_streams =
-			calloc(1, data->num_audio_streams * sizeof(void *));
+		data->audio_infos = calloc(data->num_audio_streams,
+					   sizeof(*data->audio_infos));
 		for (int i = 0; i < data->num_audio_streams; i++) {
 			if (!create_audio_stream(data, i))
 				return false;
@@ -402,10 +423,6 @@ static inline bool open_output_file(struct ffmpeg_data *data)
 		}
 	}
 
-	strncpy(data->output->filename, data->config.url,
-		sizeof(data->output->filename));
-	data->output->filename[sizeof(data->output->filename) - 1] = 0;
-
 	ret = avformat_write_header(data->output, &dict);
 	if (ret < 0) {
 		ffmpeg_log_error(LOG_WARNING, data, "Error opening '%s': %s",
@@ -432,7 +449,11 @@ static inline bool open_output_file(struct ffmpeg_data *data)
 
 static void close_video(struct ffmpeg_data *data)
 {
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+	avcodec_free_context(&data->video_ctx);
+#else
 	avcodec_close(data->video->codec);
+#endif
 	av_frame_unref(data->vframe);
 
 	// This format for some reason derefs video frame
@@ -452,8 +473,13 @@ static void close_audio(struct ffmpeg_data *data)
 
 		if (data->samples[idx][0])
 			av_freep(&data->samples[idx][0]);
-		if (data->audio_streams[idx])
-			avcodec_close(data->audio_streams[idx]->codec);
+		if (data->audio_infos[idx].ctx) {
+#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
+			avcodec_free_context(&data->audio_infos[idx].ctx);
+#else
+			avcodec_close(data->audio_infos[idx].stream->codec);
+#endif
+		}
 		if (data->aframe[idx])
 			av_frame_free(&data->aframe[idx]);
 	}
@@ -466,10 +492,10 @@ void ffmpeg_data_free(struct ffmpeg_data *data)
 
 	if (data->video)
 		close_video(data);
-	if (data->audio_streams) {
+	if (data->audio_infos) {
 		close_audio(data);
-		free(data->audio_streams);
-		data->audio_streams = NULL;
+		free(data->audio_infos);
+		data->audio_infos = NULL;
 	}
 
 	if (data->output) {
@@ -555,7 +581,7 @@ bool ffmpeg_data_init(struct ffmpeg_data *data, struct ffmpeg_cfg *config)
 	}
 
 	avformat_alloc_output_context2(&data->output, output_format, NULL,
-				       NULL);
+				       data->config.url);
 
 	if (!data->output) {
 		ffmpeg_log_error(LOG_WARNING, data,
@@ -688,7 +714,7 @@ static void receive_video(void *param, struct video_data *frame)
 	if (!data->video)
 		return;
 
-	AVCodecContext *context = data->video->codec;
+	AVCodecContext *context = data->video_ctx;
 	AVPacket packet = {0};
 	int ret = 0, got_packet;
 
@@ -833,13 +859,13 @@ static void encode_audio(struct ffmpeg_output *output, int idx,
 		return;
 
 	packet.pts = rescale_ts(packet.pts, context,
-				data->audio_streams[idx]->time_base);
+				data->audio_infos[idx].stream->time_base);
 	packet.dts = rescale_ts(packet.dts, context,
-				data->audio_streams[idx]->time_base);
+				data->audio_infos[idx].stream->time_base);
 	packet.duration =
 		(int)av_rescale_q(packet.duration, context->time_base,
-				  data->audio_streams[idx]->time_base);
-	packet.stream_index = data->audio_streams[idx]->index;
+				  data->audio_infos[idx].stream->time_base);
+	packet.stream_index = data->audio_infos[idx].stream->index;
 
 	pthread_mutex_lock(&output->write_mutex);
 	da_push_back(output->packets, &packet);
@@ -868,7 +894,7 @@ static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame)
 	int track_order;
 
 	// codec doesn't support audio or none configured
-	if (!data->audio_streams)
+	if (!data->audio_infos)
 		return;
 
 	/* check that the track was selected */
@@ -878,7 +904,7 @@ static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame)
 	/* get track order (first selected, etc ...) */
 	track_order = get_track_order(data->audio_tracks, mix_idx);
 
-	AVCodecContext *context = data->audio_streams[track_order]->codec;
+	AVCodecContext *context = data->audio_infos[track_order].ctx;
 
 	if (!data->start_timestamp)
 		return;
@@ -916,7 +942,7 @@ static uint64_t get_packet_sys_dts(struct ffmpeg_output *output,
 		time_base = data->video->time_base;
 		start_ts = output->video_start_ts;
 	} else {
-		time_base = data->audio_streams[0]->time_base;
+		time_base = data->audio_infos[0].stream->time_base;
 		start_ts = output->audio_start_ts;
 	}
 
@@ -949,10 +975,8 @@ static int process_packet(struct ffmpeg_output *output)
 
 	if (stopping(output)) {
 		uint64_t sys_ts = get_packet_sys_dts(output, &packet);
-		if (sys_ts >= output->stop_ts) {
-			ffmpeg_output_full_stop(output);
+		if (sys_ts >= output->stop_ts)
 			return 0;
-		}
 	}
 
 	output->total_bytes += packet.size;
@@ -1159,12 +1183,12 @@ static void ffmpeg_output_stop(void *data, uint64_t ts)
 	struct ffmpeg_output *output = data;
 
 	if (output->active) {
-		if (ts == 0) {
-			ffmpeg_output_full_stop(output);
-		} else {
-			os_atomic_set_bool(&output->stopping, true);
+		if (ts > 0) {
 			output->stop_ts = ts;
+			os_atomic_set_bool(&output->stopping, true);
 		}
+
+		ffmpeg_output_full_stop(output);
 	}
 }
 

+ 7 - 1
plugins/obs-ffmpeg/obs-ffmpeg-output.h

@@ -30,9 +30,15 @@ struct ffmpeg_cfg {
 	int height;
 };
 
+struct ffmpeg_audio_info {
+	AVStream *stream;
+	AVCodecContext *ctx;
+};
+
 struct ffmpeg_data {
 	AVStream *video;
-	AVStream **audio_streams;
+	AVCodecContext *video_ctx;
+	struct ffmpeg_audio_info *audio_infos;
 	AVCodec *acodec;
 	AVCodec *vcodec;
 	AVFormatContext *output;