google / universal-dash-transmuxer

UDT (Dash Transmuxer) Project: Can transmux DASH -> HLS or other formats.
http://www.google.com
Apache License 2.0
54 stars 25 forks source link

Could it support latest version(3.2) of guidelines for implementation:DASH-IF interoperability points #12

Closed Sean-X closed 2 years ago

Sean-X commented 8 years ago

According to the latest version(3.2) of guidelines for implementation: DASH-IF interoperability points, ‘pssh’ boxes SHOULD NOT be present in Initialization Segments, and cenc:pssh elements in ContentProtection Descriptors used instead. But, the current iOS_CDM_Player could not support it and report error message when play it as: 'Message':'Missing boxes.’, 'File':'/Developer/workshed/google3/third_party/video/udt_dash_transmuxer/library/dash_to_hls_api.cc', 'Line':242, 'Reason':'Missing pssh box', 'Extra':'' So is it possible to to make the sdk that compatible with the DASH-IF-IOP-V3.2? If yes, could let us know the schedule? Sorry to ask you question from here.

joeyparrish commented 8 years ago

@Sean-X Here's a couple relevant quotes from IOP v3.2:

'pssh’ boxes may be stored in Initialization or Media Segments (see [31] 8.1 and 8.2). It may also be present in a cenc:pssh element in the MPD (see [5] 5.8.4.1, [31] 11.2.1).

PSSH boxes in the media are not prohibited in any way, and we will continue to support them.

cenc:pssh information in the MPD allows faster parsing, earlier access, identification of duplicate license requests, and addition of DRMs without content modification. ‘pssh’ boxes in Initialization Segments are not recommended because they trigger a license request each time an Initialization Segment is processed in a Web browser for each Representation and bitrate switch.

This recommendation against PSSH in init data is specifically designed to avoid duplicate requests in a web browser. Web-based players already screen duplicate init data to handle this, so I'm not sure what the value of this recommendation is for the web. Further, this does not apply to UDT as far as I can tell.

cenc:pssh elements are meant to override the PSSH in the content. Since UDT doesn't handle DASH manifests directly, it sounds like what you are really asking for is an API to feed in a PSSH from the manifest that overrides and ignores any PSSHs from the content.

Is that accurate?

Sean-X commented 8 years ago

@joeyparrish Thanks for your reply. Your understanding is correct and it will perfectly solve our problem. BTW, we tried the same case(without pssh in content) with exoplayer, it's just working well. So, it would be really helpful if the implementation could be the same way with other players since we couldn't make any change on it.

joeyparrish commented 8 years ago

When a web browser encounters a PSSH, it emits an 'encrypted' event from the video element. If there is a PSSH embedded in the manifest, a web player should simply ignore the video element's 'encrypted' event and use the embedded PSSH to generate a license request.

UDT works much the same way. When UDT encounters a PSSH in the content, it invokes the CENC_PsshHandler set by the application. So if you have an embedded PSSH in the manifest, simply set a dummy CENC_PsshHandler (equivalent to ignoring 'encrypted' events), then pass the PSSH from the manifest to whatever your normal PSSH handler is. The PSSH from the manifest is then used to generate a license request.

Since all of this happens at the DASH manifest level (XML parsing) and the CDM level (generating license requests), it seems that there are no changes required in UDT to support embedded PSSHs in a manifest.

joeyparrish commented 8 years ago

@Sean-X, please let me know if this makes sense. If you need any help making this work in your application, I would happy to assist.

Sean-X commented 8 years ago

@joeyparrish thank your very much for your help. We will check if this solution works.

Sean-X commented 8 years ago

@joeyparrish my understanding is you suggest that put a dummy pssh in the content, which will be ignored by the pssh from manifest. Is that correct? Actually now we don't add any pssh in the content(recommended by the spec) and then seems like the CENC_PsshHandler won't be invoked, so the license acquisition couldn't happen.

joeyparrish commented 8 years ago

@Sean-X I'm not suggesting a dummy PSSH. That is not necessary.

In the general case, you may or may not have a PSSH in the content. Any PSSH that may be in the content needs to be overridden with the PSSH in the manifest.

To ignore any PSSH in the content, you would install a dummy CENC_PsshHandler by calling DashToHls_SetCenc_PsshHandler. (If you don't have PSSH in your content, feel free to skip this step. It is, however, necessary in the general case.)

To acquire a license with the PSSH from the manifest, simply call the real CENC_PsshHandler with the manifest-derived PSSH box.

Here's a sample of how this would flow:

DashToHlsStatus RealPsshHandler(DashToHlsContext context,
                                const uint8_t* pssh,
                                size_t pssh_length) {
  // TODO: Generate a license request!
}

DashToHlsStatus DummyPsshHandler(DashToHlsContext context,
                                 const uint8_t* pssh,
                                 size_t pssh_length) {
  return kDashToHlsStatus_OK;
}

// Later, in your app:

// Ignore PSSH from content (if any):
DashToHls_SetCenc_PsshHandler(DummyPsshHandler);

// Get the PSSH from the manifest:
char* base64_pssh_from_manifest = SomeHowExtractCencPsshContentsFromXml();
size_t raw_pssh_from_manifest_length;
uint8_t* raw_pssh_from_manifest = SomeBase64DecodeFunction(
    base64_pssh_from_manifest, &raw_pssh_from_manifest_length);

// Trigger a license request with the manifest-derived PSSH:
RealPsshHandler(raw_pssh_from_manifest, raw_pssh_from_manifest_length);
Sean-X commented 8 years ago

Thanks for your suggestion. We have tried according to your description. 1) We set a dummy CENC callback using DashToHls_SetCenc_PsshHandler() 2) We explicitly call the real CENCpssh handler to trigger license acquisition.

This works fine if the mp4 files contains pssh boxes. But when removing the pssh boxes from the mp4 files DashToHls_ParseDash() fails with error code kDashToHlsStatus_BadConfiguration. Log: CDMPlayer[] { 'Message':'Missing boxes.', 'File':'/Developer/workshed/google3/third_party/video/udt_dash_transmuxer/library/dash_to_hls_api.cc', 'Line':242, 'Reason':'Missing pssh box', 'Extra':'' }

From the implementation we can see that DashToHls_ParseDash() does require a pssh to be included:

const std::vector<const Box*> pssh_boxes = dashsession->parser.FindDeepAll(BoxType::kBox_pssh); if (pssh_boxes.empty()) { DASH_LOG("Missing boxes.", "Missing pssh box", ""); return kDashToHlsStatus_BadConfiguration; }

Is there some other way to play content without the pssh box in the mp4 file?

joeyparrish commented 8 years ago

@Sean-X, then it seems to me that this check should be removed.

joeyparrish commented 2 years ago

The project is dead. We apologize for any inconvenience. Feel free to continue it in a fork if you wish. See also a bit more detail in #19.