From: Haesu Gwon Date: Mon, 7 Oct 2024 07:37:32 +0000 (+0900) Subject: Support DRM playback X-Git-Tag: accepted/tizen/unified/20241017.114640^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Faccepted%2Ftizen_unified_toolchain;p=platform%2Fcore%2Fmultimedia%2Ftrackrenderer.git Support DRM playback - Change video and audio pipeline for DRM playback [Version] 0.1.3 [Issue Type] Add feature Change-Id: I1c76006dad9f6cd81306ec4d434c08eed6c50123 --- diff --git a/packaging/libtrackrenderer.spec b/packaging/libtrackrenderer.spec index 6905530..5f41d77 100644 --- a/packaging/libtrackrenderer.spec +++ b/packaging/libtrackrenderer.spec @@ -1,6 +1,6 @@ Name: libtrackrenderer Summary: new multimedia streaming player trackrenderer -Version: 0.1.2 +Version: 0.1.3 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/gstcaps_builder.cpp b/src/gstcaps_builder.cpp index 41b2984..9b89121 100644 --- a/src/gstcaps_builder.cpp +++ b/src/gstcaps_builder.cpp @@ -75,9 +75,10 @@ static void FillStreamFormat(const GstCapsWrapper& caps, const Track& track) { caps.SetValue("adaptive-streaming", G_TYPE_BOOLEAN, true); } -static void FillDrmInfo(const GstCapsWrapper& caps, const Track& track) { - if (!track.original_media_type.empty()) - caps.SetValue("original-media-type", G_TYPE_STRING, track.original_media_type.c_str()); +static void FillDrmInfo(const GstCapsWrapper& caps, const Track& track, const std::string& originalMediaType) { + if (!originalMediaType.empty()) + caps.SetValue("original-media-type", G_TYPE_STRING, originalMediaType.c_str()); + if (!track.protection_system.empty()) caps.SetValue("protection-system", G_TYPE_STRING, track.protection_system.c_str()); @@ -259,7 +260,7 @@ GstCapsWrapper GstCapsBuilder::Build(const Track& track, bool is_drm) { internal::FillStreamType(caps, track); internal::FillCodecData(caps, track); internal::FillStreamFormat(caps, track); - internal::FillDrmInfo(caps, track); + internal::FillDrmInfo(caps, track, is_drm ? media_type : std::string()); internal::FillChannelMaskField(caps, track); caps.PrintCapsString(); diff --git a/src/trackrenderer.cpp b/src/trackrenderer.cpp index 7f301d4..69d6efc 100644 --- a/src/trackrenderer.cpp +++ b/src/trackrenderer.cpp @@ -1061,21 +1061,16 @@ static GstCaps* ChooseDecoderCaps(GstCaps* inputCaps, GstCaps* parseCaps) bool TrackRenderer::CreateVideoPipeline_(const Track* track) { TRACKRENDERER_ENTER; - auto caps = caps_builder_.Build(*track, internal::IsDrmEmeElementNecessary( - drm_property_, track->mimetype)); - CreateAppSrc_(kTrackTypeVideo, caps.GetCaps_()); - - if (internal::IsDecryptorElementNecessary(drm_property_)) { - auto caps_for_parser = caps_builder_.BuildOrgMediaType(*track, internal::IsDrmEmeElementNecessary( - drm_property_, track->mimetype)); - if (!pipeline_->FactoryMake(Elements::kParseVideo, caps_for_parser.GetCaps_(), + bool is_drm = internal::IsDrmEmeElementNecessary(drm_property_, track->mimetype); + + auto caps = caps_builder_.Build(*track, false); + + LOGD("track->mimetype[%s]", track->mimetype.c_str()); + CreateAppSrc_(kTrackTypeVideo, is_drm ? caps_builder_.Build(*track, true).GetCaps_() : caps.GetCaps_()); + + if (!pipeline_->FactoryMake(Elements::kParseVideo, caps.GetCaps_(), GST_ELEMENT_FACTORY_TYPE_PARSER, NULL)) - TRACKRENDERER_ERROR("Failed to make parser"); - } else { - if (!pipeline_->FactoryMake(Elements::kParseVideo, caps.GetCaps_(), - GST_ELEMENT_FACTORY_TYPE_PARSER, NULL)) - TRACKRENDERER_ERROR("Failed to make parser"); - } + TRACKRENDERER_ERROR("Failed to make parser"); auto parse_caps = gstguard::make_guard(pipeline_->GetSrcPadCaps(Elements::kParseVideo)); @@ -1102,15 +1097,7 @@ bool TrackRenderer::CreateVideoPipeline_(const Track* track) { pipeline_->SignalConnect(Elements::kCCExtractor, "pad-added", G_CALLBACK(GstClosedCaptionPadAddedCb_), this); - // TODO: need to implement drmdecryptor plugin - // FIXME: drm plugin should be added before parser - if (internal::IsDecryptorElementNecessary(drm_property_)) { - pipeline_->FactoryMake(Elements::kDrmVideo, "cencdecrypt", NULL); - pipeline_->SetProperty(Elements::kDrmVideo, "getrights-complete-cb", - GstVideoDrmInitDataCb_); - pipeline_->SetProperty(Elements::kDrmVideo, "getrights-complete-cb-data", - this); - } else if (internal::IsDrmEmeElementNecessary(drm_property_, track->mimetype)) { + if (is_drm) { pipeline_->FactoryMake(Elements::kDrmVideo, "drm_eme", "video_drm"); pipeline_->SetProperty(Elements::kDrmVideo, "plus-player-eme", TRUE); if (!internal::IsExternalDecryptionCase(drm_property_)) { @@ -1160,11 +1147,18 @@ void TrackRenderer::SetOpusChannelMappingFamily(const GstCapsWrapper& caps) { bool TrackRenderer::CreateAudioPipeline_(const Track* track) { TRACKRENDERER_ENTER; + bool is_drm = internal::IsDrmEmeElementNecessary(drm_property_, track->mimetype); + auto caps = caps_builder_.Build(*track, false); - if (track->mimetype.find("audio/x-opus") != std::string::npos) + auto drm_caps = caps_builder_.Build(*track, true); + if (track->mimetype.find("audio/x-opus") != std::string::npos) { SetOpusChannelMappingFamily(caps); - CreateAppSrc_(kTrackTypeAudio, caps.GetCaps_()); + if (is_drm) + SetOpusChannelMappingFamily(drm_caps); + } + + CreateAppSrc_(kTrackTypeAudio, is_drm ? drm_caps.GetCaps_() : caps.GetCaps_()); if (!pipeline_->FactoryMake(Elements::kParseAudio, caps.GetCaps_(), GST_ELEMENT_FACTORY_TYPE_PARSER, NULL)) @@ -1190,7 +1184,18 @@ bool TrackRenderer::CreateAudioPipeline_(const Track* track) { pipeline_->FactoryMake(Elements::kAudioConvert, "audioconvert", nullptr); pipeline_->FactoryMake(Elements::kAudioResample, "audioresample", nullptr); - pipeline_->BinAdd(Elements::kBinAudio, Elements::kAppSrcAudio, + if (is_drm) { + pipeline_->FactoryMake(Elements::kDrmAudio, "drm_eme", "audio_drm"); + pipeline_->SetProperty(Elements::kDrmAudio, "plus-player-eme", TRUE); + if (!internal::IsExternalDecryptionCase(drm_property_)) { + pipeline_->SetProperty(Elements::kDrmAudio, "getrights-complete-cb", + GstAudioDrmInitDataCb_); + pipeline_->SetProperty(Elements::kDrmAudio, "getrights-complete-cb-data", + this); + } + } + + pipeline_->BinAdd(Elements::kBinAudio, Elements::kAppSrcAudio, Elements::kDrmAudio, Elements::kParseAudio, Elements::kDecAudio, Elements::kAudioConvert, Elements::kAudioResample, Elements::kSinkAudio); @@ -1914,6 +1919,17 @@ GstPadProbeReturn TrackRenderer::GstPadProbeAppsrcEventCb_(GstPad* pad, type = kTrackTypeVideo; } else if (strstr(name, "text")) { type = kTrackTypeSubtitle; + } else if (strstr(name, "drm/eme")) { + const gchar * original_media_type = gst_structure_get_string(str, "original-media-type"); + + if (strstr(original_media_type, "audio")) { + type = kTrackTypeAudio; + } else if (strstr(original_media_type, "video")) { + type = kTrackTypeVideo; + } else { + TRACKRENDERER_WARN("invalid name %s", name); + return GST_PAD_PROBE_PASS; + } } else { TRACKRENDERER_WARN("invalid name %s", name); return GST_PAD_PROBE_PASS; @@ -2188,7 +2204,7 @@ bool TrackRenderer::Activate(TrackType type, const Track& track) { pipeline_->SetProperty(Elements::kDrmVideo, "getrights-complete-cb-data", this); } - pipeline_->BinAdd(Elements::kBinVideo, Elements::kDrmVideo, + pipeline_->BinAdd(Elements::kBinVideo, Elements::kDrmVideo, Elements::kParseVideo, Elements::kDecVideo, Elements::kSinkVideo); pipeline_->SetProperty(Elements::kSinkVideo, "async", TRUE); GstElementLowLatency_(kTrackTypeVideo);