static GF_Err HEVC_ProcessData(GF_MediaDecoder *ifcg, char *inBuffer, u32 inBufferLength, u16 ES_ID, u32 *CTS, char *outBuffer, u32 *outBufferLength, u8 PaddingBits, u32 mmlevel) { GF_Err e; int got_pic; HEVCDec *ctx = (HEVCDec*) ifcg->privateStack; if (!inBuffer) { if ( libOpenHevcDecode(ctx->openHevcHandle, NULL, 0, 0) ) { return HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS); } //quick hack, we have an issue with openHEVC resuming after being flushed ... ctx->had_pic = GF_FALSE; libOpenHevcClose(ctx->openHevcHandle); ctx->openHevcHandle = NULL; ctx->is_init = GF_FALSE; HEVC_ConfigureStream(ctx, ctx->esd); return GF_OK; } if (!ES_ID) { *outBufferLength = 0; return GF_OK; } if (*outBufferLength < ctx->out_size) { *outBufferLength = ctx->out_size; return GF_BUFFER_TOO_SMALL; } *outBufferLength = 0; if (ctx->had_pic) { ctx->had_pic = GF_FALSE; return HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS); } ctx->dec_frames++; got_pic = libOpenHevcDecode(ctx->openHevcHandle, (u8 *) inBuffer, inBufferLength, *CTS); if (ctx->raw_out) fwrite((u8 *) inBuffer, 1, inBufferLength, ctx->raw_out); GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[HEVC Decoder] Decode CTS %d - size %d - got pic %d\n", *CTS, inBufferLength, got_pic)); if (got_pic>0) { e = HEVC_flush_picture(ctx, outBuffer, outBufferLength, CTS); if (e) return e; got_pic = 0; } return GF_OK; }
static GF_Err HEVC_ConfigurationScalableStream(HEVCDec *ctx, GF_ESD *esd) { GF_HEVCConfig *cfg = NULL; char *data; u32 data_len; GF_BitStream *bs; u32 i, j; if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return GF_OK; cfg = gf_odf_hevc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_FALSE); if (!cfg) return GF_NON_COMPLIANT_BITSTREAM; if (ctx->nalu_size_length != cfg->nal_unit_size) return GF_NON_COMPLIANT_BITSTREAM; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); for (i=0; i< gf_list_count(cfg->param_array); i++) { GF_HEVCParamArray *ar = (GF_HEVCParamArray *)gf_list_get(cfg->param_array, i); for (j=0; j< gf_list_count(ar->nalus); j++) { GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(ar->nalus, j); gf_bs_write_int(bs, sl->size, 8*ctx->nalu_size_length); gf_bs_write_data(bs, sl->data, sl->size); } } gf_bs_get_content(bs, &data, &data_len); gf_bs_del(bs); libOpenHevcDecode(ctx->openHevcHandle, (u8 *)data, data_len, 0); if (ctx->raw_out) fwrite((u8 *)data, 1, data_len, ctx->raw_out); gf_free(data); libOpenHevcSetActiveDecoders(ctx->openHevcHandle, 2); libOpenHevcSetViewLayers(ctx->openHevcHandle, 1); return GF_OK; }