1 /******************************************************************************
2     Copyright (C) 2014 by Hugh Bailey <obs.jim@gmail.com>
3 
4     This program is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 ******************************************************************************/
17 
18 #include "ffmpeg-decode.h"
19 #include "obs-ffmpeg-compat.h"
20 #include <obs-avc.h>
21 
22 #if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 4, 100)
23 #define USE_NEW_HARDWARE_CODEC_METHOD
24 #endif
25 
26 #ifdef USE_NEW_HARDWARE_CODEC_METHOD
27 enum AVHWDeviceType hw_priority[] = {
28 	AV_HWDEVICE_TYPE_NONE,
29 };
30 
has_hw_type(AVCodec * c,enum AVHWDeviceType type)31 static bool has_hw_type(AVCodec *c, enum AVHWDeviceType type)
32 {
33 	for (int i = 0;; i++) {
34 		const AVCodecHWConfig *config = avcodec_get_hw_config(c, i);
35 		if (!config) {
36 			break;
37 		}
38 
39 		if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
40 		    config->device_type == type)
41 			return true;
42 	}
43 
44 	return false;
45 }
46 
init_hw_decoder(struct ffmpeg_decode * d)47 static void init_hw_decoder(struct ffmpeg_decode *d)
48 {
49 	enum AVHWDeviceType *priority = hw_priority;
50 	AVBufferRef *hw_ctx = NULL;
51 
52 	while (*priority != AV_HWDEVICE_TYPE_NONE) {
53 		if (has_hw_type(d->codec, *priority)) {
54 			int ret = av_hwdevice_ctx_create(&hw_ctx, *priority,
55 							 NULL, NULL, 0);
56 			if (ret == 0)
57 				break;
58 		}
59 
60 		priority++;
61 	}
62 
63 	if (hw_ctx) {
64 		d->decoder->hw_device_ctx = av_buffer_ref(hw_ctx);
65 		d->hw = true;
66 	}
67 }
68 #endif
69 
ffmpeg_decode_init(struct ffmpeg_decode * decode,enum AVCodecID id,bool use_hw)70 int ffmpeg_decode_init(struct ffmpeg_decode *decode, enum AVCodecID id,
71 		       bool use_hw)
72 {
73 	int ret;
74 
75 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
76 	avcodec_register_all();
77 #endif
78 	memset(decode, 0, sizeof(*decode));
79 
80 	decode->codec = avcodec_find_decoder(id);
81 	if (!decode->codec)
82 		return -1;
83 
84 	decode->decoder = avcodec_alloc_context3(decode->codec);
85 
86 	decode->decoder->thread_count = 0;
87 
88 #ifdef USE_NEW_HARDWARE_CODEC_METHOD
89 	if (use_hw)
90 		init_hw_decoder(decode);
91 #else
92 	(void)use_hw;
93 #endif
94 
95 	ret = avcodec_open2(decode->decoder, decode->codec, NULL);
96 	if (ret < 0) {
97 		ffmpeg_decode_free(decode);
98 		return ret;
99 	}
100 
101 	if (decode->codec->capabilities & CODEC_CAP_TRUNC)
102 		decode->decoder->flags |= CODEC_FLAG_TRUNC;
103 
104 	return 0;
105 }
106 
ffmpeg_decode_free(struct ffmpeg_decode * decode)107 void ffmpeg_decode_free(struct ffmpeg_decode *decode)
108 {
109 	if (decode->hw_frame)
110 		av_frame_free(&decode->hw_frame);
111 
112 	if (decode->decoder) {
113 		avcodec_close(decode->decoder);
114 		av_free(decode->decoder);
115 	}
116 
117 	if (decode->frame)
118 		av_frame_free(&decode->frame);
119 
120 	if (decode->packet_buffer)
121 		bfree(decode->packet_buffer);
122 
123 	memset(decode, 0, sizeof(*decode));
124 }
125 
convert_pixel_format(int f)126 static inline enum video_format convert_pixel_format(int f)
127 {
128 	switch (f) {
129 	case AV_PIX_FMT_NONE:
130 		return VIDEO_FORMAT_NONE;
131 	case AV_PIX_FMT_YUV420P:
132 	case AV_PIX_FMT_YUVJ420P:
133 		return VIDEO_FORMAT_I420;
134 	case AV_PIX_FMT_NV12:
135 		return VIDEO_FORMAT_NV12;
136 	case AV_PIX_FMT_YUYV422:
137 		return VIDEO_FORMAT_YUY2;
138 	case AV_PIX_FMT_UYVY422:
139 		return VIDEO_FORMAT_UYVY;
140 	case AV_PIX_FMT_YUV422P:
141 	case AV_PIX_FMT_YUVJ422P:
142 		return VIDEO_FORMAT_I422;
143 	case AV_PIX_FMT_RGBA:
144 		return VIDEO_FORMAT_RGBA;
145 	case AV_PIX_FMT_BGRA:
146 		return VIDEO_FORMAT_BGRA;
147 	case AV_PIX_FMT_BGR0:
148 		return VIDEO_FORMAT_BGRX;
149 	default:;
150 	}
151 
152 	return VIDEO_FORMAT_NONE;
153 }
154 
convert_sample_format(int f)155 static inline enum audio_format convert_sample_format(int f)
156 {
157 	switch (f) {
158 	case AV_SAMPLE_FMT_U8:
159 		return AUDIO_FORMAT_U8BIT;
160 	case AV_SAMPLE_FMT_S16:
161 		return AUDIO_FORMAT_16BIT;
162 	case AV_SAMPLE_FMT_S32:
163 		return AUDIO_FORMAT_32BIT;
164 	case AV_SAMPLE_FMT_FLT:
165 		return AUDIO_FORMAT_FLOAT;
166 	case AV_SAMPLE_FMT_U8P:
167 		return AUDIO_FORMAT_U8BIT_PLANAR;
168 	case AV_SAMPLE_FMT_S16P:
169 		return AUDIO_FORMAT_16BIT_PLANAR;
170 	case AV_SAMPLE_FMT_S32P:
171 		return AUDIO_FORMAT_32BIT_PLANAR;
172 	case AV_SAMPLE_FMT_FLTP:
173 		return AUDIO_FORMAT_FLOAT_PLANAR;
174 	default:;
175 	}
176 
177 	return AUDIO_FORMAT_UNKNOWN;
178 }
179 
convert_speaker_layout(uint8_t channels)180 static inline enum speaker_layout convert_speaker_layout(uint8_t channels)
181 {
182 	switch (channels) {
183 	case 0:
184 		return SPEAKERS_UNKNOWN;
185 	case 1:
186 		return SPEAKERS_MONO;
187 	case 2:
188 		return SPEAKERS_STEREO;
189 	case 3:
190 		return SPEAKERS_2POINT1;
191 	case 4:
192 		return SPEAKERS_4POINT0;
193 	case 5:
194 		return SPEAKERS_4POINT1;
195 	case 6:
196 		return SPEAKERS_5POINT1;
197 	case 8:
198 		return SPEAKERS_7POINT1;
199 	default:
200 		return SPEAKERS_UNKNOWN;
201 	}
202 }
203 
copy_data(struct ffmpeg_decode * decode,uint8_t * data,size_t size)204 static inline void copy_data(struct ffmpeg_decode *decode, uint8_t *data,
205 			     size_t size)
206 {
207 	size_t new_size = size + INPUT_BUFFER_PADDING_SIZE;
208 
209 	if (decode->packet_size < new_size) {
210 		decode->packet_buffer =
211 			brealloc(decode->packet_buffer, new_size);
212 		decode->packet_size = new_size;
213 	}
214 
215 	memset(decode->packet_buffer + size, 0, INPUT_BUFFER_PADDING_SIZE);
216 	memcpy(decode->packet_buffer, data, size);
217 }
218 
ffmpeg_decode_audio(struct ffmpeg_decode * decode,uint8_t * data,size_t size,struct obs_source_audio * audio,bool * got_output)219 bool ffmpeg_decode_audio(struct ffmpeg_decode *decode, uint8_t *data,
220 			 size_t size, struct obs_source_audio *audio,
221 			 bool *got_output)
222 {
223 	AVPacket packet = {0};
224 	int got_frame = false;
225 	int ret = 0;
226 
227 	*got_output = false;
228 
229 	copy_data(decode, data, size);
230 
231 	av_init_packet(&packet);
232 	packet.data = decode->packet_buffer;
233 	packet.size = (int)size;
234 
235 	if (!decode->frame) {
236 		decode->frame = av_frame_alloc();
237 		if (!decode->frame)
238 			return false;
239 	}
240 
241 	if (data && size)
242 		ret = avcodec_send_packet(decode->decoder, &packet);
243 	if (ret == 0)
244 		ret = avcodec_receive_frame(decode->decoder, decode->frame);
245 
246 	got_frame = (ret == 0);
247 
248 	if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
249 		ret = 0;
250 
251 	if (ret < 0)
252 		return false;
253 	else if (!got_frame)
254 		return true;
255 
256 	for (size_t i = 0; i < MAX_AV_PLANES; i++)
257 		audio->data[i] = decode->frame->data[i];
258 
259 	audio->samples_per_sec = decode->frame->sample_rate;
260 	audio->format = convert_sample_format(decode->frame->format);
261 	audio->speakers =
262 		convert_speaker_layout((uint8_t)decode->decoder->channels);
263 
264 	audio->frames = decode->frame->nb_samples;
265 
266 	if (audio->format == AUDIO_FORMAT_UNKNOWN)
267 		return false;
268 
269 	*got_output = true;
270 	return true;
271 }
272 
273 static enum video_colorspace
convert_color_space(enum AVColorSpace s,enum AVColorTransferCharacteristic trc)274 convert_color_space(enum AVColorSpace s, enum AVColorTransferCharacteristic trc)
275 {
276 	switch (s) {
277 	case AVCOL_SPC_BT709:
278 		return (trc == AVCOL_TRC_IEC61966_2_1) ? VIDEO_CS_SRGB
279 						       : VIDEO_CS_709;
280 	case AVCOL_SPC_FCC:
281 	case AVCOL_SPC_BT470BG:
282 	case AVCOL_SPC_SMPTE170M:
283 	case AVCOL_SPC_SMPTE240M:
284 		return VIDEO_CS_601;
285 	default:
286 		return VIDEO_CS_DEFAULT;
287 	}
288 }
289 
ffmpeg_decode_video(struct ffmpeg_decode * decode,uint8_t * data,size_t size,long long * ts,enum video_range_type range,struct obs_source_frame2 * frame,bool * got_output)290 bool ffmpeg_decode_video(struct ffmpeg_decode *decode, uint8_t *data,
291 			 size_t size, long long *ts,
292 			 enum video_range_type range,
293 			 struct obs_source_frame2 *frame, bool *got_output)
294 {
295 	AVPacket packet = {0};
296 	int got_frame = false;
297 	AVFrame *out_frame;
298 	int ret;
299 
300 	*got_output = false;
301 
302 	copy_data(decode, data, size);
303 
304 	av_init_packet(&packet);
305 	packet.data = decode->packet_buffer;
306 	packet.size = (int)size;
307 	packet.pts = *ts;
308 
309 	if (decode->codec->id == AV_CODEC_ID_H264 &&
310 	    obs_avc_keyframe(data, size))
311 		packet.flags |= AV_PKT_FLAG_KEY;
312 
313 	if (!decode->frame) {
314 		decode->frame = av_frame_alloc();
315 		if (!decode->frame)
316 			return false;
317 
318 		if (decode->hw && !decode->hw_frame) {
319 			decode->hw_frame = av_frame_alloc();
320 			if (!decode->hw_frame)
321 				return false;
322 		}
323 	}
324 
325 	out_frame = decode->hw ? decode->hw_frame : decode->frame;
326 
327 	ret = avcodec_send_packet(decode->decoder, &packet);
328 	if (ret == 0) {
329 		ret = avcodec_receive_frame(decode->decoder, out_frame);
330 	}
331 
332 	got_frame = (ret == 0);
333 
334 	if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
335 		ret = 0;
336 
337 	if (ret < 0)
338 		return false;
339 	else if (!got_frame)
340 		return true;
341 
342 #ifdef USE_NEW_HARDWARE_CODEC_METHOD
343 	if (got_frame && decode->hw) {
344 		ret = av_hwframe_transfer_data(decode->frame, out_frame, 0);
345 		if (ret < 0) {
346 			return false;
347 		}
348 	}
349 #endif
350 
351 	for (size_t i = 0; i < MAX_AV_PLANES; i++) {
352 		frame->data[i] = decode->frame->data[i];
353 		frame->linesize[i] = decode->frame->linesize[i];
354 	}
355 
356 	frame->format = convert_pixel_format(decode->frame->format);
357 
358 	if (range == VIDEO_RANGE_DEFAULT) {
359 		range = (decode->frame->color_range == AVCOL_RANGE_JPEG)
360 				? VIDEO_RANGE_FULL
361 				: VIDEO_RANGE_PARTIAL;
362 	}
363 
364 	const enum video_colorspace cs = convert_color_space(
365 		decode->frame->colorspace, decode->frame->color_trc);
366 
367 	const bool success = video_format_get_parameters(
368 		cs, range, frame->color_matrix, frame->color_range_min,
369 		frame->color_range_max);
370 	if (!success) {
371 		blog(LOG_ERROR,
372 		     "Failed to get video format "
373 		     "parameters for video format %u",
374 		     cs);
375 		return false;
376 	}
377 
378 	frame->range = range;
379 
380 	*ts = decode->frame->pkt_pts;
381 
382 	frame->width = decode->frame->width;
383 	frame->height = decode->frame->height;
384 	frame->flip = false;
385 
386 	if (frame->format == VIDEO_FORMAT_NONE)
387 		return false;
388 
389 	*got_output = true;
390 	return true;
391 }
392