<commit_before>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: <NAME> 
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / ISO Media File Format sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *   
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */

#include <gpac/internal/isomedia_dev.h>
#include <gpac/constants.h>

#ifndef GPAC_DISABLE_AV_PARSERS
#include <gpac/internal/media_dev.h>
#endif

#ifndef GPAC_DISABLE_ISOM


Bool gf_isom_is_nalu_based_entry(GF_MediaBox *mdia, GF_SampleEntryBox *_entry)
{
	GF_MPEGVisualSampleEntryBox *entry;
	if (mdia->handler->handlerType != GF_ISOM_MEDIA_VISUAL) return 0;
	if (_entry->type==GF_ISOM_BOX_TYPE_GNRV) return 0;
	entry = (GF_MPEGVisualSampleEntryBox*)_entry;
	if (!entry) return 0;
	if (entry->avc_config || entry->svc_config || entry->hevc_config || entry->shvc_config) return 1;
	return 0;
}


static void rewrite_nalus_list(GF_List *nalus, GF_BitStream *bs, Bool rewrite_start_codes, u32 nal_unit_size_field)
{
	u32 i, count = gf_list_count(nalus);
	for (i=0; i<count; i++) {
		GF_AVCConfigSlot *sl = gf_list_get(nalus, i);
		if (rewrite_start_codes) gf_bs_write_u32(bs, 1);
		else gf_bs_write_int(bs, sl->size, 8*nal_unit_size_field);
		gf_bs_write_data(bs, sl->data, sl->size);
	}				
}

/* FIXME : unused function
static void merge_nalus_list(GF_List  *src, GF_List *dst)
{
	u32 i, count = gf_list_count(src);
	for (i=0; i<count; i++) {
		void *p = gf_list_get(src, i);
		if (p) gf_list_add(dst, p);
	}
}


static void merge_nalus(GF_MPEGVisualSampleEntryBox *entry, GF_List *sps, GF_List *pps)
{
	if (entry->avc_config) {
		merge_nalus_list(entry->avc_config->config->sequenceParameterSets, sps);
		merge_nalus_list(entry->avc_config->config->sequenceParameterSetExtensions, sps);
		merge_nalus_list(entry->avc_config->config->pictureParameterSets, pps);
	}
	if (entry->svc_config) {
		merge_nalus_list(entry->svc_config->config->sequenceParameterSets, sps);
		merge_nalus_list(entry->svc_config->config->pictureParameterSets, pps);
	}
}*/

static GF_Err process_extractor(GF_ISOFile *file, u32 sampleNumber, u32 nal_size, u16 nal_hdr, u32 nal_unit_size_field, Bool is_hevc, Bool rewrite_ps, Bool rewrite_start_codes, GF_BitStream *src_bs, GF_BitStream *dst_bs, u32 extractor_mode)
{
	GF_Err e;
	u32 di, ref_track_ID, ref_track_num, data_offset, data_length, cur_extract_mode, ref_extract_mode, ref_nalu_size, nb_bytes_nalh;
	GF_ISOSample *ref_samp;
	GF_BitStream *ref_bs;
	GF_TrackBox *ref_trak;
	s8 sample_offset;
	char*buffer = NULL;
	u32 max_size = 0;

	nb_bytes_nalh = is_hevc ? 2 : 1;

	switch (extractor_mode) {
	case 0:
		if (!is_hevc) gf_bs_read_int(src_bs, 24); //1 byte for HEVC , 3 bytes for AVC of NALUHeader in extractor
		ref_track_ID = gf_bs_read_u8(src_bs);
		sample_offset = (s8) gf_bs_read_int(src_bs, 8);
		data_offset = gf_bs_read_int(src_bs, nal_unit_size_field*8);
		data_length = gf_bs_read_int(src_bs, nal_unit_size_field*8);

		ref_track_num = gf_isom_get_track_by_id(file, ref_track_ID);
		if (!ref_track_num) return GF_ISOM_INVALID_FILE;

		cur_extract_mode = gf_isom_get_nalu_extract_mode(file, ref_track_num);
		ref_extract_mode = GF_ISOM_NALU_EXTRACT_INSPECT;
		if (rewrite_ps)
			ref_extract_mode |= GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG;
		gf_isom_set_nalu_extract_mode(file, ref_track_num, ref_extract_mode);
		ref_trak = gf_isom_get_track_from_file(file, ref_track_num);
		if (!ref_trak) return GF_ISOM_INVALID_FILE;

		ref_samp = gf_isom_sample_new();
		if (!ref_samp) return GF_IO_ERR;

		//fixeme - we assume that the sampleNumber in the refered track is the same as this sample number
		//are there cases were this wouldn't be the case ?
		if (sample_offset < -sample_offset) 
			sample_offset = 0;
		e = Media_GetSample(ref_trak->Media, sampleNumber + sample_offset, &ref_samp, &di, 0, NULL);
		if (e) return e;

		if (rewrite_start_codes) {
			gf_bs_write_int(dst_bs, 1, 32);
			if (is_hevc) {
				gf_bs_write_int(dst_bs, 0, 1);
				gf_bs_write_int(dst_bs, GF_HEVC_NALU_ACCESS_UNIT, 6);
				gf_bs_write_int(dst_bs, 0, 9);
				/*pic-type - by default we signal all slice types possible*/
				gf_bs_write_int(dst_bs, 2, 3);
				gf_bs_write_int(dst_bs, 0, 5);
			} else {
				gf_bs_write_int(dst_bs, (ref_samp->data[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT, 8);
				gf_bs_write_int(dst_bs, 0xF0 , 8); /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/;
			}
		}
		ref_bs = gf_bs_new(ref_samp->data + data_offset, ref_samp->dataLength - data_offset, GF_BITSTREAM_READ);
		while (gf_bs_available(ref_bs)) {
			ref_nalu_size = gf_bs_read_int(ref_bs, 8*nal_unit_size_field);
			assert(ref_nalu_size <= data_length);
			
			if (ref_nalu_size > max_size) {
				buffer = (char*) gf_realloc(buffer, sizeof(char) * ref_nalu_size );
				max_size = ref_nalu_size;
			}			
			gf_bs_read_data(ref_bs, buffer, ref_nalu_size);

			if (rewrite_start_codes) 
				gf_bs_write_u32(dst_bs, 1);
			else
				gf_bs_write_int(dst_bs, ref_nalu_size, 8*nal_unit_size_field);

			gf_bs_write_data(dst_bs, buffer, ref_nalu_size);
			data_length -= ref_nalu_size + nal_unit_size_field;
		}

		gf_isom_sample_del(&ref_samp);
		ref_samp = NULL;
		gf_bs_del(ref_bs);
		ref_bs = NULL;
		if (buffer) gf_free(buffer);
		gf_isom_set_nalu_extract_mode(file, ref_track_num, cur_extract_mode);
		break;
	case 1:
		//skip to end of this NALU
		gf_bs_skip_bytes(src_bs, nal_size - nb_bytes_nalh);
		break;
	case 2:
		buffer = (char*) gf_malloc( sizeof(char) * (nal_size - nb_bytes_nalh));<commit_msg>Fixed bug with extractors<commit_after>/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: <NAME> 
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / ISO Media File Format sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *   
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 */

#include <gpac/internal/isomedia_dev.h>
#include <gpac/constants.h>

#ifndef GPAC_DISABLE_AV_PARSERS
#include <gpac/internal/media_dev.h>
#endif

#ifndef GPAC_DISABLE_ISOM


Bool gf_isom_is_nalu_based_entry(GF_MediaBox *mdia, GF_SampleEntryBox *_entry)
{
	GF_MPEGVisualSampleEntryBox *entry;
	if (mdia->handler->handlerType != GF_ISOM_MEDIA_VISUAL) return 0;
	if (_entry->type==GF_ISOM_BOX_TYPE_GNRV) return 0;
	entry = (GF_MPEGVisualSampleEntryBox*)_entry;
	if (!entry) return 0;
	if (entry->avc_config || entry->svc_config || entry->hevc_config || entry->shvc_config) return 1;
	return 0;
}


static void rewrite_nalus_list(GF_List *nalus, GF_BitStream *bs, Bool rewrite_start_codes, u32 nal_unit_size_field)
{
	u32 i, count = gf_list_count(nalus);
	for (i=0; i<count; i++) {
		GF_AVCConfigSlot *sl = gf_list_get(nalus, i);
		if (rewrite_start_codes) gf_bs_write_u32(bs, 1);
		else gf_bs_write_int(bs, sl->size, 8*nal_unit_size_field);
		gf_bs_write_data(bs, sl->data, sl->size);
	}				
}

/* FIXME : unused function
static void merge_nalus_list(GF_List  *src, GF_List *dst)
{
	u32 i, count = gf_list_count(src);
	for (i=0; i<count; i++) {
		void *p = gf_list_get(src, i);
		if (p) gf_list_add(dst, p);
	}
}


static void merge_nalus(GF_MPEGVisualSampleEntryBox *entry, GF_List *sps, GF_List *pps)
{
	if (entry->avc_config) {
		merge_nalus_list(entry->avc_config->config->sequenceParameterSets, sps);
		merge_nalus_list(entry->avc_config->config->sequenceParameterSetExtensions, sps);
		merge_nalus_list(entry->avc_config->config->pictureParameterSets, pps);
	}
	if (entry->svc_config) {
		merge_nalus_list(entry->svc_config->config->sequenceParameterSets, sps);
		merge_nalus_list(entry->svc_config->config->pictureParameterSets, pps);
	}
}*/

static GF_Err process_extractor(GF_ISOFile *file, u32 sampleNumber, u32 nal_size, u16 nal_hdr, u32 nal_unit_size_field, Bool is_hevc, Bool rewrite_ps, Bool rewrite_start_codes, GF_BitStream *src_bs, GF_BitStream *dst_bs, u32 extractor_mode)
{
	GF_Err e;
	u32 di, ref_track_ID, ref_track_num, data_offset, data_length, cur_extract_mode, ref_extract_mode, ref_nalu_size, nb_bytes_nalh;
	GF_ISOSample *ref_samp;
	GF_BitStream *ref_bs;
	GF_TrackBox *ref_trak;
	s8 sample_offset;
	char*buffer = NULL;
	u32 max_size = 0;

	nb_bytes_nalh = is_hevc ? 2 : 1;

	switch (extractor_mode) {
	case 0:
		if (!is_hevc) gf_bs_read_int(src_bs, 24); //1 byte for HEVC , 3 bytes for AVC of NALUHeader in extractor
		ref_track_ID = gf_bs_read_u8(src_bs);
		sample_offset = (s8) gf_bs_read_int(src_bs, 8);
		data_offset = gf_bs_read_int(src_bs, nal_unit_size_field*8);
		data_length = gf_bs_read_int(src_bs, nal_unit_size_field*8);

		ref_track_num = gf_isom_get_track_by_id(file, ref_track_ID);
		if (!ref_track_num) return GF_ISOM_INVALID_FILE;

		cur_extract_mode = gf_isom_get_nalu_extract_mode(file, ref_track_num);
		ref_extract_mode = GF_ISOM_NALU_EXTRACT_INSPECT;
		if (rewrite_ps)
			ref_extract_mode |= GF_ISOM_NALU_EXTRACT_INBAND_PS_FLAG;
		gf_isom_set_nalu_extract_mode(file, ref_track_num, ref_extract_mode);
		ref_trak = gf_isom_get_track_from_file(file, ref_track_num);
		if (!ref_trak) return GF_ISOM_INVALID_FILE;

		ref_samp = gf_isom_sample_new();
		if (!ref_samp) return GF_IO_ERR;

		//fixeme - we assume that the sampleNumber in the refered track is the same as this sample number
		//are there cases were this wouldn't be the case ?
		if (sample_offset < -sample_offset) 
			sample_offset = 0;
		e = Media_GetSample(ref_trak->Media, sampleNumber + sample_offset, &ref_samp, &di, 0, NULL);
		if (e) return e;

		if (rewrite_start_codes) {
			gf_bs_write_int(dst_bs, 1, 32);
			if (is_hevc) {
				gf_bs_write_int(dst_bs, 0, 1);
				gf_bs_write_int(dst_bs, GF_HEVC_NALU_ACCESS_UNIT, 6);
				gf_bs_write_int(dst_bs, 0, 9);
				/*pic-type - by default we signal all slice types possible*/
				gf_bs_write_int(dst_bs, 2, 3);
				gf_bs_write_int(dst_bs, 0, 5);
			} else {
				gf_bs_write_int(dst_bs, (ref_samp->data[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT, 8);
				gf_bs_write_int(dst_bs, 0xF0 , 8); /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/;
			}
		}
		ref_bs = gf_bs_new(ref_samp->data + data_offset, ref_samp->dataLength - data_offset, GF_BITSTREAM_READ);
		if (!data_length)
			data_length = ref_samp->dataLength - data_offset;

		assert(ref_samp->dataLength - data_offset >= data_length);

		while (data_length && gf_bs_available(ref_bs)) {
			ref_nalu_size = gf_bs_read_int(ref_bs, 8*nal_unit_size_field);
			assert(ref_nalu_size <= data_length);
			
			if (ref_nalu_size > max_size) {
				buffer = (char*) gf_realloc(buffer, sizeof(char) * ref_nalu_size );
				max_size = ref_nalu_size;
			}			
			gf_bs_read_data(ref_bs, buffer, ref_nalu_size);

			if (rewrite_start_codes) 
				gf_bs_write_u32(dst_bs, 1);
			else
				gf_bs_write_int(dst_bs, ref_nalu_size, 8*nal_unit_size_field);

			gf_bs_write_data(dst_bs, buffer, ref_nalu_size);
			data_length -= ref_nalu_size + nal_unit_size_field;
		}

		gf_isom_sample_del(&ref_samp);
		ref_samp = NULL;
		gf_bs_del(ref_bs);
		ref_bs = NULL;
		if (buffer) gf_free(buffer);
		gf_isom_set_nalu_extract_mode(file, ref_track_num, cur_extract_mode);
		break;
	case 1:
		//skip to end of this NALU
		gf_bs_skip_bytes(src_bs, nal_size - nb_bytes_nalh);
		break;
	case 2:
		buffer = (char*) gf_malloc( sizeof(char) * (nal_size - nb_bytes_nalh));
{'fraction_non_alphanumeric': 0.10377131876050925, 'fraction_numerical': 0.016014092401313157, 'mean_word_length': 4.973218555714969, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 78, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6575773', 'n_tokens_mistral': 5477, 'n_tokens_neox': 4977, 'n_words': 1095}