Exemplo n.º 1
0
void ElementaryStream::finish(DemuxerStream& stream) // not multithread-safe (or safe?)
{
	u32 addr;
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		//if (fidMajor != 0xbd) LOG_NOTICE(HLE, ">>> es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size);

		addr = put;

		auto info = vm::ptr<CellDmuxAuInfo>::make(put);
		//if (fidMajor != 0xbd) LOG_WARNING(HLE, "es::finish(): (%s) size = 0x%x, info_addr=0x%x, pts = 0x%x",
		//wxString(fidMajor == 0xbd ? "ATRAC3P Audio" : "Video AVC").wx_str(),
		//(u32)info->auSize, put, (u32)info->ptsLower);

		u32 new_addr = a128(put + 128 + size);
		put = ((new_addr + GetMaxAU()) > (memAddr + memSize))
			? memAddr : new_addr;

		size = 0;

		put_count++;
		//if (fidMajor != 0xbd) LOG_NOTICE(HLE, "<<< es::finish(): peek=0x%x, first=0x%x, put=0x%x, size=0x%x", peek, first, put, size);
	}
	if (!entries.Push(addr))
	{
		cellDmux->Error("es::finish() aborted (no space)");
	}
}
Exemplo n.º 2
0
int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::ptr<u8> outBuff)
{
	cellVdec->Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, outBuff_addr=0x%x)", handle, format.addr(), outBuff.addr());

	std::shared_ptr<VideoDecoder> vdec;
	if (!Emu.GetIdManager().GetIDData(handle, vdec))
	{
		return CELL_VDEC_ERROR_ARG;
	}

	VdecFrame vf;
	if (!vdec->frames.try_pop(vf))
	{
		//std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
		return CELL_VDEC_ERROR_EMPTY;
	}

	if (!vf.data)
	{
		// hack
		return CELL_OK;
	}

	if (outBuff)
	{
		u32 buf_size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1));

		if (format->formatType != CELL_VDEC_PICFMT_YUV420_PLANAR)
		{
			cellVdec->Todo("cellVdecGetPicture: unknown formatType(%d)", (u32)format->formatType);
			return CELL_OK;
		}

		if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709)
		{
			cellVdec->Todo("cellVdecGetPicture: unknown colorMatrixType(%d)", (u32)format->colorMatrixType);
			return CELL_OK;
		}

		AVFrame& frame = *vf.data;

		// TODO: zero padding bytes

		int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1);
		if (err < 0)
		{
			cellVdec->Error("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err);
			Emu.Pause();
		}
	}

	av_frame_unref(vf.data);
	av_frame_free(&vf.data);
	return CELL_OK;
}
Exemplo n.º 3
0
int cellVdecGetPicture(u32 handle, const mem_ptr_t<CellVdecPicFormat> format, u32 out_addr)
{
	cellVdec->Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, out_addr=0x%x)", handle, format.GetAddr(), out_addr);

	VideoDecoder* vdec;
	if (!Emu.GetIdManager().GetIDData(handle, vdec))
	{
		return CELL_VDEC_ERROR_ARG;
	}

	if (vdec->frames.IsEmpty())
	{
		return CELL_VDEC_ERROR_EMPTY;
	}

	if (out_addr)
	{
		u32 buf_size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1));

		if (format->formatType != CELL_VDEC_PICFMT_YUV420_PLANAR)
		{
			cellVdec->Todo("cellVdecGetPicture: unknown formatType(%d)", (u32)format->formatType);
			return CELL_OK;
		}

		if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709)
		{
			cellVdec->Todo("cellVdecGetPicture: unknown colorMatrixType(%d)", (u32)format->colorMatrixType);
			return CELL_OK;
		}

		VdecFrame vf;

		vdec->frames.Pop(vf);

		AVFrame& frame = *vf.data;

		// TODO: zero padding bytes

		int err = av_image_copy_to_buffer(Memory.GetMemFromAddr(out_addr), buf_size, frame.data, frame.linesize, vdec->ctx->pix_fmt, frame.width, frame.height, 1);
		if (err < 0)
		{
			cellVdec->Error("cellVdecGetPicture: av_image_copy_to_buffer failed(%d)", err);
			Emu.Pause();
		}

		av_frame_unref(vf.data);
		av_frame_free(&vf.data);
	}

	return CELL_OK;
}
Exemplo n.º 4
0
int cellVdecGetPicItem(u32 handle, vm::ptr<u32> picItem_ptr)
{
	cellVdec->Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.addr());

	std::shared_ptr<VideoDecoder> vdec;
	if (!Emu.GetIdManager().GetIDData(handle, vdec))
	{
		return CELL_VDEC_ERROR_ARG;
	}

	VdecFrame vf;
	if (!vdec->frames.try_peek(vf))
	{
		//std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
		return CELL_VDEC_ERROR_EMPTY;
	}

	AVFrame& frame = *vf.data;

	auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias);

	vdec->memBias += 512;
	if (vdec->memBias + 512 > vdec->memSize)
	{
		vdec->memBias = 0;
	}

	info->codecType = vdec->type;
	info->startAddr = 0x00000123; // invalid value (no address for picture)
	info->size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1));
	info->auNum = 1;
	info->auPts[0].lower = (u32)vf.pts;
	info->auPts[0].upper = vf.pts >> 32;
	info->auPts[1].lower = (u32)CODEC_TS_INVALID;
	info->auPts[1].upper = (u32)CODEC_TS_INVALID;
	info->auDts[0].lower = (u32)vf.dts;
	info->auDts[0].upper = vf.dts >> 32;
	info->auDts[1].lower = (u32)CODEC_TS_INVALID;
	info->auDts[1].upper = (u32)CODEC_TS_INVALID;
	info->auUserData[0] = vf.userdata;
	info->auUserData[1] = 0;
	info->status = CELL_OK;
	info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL;
	info->picInfo_addr = info.addr() + sizeof(CellVdecPicItem);

	if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC)
	{
		auto avc = vm::ptr<CellVdecAvcInfo>::make(info.addr() + sizeof(CellVdecPicItem));

		avc->horizontalSize = frame.width;
		avc->verticalSize = frame.height;
		switch (frame.pict_type)
		{
		case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break;
		case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break;
		case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break;
		default: cellVdec->Error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame.pict_type);
		}
		avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ???
		avc->idrPictureFlag = false; // ???
		avc->aspect_ratio_idc = CELL_VDEC_AVC_ARI_SAR_UNSPECIFIED; // ???
		avc->sar_height = 0;
		avc->sar_width = 0;
		avc->pic_struct = CELL_VDEC_AVC_PSTR_FRAME; // ???
		avc->picOrderCount[0] = 0; // ???
		avc->picOrderCount[1] = 0;
		avc->vui_parameters_present_flag = true; // ???
		avc->frame_mbs_only_flag = true; // ??? progressive
		avc->video_signal_type_present_flag = true; // ???
		avc->video_format = CELL_VDEC_AVC_VF_COMPONENT; // ???
		avc->video_full_range_flag = false; // ???
		avc->colour_description_present_flag = true;
		avc->colour_primaries = CELL_VDEC_AVC_CP_ITU_R_BT_709_5; // ???
		avc->transfer_characteristics = CELL_VDEC_AVC_TC_ITU_R_BT_709_5;
		avc->matrix_coefficients = CELL_VDEC_AVC_MXC_ITU_R_BT_709_5; // important
		avc->timing_info_present_flag = true;
		
		switch (vf.frc)
		{
		case CELL_VDEC_FRC_24000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_24000DIV1001; break;
		case CELL_VDEC_FRC_24: avc->frameRateCode = CELL_VDEC_AVC_FRC_24; break;
		case CELL_VDEC_FRC_25: avc->frameRateCode = CELL_VDEC_AVC_FRC_25; break;
		case CELL_VDEC_FRC_30000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_30000DIV1001; break;
		case CELL_VDEC_FRC_30: avc->frameRateCode = CELL_VDEC_AVC_FRC_30; break;
		case CELL_VDEC_FRC_50: avc->frameRateCode = CELL_VDEC_AVC_FRC_50; break;
		case CELL_VDEC_FRC_60000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_60000DIV1001; break;
		case CELL_VDEC_FRC_60: avc->frameRateCode = CELL_VDEC_AVC_FRC_60; break;
		default: cellVdec->Error("cellVdecGetPicItem(AVC): unknown frc value (0x%x)", vf.frc);
		}

		avc->fixed_frame_rate_flag = true;
		avc->low_delay_hrd_flag = true; // ???
		avc->entropy_coding_mode_flag = true; // ???
		avc->nalUnitPresentFlags = 0; // ???
		avc->ccDataLength[0] = 0;
		avc->ccDataLength[1] = 0;
		avc->reserved[0] = 0;
		avc->reserved[1] = 0;
	}
	else if (vdec->type == CELL_VDEC_CODEC_TYPE_DIVX)
	{
		auto dvx = vm::ptr<CellVdecDivxInfo>::make(info.addr() + sizeof(CellVdecPicItem));

		switch (frame.pict_type)
		{
		case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break;
		case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break;
		case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break;
		default: cellVdec->Error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame.pict_type);
		}
		dvx->horizontalSize = frame.width;
		dvx->verticalSize = frame.height;
		dvx->pixelAspectRatio = CELL_VDEC_DIVX_ARI_PAR_1_1; // ???
		dvx->parHeight = 0;
		dvx->parWidth = 0;
		dvx->colourDescription = false; // ???
		dvx->colourPrimaries = CELL_VDEC_DIVX_CP_ITU_R_BT_709; // ???
		dvx->transferCharacteristics = CELL_VDEC_DIVX_TC_ITU_R_BT_709; // ???
		dvx->matrixCoefficients = CELL_VDEC_DIVX_MXC_ITU_R_BT_709; // ???
		dvx->pictureStruct = CELL_VDEC_DIVX_PSTR_FRAME; // ???
		switch (vf.frc)
		{
		case CELL_VDEC_FRC_24000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_24000DIV1001; break;
		case CELL_VDEC_FRC_24: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_24; break;
		case CELL_VDEC_FRC_25: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_25; break;
		case CELL_VDEC_FRC_30000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_30000DIV1001; break;
		case CELL_VDEC_FRC_30: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_30; break;
		case CELL_VDEC_FRC_50: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_50; break;
		case CELL_VDEC_FRC_60000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60000DIV1001; break;
		case CELL_VDEC_FRC_60: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60; break;
		default: cellVdec->Error("cellVdecGetPicItem(DivX): unknown frc value (0x%x)", vf.frc);
		}
	}
	else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2)
	{
		auto mp2 = vm::ptr<CellVdecMpeg2Info>::make(info.addr() + sizeof(CellVdecPicItem));

		cellVdec->Todo("cellVdecGetPicItem(MPEG2)");
		Emu.Pause();
	}

	*picItem_ptr = info.addr();
	return CELL_OK;
}
Exemplo n.º 5
0
int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr)
{
    cellVdec->Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.GetAddr());

    VideoDecoder* vdec;
    if (!Emu.GetIdManager().GetIDData(handle, vdec))
    {
        return CELL_VDEC_ERROR_ARG;
    }

    if (!picItem_ptr.IsGood())
    {
        return CELL_VDEC_ERROR_FATAL;
    }

    VdecFrame& vf = vdec->frames.Peek();

    if (vdec->frames.IsEmpty())
    {
        Sleep(1);
        return CELL_VDEC_ERROR_EMPTY;
    }

    AVFrame& frame = *vf.data;

    mem_ptr_t<CellVdecPicItem> info(vdec->memAddr + vdec->memBias);

    vdec->memBias += 512;
    if (vdec->memBias + 512 > vdec->memSize)
    {
        vdec->memBias = 0;
    }

    info->codecType = vdec->type;
    info->startAddr = 0x00000123; // invalid value (no address for picture)
    info->size = a128(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1));
    info->auNum = 1;
    info->auPts[0].lower = vf.pts;
    info->auPts[0].upper = vf.pts >> 32;
    info->auPts[1].lower = 0xffffffff;
    info->auPts[1].upper = 0xffffffff;
    info->auDts[0].lower = vf.dts;
    info->auDts[0].upper = vf.dts >> 32;
    info->auDts[1].lower = 0xffffffff;
    info->auDts[1].upper = 0xffffffff;
    info->auUserData[0] = vf.userdata;
    info->auUserData[1] = 0;
    info->status = CELL_OK;
    info->attr = CELL_VDEC_PICITEM_ATTR_NORMAL;
    info->picInfo_addr = info.GetAddr() + sizeof(CellVdecPicItem);

    mem_ptr_t<CellVdecAvcInfo> avc(info.GetAddr() + sizeof(CellVdecPicItem));

    avc->horizontalSize = frame.width;
    avc->verticalSize = frame.height;
    switch (frame.pict_type)
    {
    case AV_PICTURE_TYPE_I:
        avc->pictureType[0] = CELL_VDEC_AVC_PCT_I;
        break;
    case AV_PICTURE_TYPE_P:
        avc->pictureType[0] = CELL_VDEC_AVC_PCT_P;
        break;
    case AV_PICTURE_TYPE_B:
        avc->pictureType[0] = CELL_VDEC_AVC_PCT_B;
        break;
    default:
        avc->pictureType[0] = CELL_VDEC_AVC_PCT_UNKNOWN;
        break; // ???
    }
    avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ???
    avc->idrPictureFlag = false; // ???
    avc->aspect_ratio_idc = CELL_VDEC_AVC_ARI_SAR_UNSPECIFIED; // ???
    avc->sar_height = 0;
    avc->sar_width = 0;
    avc->pic_struct = CELL_VDEC_AVC_PSTR_FRAME; // ???
    avc->picOrderCount[0] = 0; // ???
    avc->picOrderCount[1] = 0;
    avc->vui_parameters_present_flag = true; // ???
    avc->frame_mbs_only_flag = true; // ??? progressive
    avc->video_signal_type_present_flag = true; // ???
    avc->video_format = CELL_VDEC_AVC_VF_COMPONENT; // ???
    avc->video_full_range_flag = false; // ???
    avc->colour_description_present_flag = true;
    avc->colour_primaries = CELL_VDEC_AVC_CP_ITU_R_BT_709_5; // ???
    avc->transfer_characteristics = CELL_VDEC_AVC_TC_ITU_R_BT_709_5;
    avc->matrix_coefficients = CELL_VDEC_AVC_MXC_ITU_R_BT_709_5; // important
    avc->timing_info_present_flag = true;
    if (vdec->ctx->time_base.num == 1001)
    {
        if (vdec->ctx->time_base.den == 48000 && vdec->ctx->ticks_per_frame == 2)
        {
            avc->frameRateCode = CELL_VDEC_AVC_FRC_24000DIV1001;
        }
        else if (vdec->ctx->time_base.den == 60000 && vdec->ctx->ticks_per_frame == 2)
        {
            avc->frameRateCode = CELL_VDEC_AVC_FRC_30000DIV1001;
        }
        else
        {
            LOG_ERROR(HLE, "cellVdecGetPicItem: unsupported time_base.den (%d)", vdec->ctx->time_base.den);
            Emu.Pause();
        }
    }
    else
    {
        LOG_ERROR(HLE, "cellVdecGetPicItem: unsupported time_base.num (%d)", vdec->ctx->time_base.num);
        Emu.Pause();
    }
    avc->fixed_frame_rate_flag = true;
    avc->low_delay_hrd_flag = true; // ???
    avc->entropy_coding_mode_flag = true; // ???
    avc->nalUnitPresentFlags = 0; // ???
    avc->ccDataLength[0] = 0;
    avc->ccDataLength[1] = 0;
    avc->reserved[0] = 0;
    avc->reserved[1] = 0;

    picItem_ptr = info.GetAddr();

    return CELL_OK;
}