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