如何从 Android Gingerbread 中的 libmedia_jni 访问自己的 libmediaplayerservice 库

Posted

技术标签:

【中文标题】如何从 Android Gingerbread 中的 libmedia_jni 访问自己的 libmediaplayerservice 库【英文标题】:How to access own libmediaplayerservice library from libmedia_jni in Android Gingerbread 【发布时间】:2012-05-21 03:46:14 【问题描述】:

默认情况下,android Gigerbread 2.3 使用 PV_Player(opencore 库)。我找到了一种解决方案,它应该是修补系统 build.prop 文件,但我不想修补系统。我想使用将使用 StageFright 播放器的 android 媒体框架创建我自己的库。我知道 libmediaplayerservice 决定播放器的选择。看看media framework

我想根据android框架创建库-

libmedia_jni_own libmedia_own libmediaplayerservice_own

但问题是 libmedia 不直接与 libmediaplayerservice 库交互,它不直接依赖于 libmediaplayerservice 库。以至于无法创造出怯场的播放器。 Libmedia 通过 Binder IPC 机制与 libmediaplayerservice 库进行通信。 如何修补 libmedia 源库,以便它可以访问我的 libmediaplayerservice 库并能够创建 StageFright 播放器以及 StageFright 记录器等的所有访问权限,而不是 opencore 库。

【问题讨论】:

【参考方案1】:

我不认为你可以修改媒体服务的工作方式而不修补系统。由于媒体服务及其库位于系统分区上,因此您实际上无法劫持 jni 负载。如果您运行的是非 AOSP rom(如三星、HTC 等),您将无法只更换库,因为来自库存 rom 的库包含许多与专有库的链接。

【讨论】:

【参考方案2】:

通过查看您提到的 Binder 机制的 android 源代码,您应该查看方法“getMediaPlayerService()”并检查服务管理器如何处理媒体服务。如果您可以修补此方法并正确定义您的服务,您应该没问题。

IMediaDeathNotifier::getMediaPlayerService()

    LOGV("getMediaPlayerService");
    Mutex::Autolock _l(sServiceLock);
    if (sMediaPlayerService.get() == 0) 
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do 
            binder = sm->getService(String16("media.player"));
            if (binder != 0) 
                break;
             
             LOGW("Media player service not published, waiting...");
             usleep(500000); // 0.5 s
         while(true);

        if (sDeathNotifier == NULL) 
        sDeathNotifier = new DeathNotifier();
    
    binder->linkToDeath(sDeathNotifier);
    sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    
    LOGE_IF(sMediaPlayerService == 0, "no media player service!?");
    return sMediaPlayerService;

有问题的方法位于: frameworks/base/media/libmedia/IMediaDeathNotifier.cpp

另外,服务是通过调用来设置的:

 void MediaPlayerService::instantiate() 
             defaultServiceManager()->addService(
             String16("media.player"), new MediaPlayerService());
 

可以在以下位置找到:/frameworks/base/media/libmediaplayerservice/MediaPlayerService.cpp

【讨论】:

我已经修补了这段代码并尝试从 libmedia 访问它。但它造成了崩溃。我试图访问 StagefrightPlayer libmedia_jni,但它在 setsurfaceview 中发生了崩溃。 你应该在帖子中提到这一点。 我正在使用 cygwin 在 Windows 上构建应用程序。你能告诉我,如果我在 Linux 平台上构建应用程序,这些库将提供相同的性能。因为在构建的情况下,windows 上的库大小与 linux 平台上的不同。 构建和相应的编译代码取决于编译器。如何优化代码取决于编译器。因此,性能可能会有所不同,但可能是相同的。

以上是关于如何从 Android Gingerbread 中的 libmedia_jni 访问自己的 libmediaplayerservice 库的主要内容,如果未能解决你的问题,请参考以下文章

如何使用适用于 Gingerbread 和 Froyo 的 ICS UI 创建 Android 应用程序?

在 Gingerbread 中实现拖放

Android Gingerbread 上 LocalStorage 的非法访问异常

在 Android 2.3 .X (Gingerbread) 及更低版本上修改 LayerDrawable 层

如何在 Android 中启用 A2DP 接收器功能?

Android - 如何根据 Android 版本使用不同的代码行