Kurento 源码解析系列(1)- PlayerEndpoint的play方法

PlayerEndpoint.cpp 播放的流程解析

补充一个将源项目各个子项目整合并编译以后的工程地址

https://github.com/ywcai/JKms.git

针对如何编译源代码并在vscode中跑起来,后续文章再进行介绍。

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Playendpoint 收到java层的rpc指令,启动play方法

Play方直接调了start()方法,start方法来自继承的父类,UriEndpoint.cpp的start方法;

UriEndpoint.cpp的调用方法调用了

  if (!kms_uri_endpoint_set_state (KMS_URI_ENDPOINT (getGstreamerElement() ),

                                   KMS_URI_ENDPOINT_STATE_START, &error) ) {

    GST_ERROR_OBJECT (getGstreamerElement(), "Error: %s", error->message);

    g_error_free (error);

  }

通过kms_uri_endpoint_set_state()方法,设置了基类中Eelement的状态。

gboolean

kms_uri_endpoint_set_state (KmsUriEndpoint * self, KmsUriEndpointState next,

    GError ** err)

{

  gboolean ret;



  KMS_ELEMENT_LOCK (KMS_ELEMENT (self));

  ret = kms_uri_endpoint_change_state (self, next, err);

  KMS_ELEMENT_UNLOCK (KMS_ELEMENT (self));

  return ret;

}

kms_uri_endpoint_set_state方法则是在 kmsuriendpoint.c代码中。在这个方法中,访问了C层的指针。并且返回一个设置是否成功的布尔值

kms_uri_endpoint_change_state (self, next, err);

具体设置C层对象(GOBJECT模拟的对象)状态的方法:

static gboolean
kms_uri_endpoint_change_state (KmsUriEndpoint * self, KmsUriEndpointState next,
    GError ** err)
{
  if (self->priv->state == next) {
    g_set_error (err, KMS_URI_ENDPOINT_ERROR,
        KMS_URI_ENDPOINT_INVALID_TRANSITION, "Already in state %s",
        kms_uriendpoint_state_to_string (next));
    return FALSE;
  }

  switch (next) {
    case KMS_URI_ENDPOINT_STATE_STOP:
      return CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->stopped,
          err);
    case KMS_URI_ENDPOINT_STATE_START:
      return CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->started,
          err);
    case KMS_URI_ENDPOINT_STATE_PAUSE:
      return CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->paused,
          err);
  }

  g_set_error (err, KMS_URI_ENDPOINT_ERROR,
      KMS_URI_ENDPOINT_UNEXPECTED_ERROR, "Invalid state %u", next);

  return FALSE;
}

 

具体下面的代码调用了C 层的方法。

 

case KMS_URI_ENDPOINT_STATE_START:

      return CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->started,

          err);

 

CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->started,err) 这个宏可以在头文件中看到,实际上则是调用self的started

而当前的self实际上是kmsplayerelement.c创建的模拟对象。  这个具体创建的需要参考PlayerEndpoint.cpp的对象初始化方法,里面通过传递factoryname,在基类的构造方法中通过make方式创建了一个gobject的模拟对象.而PlayerEndpoint.cpp传递的是playerendpoint的模拟对象。再次回到上面的

CALL_IF_DEFINED (self, KMS_URI_ENDPOINT_GET_CLASS (self)->started, err)  这个方法。

而kmsuriendpoint.c中的stared是一个虚方法,他实际上是调用了playerendpoint.c中的started方法,我们继续查找playerendpoint.c文件中的started方法的实现,调用如下:

static gboolean

kms_player_endpoint_started (KmsUriEndpoint *obj, GError **error)

{

  KmsPlayerEndpoint *self = KMS_PLAYER_ENDPOINT (obj);

  GST_INFO_OBJECT (self, "PlayerEndpoint Pipeline started");

   g_object_set (G_OBJECT (self->priv->uridecodebin), "uri",

      KMS_URI_ENDPOINT (self)->uri, NULL);

   gst_element_set_state (self->priv->pipeline, GST_STATE_PLAYING);

  KMS_URI_ENDPOINT_GET_CLASS (self)->change_state (

      KMS_URI_ENDPOINT (self), KMS_URI_ENDPOINT_STATE_START);

  return TRUE;

}

 

 

在这里,设置了uridecodebin的 uri地址,并设置这个self->priv->pipeline上的所有bin为playing状态,pipeline是gstreame的基本结构,这个需要自行对gstreamer进行了解。  下面一句,同时把kmsuriendpoint的状态进行了同步处理,并且在里面将该状态通过信号系统向CPP层进行了回调发送。

KMS_URI_ENDPOINT_GET_CLASS(self)->change_state (KMS_URI_ENDPOINT (self),KMS_URI_ENDPOINT_STATE_START);

实现代码如下:

static void

kms_uri_endpoint_change_state_impl (KmsUriEndpoint * self,

    KmsUriEndpointState state)

{

  if (self->priv->state == state)

    return;



  GST_DEBUG_OBJECT (self, "State changed from %s to %s",

      kms_uriendpoint_state_to_string (self->priv->state),

      kms_uriendpoint_state_to_string (state));



  self->priv->state = state;

  g_signal_emit (G_OBJECT (self), kms_uri_endpoint_signals[STATE_CHANGED], 0,

      state);

}

 

到此, palyerendpoint就开始了多媒体资源的播放。但开始播放后,又是如何进行解析的,下一篇文章进行分析。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值