Ejemplo n.º 1
0
static GF_Err OSVC_ProcessData(GF_MediaDecoder *ifcg,
                               char *inBuffer, u32 inBufferLength,
                               u16 ES_ID, u32 *CTS,
                               char *outBuffer, u32 *outBufferLength,
                               u8 PaddingBits, u32 mmlevel)
{

	s32 got_pic;
	OPENSVCFRAME pic;
	int Layer[4];
	u32 i, nalu_size, sc_size;
	u8 *ptr;
	OSVCDec *ctx = (OSVCDec*) ifcg->privateStack;
	u32 curMaxDqId = ctx->MaxDqId;

	if (!ES_ID || !ctx->codec) {
		*outBufferLength = 0;
		return GF_OK;
	}
	if (*outBufferLength < ctx->out_size) {
		*outBufferLength = ctx->out_size;
		return GF_BUFFER_TOO_SMALL;
	}

	ctx->MaxDqId = GetDqIdMax((unsigned char *) inBuffer, inBufferLength, ctx->nalu_size_length, ctx->DqIdTable, ctx->nalu_size_length ? 1 : 0);
	if (!ctx->init_layer_set) {
		//AVC stream in a h264 file
		if (ctx->MaxDqId == -1)
			ctx->MaxDqId = 0;

		ctx->CurrentDqId = ctx->MaxDqId;
		ctx->init_layer_set = 1;
	}
	if (curMaxDqId != ctx->MaxDqId)
		ctx->CurrentDqId = ctx->MaxDqId;
	/*decode only current layer*/
	SetCommandLayer(Layer, ctx->MaxDqId, ctx->CurrentDqId, &ctx->TemporalCom, ctx->TemporalId);

	got_pic = 0;
	nalu_size = 0;
	ptr = (u8 *) inBuffer;

	if (!ctx->nalu_size_length) {
		u32 size;
		sc_size = 0;
		size = gf_media_nalu_next_start_code((u8 *) inBuffer, inBufferLength, &sc_size);
		if (sc_size) {
			ptr += size+sc_size;
			assert(inBufferLength >= size+sc_size);
			inBufferLength -= size+sc_size;
		} else {
			/*no annex-B start-code found, discard */
			*outBufferLength = 0;
			return GF_OK;
		}
	}

	while (inBufferLength) {
		if (ctx->nalu_size_length) {
			for (i=0; i<ctx->nalu_size_length; i++) {
				nalu_size = (nalu_size<<8) + ptr[i];
			}
			ptr += ctx->nalu_size_length;
		} else {
			u32 sc_size;
			nalu_size = gf_media_nalu_next_start_code(ptr, inBufferLength, &sc_size);
		}
#ifndef GPAC_DISABLE_LOG
		switch (ptr[0] & 0x1F) {
		case GF_AVC_NALU_SEQ_PARAM:
		case GF_AVC_NALU_SVC_SUBSEQ_PARAM:
		{
			u32 sps_id;
			gf_avc_get_sps_info((char *)ptr, nalu_size, &sps_id, NULL, NULL, NULL, NULL);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SVC Decoder] ES%d: SPS id=\"%d\" code=\"%d\" size=\"%d\"\n", ES_ID, sps_id, ptr[0] & 0x1F, nalu_size));
		}
		break;
		case GF_AVC_NALU_PIC_PARAM:
		{
			u32 sps_id, pps_id;
			gf_avc_get_pps_info((char *)ptr, nalu_size, &pps_id, &sps_id);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SVC Decoder] ES%d: PPS id=\"%d\" code=\"%d\" size=\"%d\" sps_id=\"%d\"\n", ES_ID, pps_id, ptr[0] & 0x1F, nalu_size, sps_id));
		}
		break;
		default:
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SVC Decoder] ES%d: NALU code=\"%d\" size=\"%d\"\n", ES_ID, ptr[0] & 0x1F, nalu_size));
		}
#endif
		if (!ctx->state_found) {
			u8 nal_type = (ptr[0] & 0x1F) ;
			switch (nal_type) {
			case GF_AVC_NALU_SEQ_PARAM:
			case GF_AVC_NALU_PIC_PARAM:
				if (ctx->baseES_ID == ES_ID)
					ctx->state_found = 1;
				break;
			}
		}

		if (ctx->state_found) {
			if (!got_pic)
				got_pic = decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer);
			else
				decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer);
		}

		ptr += nalu_size;
		if (ctx->nalu_size_length) {
			if (inBufferLength < nalu_size + ctx->nalu_size_length) break;
			inBufferLength -= nalu_size + ctx->nalu_size_length;
		} else {
			if (!sc_size || (inBufferLength < nalu_size + sc_size)) break;
			inBufferLength -= nalu_size + sc_size;
			ptr += sc_size;
		}
	}

	if (got_pic!=1) {
		*outBufferLength = 0;
		return GF_OK;
	}

	if ((curMaxDqId != ctx->MaxDqId) || (pic.Width != ctx->width) || (pic.Height!=ctx->height)) {
		GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[SVC Decoder] Resizing from %dx%d to %dx%d\n", ctx->width, ctx->height, pic.Width, pic.Height ));
		ctx->width = pic.Width;
		ctx->stride = pic.Width + 32;
		ctx->height = pic.Height;
		ctx->out_size = ctx->stride * ctx->height * 3 / 2;
		/*always force layer resize*/
		*outBufferLength = ctx->out_size;
		return GF_BUFFER_TOO_SMALL;
	}
	*outBufferLength = ctx->out_size;
	memcpy(outBuffer, pic.pY[0], ctx->stride*ctx->height);
	memcpy(outBuffer + ctx->stride * ctx->height, pic.pU[0], ctx->stride*ctx->height/4);
	memcpy(outBuffer + 5*ctx->stride * ctx->height/4, pic.pV[0], ctx->stride*ctx->height/4);

	return GF_OK;
}
Ejemplo n.º 2
0
static GF_Err VTB_RewriteNALs(VTBDec *ctx, char *inBuffer, u32 inBufferLength, char **out_buffer, u32 *out_size)
{
	u32 i, sc_size;
	char *ptr = inBuffer;
	u32 nal_size;
	GF_Err e = GF_OK;
	GF_BitStream *bs = NULL;
	
	*out_buffer = NULL;
	*out_size = 0;
	
	if (!ctx->nalu_size_length) {
		nal_size = gf_media_nalu_next_start_code((u8 *) inBuffer, inBufferLength, &sc_size);
		if (!sc_size) return GF_NON_COMPLIANT_BITSTREAM;
		ptr += nal_size + sc_size;
		assert(inBufferLength >= nal_size + sc_size);
		inBufferLength -= nal_size + sc_size;
	}
	
	while (inBufferLength) {
		Bool add_nal = GF_TRUE;
		u8 nal_type;
		
		if (ctx->nalu_size_length) {
			for (i=0; i<ctx->nalu_size_length; i++) {
				nal_size = (nal_size<<8) + ptr[i];
			}
			ptr += ctx->nalu_size_length;
		} else {
			nal_size = gf_media_nalu_next_start_code(ptr, inBufferLength, &sc_size);
		}
		
		nal_type = ptr[0] & 0x1F;
		switch (nal_type) {
		case GF_AVC_NALU_SEQ_PARAM:
			if (!ctx->vtb_session) {
				ctx->sps = gf_malloc(sizeof(char)*nal_size);
				memcpy(ctx->sps, ptr, sizeof(char)*nal_size);
				ctx->sps_size=nal_size;
				add_nal = GF_FALSE;
			}
			break;
		case GF_AVC_NALU_PIC_PARAM:
			if (!ctx->vtb_session) {
				ctx->pps = gf_malloc(sizeof(char)*nal_size);
				memcpy(ctx->pps, ptr, sizeof(char)*nal_size);
				ctx->pps_size=nal_size;
				add_nal = GF_FALSE;
			}
			break;
		case GF_AVC_NALU_ACCESS_UNIT:
		case GF_AVC_NALU_END_OF_SEQ:
		case GF_AVC_NALU_END_OF_STREAM:
		case GF_AVC_NALU_FILLER_DATA:
			add_nal = GF_FALSE;
			break;
		default:
			break;
		}
		
		//if sps and pps are ready, init decoder
		if (!ctx->vtb_session && ctx->sps && ctx->pps) {
			e = VTBDec_InitDecoder(ctx, GF_TRUE);
			if (e) return e;
		}
		
		if (add_nal && !ctx->vtb_session) add_nal = GF_FALSE;

		if (add_nal) {
			if (!bs) bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			
			gf_bs_write_u32(bs, nal_size);
			gf_bs_write_data(bs, ptr, nal_size);
		}
		
		ptr += nal_size;
		if (ctx->nalu_size_length) {
			if (inBufferLength < nal_size + ctx->nalu_size_length) break;
			inBufferLength -= nal_size + ctx->nalu_size_length;
		} else {
			if (!sc_size || (inBufferLength < nal_size + sc_size)) break;
			inBufferLength -= nal_size + sc_size;
			ptr += sc_size;
		}
	}
	
	if (bs) {
		gf_bs_get_content(bs, out_buffer, out_size);
		gf_bs_del(bs);
	}
	return e;
}
Ejemplo n.º 3
0
static GF_Err MCDec_ParseNALs(MCDec *ctx, char *inBuffer, u32 inBufferLength, char **out_buffer, u32 *out_size)
{
	u32 i, sc_size;
	char *ptr = inBuffer;
	u32 nal_size;
	GF_Err e = GF_OK;
	GF_BitStream *bs = NULL;

	if (out_buffer) {
		*out_buffer = NULL;
		*out_size = 0;
	}
	
	if (!ctx->nalu_size_length) {
		sc_size = 0;
		nal_size = gf_media_nalu_next_start_code((u8 *)inBuffer, inBufferLength, &sc_size);
		if (!sc_size) return GF_NON_COMPLIANT_BITSTREAM;
		ptr += nal_size + sc_size;
		assert(inBufferLength >= nal_size + sc_size);
		inBufferLength -= nal_size + sc_size;
	}
	
	while (inBufferLength) {
		Bool add_nal = GF_TRUE;
		u8 nal_type, nal_hdr;
		GF_BitStream *nal_bs = NULL;
		if (ctx->nalu_size_length) {
			nal_size = 0;
			for (i = 0; i<ctx->nalu_size_length; i++) {
				nal_size = (nal_size << 8) + ((u8)ptr[i]);
			}
			ptr += ctx->nalu_size_length;
		}
		else {
			nal_size = gf_media_nalu_next_start_code(ptr, inBufferLength, &sc_size);
		}
		nal_bs = gf_bs_new(ptr, nal_size, GF_BITSTREAM_READ);
		nal_hdr = gf_bs_read_u8(nal_bs);
		nal_type = nal_hdr & 0x1F;
		switch (nal_type) {
			case GF_AVC_NALU_SEQ_PARAM:
				MCDec_RegisterParameterSet(ctx, ptr, nal_size, GF_TRUE);
				add_nal = GF_FALSE;
				break;
			case GF_AVC_NALU_PIC_PARAM:
				MCDec_RegisterParameterSet(ctx, ptr, nal_size, GF_FALSE);
				add_nal = GF_FALSE;
				break;
			case GF_AVC_NALU_ACCESS_UNIT:
			case GF_AVC_NALU_END_OF_SEQ:
			case GF_AVC_NALU_END_OF_STREAM:
			case GF_AVC_NALU_FILLER_DATA:
				add_nal = GF_FALSE;
				break;
			default:
				break;
		}
		gf_media_avc_parse_nalu(nal_bs, nal_hdr, &ctx->avc);
		gf_bs_del(nal_bs);
		if ((nal_type <= GF_AVC_NALU_IDR_SLICE) && ctx->avc.s_info.sps) {
			if (ctx->avc.sps_active_idx != ctx->active_sps) {
				ctx->reconfig_needed = 1;
				ctx->active_sps = ctx->avc.sps_active_idx;
				ctx->active_pps = ctx->avc.s_info.pps->id;
				return GF_OK;
			}
		}

		//if sps and pps are ready, init decoder
		if (!ctx->codec && gf_list_count(ctx->SPSs) && gf_list_count(ctx->PPSs)) {
			e = MCDec_InitDecoder(ctx);
			if (e) return e;
		}
		if (!out_buffer) add_nal = GF_FALSE;
		else if (add_nal && !ctx->codec) add_nal = GF_FALSE;
		if (add_nal) {
			if (!bs) bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			gf_bs_write_u32(bs, nal_size);
			gf_bs_write_data(bs, ptr, nal_size);
		}

		ptr += nal_size;
		if (ctx->nalu_size_length) {
			if (inBufferLength < nal_size + ctx->nalu_size_length) break;
			inBufferLength -= nal_size + ctx->nalu_size_length;
		}
		else {
			
			if (!sc_size || (inBufferLength < nal_size + sc_size)) break;
			inBufferLength -= nal_size + sc_size;
			ptr += sc_size;
		}
	}
	
	if (bs) {
		gf_bs_get_content(bs, out_buffer, out_size);
		gf_bs_del(bs);
	}
	return e;
}
Ejemplo n.º 4
0
int dc_gpac_video_isom_write(VideoOutputFile *video_output_file)
{
	GF_Err ret;
	AVCodecContext *video_codec_ctx = video_output_file->codec_ctx;

	u32 sc_size = 0;
	u32 nalu_size = 0;

	u32 buf_len = video_output_file->encoded_frame_size;
	u8 *buf_ptr = video_output_file->vbuf;

	GF_BitStream *out_bs = gf_bs_new(NULL, 2 * buf_len, GF_BITSTREAM_WRITE);
	nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size);
	if (nalu_size != 0) {
		gf_bs_write_u32(out_bs, nalu_size);
		gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size);
	}
	if (sc_size) {
		buf_ptr += (nalu_size + sc_size);
		buf_len -= (nalu_size + sc_size);
	}

	while (buf_len) {
		nalu_size = gf_media_nalu_next_start_code(buf_ptr, buf_len, &sc_size);
		if (nalu_size != 0) {
			gf_bs_write_u32(out_bs, nalu_size);
			gf_bs_write_data(out_bs, (const char*) buf_ptr, nalu_size);
		}

		buf_ptr += nalu_size;

		if (!sc_size || (buf_len < nalu_size + sc_size))
			break;
		buf_len -= nalu_size + sc_size;
		buf_ptr += sc_size;
	}

	gf_bs_get_content(out_bs, &video_output_file->sample->data, &video_output_file->sample->dataLength);
	//video_output_file->sample->data = //(char *) (video_output_file->vbuf + nalu_size + sc_size);
	//video_output_file->sample->dataLength = //video_output_file->encoded_frame_size - (sc_size + nalu_size);

	video_output_file->sample->DTS = video_codec_ctx->coded_frame->pkt_dts;
	video_output_file->sample->CTS_Offset = (s32) (video_codec_ctx->coded_frame->pts - video_output_file->sample->DTS);
	video_output_file->sample->IsRAP = video_codec_ctx->coded_frame->key_frame;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("Isom Write: RAP %d , DTS "LLD" CTS offset %d \n", video_output_file->sample->IsRAP, video_output_file->sample->DTS, video_output_file->sample->CTS_Offset));

	ret = gf_isom_fragment_add_sample(video_output_file->isof, video_output_file->trackID, video_output_file->sample, 1, video_output_file->use_source_timing ? (u32) video_output_file->frame_dur : 1, 0, 0, 0);
	if (ret != GF_OK) {
		gf_bs_del(out_bs);
		GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("%s: gf_isom_fragment_add_sample\n", gf_error_to_string(ret)));
		return -1;
	}

	//free data but keep sample structure alive
	gf_free(video_output_file->sample->data);
	video_output_file->sample->data = NULL;
	video_output_file->sample->dataLength = 0;

	gf_bs_del(out_bs);
	return 0;
}