Ejemplo n.º 1
0
void UPnpCDSVideo::PopulateArtworkURIS(CDSObject* pItem, int nVidID,
                                       const QUrl& URIBase)
{
    QUrl artURI = URIBase;
    artURI.setPath("/Content/GetVideoArtwork");
    QUrlQuery artQuery;
    artQuery.addQueryItem("Id", QString::number(nVidID));
    artURI.setQuery(artQuery);

    // Prefer JPEG over PNG here, although PNG is allowed JPEG probably
    // has wider device support and crucially the filesizes are smaller
    // which speeds up loading times over the network

    // We MUST include the thumbnail size, but since some clients may use the
    // first image they see and the thumbnail is tiny, instead return the
    // medium first. The large could be very large, which is no good if the
    // client is pulling images for an entire list at once!

    // Thumbnail
    // At least one albumArtURI must be a ThumbNail (TN) no larger
    // than 160x160, and it must also be a jpeg
    QUrl thumbURI = artURI;
    QUrlQuery thumbQuery(thumbURI.query());
    if (pItem->m_sClass == "object.item.videoItem") // Show screenshot for TV, coverart for movies
        thumbQuery.addQueryItem("Type", "screenshot");
    else
        thumbQuery.addQueryItem("Type", "coverart");
    thumbQuery.addQueryItem("Width", "160");
    thumbQuery.addQueryItem("Height", "160");
    thumbURI.setQuery(thumbQuery);

    // Small
    // Must be no more than 640x480
    QUrl smallURI = artURI;
    QUrlQuery smallQuery(smallURI.query());
    smallQuery.addQueryItem("Type", "coverart");
    smallQuery.addQueryItem("Width", "640");
    smallQuery.addQueryItem("Height", "480");
    smallURI.setQuery(smallQuery);

    // Medium
    // Must be no more than 1024x768
    QUrl mediumURI = artURI;
    QUrlQuery mediumQuery(mediumURI.query());
    mediumQuery.addQueryItem("Type", "coverart");
    mediumQuery.addQueryItem("Width", "1024");
    mediumQuery.addQueryItem("Height", "768");
    mediumURI.setQuery(mediumQuery);

    // Large
    // Must be no more than 4096x4096 - for our purposes, just return
    // a fullsize image
    QUrl largeURI = artURI;
    QUrlQuery largeQuery(largeURI.query());
    largeQuery.addQueryItem("Type", "fanart");
    largeURI.setQuery(largeQuery);

    QList<Property*> propList = pItem->GetProperties("albumArtURI");
    if (propList.size() >= 4)
    {
        Property *pProp = propList.at(0);
        if (pProp)
        {
            pProp->SetValue(mediumURI.toEncoded());
            pProp->AddAttribute("dlna:profileID", "JPEG_MED");
            pProp->AddAttribute("xmlns:dlna", "urn:schemas-dlna-org:metadata-1-0");
        }

        pProp = propList.at(1);
        if (pProp)
        {

            pProp->SetValue(thumbURI.toEncoded());
            pProp->AddAttribute("dlna:profileID", "JPEG_TN");
            pProp->AddAttribute("xmlns:dlna", "urn:schemas-dlna-org:metadata-1-0");
        }

        pProp = propList.at(2);
        if (pProp)
        {
            pProp->SetValue(smallURI.toEncoded());
            pProp->AddAttribute("dlna:profileID", "JPEG_SM");
            pProp->AddAttribute("xmlns:dlna", "urn:schemas-dlna-org:metadata-1-0");
        }

        pProp = propList.at(3);
        if (pProp)
        {
            pProp->SetValue(largeURI.toEncoded());
            pProp->AddAttribute("dlna:profileID", "JPEG_LRG");
            pProp->AddAttribute("xmlns:dlna", "urn:schemas-dlna-org:metadata-1-0");
        }
    }

    if (pItem->m_sClass.startsWith("object.item.videoItem"))
    {
        QString sProtocol;

        sProtocol = DLNA::ProtocolInfoString(UPNPProtocol::kHTTP,
                                             "image/jpeg", QSize(1024, 768));
        pItem->AddResource( sProtocol, mediumURI.toEncoded());

        sProtocol = DLNA::ProtocolInfoString(UPNPProtocol::kHTTP,
                                             "image/jpeg", QSize(160, 160));
        pItem->AddResource( sProtocol, thumbURI.toEncoded());

        sProtocol = DLNA::ProtocolInfoString(UPNPProtocol::kHTTP,
                                             "image/jpeg", QSize(640, 480));
        pItem->AddResource( sProtocol, smallURI.toEncoded());

        sProtocol = DLNA::ProtocolInfoString(UPNPProtocol::kHTTP,
                                             "image/jpeg", QSize(1920, 1080)); // Not the actual res, we don't know that
        pItem->AddResource( sProtocol, largeURI.toEncoded());
    }
}
Ejemplo n.º 2
0
Vec3f PhotonTracer::traceSample(Vec2u pixel, const KdTree<Photon> &surfaceTree,
        const KdTree<VolumePhoton> *mediumTree, PathSampleGenerator &sampler,
        float gatherRadius)
{
    PositionSample point;
    if (!_scene->cam().samplePosition(sampler, point))
        return Vec3f(0.0f);
    DirectionSample direction;
    if (!_scene->cam().sampleDirection(sampler, point, pixel, direction))
        return Vec3f(0.0f);
    sampler.advancePath();

    Vec3f throughput = point.weight*direction.weight;
    Ray ray(point.p, direction.d);
    ray.setPrimaryRay(true);

    IntersectionTemporary data;
    IntersectionInfo info;
    const Medium *medium = _scene->cam().medium().get();

    Vec3f result(0.0f);
    int bounce = 0;
    bool didHit = _scene->intersect(ray, data, info);
    while ((medium || didHit) && bounce < _settings.maxBounces - 1) {
        if (medium) {
            if (mediumTree) {
                Vec3f beamEstimate(0.0f);
                mediumTree->beamQuery(ray.pos(), ray.dir(), ray.farT(), [&](const VolumePhoton &p, float t, float distSq) {
                    Ray mediumQuery(ray);
                    mediumQuery.setFarT(t);
                    beamEstimate += (3.0f*INV_PI*sqr(1.0f - distSq/p.radiusSq))/p.radiusSq
                            *medium->phaseFunction(p.pos)->eval(ray.dir(), -p.dir)
                            *medium->transmittance(mediumQuery)*p.power;
                });
                result += throughput*beamEstimate;
            }
            throughput *= medium->transmittance(ray);
        }
        if (!didHit)
            break;

        const Bsdf &bsdf = *info.bsdf;

        SurfaceScatterEvent event = makeLocalScatterEvent(data, info, ray, &sampler);

        Vec3f transparency = bsdf.eval(event.makeForwardEvent(), false);
        float transparencyScalar = transparency.avg();

        Vec3f wo;
        if (sampler.nextBoolean(DiscreteTransparencySample, transparencyScalar)) {
            wo = ray.dir();
            throughput *= transparency/transparencyScalar;
        } else {
            event.requestedLobe = BsdfLobes::SpecularLobe;
            if (!bsdf.sample(event, false))
                break;

            wo = event.frame.toGlobal(event.wo);

            throughput *= event.weight;
        }

        bool geometricBackside = (wo.dot(info.Ng) < 0.0f);
        medium = info.primitive->selectMedium(medium, geometricBackside);

        ray = ray.scatter(ray.hitpoint(), wo, info.epsilon);

        if (std::isnan(ray.dir().sum() + ray.pos().sum()))
            break;
        if (std::isnan(throughput.sum()))
            break;

        sampler.advancePath();
        bounce++;
        if (bounce < _settings.maxBounces)
            didHit = _scene->intersect(ray, data, info);
    }

    if (!didHit) {
        if (!medium && _scene->intersectInfinites(ray, data, info))
            result += throughput*info.primitive->evalDirect(data, info);
        return result;
    }
    if (info.primitive->isEmissive())
        result += throughput*info.primitive->evalDirect(data, info);

    int count = surfaceTree.nearestNeighbours(ray.hitpoint(), _photonQuery.get(), _distanceQuery.get(),
            _settings.gatherCount, gatherRadius);
    if (count == 0)
        return result;

    const Bsdf &bsdf = *info.bsdf;
    SurfaceScatterEvent event = makeLocalScatterEvent(data, info, ray, &sampler);

    Vec3f surfaceEstimate(0.0f);
    for (int i = 0; i < count; ++i) {
        event.wo = event.frame.toLocal(-_photonQuery[i]->dir);
        // Asymmetry due to shading normals already compensated for when storing the photon,
        // so we don't use the adjoint BSDF here
        surfaceEstimate += _photonQuery[i]->power*bsdf.eval(event, false)/std::abs(event.wo.z());
    }
    float radiusSq = count == int(_settings.gatherCount) ? _distanceQuery[0] : gatherRadius*gatherRadius;
    result += throughput*surfaceEstimate*(INV_PI/radiusSq);

    return result;
}