RDKEMW-6776 Encrypted Pipeline Changes with SVPPAY on AAMP#196
RDKEMW-6776 Encrypted Pipeline Changes with SVPPAY on AAMP#196suryaiyappan2k wants to merge 1 commit into
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
Pull request overview
This PR is intended to adjust encrypted playback pipeline behavior (per description: insert svppayload immediately after aampdecryptor), and it also refactors DRM decryptor src-pad caps advertisement to be built dynamically based on a runtime-discovered platform secure-memory feature.
Changes:
- Adds a new
element_setupcallback hookup for video streams inInterfacePlayerRDK(currently only logs element names). - Builds Widevine/PlayReady decryptor src pad-template caps dynamically at
class_inittime using newgst_cdmidecryptor_*helper APIs. - Adds runtime discovery of platform secure-memory caps feature in
gstcdmidecryptorand updates caps-transform logging.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| InterfacePlayerRDK.cpp | Adds a new element_setup callback for video streams (currently logging-only). |
| gst-plugins/drm/gst/gstwidevinedecryptor.cpp | Replaces static src pad-template caps with dynamically generated caps string. |
| gst-plugins/drm/gst/gstplayreadydecryptor.cpp | Same dynamic src pad-template caps approach as Widevine. |
| gst-plugins/drm/gst/gstcdmidecryptor.h | Exposes new public APIs for platform memory-feature discovery and caps-string building. |
| gst-plugins/drm/gst/gstcdmidecryptor.cpp | Implements platform memory-feature discovery, dynamic mime-type/caps generation, and adds additional caps-transform logging. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| static void element_setup_cb_svppay(GstElement *playbin, GstElement *element, gpointer user_data) | ||
| { | ||
| const gchar *name = gst_element_get_name(element); | ||
| MW_LOG_ERR("muthumani: Received element:%s", name); | ||
| } |
| static void element_setup_cb_svppay(GstElement *playbin, GstElement *element, gpointer user_data) | ||
| { | ||
| const gchar *name = gst_element_get_name(element); | ||
| MW_LOG_ERR("muthumani: Received element:%s", name); | ||
| } |
| if (eGST_MEDIATYPE_VIDEO == streamId) | ||
| { | ||
| g_signal_connect(stream->sinkbin, "element_setup", G_CALLBACK(element_setup_cb_svppay), pInterfacePlayerRDK); | ||
| } |
| @@ -127,6 +127,183 @@ | |||
|
|
|||
| static const gchar *srcMimeTypes[] = { "video/x-h264", "video/x-h264(memory:SecMem)", "audio/mpeg", "video/x-h265", "video/x-h265(memory:SecMem)", "audio/x-eac3", "audio/x-gst-fourcc-ec_3", "audio/x-ac3","audio/x-opus", nullptr }; | |||
| static const gchar *baseMimeTypes[] = { | ||
| "video/x-h264", "video/x-h265", | ||
| "audio/mpeg", "audio/x-eac3", "audio/x-gst-fourcc-ec_3", "audio/x-ac3", "audio/x-opus", | ||
| nullptr | ||
| }; |
| if (direction == GST_PAD_SINK && !gst_caps_is_empty(transformedCaps)) | ||
| { | ||
| gchar *caps_before = gst_caps_to_string(transformedCaps); | ||
| g_print("muthumani: OCDMGstTransformCaps - caps BEFORE transform: %s\n", caps_before); | ||
| g_free(caps_before); | ||
|
|
||
| if (OCDMGstTransformCaps) | ||
| { | ||
| OpenCDMError ret = OCDMGstTransformCaps(&transformedCaps); | ||
| gchar *caps_after = gst_caps_to_string(transformedCaps); | ||
| g_print("muthumani: OCDMGstTransformCaps - called, ret=%d, caps AFTER transform: %s\n", ret, caps_after); | ||
| g_free(caps_after); | ||
| } | ||
| else | ||
| { | ||
| g_print("muthumani: OCDMGstTransformCaps is NULL - skipping caps transform\n"); | ||
| } | ||
| } |
| const gchar *platformMemFeature = gst_cdmidecryptor_get_platform_memory_feature(); | ||
| gchar *srcCapsStr = gst_cdmidecryptor_build_src_caps_string(platformMemFeature); | ||
| GstCaps *srcCaps = gst_caps_from_string(srcCapsStr); | ||
| g_free(srcCapsStr); | ||
|
|
||
| GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps); | ||
| gst_caps_unref(srcCaps); | ||
| gst_element_class_add_pad_template(elementClass, srcTemplate); |
| const gchar *platformMemFeature = gst_cdmidecryptor_get_platform_memory_feature(); | ||
| gchar *srcCapsStr = gst_cdmidecryptor_build_src_caps_string(platformMemFeature); | ||
| GstCaps *srcCaps = gst_caps_from_string(srcCapsStr); | ||
| g_free(srcCapsStr); | ||
|
|
||
| GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps); | ||
| gst_caps_unref(srcCaps); | ||
| gst_element_class_add_pad_template(elementClass, srcTemplate); | ||
|
|
| * The returned string is allocated with g_strdup_printf and must be freed with g_free(). | ||
| * Typically called from a subclass class_init to construct a dynamic pad template. |
| /* Base video/audio media types supported by all platforms */ | ||
| static const gchar *baseMimeTypes[] = { | ||
| "video/x-h264", "video/x-h265", | ||
| "audio/mpeg", "audio/x-eac3", "audio/x-gst-fourcc-ec_3", "audio/x-ac3", "audio/x-opus", | ||
| nullptr | ||
| }; |
c4f02be to
4f76608
Compare
|
b'## WARNING: A Blackduck scan failure has been waived A prior failure has been upvoted
|
4f76608 to
ecc97aa
Compare
| @@ -127,6 +127,182 @@ static unsigned char* ReplaceKIDPsshData(const unsigned char *InputData, const s | |||
|
|
|||
| static const gchar *srcMimeTypes[] = { "video/x-h264", "video/x-h264(memory:SecMem)", "audio/mpeg", "video/x-h265", "video/x-h265(memory:SecMem)", "audio/x-eac3", "audio/x-gst-fourcc-ec_3", "audio/x-ac3","audio/x-opus", nullptr }; | |||
| gchar *caps_before = gst_caps_to_string(transformedCaps); | ||
| g_free(caps_before); | ||
|
|
||
| if (OCDMGstTransformCaps) | ||
| { | ||
| OpenCDMError ret = OCDMGstTransformCaps(&transformedCaps); | ||
| gchar *caps_after = gst_caps_to_string(transformedCaps); | ||
| g_free(caps_after); | ||
| } | ||
| else | ||
| { | ||
| GST_WARNING("OCDMGstTransformCaps is NULL - skipping caps transform"); | ||
| } |
| GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps); | ||
| gst_caps_unref(srcCaps); | ||
| gst_element_class_add_pad_template(elementClass, srcTemplate); |
| GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps); | ||
| gst_caps_unref(srcCaps); | ||
| gst_element_class_add_pad_template(elementClass, srcTemplate); |
| * @brief Build a dynamic GstCaps string for the src pad template of a decryptor, | ||
| * appending the platform-specific secure memory feature (if any) to video types. | ||
| * | ||
| * The returned string is allocated with g_strdup_printf and must be freed with g_free(). |
| static void element_setup_cb_svppay(GstElement *playbin, GstElement *element, gpointer user_data) | ||
| { | ||
| const gchar *name = gst_element_get_name(element); | ||
| MW_LOG_INFO( "Received element: %s", name); | ||
| } |
ecc97aa to
c39b353
Compare
Reason for change: To insert the svppayload element into encrypted pipeline immediately after the aampdecryptor element. Test procedure: Test playback across all the apps. Risks: Low.
c39b353 to
e834710
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (7)
InterfacePlayerRDK.cpp:2075
- The new element_setup_cb_svppay logs at INFO for every element_setup invocation, which can spam logs and add overhead. Consider lowering the log level and/or filtering to the specific element(s) you care about (e.g., the decryptor) and mark unused parameters explicitly.
static void element_setup_cb_svppay(GstElement *playbin, GstElement *element, gpointer user_data)
{
const gchar *name = gst_element_get_name(element);
MW_LOG_INFO( "Received element: %s", name);
}
InterfacePlayerRDK.cpp:2524
- PR description says svppayload should be inserted immediately after aampdecryptor in the encrypted pipeline, but the current change only connects a callback that logs element names and does not perform any insertion/relinking. Either implement the insertion here (e.g., when the decryptor element is created) or update the PR description to match the actual behavior.
if (eGST_MEDIATYPE_VIDEO == streamId)
{
g_signal_connect(stream->sinkbin, "element_setup", G_CALLBACK(element_setup_cb_svppay), pInterfacePlayerRDK);
}
gst-plugins/drm/gst/gstcdmidecryptor.cpp:133
- The dynamically-built baseMimeTypes list dropped audio/x-ac4, but both Widevine and PlayReady sink templates still advertise audio/x-ac4. This can break caps negotiation for AC4 content (regression vs the previous static src caps).
static const gchar *baseMimeTypes[] = {
"video/x-h264", "video/x-h265",
"audio/mpeg", "audio/x-eac3", "audio/x-gst-fourcc-ec_3", "audio/x-ac3", "audio/x-opus",
nullptr
};
gst-plugins/drm/gst/gstcdmidecryptor.cpp:640
- This block creates caps strings (and a ret variable) but immediately frees/ignores them, which is wasted work and may trigger -Wunused-variable warnings in builds that treat warnings as errors. Either remove it entirely or log the values via GST_* macros.
gchar *caps_before = gst_caps_to_string(transformedCaps);
g_free(caps_before);
if (OCDMGstTransformCaps)
{
gst-plugins/drm/gst/gstwidevinedecryptor.cpp:92
- gst_caps_from_string() can return NULL; the current code unrefs srcCaps unconditionally, which can crash and/or fail to register the src pad template. Add a fallback (e.g., retry without the platform memory feature or use gst_caps_new_any()) before creating the pad template.
GstCaps *srcCaps = gst_caps_from_string(srcCapsStr);
g_free(srcCapsStr);
GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps);
gst_caps_unref(srcCaps);
gst-plugins/drm/gst/gstplayreadydecryptor.cpp:95
- gst_caps_from_string() can return NULL; the current code unrefs srcCaps unconditionally, which can crash and/or fail to register the src pad template. Add a fallback (e.g., retry without the platform memory feature or use gst_caps_new_any()) before creating the pad template.
GstCaps *srcCaps = gst_caps_from_string(srcCapsStr);
g_free(srcCapsStr);
GstPadTemplate *srcTemplate = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, srcCaps);
gst_caps_unref(srcCaps);
gst-plugins/drm/gst/gstcdmidecryptor.h:91
- The docstring says the returned string is allocated with g_strdup_printf, but the implementation uses GString/g_string_free(). Update the comment to avoid misleading callers (the important part is that g_free() must be used).
* The returned string is allocated with g_strdup_printf and must be freed with g_free().
Reason for change: To insert the svppayload element into encrypted pipeline immediately after the aampdecryptor element.
Test procedure: Test playback across all the apps.
Risks: Low.