1. 程式人生 > >gstreamer 1.0 初階

gstreamer 1.0 初階

# media framworks
opencore:
 begin with PacketVideo
 av sync with master clock
 sink-node
 parallel parser/decoder/sink
 dropped in android 2.3 (died)

stagefright:
 begin with android 2.1
 video sync with audio callback data's timestamp.
 callback and videoevent
 serial parser/decoder/sink

openMAX:
 begin with android 2.3
 fill buffer, empty buffer.

gstreamer:
 autoconnect pipeline components
 recognize input streams
 vaapisink get the raw yuv planes
 dmabuf
 use VPP for hwaccel transfers to dma_buf imported buffers


# gstreamer pipeline
pipeline > bin > element

data down:
gst_pad_push
gst_pad_pull_range

gst_buffer_new
gst_buffer_pool_acquire_buffer
buffer = {timestamp, offset, duration, metadata}

event up and down:

element states: NULL, READY, PAUSED, PLAYING

內部GST_MESSAGE_SEGMENT_DONE或pad連線後,設定GST_STATE_READY。
app設定NULL/PLAYING/PAUSED驅動pipeline。
只有preroll足夠資料後,才能從READY轉換到PAUSED,對於livesource例外。

construct pipeline:
gst_pipeline_new
READY_TO_PAUSED:
 gst_bin_add
 gst_pad_link

gst_pipeline_get_bus: src -- EOS -- sink -- EOS
gst_element_query: duration, total time.
gst_element_send_event
 sink -> SEEK --> FLUSH_START -> FLUSH -> SEGMENT, running_time = 0.

gst_pad_set_chain_function(audiosink)

gst-launch.c main -> gst_parse_launch (pipeline_string, &err);

# eg. overlay text on raw video
depends: freetype, harfbuzz/uniscribe/CoreText, cairo, pango (1999, Raph Levien -- Inconsolata).
videotestsrc ! video/x-raw,width=320,height=480,pixel-aspect-ratio=2/1 ! textoverlay text=Hello font-desc=72 ! xvimagesink
gst-launch \
    filesrc location=test.mpg \
      ! decodebin2 name=demuxer \
    demuxer. \
      ! textoverlay text=Hello \
      ! x264enc ! muxer. \
    demuxer. ! audioconvert ! vorbisenc ! muxer. \
    matro?skamux name=muxer \
      ! filesink location=output.mkv
vorbisenc to faac and matroskamux to mpegtsmux to get output.mpg
clockoverlay time-format="%H:%M:%S"
#changes the colors and adds scratches and dust
gst-launch-1.0 -m videotestsrc ! agingtv ! videoconvert ! autovideosink
gst-launch filesrc location=file.jpg ! jpegdec ! imagefreeze ! mfw_isink.

#debug output
in source code:
GST_DEBUG_CATEGORY (my_cat);
GST_DEBUG_CATEGORY_INIT (my_cat, "abcplugin", 0, "abcplugin");
GST_INFO(): 3 (NONE:0, ERROR:1, WARNING:2, DEBUG:4, LOG:5)

print <=3 of abcplugin, <=4 of yy prefix, <=2 of other plugins:
GST_DEBUG=2,abcplugin:3,yy*:4

# dump pipeline

in gst-launch:
export GST_DEBUG_DUMP_DOT_DIR=.
gst-launch audiotestsrc num-buffers=1000 ! fakesink sync=false

in source code:
compile without GST_DISABLE_GST_DEBUG
export GST_DEBUG_DUMP_DOT_DIR=.

GST_DEBUG_BIN_TO_DOT_FILE_TS(pipeline, GST_DEBUG_GRAPH_SHOW_ALL, "myout");

# write plugin
巨集GST_PLUGIN_DEFINE用於定義一個plugin的入口點plugin_init和元資料。同時,它用於輸出(export)一個plugin,這樣它就就可以被其他應用程式使用。
例如:

static void init(void){
 gst_element_register(plugin, feature1_name);
}

GST_PLUGIN_DEFINE (
 GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    name,
    "my plugin description",

    init,
    VERSION,
    GST_LICENSE,
    GST_PACKAGE_NAME,
    GST_PACKAGE_ORIGIN)

GST_PLUGIN_DEFINE 根據GST_PLUGIN_BUILD_STATIC展開為靜態形式:
void gst_plugin_name_register(void){
 gst_plugin_register_static(name, init);
}

或動態庫形式(*.so):
GstPluginDesc gst_plugin_desc = {##name, init};

gst_registry_get()返回全域性變數_gst_registry_default,init_post註冊內建元件以及載入標準plugins(外掛)。

gst_init -> gst_init_check -> init_post
 gst_object_get_type
 gst_element_get_type
 gst_bus_get_type
 gst_update_registry -> load_plugin_func

load_plugin_func(filename)
 gst_plugin_load_file
 gst_registry_add_plugin (gst_registry_get(), plugin)

gst_plugin_load_file(filename) -> _priv_gst_plugin_load_file_for_registry:
 module = g_module_open (GST_PLUGIN_PATH##filename, G_MODULE_BIND_LOCAL);
 g_module_symbol (module, "gst_plugin_desc", &ptr);
 desc = (GstPluginDesc *) ptr;
 GstPlugin *plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
 return plugin;

gst_registry_add_plugin(registry, plugin):
 registry->priv->plugins = g_list_prepend (registry->priv->plugins, plugin);
 g_signal_emit (registry, gst_registry_signals[PLUGIN_ADDED], 0, plugin);
 gst_plugin_register_func -> init

gst_plugin_register_static
 GstPlugin *plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
 gst_plugin_register_func -> init


# GLib Dynamic Type System
dynamic type system:  query for object metadata at runtime.
GTypeInfo:{base, class, instance, value_table}
constructor: base --> class --> instance
copy operatortor: value_table
destructor: dispose refs/finalize free: instance -> class -> base.

# G_DEFINE_TYPE(TN, t_n, T_P) 展開

static void t_n_class_init(TNClass *kclass);
static void t_n_init(TN *self);
static gpointer t_n_parent_class = NULL; //quizz: why need this?
Gtype t_n_get_type(void)
{
 static GType type = 0;
 if(type == 0){
  type = g_type_register_static_simple(T_P, "TN",
   sizeof(TNClass), t_n_class_init,
   sizeof(TN), t_n_init, 0);
 }
 return type;
}


/////////////property/////////////
繼承關係:
element <- GST_TYPE_OBJECT <- gobject: G_TYPE_INITIALLY_UNOWNED=g_initially_unowned_get_type()

static void t_n_class_init(TNClass *kclass)
{
 GObjectClass *object_class = G_OBJECT_CLASS (klass);
 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
 object_class->set_property = set_property; //overwrite default
 object_class->get_property = get_property;
 //object_class->dispose(GObject *gobject);
 //object_class->finalize(GObject *gobject);
 

 pspec_add = g_param_spec_uint64 ("add", "Add", "Number of added samples",
      0, 4, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 g_object_class_install_property (object_class, PROP_ADD, pspec_add);

 element_class->change_state = change_state;
}

static void gst_audio_rate_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
 GstAudioRate *audiorate = GST_AUDIO_RATE (object);
 if(PROP_ADD == prop_id){
  
 }
}

static void change_state (GstElement * element, GstStateChange transition)
{
 GstAudioRate *audiorate = GST_AUDIO_RATE (element);
 if(GST_STATE_CHANGE_PAUSED_TO_READY == transition){
  //
 }
 return GST_ELEMENT_CLASS (t_n_parent_class)->change_state(element, transition);
}

g_signal_connect callback to events.

affect auto-plugger:
gst_plugin_feature_set_rank
 GST_RANK_PRIMARY+1 -- enable
 GST_RANK_NONE -- disable using this plugin

Static linking with re-locatable archives: -DPIC and -fPIC
 libgstreamer_android.so --whole-archive


# todo
gst_type_find_helper_get_range

/*
apt-get install libgstreamer1.0-dev libgstreamer-plugins-good1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev

gcc gst-hello.c -g $(pkg-config --cflags --libs  gstreamer-1.0)

GST_DEBUG="*:3" ./a.out

gst-inspect-1.0
 ...
 Total count: 196 plugins, 666 features

grep -nr 'gst_element_register' --include=*.c ./

gst-launch-1.0 playbin uri=file://$(pwd)/file.ogg

  gst-launch-1.0 filesrc location=file.ogg ! decodebin ! tee name=d  \
  d. ! queue ! audioconvert ! audioresample ! autoaudiosink \
  d. ! queue ! audioconvert ! monoscope ! videoconvert ! ximagesink \
  d. ! queue ! goom ! videoconvert ! xvimagesink

transcode:
gst-launch-1.0 filesrc location=out0.mp4 ! decodebin name=dmux ! queue ! audioconvert ! lamemp3enc ! filesink location=out.mp3

gst-launch-1.0 filesrc location=out0.mp4 ! decodebin name=dmux ! queue ! audioconvert ! lamemp3enc ! mux. dmux. ! queue ! x264enc ! mpegtsmux name=mux ! queue ! filesink location=out.ts

“! mux.” means link to mpegtsmux
lamemp3enc 需要安裝 gstreamer1.0-plugins-ugly
h264 需要安裝 gstreamer1.0-libav
轉碼後是h264+mp3,檔案大小是原來的8倍!播放時發現視訊dts < pts。
對比ffmpeg轉碼為mpeg2+mp2, 檔案大小是原來的3倍。

 gst-launch-1.0 -v audiotestsrc ! goom ! videoconvert ! xvimagesink
 v4l2src

#ref
http://wiki.oz9aec.net/index.php/Gstreamer_cheat_sheet
http://gstreamer.freedesktop.org/documentation/

*/

#include <gst/gst.h>
  
int main(int argc, char *argv[]) {
  GstElement *pipeline;
  GstBus *bus;
  GstMessage *msg;
  
  /* Initialize GStreamer */
  gst_init (&argc, &argv);
  
  /* Build the pipeline */
  pipeline = gst_parse_launch ("playbin uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
  if(!pipeline){	
	return -1;
  }
  
  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  
  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  
  /* Free resources */
  if (msg != NULL)
    gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}

相關推薦

gstreamer 1.0

# media framworks opencore:  begin with PacketVideo  av sync with master clock  sink-node  parallel parser/decoder/sink  dropped in andr

qt5.7交叉編譯gstreamer-1.0

一、交叉編譯glib 1.提前需先交叉編譯libffi CC=/home/mjl/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc ./configure --prefix=/home/mjl/buil

【英語】第1月回顧

總結 國外 除了 拓展 gpo 快速 在一起 時也 目標 回顧 四級真題做了一篇,單詞過完了四級,六級過完1/3,聽力無,閱讀幾篇新聞。 結果和改進 百詞斬背單詞挺傻的,當然過一遍混個眼熟也無所謂,不能指望真背完了能用起來 之前幾乎每天倆小時地用百詞斬背單詞,四級復習45

SQL 築基 1

1   返回每個產品相關的賬號數量 Select product_id,count(*) as accounts_per_product from Contacts Group by product_id; 注 : 這裡引出了一個小問題: SELECT C

Vue2.0元件篇1 教你秒擼(簡訊倒計時元件)

原本我想隔個幾天再發文章,剛好今天專案上線,環境有問題,導致只有乾等,剛好要為公司打造一套屬於公司自己的一系列功能元件,這個使命就交給我了,大家也一直叫我來點乾貨,說實話我只是一個溼貨,肚子裡幹一點就給你們出點貨,那從今天開始不看島國片系列教程視訊,不但自擼,還教你擼..

[Python接觸]Windows10-32bit+Python2.7.12+OpenCV3.1.0配置

       筆者在Windows10-64bit + Python2.7.12 + OpenCV3.1.0配置上進行了配置,併成功了。現在,筆者拎起另一臺電腦進行配置,並記錄如下,望共勉。    

Spark2.1.0——Spark體驗

      學習一個工具的最好途徑,就是使用它。這就好比《極品飛車》玩得好的同學,未必真的會開車,要學習車的駕駛技能,就必須用手觸控方向盤、用腳感受剎車與油門的力道。在IT領域,在深入瞭解一個系統的原理、實現細節之前,應當先準備好它的執行環境或者原始碼閱讀環境。如果能在實際環境下安裝和執行Spark,顯然能夠

【 D3.js 進系列 — 1.0 】 CSV 表格檔案的讀取

在入門系列的教程中,我們常用 d3.json() 函式來讀取 json 格式的檔案。json 格式很強大,但對於普通使用者可能不太適合,普通使用者更喜歡的是用 Microsoft Excel 或 OpenOffice Calc 等生成的表格檔案,因為簡單易懂,容易編輯。

Bean Query 第一個版本號(1.0.0)已公布

tid artifact con blog sdn tail ont tails map BeanQuery 是一個把對象轉換為Map的Java工具庫。支持選擇Bean中的一些屬性。對結果進行排序和依照條件查詢。不只能夠作用於頂層對象,也能夠作用於子對象。很多其它具體

購物系統1.0

enc break 存在 efault close def art default while #!/usr/bin/python #-*- coding:utf-8 -*- import sys #讀取商品列表 goods_list = open(‘商品列表.txt‘

Oracle 12.1.0.2 對JSON的支持

使用 lin 1.5 text lob mysq 索引 acl var Oracle 12.1.0.2版本有一個新功能就是可以存儲、查詢、索引JSON數據格式,而且也實現了使用SQL語句來解析JSON,非常方便。JSON數據在數據庫中以VARCHAR2, CLOB或者BLO

HTTP/1.0+ "keep-alive" 連接

通過 保持 就會 無法 首部 報文 response line -a 一、keep-alive 連接 (1) 我們在使用串行連接的時候,比如加載四張圖片,當加載第一張圖片時,會建立連接,加載完後會關閉連接,加載第二張圖片時同樣會先建立連接再關閉連接,以此類推,這樣就會消耗

1+1=0.5的姿勢困局!誰讓美麗蘑菇的合並泛起泡沫

人民網 互聯網 淘寶 觀察者 探路者 自從2016年1月,美麗說、蘑菇街正式合並以來,裁員風聲就沒斷過。但這並不重要。重要的是,較之其他如滴滴快的、新美大之類的同領域執牛耳者的合並,不再火並。合並後的美麗說、蘑菇街只能用慘淡來形容。從合並前2015年兩家交易額合計近200億元,到2016年

ubuntu14.04 + GTX980ti + cuda 8.0 ---Opencv3.1.0配置

install release err idt rim cut fix module b- 狂踩坑,腦袋疼。 流程: 1.逛網下載opencv source Opencv3.1.0 zip 2.unzip解壓 3.安裝一堆先決必要的環境: sudo apt-get i

debian下 Hadoop 1.0.4 集群配置及運行WordCount

速度 虛擬 裏的 否則 ado 修改 安裝包 name 節點 說明:我用的是壓縮包安裝,不是安裝包 官網安裝說明:http://hadoop.apache.org/docs/r1.1.2/cluster_setup.html,繁冗,看的眼花...大部分人應該都不是按照這個來

基於 Web 的 Go 語言 IDE - Wide 1.1.0 公布!

tab targe wide 我們 編輯 gist rtc 編譯 all 公布 1.1.0這個版本號改進了非常多細節,已經全然能夠用於正式項目的開發同一時候我們上線了 Wide 在線服務到眼下,我們提供了 Wide 和 Solo 兩個在線服務,詳情請看這裏。Wide 是什

fsockopen與HTTP 1.1/HTTP 1.0

fwrite 詳細 odi com 詳細介紹 區別 connect func 阻塞 在前面的例子中,HTTP請求信息頭有些指定了 HTTP 1.1,有些指定了 HTTP/1.0,有些又沒有指定,那麽他們之間有什麽區別呢? 關於HTTP 1.1與HTTP 1.0的一些基本情況

tensorflow 1.0 學習:參數初始化(initializer)

正交矩陣 算子 smi esc one tor pytho ops ride CNN中最重要的就是參數了,包括W,b。 我們訓練CNN的最終目的就是得到最好的參數,使得目標函數取得最小值。參數的初始化也同樣重要,因此微調受到很多人的重視,那麽tf提供了哪些初始化參數的方法呢

tensorflow 1.0 學習:模型的保存與恢復(Saver)

clas truncated 中間變量 lac tdd mini b- oat utf-8 將訓練好的模型參數保存起來,以便以後進行驗證或測試,這是我們經常要做的事情。tf裏面提供模型保存的是tf.train.Saver()模塊。 模型保存,先要創建一個Saver對象:如

tensorflow 1.0 學習:用別人訓練好的模型來進行圖像分類

ima ppi gin 什麽 dir targe spl flow blog 谷歌在大型圖像數據庫ImageNet上訓練好了一個Inception-v3模型,這個模型我們可以直接用來進來圖像分類。 下載地址:https://storage.googleapis.com/d