1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2010-2017
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / OpenHEVC decoder filter
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 
27 #include <gpac/filters.h>
28 #include <gpac/avparse.h>
29 #include <gpac/constants.h>
30 
31 #if defined(GPAC_HAS_OPENHEVC) && !defined(GPAC_DISABLE_AV_PARSERS)
32 
33 #include <gpac/internal/media_dev.h>
34 #include <libopenhevc/openhevc.h>
35 
36 #if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__)
37 #  pragma comment(lib, "openhevc")
38 #endif
39 
40 
41 #define HEVC_MAX_STREAMS 2
42 
43 typedef struct
44 {
45 	GF_FilterPid *ipid;
46 	u32 cfg_crc;
47 	u32 id;
48 	u32 dep_id;
49 	u32 codec_id;
50 	Bool sublayer;
51 
52 	u8 *inject_hdr;
53 	u32 inject_hdr_size;
54 } GF_HEVCStream;
55 
56 
57 typedef struct
58 {
59 	//options
60 	u32 threading;
61 	Bool no_copy;
62 	u32 nb_threads;
63 	Bool pack_hfr;
64 	Bool seek_reset;
65 	Bool force_stereo;
66 	Bool reset_switch;
67 
68 	//internal
69 	GF_Filter *filter;
70 	GF_FilterPid *opid;
71 	GF_HEVCStream streams[HEVC_MAX_STREAMS];
72 	u32 nb_streams;
73 	Bool is_multiview;
74 
75 	u32 width, stride, height, out_size, luma_bpp, chroma_bpp;
76 	GF_Fraction sar;
77 	GF_FilterPacket *packed_pck;
78 	u8 *packed_data;
79 
80 	u32 hevc_nalu_size_length;
81 	Bool has_pic;
82 
83 	OHHandle codec;
84 	u32 nb_layers, cur_layer;
85 
86 	Bool decoder_started;
87 
88 	u32 frame_idx;
89 	u32 dec_frames;
90 	u8  chroma_format_idc;
91 
92 #ifdef  OPENHEVC_HAS_AVC_BASE
93 	u32 avc_base_id;
94 	u32 avc_nalu_size_length;
95 	char *avc_base;
96 	u32 avc_base_size;
97 	u32 avc_base_pts;
98 #endif
99 
100 	Bool force_stereo_reset;
101 
102 	GF_FilterFrameInterface frame_ifce;
103 	OHFrame frame_ptr;
104 	Bool frame_out;
105 
106 	char *reaggregation_buffer;
107 	u32 reaggregation_alloc_size, reaggregation_size;
108 
109 	char *inject_buffer;
110 	u32 inject_buffer_alloc_size, reaggregatioinject_buffer_size;
111 
112 	Bool reconfig_pending;
113 
114 	Bool signal_reconfig;
115 
116 	GF_List *src_packets;
117 	Bool drop_non_refs;
118 } GF_OHEVCDecCtx;
119 
ohevcdec_configure_scalable_pid(GF_OHEVCDecCtx * ctx,GF_FilterPid * pid,u32 codecid)120 static GF_Err ohevcdec_configure_scalable_pid(GF_OHEVCDecCtx *ctx, GF_FilterPid *pid, u32 codecid)
121 {
122 	GF_HEVCConfig *cfg = NULL;
123 	u8 *data;
124 	u32 data_len;
125 	GF_BitStream *bs;
126 	Bool is_lhvc = GF_TRUE;
127 	u32 i, j;
128 	const GF_PropertyValue *dsi = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT);
129 
130 	if (!dsi) {
131 		dsi = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
132 		is_lhvc = GF_FALSE;
133 	}
134 
135 	if (!ctx->codec) return GF_NOT_SUPPORTED;
136 
137 	if (!dsi || !dsi->value.data.size) {
138 		ctx->nb_layers++;
139 		ctx->cur_layer++;
140 		oh_select_active_layer(ctx->codec, ctx->cur_layer-1);
141 		oh_select_view_layer(ctx->codec, ctx->cur_layer-1);
142 		return GF_OK;
143 	}
144 
145 	cfg = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, is_lhvc);
146 
147 	if (!cfg) return GF_NON_COMPLIANT_BITSTREAM;
148 	if (!ctx->hevc_nalu_size_length) ctx->hevc_nalu_size_length = cfg->nal_unit_size;
149 	else if (ctx->hevc_nalu_size_length != cfg->nal_unit_size)
150 		return GF_NON_COMPLIANT_BITSTREAM;
151 
152 	ctx->nb_layers++;
153 	ctx->cur_layer++;
154 	oh_select_active_layer(ctx->codec, ctx->nb_layers-1);
155 	oh_select_view_layer(ctx->codec, ctx->nb_layers-1);
156 
157 #ifdef  OPENHEVC_HAS_AVC_BASE
158 	//LHVC mode with base AVC layer: set extradata for LHVC
159 	if (ctx->avc_base_id) {
160 		oh_extradata_cpy_lhvc(ctx->codec, NULL, (u8 *) dsi->value.data.ptr, 0, dsi->value.data.size);
161 	} else
162 #endif
163 	//LHVC mode with base HEVC layer: decode the LHVC SPS/PPS/VPS
164 	{
165 		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
166 		for (i=0; i< gf_list_count(cfg->param_array); i++) {
167 			GF_HEVCParamArray *ar = (GF_HEVCParamArray *)gf_list_get(cfg->param_array, i);
168 			for (j=0; j< gf_list_count(ar->nalus); j++) {
169 				GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(ar->nalus, j);
170 				gf_bs_write_int(bs, sl->size, 8*ctx->hevc_nalu_size_length);
171 				gf_bs_write_data(bs, sl->data, sl->size);
172 			}
173 		}
174 
175 		gf_bs_get_content(bs, &data, &data_len);
176 		gf_bs_del(bs);
177 		//the decoder may not be already started
178 		if (!ctx->decoder_started) {
179 			oh_start(ctx->codec);
180 			ctx->decoder_started=1;
181 		}
182 
183 		oh_decode(ctx->codec, (u8 *)data, data_len, 0);
184 		gf_free(data);
185 	}
186 	gf_odf_hevc_cfg_del(cfg);
187 	return GF_OK;
188 }
189 
190 
ohevcdec_write_ps_list(GF_BitStream * bs,GF_List * list,u32 nalu_size_length)191 static void ohevcdec_write_ps_list(GF_BitStream *bs, GF_List *list, u32 nalu_size_length)
192 {
193 	u32 i, count = list ? gf_list_count(list) : 0;
194 	for (i=0; i<count; i++) {
195 		GF_AVCConfigSlot *sl = gf_list_get(list, i);
196 		gf_bs_write_int(bs, sl->size, 8*nalu_size_length);
197 		gf_bs_write_data(bs, sl->data, sl->size);
198 	}
199 }
200 
ohevcdec_create_inband(GF_HEVCStream * stream,u32 nal_unit_size,GF_List * sps,GF_List * pps,GF_List * vps)201 static void ohevcdec_create_inband(GF_HEVCStream *stream, u32 nal_unit_size, GF_List *sps, GF_List *pps, GF_List *vps)
202 {
203 	GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
204 	if (vps) ohevcdec_write_ps_list(bs, vps, nal_unit_size);
205 	if (sps) ohevcdec_write_ps_list(bs, sps, nal_unit_size);
206 	if (pps) ohevcdec_write_ps_list(bs, pps, nal_unit_size);
207 	if (stream->inject_hdr) gf_free(stream->inject_hdr);
208 	gf_bs_get_content(bs, &stream->inject_hdr, &stream->inject_hdr_size);
209 	gf_bs_del(bs);
210 }
211 
212 
213 #if defined(OPENHEVC_HAS_AVC_BASE) && !defined(GPAC_DISABLE_LOG)
openhevc_log_callback(void * udta,int l,const char * fmt,va_list vl)214 void openhevc_log_callback(void *udta, int l, const char*fmt, va_list vl)
215 {
216 	u32 level = GF_LOG_DEBUG;
217 	if (l <= OHEVC_LOG_ERROR) level = GF_LOG_ERROR;
218 	else if (l <= OHEVC_LOG_WARNING) level = GF_LOG_WARNING;
219 	else if (l <= OHEVC_LOG_INFO) level = GF_LOG_INFO;
220 //	else if (l >= OHEVC_LOG_VERBOSE) return;
221 
222 	if (gf_log_tool_level_on(GF_LOG_CODEC, level)) {
223 		gf_log_va_list(level, GF_LOG_CODEC, fmt, vl);
224 	}
225 }
226 #endif
227 
ohevcdec_set_codec_name(GF_Filter * filter)228 static void ohevcdec_set_codec_name(GF_Filter *filter)
229 {
230 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx*) gf_filter_get_udta(filter);
231 #ifdef  OPENHEVC_HAS_AVC_BASE
232 	if (ctx->avc_base_id) {
233 		if (ctx->cur_layer==1) gf_filter_set_name(filter, "OpenHEVC-v"NV_VERSION"-AVC|H264");
234 		else gf_filter_set_name(filter, "OpenHEVC-v"NV_VERSION"-AVC|H264+LHVC");
235 	}
236 	if (ctx->cur_layer==1) gf_filter_set_name(filter, "OpenHEVC-v"NV_VERSION);
237 	else gf_filter_set_name(filter, "OpenHEVC-v"NV_VERSION"-LHVC");
238 #else
239 	return gf_filter_set_name(filter, libOpenHevcVersion(ctx->codec) );
240 #endif
241 }
242 
ohevcdec_get_pixel_format(u32 luma_bpp,u8 chroma_format_idc)243 static u32 ohevcdec_get_pixel_format( u32 luma_bpp, u8 chroma_format_idc)
244 {
245 	switch (chroma_format_idc) {
246 	case 1:
247 		return (luma_bpp==10) ? GF_PIXEL_YUV_10 : GF_PIXEL_YUV;
248 	case 2:
249 		return (luma_bpp==10) ? GF_PIXEL_YUV422_10 : GF_PIXEL_YUV422;
250 	case 3:
251 		return (luma_bpp==10) ? GF_PIXEL_YUV444_10 : GF_PIXEL_YUV444;
252 	default:
253 		return 0;
254 	}
255 	return 0;
256 }
257 
ohevc_set_out_props(GF_OHEVCDecCtx * ctx)258 static void ohevc_set_out_props(GF_OHEVCDecCtx *ctx)
259 {
260 	u32 pixfmt;
261 
262 	gf_filter_pid_copy_properties(ctx->opid, ctx->streams[0].ipid);
263 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
264 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, NULL );
265 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT, NULL );
266 
267 	if (ctx->pack_hfr) {
268 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_WIDTH, &PROP_UINT(2*ctx->width) );
269 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_HEIGHT, &PROP_UINT(2*ctx->height) );
270 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STRIDE, &PROP_UINT(2*ctx->stride) );
271 	} else {
272 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_WIDTH, &PROP_UINT(ctx->width) );
273 		if (ctx->force_stereo && ctx->is_multiview && ctx->cur_layer>1) {
274 			gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_HEIGHT, &PROP_UINT(2*ctx->height) );
275 		} else {
276 			gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_HEIGHT, &PROP_UINT(ctx->height) );
277 		}
278 
279 		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STRIDE, &PROP_UINT(ctx->stride) );
280 	}
281 	pixfmt = ohevcdec_get_pixel_format(ctx->luma_bpp, ctx->chroma_format_idc);
282 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PIXFMT, &PROP_UINT(pixfmt) );
283 	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAR, &PROP_FRAC(ctx->sar) );
284 }
285 
ohevcdec_configure_pid(GF_Filter * filter,GF_FilterPid * pid,Bool is_remove)286 static GF_Err ohevcdec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
287 {
288 	u32 i, dep_id=0, id=0, cfg_crc=0, codecid;
289 	Bool has_scalable = GF_FALSE;
290 	Bool is_sublayer = GF_FALSE;
291 	u8 *patched_dsi=NULL;
292 	u32 patched_dsi_size=0;
293 	GF_HEVCStream *stream;
294 	const GF_PropertyValue *p, *dsi, *dsi_enh=NULL;
295 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx*) gf_filter_get_udta(filter);
296 
297 	if (is_remove) {
298 		if (ctx->streams[0].ipid == pid) {
299 			memset(ctx->streams, 0, HEVC_MAX_STREAMS*sizeof(GF_HEVCStream));
300 			if (ctx->opid) gf_filter_pid_remove(ctx->opid);
301 			ctx->opid = NULL;
302 			ctx->nb_streams = 0;
303 			if (ctx->codec) oh_close(ctx->codec);
304 			ctx->codec = NULL;
305 			return GF_OK;
306 		} else {
307 			for (i=0; i<ctx->nb_streams; i++) {
308 				if (ctx->streams[i].ipid == pid) {
309 					ctx->streams[i].ipid = NULL;
310 					ctx->streams[i].cfg_crc = 0;
311 					memmove(&ctx->streams[i], &ctx->streams[i+1], sizeof(GF_HEVCStream)*(ctx->nb_streams-1));
312 					ctx->nb_streams--;
313 					return GF_OK;
314 				}
315 			}
316 		}
317 		return GF_OK;
318 	}
319 	if (! gf_filter_pid_check_caps(pid))
320 		return GF_NOT_SUPPORTED;
321 
322 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_DEPENDENCY_ID);
323 	if (p) dep_id = p->value.uint;
324 
325 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_ID);
326 	if (!p) p = gf_filter_pid_get_property(pid, GF_PROP_PID_ESID);
327 	if (p) id = p->value.uint;
328 
329 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_CODECID);
330 	codecid = p ? p->value.uint : 0;
331 	if (!codecid) return GF_NOT_SUPPORTED;
332 
333 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_SCALABLE);
334 	if (p) has_scalable = p->value.boolean;
335 
336 	p = gf_filter_pid_get_property(pid, GF_PROP_PID_SUBLAYER);
337 	if (p) is_sublayer = p->value.boolean;
338 
339 	dsi = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG);
340 	cfg_crc = 0;
341 	if (dsi && dsi->value.data.ptr && dsi->value.data.size) {
342 		cfg_crc = gf_crc_32(dsi->value.data.ptr, dsi->value.data.size);
343 	}
344 	dsi_enh = gf_filter_pid_get_property(pid, GF_PROP_PID_DECODER_CONFIG_ENHANCEMENT);
345 
346 	stream = NULL;
347 	//check if this is an update
348 	for (i=0; i<ctx->nb_streams; i++) {
349 		if (ctx->streams[i].ipid == pid) {
350 			if (ctx->streams[i].cfg_crc == cfg_crc) return GF_OK;
351 			if (ctx->codec && (ctx->streams[i].codec_id != codecid)) {
352 				//we are already instantiated, flush all frames and reconfig
353 				ctx->reconfig_pending = GF_TRUE;
354 				return GF_OK;
355 			}
356 			ctx->streams[i].codec_id = codecid;
357 			ctx->streams[i].cfg_crc = cfg_crc;
358 			stream = &ctx->streams[i];
359 			break;
360 		}
361 	}
362 
363 	if (!stream) {
364 		if (ctx->nb_streams==HEVC_MAX_STREAMS) {
365 			return GF_NOT_SUPPORTED;
366 		}
367 		//insert new pid in order of dependencies
368 		for (i=0; i<ctx->nb_streams; i++) {
369 
370 			if (!dep_id && !ctx->streams[i].dep_id) {
371 				GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[SVC Decoder] Detected multiple independent base (%s and %s)\n", gf_filter_pid_get_name(pid), gf_filter_pid_get_name(ctx->streams[i].ipid)));
372 				return GF_REQUIRES_NEW_INSTANCE;
373 			}
374 
375 			if (ctx->streams[i].id == dep_id) {
376 				if (ctx->nb_streams > i+2)
377 					memmove(&ctx->streams[i+1], &ctx->streams[i+2], sizeof(GF_HEVCStream) * (ctx->nb_streams-i-1));
378 
379 				ctx->streams[i+1].ipid = pid;
380 				ctx->streams[i+1].cfg_crc = cfg_crc;
381 				ctx->streams[i+1].dep_id = dep_id;
382 				ctx->streams[i+1].id = id;
383 				ctx->streams[i+1].codec_id = codecid;
384 				ctx->streams[i+1].sublayer = is_sublayer;
385 				gf_filter_pid_set_framing_mode(pid, GF_TRUE);
386 				stream = &ctx->streams[i+1];
387 				break;
388 			}
389 			if (ctx->streams[i].dep_id == id) {
390 				if (ctx->nb_streams > i+1)
391 					memmove(&ctx->streams[i+1], &ctx->streams[i], sizeof(GF_HEVCStream) * (ctx->nb_streams-i));
392 
393 				ctx->streams[i].ipid = pid;
394 				ctx->streams[i].cfg_crc = cfg_crc;
395 				ctx->streams[i].dep_id = dep_id;
396 				ctx->streams[i].id = id;
397 				ctx->streams[i].codec_id = codecid;
398 				ctx->streams[i].sublayer = is_sublayer;
399 				gf_filter_pid_set_framing_mode(pid, GF_TRUE);
400 				stream = &ctx->streams[i];
401 				break;
402 			}
403 		}
404 		if (!stream) {
405 			ctx->streams[ctx->nb_streams].ipid = pid;
406 			ctx->streams[ctx->nb_streams].cfg_crc = cfg_crc;
407 			ctx->streams[ctx->nb_streams].id = id;
408 			ctx->streams[ctx->nb_streams].dep_id = dep_id;
409 			ctx->streams[ctx->nb_streams].codec_id = codecid;
410 			ctx->streams[ctx->nb_streams].sublayer = is_sublayer;
411 			gf_filter_pid_set_framing_mode(pid, GF_TRUE);
412 			stream = &ctx->streams[ctx->nb_streams];
413 		}
414 		ctx->nb_streams++;
415 		ctx->signal_reconfig = GF_TRUE;
416 	}
417 	ctx->nb_layers = ctx->cur_layer = 1;
418 
419 	//temporal sublayer stream setup, do nothing
420 	if (stream->sublayer)
421 		return GF_OK;
422 
423 	//scalable stream setup
424 	if (stream->dep_id) {
425 		GF_Err e;
426 		e = ohevcdec_configure_scalable_pid(ctx, pid, codecid);
427 		ohevcdec_set_codec_name(filter);
428 		return e;
429 	}
430 
431 
432 	if (codecid == GF_CODECID_AVC)
433 #ifdef  OPENHEVC_HAS_AVC_BASE
434 		ctx->avc_base_id = id;
435 #else
436 	return GF_NOT_SUPPORTED;
437 #endif
438 
439 	if (dsi && dsi->value.data.size) {
440 #ifdef  OPENHEVC_HAS_AVC_BASE
441 		if (codecid==GF_CODECID_AVC) {
442 			GF_AVCConfig *avcc = NULL;
443 			AVCState avc;
444 			memset(&avc, 0, sizeof(AVCState));
445 
446 			avcc = gf_odf_avc_cfg_read(dsi->value.data.ptr, dsi->value.data.size);
447 			if (!avcc) return GF_NON_COMPLIANT_BITSTREAM;
448 			ctx->avc_nalu_size_length = avcc->nal_unit_size;
449 
450 			for (i=0; i< gf_list_count(avcc->sequenceParameterSets); i++) {
451 				GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avcc->sequenceParameterSets, i);
452 				s32 idx = gf_media_avc_read_sps(sl->data, sl->size, &avc, 0, NULL);
453 				ctx->width = MAX(avc.sps[idx].width, ctx->width);
454 				ctx->height = MAX(avc.sps[idx].height, ctx->height);
455 				ctx->luma_bpp = avcc->luma_bit_depth;
456 				ctx->chroma_bpp = avcc->chroma_bit_depth;
457 				ctx->chroma_format_idc = avcc->chroma_format;
458 			}
459 
460 			if (ctx->codec && ctx->decoder_started) {
461 				//this seems to be broken in openhevc, we need to reconfigure the decoder ...
462 				if (ctx->reset_switch) {
463 					ctx->reconfig_pending = GF_TRUE;
464 					stream->cfg_crc = 0;
465 					gf_odf_avc_cfg_del(avcc);
466 					return GF_OK;
467 				} else {
468 					ohevcdec_create_inband(stream, avcc->nal_unit_size, avcc->sequenceParameterSets, avcc->pictureParameterSets, NULL);
469 				}
470 			}
471 			gf_odf_avc_cfg_del(avcc);
472 		} else
473 
474 #endif
475 		{
476 			GF_HEVCConfig *hvcc = NULL;
477 			GF_HEVCConfig *hvcc_enh = NULL;
478 			HEVCState hevc;
479 			u32 j;
480 			GF_List *SPSs=NULL, *PPSs=NULL, *VPSs=NULL;
481 			memset(&hevc, 0, sizeof(HEVCState));
482 
483 			hvcc = gf_odf_hevc_cfg_read(dsi->value.data.ptr, dsi->value.data.size, GF_FALSE);
484 			if (!hvcc) return GF_NON_COMPLIANT_BITSTREAM;
485 
486 			ctx->hevc_nalu_size_length = hvcc->nal_unit_size;
487 
488 			if (dsi_enh) {
489 				hvcc_enh = gf_odf_hevc_cfg_read(dsi_enh->value.data.ptr, dsi_enh->value.data.size, GF_TRUE);
490 			}
491 
492 			for (i=0; i< gf_list_count(hvcc->param_array); i++) {
493 				GF_HEVCParamArray *ar = (GF_HEVCParamArray *)gf_list_get(hvcc->param_array, i);
494 
495 				if (hvcc_enh) {
496 					for (j=0; j< gf_list_count(hvcc_enh->param_array); j++) {
497 						GF_HEVCParamArray *ar_enh = (GF_HEVCParamArray *)gf_list_get(hvcc_enh->param_array, j);
498 						if (ar->type==ar_enh->type)
499 							gf_list_transfer(ar->nalus, ar_enh->nalus);
500 					}
501 				}
502 				for (j=0; j< gf_list_count(ar->nalus); j++) {
503 					GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(ar->nalus, j);
504 					s32 idx;
505 					u16 hdr = sl->data[0] << 8 | sl->data[1];
506 
507 					if (ar->type==GF_HEVC_NALU_SEQ_PARAM) {
508 						idx = gf_media_hevc_read_sps(sl->data, sl->size, &hevc);
509 						ctx->width = MAX(hevc.sps[idx].width, ctx->width);
510 						ctx->height = MAX(hevc.sps[idx].height, ctx->height);
511 						ctx->luma_bpp = MAX(hevc.sps[idx].bit_depth_luma, ctx->luma_bpp);
512 						ctx->chroma_bpp = MAX(hevc.sps[idx].bit_depth_chroma, ctx->chroma_bpp);
513 						ctx->chroma_format_idc  = hevc.sps[idx].chroma_format_idc;
514 
515 						if (hdr & 0x1f8) {
516 							ctx->nb_layers ++;
517 						}
518 						SPSs = ar->nalus;
519 					}
520 					else if (ar->type==GF_HEVC_NALU_VID_PARAM) {
521 						s32 vps_id = gf_media_hevc_read_vps(sl->data, sl->size, &hevc);
522 						//multiview
523 						if ((vps_id>=0) && (hevc.vps[vps_id].scalability_mask[1])) {
524 							ctx->is_multiview = GF_TRUE;
525 						}
526 						VPSs = ar->nalus;
527 					}
528 					else if (ar->type==GF_HEVC_NALU_PIC_PARAM) {
529 						gf_media_hevc_read_pps(sl->data, sl->size, &hevc);
530 						PPSs = ar->nalus;
531 					}
532 				}
533 			}
534 			if (ctx->codec && ctx->decoder_started) {
535 				if (ctx->reset_switch) {
536 					ctx->reconfig_pending = GF_TRUE;
537 					stream->cfg_crc = 0;
538 					gf_odf_hevc_cfg_del(hvcc);
539 					return GF_OK;
540 				} else {
541 					ohevcdec_create_inband(stream, hvcc->nal_unit_size, SPSs, PPSs, VPSs);
542 				}
543 			}
544 			if (hvcc_enh) {
545 				gf_odf_hevc_cfg_del(hvcc_enh);
546 				gf_odf_hevc_cfg_write(hvcc, &patched_dsi, &patched_dsi_size);
547 			}
548 			gf_odf_hevc_cfg_del(hvcc);
549 		}
550 	}
551 
552 	if (!ctx->codec) {
553 #ifdef  OPENHEVC_HAS_AVC_BASE
554 		if (ctx->avc_base_id) {
555 			ctx->codec = oh_init_lhvc(ctx->nb_threads, ctx->threading);
556 		} else
557 #endif
558 		{
559 			ctx->codec = oh_init(ctx->nb_threads, ctx->threading);
560 		}
561 	}
562 
563 
564 #if defined(OPENHEVC_HAS_AVC_BASE) && !defined(GPAC_DISABLE_LOG)
565 	if (gf_log_tool_level_on(GF_LOG_CODEC, GF_LOG_DEBUG) ) {
566 		oh_set_log_level(ctx->codec, OHEVC_LOG_DEBUG);
567 	} else if (gf_log_tool_level_on(GF_LOG_CODEC, GF_LOG_INFO) ) {
568 		oh_set_log_level(ctx->codec, OHEVC_LOG_INFO);
569 	} else if (gf_log_tool_level_on(GF_LOG_CODEC, GF_LOG_WARNING) ) {
570 		oh_set_log_level(ctx->codec, OHEVC_LOG_WARNING);
571 	} else {
572 		oh_set_log_level(ctx->codec, OHEVC_LOG_ERROR);
573 	}
574 	oh_set_log_callback(ctx->codec, openhevc_log_callback);
575 #endif
576 
577 	if (dsi) {
578 		if (has_scalable) {
579 			ctx->cur_layer = ctx->nb_layers;
580 			oh_select_active_layer(ctx->codec, ctx->cur_layer-1);
581 			oh_select_view_layer(ctx->codec, ctx->cur_layer-1);
582 		} else {
583 			//there is a bug with select active layer on win32 with avc base
584 #ifdef WIN32
585 			if (!ctx->avc_base_id) {
586 #endif
587 				oh_select_active_layer(ctx->codec, 1);
588 				if (!ctx->avc_base_id)
589 					oh_select_view_layer(ctx->codec, 0);
590 #ifdef WIN32
591 			}
592 #endif
593 			}
594 
595 		if (!ctx->decoder_started) {
596 #ifdef  OPENHEVC_HAS_AVC_BASE
597 			if (ctx->avc_base_id) {
598 				oh_extradata_cpy_lhvc(ctx->codec, (u8 *) dsi->value.data.ptr, NULL, dsi->value.data.size, 0);
599 			} else
600 #endif
601 			{
602 				if (patched_dsi) {
603 					oh_extradata_cpy(ctx->codec, (u8 *) patched_dsi, patched_dsi_size);
604 				} else {
605 					oh_extradata_cpy(ctx->codec, (u8 *) dsi->value.data.ptr, dsi->value.data.size);
606 				}
607 			}
608 		}
609 	} else {
610 		//decode and display layer 0 by default - will be changed when attaching enhancement layers
611 
612 		//has_scalable_layers is set, the esd describes a set of HEVC stream but we don't know how many - for now only two decoders so easy,
613 		//but should be fixed in the future
614 		if (has_scalable) {
615 			ctx->nb_layers = 2;
616 			ctx->cur_layer = 2;
617 		}
618 		oh_select_active_layer(ctx->codec, ctx->cur_layer-1);
619 		oh_select_view_layer(ctx->codec, ctx->cur_layer-1);
620 	}
621 
622 	if (patched_dsi) gf_free(patched_dsi);
623 
624 	//in case we don't have a config record
625 	if (!ctx->chroma_format_idc) ctx->chroma_format_idc = 1;
626 
627 	//we start decoder on the first frame
628 	ctx->dec_frames = 0;
629 	ohevcdec_set_codec_name(filter);
630 
631 	if (!ctx->opid) {
632 		ctx->opid = gf_filter_pid_new(filter);
633 	}
634 
635 	//copy properties at init or reconfig
636 	if (ctx->signal_reconfig) {
637 		ohevc_set_out_props(ctx);
638 		ctx->signal_reconfig = GF_FALSE;
639 	} else {
640 		ctx->signal_reconfig = GF_TRUE;
641 	}
642 	return GF_OK;
643 }
644 
645 
646 
ohevcdec_process_event(GF_Filter * filter,const GF_FilterEvent * fevt)647 static Bool ohevcdec_process_event(GF_Filter *filter, const GF_FilterEvent *fevt)
648 {
649 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx*) gf_filter_get_udta(filter);
650 
651 	if (fevt->base.type == GF_FEVT_QUALITY_SWITCH) {
652 
653 		if (ctx->nb_layers==1) return GF_FALSE;
654 		/*switch up*/
655 		if (fevt->quality_switch.up > 0) {
656 			if (ctx->cur_layer>=ctx->nb_layers) return GF_FALSE;
657 			ctx->cur_layer++;
658 		} else {
659 			if (ctx->cur_layer<=1) return GF_FALSE;
660 			ctx->cur_layer--;
661 		}
662 		oh_select_view_layer(ctx->codec, ctx->cur_layer-1);
663 		oh_select_active_layer(ctx->codec, ctx->cur_layer-1);
664 		if (ctx->is_multiview)
665 			ctx->force_stereo_reset = ctx->force_stereo;
666 
667 		//todo: we should get the set of pids active and trigger the switch up/down based on that
668 		//rather than not canceling the event
669 		return GF_FALSE;
670 	} else if (fevt->base.type == GF_FEVT_STOP) {
671 		if (ctx->seek_reset && ctx->dec_frames) {
672 			u32 i;
673 			u32 cl = ctx->cur_layer;
674 			u32 nl = ctx->nb_layers;
675 
676 			//quick hack, we have an issue with openHEVC resuming after being flushed ...
677 			oh_close(ctx->codec);
678 			ctx->codec = NULL;
679 			ctx->decoder_started = GF_FALSE;
680 			for (i=0; i<ctx->nb_streams; i++) {
681 				ohevcdec_configure_pid(filter, ctx->streams[i].ipid, GF_FALSE);
682 			}
683 			ctx->cur_layer = cl;
684 			ctx->nb_layers = nl;
685 			if (ctx->codec) {
686 				oh_select_active_layer(ctx->codec, ctx->cur_layer-1);
687 				oh_select_view_layer(ctx->codec, ctx->cur_layer-1);
688 			}
689 		}
690 	}
691 	else if ((fevt->base.type==GF_FEVT_PLAY) || (fevt->base.type==GF_FEVT_SET_SPEED) || (fevt->base.type==GF_FEVT_RESUME)) {
692 		ctx->drop_non_refs = fevt->play.drop_non_ref;
693 	}
694 	return GF_FALSE;
695 }
696 
697 
ohevcframe_release(GF_Filter * filter,GF_FilterPid * pid,GF_FilterPacket * pck)698 void ohevcframe_release(GF_Filter *filter, GF_FilterPid *pid, GF_FilterPacket *pck)
699 {
700 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx *) gf_filter_get_udta(filter);
701 	ctx->frame_out = GF_FALSE;
702 	gf_filter_post_process_task(ctx->filter);
703 }
704 
ohevcframe_get_plane(GF_FilterFrameInterface * frame,u32 plane_idx,const u8 ** outPlane,u32 * outStride)705 GF_Err ohevcframe_get_plane(GF_FilterFrameInterface *frame, u32 plane_idx, const u8 **outPlane, u32 *outStride)
706 {
707 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx *)frame->user_data;
708 	if (! outPlane || !outStride) return GF_BAD_PARAM;
709 	*outPlane = NULL;
710 	*outStride = 0;
711 
712 	if (plane_idx==0) {
713 		*outPlane = (const u8 *) ctx->frame_ptr.data_y_p;
714 		*outStride = ctx->frame_ptr.frame_par.linesize_y;
715 	} else if (plane_idx==1) {
716 		*outPlane = (const u8 *)  ctx->frame_ptr.data_cb_p;
717 		*outStride = ctx->frame_ptr.frame_par.linesize_cb;
718 	} else if (plane_idx==2) {
719 		*outPlane = (const u8 *)  ctx->frame_ptr.data_cr_p;
720 		*outStride = ctx->frame_ptr.frame_par.linesize_cr;
721 	} else
722 		return GF_BAD_PARAM;
723 
724 	return GF_OK;
725 }
726 
ohevcdec_send_output_frame(GF_OHEVCDecCtx * ctx)727 static GF_Err ohevcdec_send_output_frame(GF_OHEVCDecCtx *ctx)
728 {
729 	GF_FilterPacket *dst_pck, *src_pck;
730 	u32 i, count;
731 
732 	ctx->frame_ifce.user_data = ctx;
733 	ctx->frame_ifce.get_plane = ohevcframe_get_plane;
734 	//we only keep one frame out, force releasing it
735 	ctx->frame_ifce.flags = GF_FRAME_IFCE_BLOCKING;
736 	oh_output_update(ctx->codec, 1, &ctx->frame_ptr);
737 
738 	dst_pck = gf_filter_pck_new_frame_interface(ctx->opid, &ctx->frame_ifce, ohevcframe_release);
739 
740 	src_pck = NULL;
741 	count = gf_list_count(ctx->src_packets);
742 	for (i=0;i<count; i++) {
743 		src_pck = gf_list_get(ctx->src_packets, i);
744 		if (gf_filter_pck_get_cts(src_pck) == ctx->frame_ptr.frame_par.pts) {
745 			u8 car_v = gf_filter_pck_get_carousel_version(src_pck);
746 			gf_filter_pck_set_carousel_version(src_pck, 0);
747 
748 			gf_filter_pck_merge_properties(src_pck, dst_pck);
749 			gf_list_rem(ctx->src_packets, i);
750 			gf_filter_pck_unref(src_pck);
751 
752 			if (car_v)
753 				ohevc_set_out_props(ctx);
754 
755 			break;
756 		}
757 		src_pck = NULL;
758 	}
759 	if (!src_pck)
760 		gf_filter_pck_set_cts(dst_pck, ctx->frame_ptr.frame_par.pts);
761 
762 	ctx->frame_out = GF_TRUE;
763 	gf_filter_pck_send(dst_pck);
764 	return GF_OK;
765 }
ohevcdec_flush_picture(GF_OHEVCDecCtx * ctx)766 static GF_Err ohevcdec_flush_picture(GF_OHEVCDecCtx *ctx)
767 {
768 	GF_FilterPacket *pck, *src_pck;
769 	u8 *data;
770 	u32 a_w, a_h, a_stride, bit_depth, i, count;
771 	u64 cts;
772 	OHFrame_cpy openHevcFrame_FL, openHevcFrame_SL;
773 	int chromat_format;
774 
775 	if (ctx->no_copy && !ctx->pack_hfr) {
776 		oh_frameinfo_update(ctx->codec, &openHevcFrame_FL.frame_par);
777 	} else {
778 		oh_cropped_frameinfo(ctx->codec, &openHevcFrame_FL.frame_par);
779 		if (ctx->nb_layers == 2) oh_cropped_frameinfo_from_layer(ctx->codec, &openHevcFrame_SL.frame_par, 1);
780 	}
781 
782 	a_w = openHevcFrame_FL.frame_par.width;
783 	a_h = openHevcFrame_FL.frame_par.height;
784 	a_stride = openHevcFrame_FL.frame_par.linesize_y;
785 	bit_depth = openHevcFrame_FL.frame_par.bitdepth;
786 	chromat_format = openHevcFrame_FL.frame_par.chromat_format;
787 	cts = (u32) openHevcFrame_FL.frame_par.pts;
788 	if (!openHevcFrame_FL.frame_par.sample_aspect_ratio.den || !openHevcFrame_FL.frame_par.sample_aspect_ratio.num)
789 		openHevcFrame_FL.frame_par.sample_aspect_ratio.den = openHevcFrame_FL.frame_par.sample_aspect_ratio.num = 1;
790 
791 	src_pck = NULL;
792 	count = gf_list_count(ctx->src_packets);
793 	for (i=0;i<count; i++) {
794 		src_pck = gf_list_get(ctx->src_packets, i);
795 		if (gf_filter_pck_get_cts(src_pck) == cts) break;
796 		src_pck = NULL;
797 	}
798 
799 	if (src_pck && gf_filter_pck_get_seek_flag(src_pck)) {
800 		gf_list_del_item(ctx->src_packets, src_pck);
801 		gf_filter_pck_unref(src_pck);
802 		return GF_OK;
803 	}
804 
805 	if (ctx->force_stereo_reset || !ctx->out_size || (ctx->width != a_w) || (ctx->height!=a_h) || (ctx->stride != a_stride)
806 		|| (ctx->luma_bpp!= bit_depth)  || (ctx->chroma_bpp != bit_depth) || (ctx->chroma_format_idc != (chromat_format + 1))
807 		|| (ctx->sar.num*openHevcFrame_FL.frame_par.sample_aspect_ratio.den != ctx->sar.den*openHevcFrame_FL.frame_par.sample_aspect_ratio.num)
808 	 ) {
809 		ctx->width = a_w;
810 		ctx->stride = a_stride;
811 		ctx->height = a_h;
812 		if( chromat_format == OH_YUV420 ) {
813 			ctx->out_size = ctx->stride * ctx->height * 3 / 2;
814 		} else if  ( chromat_format == OH_YUV422 ) {
815 			ctx->out_size = ctx->stride * ctx->height * 2;
816 		} else if ( chromat_format == OH_YUV444 ) {
817 			ctx->out_size = ctx->stride * ctx->height * 3;
818 		}
819 		//force top/bottom output of left and right frame, double height
820 		if (ctx->pack_hfr) {
821 			ctx->out_size *= 4;
822 		} else if ((ctx->cur_layer==2) && (ctx->is_multiview || ctx->force_stereo) ){
823 			ctx->out_size *= 2;
824 		}
825 
826 		ctx->luma_bpp = ctx->chroma_bpp = bit_depth;
827 		ctx->chroma_format_idc = chromat_format + 1;
828 		ctx->sar.num = openHevcFrame_FL.frame_par.sample_aspect_ratio.num;
829 		ctx->sar.den = openHevcFrame_FL.frame_par.sample_aspect_ratio.den;
830 		if (!ctx->sar.num) ctx->sar.num = ctx->sar.den = 1;
831 
832 		ohevc_set_out_props(ctx);
833 	}
834 
835 	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] Sending ouput frame CTS "LLU"\n", openHevcFrame_FL.frame_par.pts ));
836 
837 	if (ctx->no_copy && !ctx->pack_hfr) {
838 		return ohevcdec_send_output_frame(ctx);
839 	}
840 
841 	if (ctx->pack_hfr) {
842 		OHFrame openHFrame;
843 		u8 *pY, *pU, *pV;
844 		u32 idx_w, idx_h;
845 
846 		idx_w = ((ctx->frame_idx==0) || (ctx->frame_idx==2)) ? 0 : ctx->stride;
847 		idx_h = ((ctx->frame_idx==0) || (ctx->frame_idx==1)) ? 0 : ctx->height*2*ctx->stride;
848 
849 		if (!ctx->packed_pck) {
850 			ctx->packed_pck = gf_filter_pck_new_alloc(ctx->opid, ctx->out_size, &ctx->packed_data);
851 			if (src_pck) gf_filter_pck_merge_properties(src_pck, ctx->packed_pck);
852 			else gf_filter_pck_set_cts(ctx->packed_pck, cts);
853 		}
854 		if (src_pck) {
855 			gf_list_del_item(ctx->src_packets, src_pck);
856 			gf_filter_pck_unref(src_pck);
857 		}
858 
859 		pY = (u8*) (ctx->packed_data + idx_h + idx_w );
860 
861 		if (chromat_format == OH_YUV422) {
862 			pU = (u8*)(ctx->packed_data + 4 * ctx->stride  * ctx->height + idx_w / 2 + idx_h / 2);
863 			pV = (u8*)(ctx->packed_data + 4 * (3 * ctx->stride * ctx->height /2)  + idx_w / 2 + idx_h / 2);
864 		} else if (chromat_format == OH_YUV444) {
865 			pU = (u8*)(ctx->packed_data + 4 * ctx->stride * ctx->height + idx_w + idx_h);
866 			pV = (u8*)(ctx->packed_data + 4 * ( 2 * ctx->stride * ctx->height) + idx_w + idx_h);
867 		} else {
868 			pU = (u8*)(ctx->packed_data + 2 * ctx->stride * 2 * ctx->height + idx_w / 2 + idx_h / 4);
869 			pV = (u8*)(ctx->packed_data + 4 * ( 5 *ctx->stride  * ctx->height  / 4) + idx_w / 2 + idx_h / 4);
870 
871 		}
872 
873 		if (oh_output_update(ctx->codec, 1, &openHFrame)) {
874 			u32 i, s_stride, hs_stride, qs_stride, d_stride, dd_stride, hd_stride;
875 
876 			s_stride = openHFrame.frame_par.linesize_y;
877 			qs_stride = s_stride / 4;
878 			hs_stride = s_stride / 2;
879 
880 			d_stride = ctx->stride;
881 			dd_stride = 2*ctx->stride;
882 			hd_stride = ctx->stride/2;
883 
884 			if (chromat_format == OH_YUV422) {
885 				for (i = 0; i < ctx->height; i++) {
886 					memcpy(pY, (u8 *)openHFrame.data_y_p + i*s_stride, d_stride);
887 					pY += dd_stride;
888 
889 					memcpy(pU, (u8 *)openHFrame.data_cb_p + i*hs_stride, hd_stride);
890 					pU += d_stride;
891 
892 					memcpy(pV, (u8 *)openHFrame.data_cr_p + i*hs_stride, hd_stride);
893 					pV += d_stride;
894 				}
895 			} else if (chromat_format == OH_YUV444) {
896 				for (i = 0; i < ctx->height; i++) {
897 					memcpy(pY, (u8 *)openHFrame.data_y_p + i*s_stride, d_stride);
898 					pY += dd_stride;
899 
900 					memcpy(pU, (u8 *)openHFrame.data_cb_p + i*s_stride, d_stride);
901 					pU += dd_stride;
902 
903 					memcpy(pV, (u8 *)openHFrame.data_cr_p + i*s_stride, d_stride);
904 					pV += dd_stride;
905 				}
906 			} else {
907 				for (i = 0; i<ctx->height; i++) {
908 					memcpy(pY, (u8 *)openHFrame.data_y_p + i*s_stride, d_stride);
909 					pY += dd_stride;
910 
911 					if (!(i % 2)) {
912 						memcpy(pU, (u8 *)openHFrame.data_cb_p + i*qs_stride, hd_stride);
913 						pU += d_stride;
914 
915 						memcpy(pV, (u8 *)openHFrame.data_cr_p + i*qs_stride, hd_stride);
916 						pV += d_stride;
917 					}
918 				}
919 			}
920 
921 			ctx->frame_idx++;
922 			if (ctx->frame_idx==4) {
923 				gf_filter_pck_send(ctx->packed_pck);
924 				ctx->packed_pck = NULL;
925 				ctx->frame_idx = 0;
926 			}
927 		}
928 		return GF_OK;
929 	}
930 
931 	pck = gf_filter_pck_new_alloc(ctx->opid, ctx->out_size, &data);
932 
933 	openHevcFrame_FL.data_y = (void*) data;
934 
935 	if (ctx->nb_layers==2 && ctx->is_multiview && !ctx->no_copy){
936 		int out1, out2;
937 		if( chromat_format == OH_YUV420){
938 			openHevcFrame_SL.data_y = (void*) (data +  ctx->stride * ctx->height);
939 			openHevcFrame_FL.data_cb = (void*) (data + 2*ctx->stride * ctx->height);
940 			openHevcFrame_SL.data_cb = (void*) (data +  9*ctx->stride * ctx->height/4);
941 			openHevcFrame_FL.data_cr = (void*) (data + 5*ctx->stride * ctx->height/2);
942 			openHevcFrame_SL.data_cr = (void*) (data + 11*ctx->stride * ctx->height/4);
943 		}
944 
945 		out1 = oh_output_cropped_cpy_from_layer(ctx->codec, &openHevcFrame_FL, 0);
946 		out2 = oh_output_cropped_cpy_from_layer(ctx->codec, &openHevcFrame_SL, 1);
947 
948 		if (out1 && out2) {
949 			gf_filter_pck_set_cts(pck, cts);
950 			gf_filter_pck_send(pck);
951 		} else {
952 			gf_filter_pck_discard(pck);
953 		}
954 	} else {
955 		openHevcFrame_FL.data_cb = (void*) (data + ctx->stride * ctx->height);
956 		if( chromat_format == OH_YUV420) {
957 			openHevcFrame_FL.data_cr = (void*) (data + 5*ctx->stride * ctx->height/4);
958 		} else if (chromat_format == OH_YUV422) {
959 			openHevcFrame_FL.data_cr = (void*) (data + 3*ctx->stride * ctx->height/2);
960 		} else if ( chromat_format == OH_YUV444) {
961 			openHevcFrame_FL.data_cr = (void*) (data + 2*ctx->stride * ctx->height);
962 		}
963 
964 		if (oh_output_cropped_cpy(ctx->codec, &openHevcFrame_FL)) {
965 			if (src_pck) {
966 				u8 car_v = gf_filter_pck_get_carousel_version(src_pck);
967 				gf_filter_pck_set_carousel_version(src_pck, 0);
968 
969 				gf_filter_pck_merge_properties(src_pck, pck);
970 				gf_list_del_item(ctx->src_packets, src_pck);
971 				gf_filter_pck_unref(src_pck);
972 
973 				if (car_v)
974 					ohevc_set_out_props(ctx);
975 			} else {
976 				gf_filter_pck_set_cts(pck, cts);
977 			}
978 			gf_filter_pck_send(pck);
979 		} else
980 			gf_filter_pck_discard(pck);
981 	}
982 	return GF_OK;
983 }
984 
ohevcdec_process(GF_Filter * filter)985 static GF_Err ohevcdec_process(GF_Filter *filter)
986 {
987 	s32 got_pic;
988 	u64 min_dts = GF_FILTER_NO_TS;
989 	u64 min_cts = GF_FILTER_NO_TS;
990 	u32 idx, nb_eos=0;
991 	u32 data_size, nbpck;
992 	char *data;
993 	Bool has_pic = GF_FALSE;
994 	GF_FilterPacket *pck_ref = NULL;
995 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx*) gf_filter_get_udta(filter);
996 
997 	if (ctx->frame_out) return GF_EOS;
998 
999 
1000 	if (ctx->reconfig_pending) {
1001 		//wait for each input pid to be ready - this will force reconfig on pids if needed
1002 		for (idx=0; idx<ctx->nb_streams; idx++) {
1003 			GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->streams[idx].ipid);
1004 			if (!pck) return GF_OK;
1005 		}
1006 		oh_flush(ctx->codec);
1007 		//flush
1008 #ifdef  OPENHEVC_HAS_AVC_BASE
1009 		if (ctx->avc_base_id) {
1010 			got_pic = oh_decode_lhvc(ctx->codec, NULL, NULL, 0, 0, 0, 0);
1011 		} else
1012 #endif
1013 			got_pic = oh_decode(ctx->codec, NULL, 0, 0);
1014 
1015 		if ( got_pic ) {
1016 			return ohevcdec_flush_picture(ctx);
1017 		}
1018 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] Closing decoder for reconfigure\n"));
1019 		//good to go: no more pics in decoder, no frame out
1020 		ctx->reconfig_pending = GF_FALSE;
1021 		oh_close(ctx->codec);
1022 		ctx->codec = NULL;
1023 		ctx->decoder_started = GF_FALSE;
1024 		for (idx=0; idx<ctx->nb_streams; idx++) {
1025 			ohevcdec_configure_pid(filter, ctx->streams[idx].ipid, GF_FALSE);
1026 		}
1027 	}
1028 	if (!ctx->codec) return GF_SERVICE_ERROR;
1029 
1030 	//probe all streams
1031 	for (idx=0; idx<ctx->nb_streams; idx++) {
1032 		u64 dts, cts;
1033 		GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->streams[idx].ipid);
1034 
1035 		if (ctx->reconfig_pending) return GF_OK;
1036 
1037 		if (!pck) {
1038 			if (gf_filter_pid_is_eos(ctx->streams[idx].ipid))
1039 				nb_eos++;
1040 			//make sure we do have a packet on the enhancement
1041 			else {
1042 				GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[OpenHEVC] no input packets on running pid %s - postponing decode\n", gf_filter_pid_get_name(ctx->streams[idx].ipid) ) );
1043 				return GF_OK;
1044 			}
1045 			continue;
1046 		}
1047 		if (ctx->drop_non_refs && !gf_filter_pck_get_sap(pck)) {
1048 			gf_filter_pid_drop_packet(ctx->streams[idx].ipid);
1049 			continue;
1050 		}
1051 
1052 		dts = gf_filter_pck_get_dts(pck);
1053 		cts = gf_filter_pck_get_cts(pck);
1054 
1055 		data = (char *) gf_filter_pck_get_data(pck, &data_size);
1056 		//TODO: this is a clock signaling, for now just trash ..
1057 		if (!data) {
1058 			gf_filter_pid_drop_packet(ctx->streams[idx].ipid);
1059 			idx--;
1060 			continue;
1061 		}
1062 		if (dts==GF_FILTER_NO_TS) dts = cts;
1063 		//get packet with min dts (either a timestamp or a decode order number)
1064 		if (min_dts > dts) {
1065 			min_dts = dts;
1066 			if (cts == GF_FILTER_NO_TS) min_cts = min_dts;
1067 			else min_cts = cts;
1068 			pck_ref = pck;
1069 		}
1070 	}
1071 
1072 	//start decoder
1073 	if (!ctx->decoder_started) {
1074 		oh_start(ctx->codec);
1075 		ctx->decoder_started = GF_TRUE;
1076 	}
1077 
1078 	if (nb_eos == ctx->nb_streams) {
1079 		while (1) {
1080 #ifdef  OPENHEVC_HAS_AVC_BASE
1081 			if (ctx->avc_base_id)
1082 				got_pic = oh_decode_lhvc(ctx->codec, NULL, NULL, 0, 0, 0, 0);
1083 			else
1084 #endif
1085 				got_pic = oh_decode(ctx->codec, NULL, 0, 0);
1086 
1087 			if (got_pic) {
1088 				ohevcdec_flush_picture(ctx);
1089 				//we are in direct output mode, wait for frame to be consummed before flushing next frame
1090 				if (ctx->frame_out) return GF_OK;
1091 			}
1092 			else
1093 				break;
1094 		}
1095 		gf_filter_pid_set_eos(ctx->opid);
1096 		while (gf_list_count(ctx->src_packets)) {
1097 			GF_FilterPacket *pck = gf_list_pop_back(ctx->src_packets);
1098 			gf_filter_pck_unref(pck);
1099 		}
1100 		return GF_EOS;
1101 	}
1102 
1103 	if (min_cts == GF_FILTER_NO_TS)
1104 		return GF_OK;
1105 
1106 	//queue reference to source packet props
1107 	gf_filter_pck_ref_props(&pck_ref);
1108 	gf_list_add(ctx->src_packets, pck_ref);
1109 	gf_filter_pck_set_carousel_version(pck_ref, ctx->signal_reconfig ? 1 : 0);
1110 	ctx->signal_reconfig = GF_FALSE;
1111 
1112 	ctx->dec_frames++;
1113 	got_pic = 0;
1114 	ctx->reaggregation_size = 0;
1115 	nbpck = 0;
1116 
1117 	for (idx=0; idx<ctx->nb_streams; idx++) {
1118 		u64 dts, cts;
1119 
1120 		GF_FilterPacket *pck = gf_filter_pid_get_packet(ctx->streams[idx].ipid);
1121 		if (!pck) continue;
1122 
1123 		dts = gf_filter_pck_get_dts(pck);
1124 		cts = gf_filter_pck_get_cts(pck);
1125 		if (dts==GF_FILTER_NO_TS) dts = cts;
1126 
1127 		if (min_dts != GF_FILTER_NO_TS) {
1128 			if (min_dts != dts) continue;
1129 		} else if (min_cts != cts) {
1130 			continue;
1131 		}
1132 
1133 		data = (char *) gf_filter_pck_get_data(pck, &data_size);
1134 
1135 		if (ctx->streams[idx].inject_hdr) {
1136 			if (ctx->inject_buffer_alloc_size < ctx->streams[idx].inject_hdr_size + data_size) {
1137 				ctx->inject_buffer_alloc_size = ctx->streams[idx].inject_hdr_size + data_size;
1138 				ctx->inject_buffer = gf_realloc(ctx->inject_buffer, ctx->inject_buffer_alloc_size);
1139 			}
1140 			memcpy(ctx->inject_buffer, ctx->streams[idx].inject_hdr, ctx->streams[idx].inject_hdr_size);
1141 			memcpy(ctx->inject_buffer+ctx->streams[idx].inject_hdr_size, data, data_size);
1142 			data = ctx->inject_buffer;
1143 			data_size += ctx->streams[idx].inject_hdr_size;
1144 
1145 			gf_free(ctx->streams[idx].inject_hdr);
1146 			ctx->streams[idx].inject_hdr=NULL;
1147 			ctx->streams[idx].inject_hdr_size=0;
1148 
1149 			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] Config changed, injecting param sets inband at DTS "LLU" CTS "LLU"\n", dts, cts));
1150 		}
1151 
1152 #ifdef  OPENHEVC_HAS_AVC_BASE
1153 		if (ctx->avc_base_id) {
1154 			if (ctx->avc_base_id == ctx->streams[idx].id) {
1155 				got_pic = oh_decode_lhvc(ctx->codec, (u8 *) data, NULL, data_size, 0, cts, 0);
1156 			} else if (ctx->cur_layer>1) {
1157 				got_pic = oh_decode_lhvc(ctx->codec, (u8*)NULL, (u8 *) data, 0, data_size, 0, cts);
1158 			}
1159 		} else
1160 #endif
1161 		{
1162 			if (ctx->nb_streams>1) {
1163 				if (ctx->reaggregation_alloc_size < ctx->reaggregation_size + data_size) {
1164 					ctx->reaggregation_alloc_size = ctx->reaggregation_size + data_size;
1165 					ctx->reaggregation_buffer = gf_realloc(ctx->reaggregation_buffer, sizeof(char)*ctx->reaggregation_alloc_size);
1166 				}
1167 				memcpy(ctx->reaggregation_buffer + ctx->reaggregation_size, data, sizeof(char)*data_size);
1168 				ctx->reaggregation_size += data_size;
1169 			} else {
1170 				got_pic = oh_decode(ctx->codec, (u8 *) data, data_size, cts);
1171 			}
1172 		}
1173 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] PID %s Decode CTS %d - size %d - got pic %d\n", gf_filter_pid_get_name(ctx->streams[idx].ipid), min_cts, data_size, got_pic));
1174 
1175 		if (got_pic>0)
1176 			has_pic = GF_TRUE;
1177 
1178 		gf_filter_pid_drop_packet(ctx->streams[idx].ipid);
1179 		nbpck++;
1180 	}
1181 
1182 	if (ctx->reaggregation_size) {
1183 		got_pic = oh_decode(ctx->codec, (u8 *) ctx->reaggregation_buffer, ctx->reaggregation_size, min_cts);
1184 		ctx->reaggregation_size = 0;
1185 		if (got_pic)
1186 			has_pic = GF_TRUE;
1187 	}
1188 
1189 
1190 	if (!has_pic) return GF_OK;
1191 
1192 	return ohevcdec_flush_picture(ctx);
1193 }
1194 
ohevcdec_initialize(GF_Filter * filter)1195 static GF_Err ohevcdec_initialize(GF_Filter *filter)
1196 {
1197 	GF_SystemRTInfo rti;
1198 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx *) gf_filter_get_udta(filter);
1199 	ctx->filter = filter;
1200 	if (!ctx->nb_threads) {
1201 		if (gf_sys_get_rti(0, &rti, 0) ) {
1202 			ctx->nb_threads = (rti.nb_cores>1) ? rti.nb_cores-1 : 1;
1203 			GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[OpenHEVCDec] Initializing with %d threads\n", ctx->nb_threads));
1204 		}
1205 	}
1206 	ctx->src_packets = gf_list_new();
1207 	return GF_OK;
1208 }
1209 
ohevcdec_finalize(GF_Filter * filter)1210 static void ohevcdec_finalize(GF_Filter *filter)
1211 {
1212 	GF_OHEVCDecCtx *ctx = (GF_OHEVCDecCtx *) gf_filter_get_udta(filter);
1213 	if (ctx->codec) {
1214 		if (!ctx->decoder_started) oh_start(ctx->codec);
1215 		oh_close(ctx->codec);
1216 	}
1217 	if (ctx->reaggregation_buffer) gf_free(ctx->reaggregation_buffer);
1218 	if (ctx->inject_buffer) gf_free(ctx->inject_buffer);
1219 
1220 	while (gf_list_count(ctx->src_packets)) {
1221 		GF_FilterPacket *pck = gf_list_pop_back(ctx->src_packets);
1222 		gf_filter_pck_unref(pck);
1223 	}
1224 	gf_list_del(ctx->src_packets);
1225 }
1226 
1227 static const GF_FilterCapability OHEVCDecCaps[] =
1228 {
1229 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
1230 	CAP_BOOL(GF_CAPS_INPUT_EXCLUDED, GF_PROP_PID_UNFRAMED, GF_TRUE),
1231 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_HEVC),
1232 	CAP_UINT(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_LHVC),
1233 	CAP_BOOL(GF_CAPS_INPUT_EXCLUDED,GF_PROP_PID_TILE_BASE, GF_TRUE),
1234 
1235 #ifdef  OPENHEVC_HAS_AVC_BASE
1236 	CAP_UINT_PRIORITY(GF_CAPS_INPUT,GF_PROP_PID_CODECID, GF_CODECID_AVC, 255),
1237 #endif
1238 
1239 	CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_STREAM_TYPE, GF_STREAM_VISUAL),
1240 	CAP_UINT(GF_CAPS_OUTPUT, GF_PROP_PID_CODECID, GF_CODECID_RAW)
1241 };
1242 
1243 #define OFFS(_n)	#_n, offsetof(GF_OHEVCDecCtx, _n)
1244 
1245 static const GF_FilterArgs OHEVCDecArgs[] =
1246 {
1247 	{ OFFS(threading), "set threading mode\n"
1248 	"- frameslice: parallel decoding of both frames and slices\n"
1249 	"- frame: parallel decoding of frames\n"
1250 	"- slice: parallel decoding of slices", GF_PROP_UINT, "frame", "frameslice|frame|slice", GF_FS_ARG_HINT_ADVANCED},
1251 	{ OFFS(nb_threads), "set number of threads. If 0, uses number of cores minus one", GF_PROP_UINT, "0", NULL, 0},
1252 	{ OFFS(no_copy), "directly dispatch internal decoded frame without copy", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED},
1253 	{ OFFS(pack_hfr), "pack 4 consecutive frames in a single output", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_EXPERT},
1254 	{ OFFS(seek_reset), "reset decoder when seeking", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_ADVANCED},
1255 	{ OFFS(force_stereo), "force stereo output for multiview (top-bottom only)", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_EXPERT},
1256 	{ OFFS(reset_switch), "reset decoder at config change", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_HINT_EXPERT},
1257 	{0}
1258 };
1259 
1260 GF_FilterRegister OHEVCDecRegister = {
1261 	.name = "ohevcdec",
1262 	GF_FS_SET_DESCRIPTION("OpenHEVC decoder")
1263 	GF_FS_SET_HELP("This filter decodes HEVC and LHVC (HEVC scalable extensions) from one or more PIDs through the OpenHEVC library")
1264 	.private_size = sizeof(GF_OHEVCDecCtx),
1265 	SETCAPS(OHEVCDecCaps),
1266 	.initialize = ohevcdec_initialize,
1267 	.finalize = ohevcdec_finalize,
1268 	.args = OHEVCDecArgs,
1269 	.configure_pid = ohevcdec_configure_pid,
1270 	.process = ohevcdec_process,
1271 	.process_event = ohevcdec_process_event,
1272 	.max_extra_pids = (HEVC_MAX_STREAMS-1),
1273 	//by default take over FFMPEG
1274 	.priority = 100
1275 };
1276 
1277 #endif // defined(GPAC_HAS_OPENHEVC) && !defined(GPAC_DISABLE_AV_PARSERS)
1278 
1279 
1280 #ifndef GPAC_OPENHEVC_STATIC
1281 
1282 GPAC_MODULE_EXPORT
RegisterFilter(GF_FilterSession * session)1283 GF_FilterRegister *RegisterFilter(GF_FilterSession *session)
1284 #else
1285 const GF_FilterRegister *ohevcdec_register(GF_FilterSession *session)
1286 #endif
1287 
1288 {
1289 #if defined(GPAC_HAS_OPENHEVC) && !defined(GPAC_DISABLE_AV_PARSERS)
1290 	return &OHEVCDecRegister;
1291 #else
1292 	return NULL;
1293 #endif
1294 }
1295