コード例 #1
0
ファイル: opensvc_dec.c プロジェクト: Bevara/GPAC
static GF_Err OSVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd)
{
	u32 i, count;
	s32 res;
	OPENSVCFRAME Picture;
	int Layer[4];
	OSVCDec *ctx = (OSVCDec*) ifcg->privateStack;

	/*todo: we should check base layer of this stream is indeed our base layer*/
	if (!ctx->ES_ID) {
		ctx->ES_ID = esd->ESID;
		ctx->width = ctx->height = ctx->out_size = 0;
		if (!esd->dependsOnESID) ctx->baseES_ID = esd->ESID;
	}

	if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {
		GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength);
		if (!cfg) return GF_NON_COMPLIANT_BITSTREAM;
		if (!esd->dependsOnESID) {
			ctx->nalu_size_length = cfg->nal_unit_size;
			if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR;
		}

		/*decode all NALUs*/
		count = gf_list_count(cfg->sequenceParameterSets);
		SetCommandLayer(Layer, 255, 0, &res, 0);//bufindex can be reset without pb
		for (i=0; i<count; i++) {
			u32 w=0, h=0, sid;
			s32 par_n=0, par_d=0;
			GF_AVCConfigSlot *slc = gf_list_get(cfg->sequenceParameterSets, i);

#ifndef GPAC_DISABLE_AV_PARSERS
			gf_avc_get_sps_info(slc->data, slc->size, &sid, &w, &h, &par_n, &par_d);
#endif
			/*by default use the base layer*/
			if (!i) {
				if ((ctx->width<w) || (ctx->height<h)) {
					ctx->width = w;
					ctx->height = h;
					if ( ((s32)par_n>0) && ((s32)par_d>0) )
						ctx->pixel_ar = (par_n<<16) || par_d;
				}
			}
			res = decodeNAL(ctx->codec, (unsigned char *) slc->data, slc->size, &Picture, Layer);
			if (res<0) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res));
			}
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SVC Decoder] Attach: SPS id=\"%d\" code=\"%d\" size=\"%d\"\n", slc->id, slc->data[0] & 0x1F, slc->size));
		}

		count = gf_list_count(cfg->pictureParameterSets);
		for (i=0; i<count; i++) {
			u32 sps_id, pps_id;
			GF_AVCConfigSlot *slc = gf_list_get(cfg->pictureParameterSets, i);
			gf_avc_get_pps_info(slc->data, slc->size, &pps_id, &sps_id);
			res = decodeNAL(ctx->codec, (unsigned char *) slc->data, slc->size, &Picture, Layer);
			if (res<0) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res));
			}
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SVC Decoder] Attach: PPS id=\"%d\" code=\"%d\" size=\"%d\" sps_id=\"%d\"\n", pps_id, slc->data[0] & 0x1F, slc->size, sps_id));
		}
		ctx->state_found = 1;
		gf_odf_avc_cfg_del(cfg);
	} else {
		if (ctx->nalu_size_length) {
			return GF_NOT_SUPPORTED;
		}
		ctx->nalu_size_length = 0;
		if (!esd->dependsOnESID) {
			if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR;
		}
		ctx->pixel_ar = (1<<16) || 1;
	}
	ctx->stride = ctx->width + 32;
	ctx->CurrentDqId = ctx->MaxDqId = 0;
	ctx->out_size = ctx->stride * ctx->height * 3 / 2;
	return GF_OK;
}
コード例 #2
0
ファイル: opensvc_dec.c プロジェクト: noelove/GPAC-old
static GF_Err OSVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd)
{
	u32 i, count;
	s32 res;
	OPENSVCFRAME Picture;
	int Layer[4];
	OSVCDec *ctx = (OSVCDec*) ifcg->privateStack;

	/*not supported in this version*/
	if (esd->dependsOnESID) return GF_NOT_SUPPORTED;
	
	ctx->ES_ID = esd->ESID;
	ctx->width = ctx->height = ctx->out_size = 0;
	
	if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) {
		GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength);
		if (!cfg) return GF_NON_COMPLIANT_BITSTREAM;
		ctx->nalu_size_length = cfg->nal_unit_size;
		if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR;

		/*decode all NALUs*/
		count = gf_list_count(cfg->sequenceParameterSets);
        SetCommandLayer(Layer, 255, 0, &i, 0);//bufindex can be reset without pb
		for (i=0; i<count; i++) {
			u32 w, h, par_n, par_d;
			GF_AVCConfigSlot *slc = gf_list_get(cfg->sequenceParameterSets, i);

			gf_avc_get_sps_info(slc->data, slc->size, &slc->id, &w, &h, &par_n, &par_d);
			/*by default use the base layer*/
			if (!i) {
				if ((ctx->width<w) || (ctx->height<h)) {
					ctx->width = w;
					ctx->height = h;
					if ( ((s32)par_n>0) && ((s32)par_d>0) )
						ctx->pixel_ar = (par_n<<16) || par_d;
				}
			}
			res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer);
			if (res<0) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res));
			}
		}

		count = gf_list_count(cfg->pictureParameterSets);
		for (i=0; i<count; i++) {
			GF_AVCConfigSlot *slc = gf_list_get(cfg->pictureParameterSets, i);
			res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer);
			if (res<0) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res));
			}
		}

		gf_odf_avc_cfg_del(cfg);
	} else {
		ctx->nalu_size_length = 0;
		if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR;
	}
	ctx->stride = ctx->width + 32;
	ctx->layer = 0;
	ctx->CurrDqId = ctx->layer;
	ctx->out_size = ctx->stride * ctx->height * 3 / 2;
	return GF_OK;
}
コード例 #3
0
ファイル: opensvc_dec.c プロジェクト: Bevara/GPAC
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;
}
コード例 #4
0
ファイル: opensvc_dec.c プロジェクト: noelove/GPAC-old
static GF_Err OSVC_ProcessData(GF_MediaDecoder *ifcg, 
		char *inBuffer, u32 inBufferLength,
		u16 ES_ID,
		char *outBuffer, u32 *outBufferLength,
		u8 PaddingBits, u32 mmlevel)
{

	s32 got_pic;
	OPENSVCFRAME pic;
    int Layer[4];
	OSVCDec *ctx = (OSVCDec*) ifcg->privateStack;

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

	got_pic = 0;
	if (ctx->nalu_size_length) {
		u32 i, nalu_size = 0;
		u8 *ptr = inBuffer;

		ctx->MaxDqId = GetDqIdMax(inBuffer, inBufferLength, ctx->nalu_size_length, ctx->DqIdTable, 1);
		if(!ctx->InitParseAU){
			if (ctx->MaxDqId == -1) {
				//AVC stream in a h264 file 
				ctx->MaxDqId = 0;
			} else {
				//Firts time only, we parse the first AU to know the file configuration
				//does not need to ba called again ever after, unless SPS or PPS changed
				ParseAuPlayers(ctx->codec, inBuffer, inBufferLength, ctx->nalu_size_length, 1);
			}
			ctx->InitParseAU = 1;
		}
        SetCommandLayer(Layer, ctx->MaxDqId, ctx->CurrDqId, &ctx->TemporalCom, ctx->TemporalId);

		while (inBufferLength) {
			for (i=0; i<ctx->nalu_size_length; i++) {
				nalu_size = (nalu_size<<8) + ptr[i];
			}
			ptr += ctx->nalu_size_length;

			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 (inBufferLength < nalu_size + ctx->nalu_size_length) break;

			inBufferLength -= nalu_size + ctx->nalu_size_length;
		}
	} else {
	}
	if (got_pic!=1) return GF_OK;

	if ((pic.Width != ctx->width) || (pic.Height!=ctx->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;
}