最近看了下在android下使用gstplayer的一些代码, 还存在着一些疑问需要以后去证实。
在MediaPlayerService createPlayer创建GstPlayer的时候过程如下:
GstPlayer::GstPlayer() { //call by factory or mediaplayerservice. mDataSourcePath = NULL; mGstPlayerPipeline = new GstPlayerPipeline(this); if (mGstPlayerPipeline != NULL) { mInit = OK; } else { mInit = NO_INIT; } mIsDataSourceSet = false; mDuration = -1; mSurface = NULL; GST_PLAYER_LOG ("Leave\n"); }
这里的GstPlayerPipeline 并不是由gstreamer的库函数 gst_pipeline_new("pipeline"); 返回的pipeline。 这个对象定义在GstPlayerPipleline.cpp中。 实际上GstPlayer的所有操作都有GstPlayerPipeline来实现, GstPlayer只是实现了PlayerInterface的接口。 这里面有些疑问是:
MediaPlayerService中setAudioStreamType指出如果使用硬件解码的话, 需要调用硬件的相关方法来实现setAudioStreamType. 但是GstPlayer中:
status_t GstPlayer::setAudioStreamType(int type) { mStreamType = type; return OK; }
只是简单的保存了相应的变量, mStreamType在其他地方并没有使用。 而MediaPlayerService中也只是在软解码的时候调用设置了mAudioOutput的stream type:
if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
这会不会是声音切换总是很慢的原因呢?需要继续看代码去证实。
下面看下如何在android中使用gstreamer
GstPlayerPipeline::GstPlayerPipeline(GstPlayer* gstPlayer)跟惯例一样对变量进行下初始化需要注意的几个地方是:
sem_init(&sem_eos, 0, 0); init_gst(); create_pipeline();
sem_init初始化信号量这个是linux/unix系统函数, init_gst初始化gst framework, create_pipeline创建管道。
init_gst的代码如下:
static gboolean init_gst() { //根据gst_inited变量判断framework是否已经初始化过了. if (!gst_inited) { char * argv[2]; char**argv2; int argc = 0; //多线程环境下需要调用此函数, 来是gstreamer支持多线成。 if (!g_thread_supported ()) g_thread_init (NULL); //从配置文件中读取配置 get_gst_env_from_conf(); argv2 = argv; argv[0] = "GstPlayer"; argv[1] = NULL; argc++; //gststreamer使用的惯例, 先调用gst_init来初始化gstreamer framework. gst_init(&argc, &argv2); gst_inited = TRUE; } else { GST_PLAYER_LOG ("Gst has been initialized\n"); } return TRUE; }
create_pipeline创建用于媒体播放的管道:
bool GstPlayerPipeline::create_pipeline () { GstBus *bus = NULL; mPlayBin = gst_element_factory_make ("playbin2", NULL); if(mPlayBin == NULL) { GST_PLAYER_ERROR("Failed to create playbin2\n"); goto ERROR; } // add watch message mMainLoop = g_main_loop_new (NULL, FALSE); if (mMainLoop == NULL) { GST_PLAYER_ERROR ("Failed to create MainLoop.\n"); goto ERROR; } bus = gst_pipeline_get_bus (GST_PIPELINE (mPlayBin)); g_assert (bus); gst_bus_add_watch (bus, bus_callback, this); gst_object_unref (bus); // start a thread to run main loop mBusMessageThread = g_thread_create ((GThreadFunc)g_main_loop_run, mMainLoop, TRUE, NULL); if (mBusMessageThread == NULL) { GST_PLAYER_ERROR ("Failed to create Bus Message Thread.\n"); goto ERROR; } // create audio & video sink elements for playbin2 mAudioSink = gst_element_factory_make("audioflingersink", NULL); //mAudioSink = gst_element_factory_make("fakesink", NULL); if (mAudioSink == NULL) { GST_PLAYER_ERROR ("Failed to create audioflingersink\n"); goto ERROR; } g_object_set (mPlayBin, "audio-sink", mAudioSink, NULL); mVideoSink = gst_element_factory_make("surfaceflingersink", NULL); if (mVideoSink == NULL) { GST_PLAYER_ERROR ("Failed to create surfaceflingersink\n"); goto ERROR; } g_object_set (mPlayBin, "video-sink", mVideoSink, NULL); return true; ERROR: GST_PLAYER_ERROR ("Pipeline is created failed\n"); // release resource return false; }
这个过程注册了 bus_callback, 用于framework的回调。 另外这里创建的mAudioSink和mVideoSink并不会被使用, 真正用到的mAudioSink和mVideoSink是由setAudioSink和setVideoSurface来定义的。
使用gstreamer的时候, 只需要设置下pipeline的状态就可以实现播放暂停等功能:
stop: gst_element_set_state (mPlayBin, GST_STATE_READY);
play: gst_element_set_state (mPlayBin, GST_STATE_PLAYING);
原文链接: https://www.cnblogs.com/wanzhongwuyi/archive/2010/12/26/1917109.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/19296
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!