Changeset View
Changeset View
Standalone View
Standalone View
plugins/dockers/recorder/encoder.cpp
- This file was added.
| 1 | #include "encoder.h" | ||||
|---|---|---|---|---|---|
| 2 | #include <QDebug> | ||||
| 3 | | ||||
| 4 | void Encoder::init(const char* filename, int width, int height) | ||||
| 5 | { | ||||
| 6 | GstStateChangeReturn state_ret; | ||||
| 7 | gst_init(NULL, NULL); | ||||
| 8 | | ||||
| 9 | m_width = width; | ||||
| 10 | m_height = height; | ||||
| 11 | | ||||
| 12 | m_pipeline = (GstPipeline*)gst_pipeline_new("mypipeline"); | ||||
| 13 | m_src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc"); | ||||
| 14 | m_filter1 = gst_element_factory_make ("capsfilter", "myfilter1"); | ||||
| 15 | m_videoconvert = gst_element_factory_make ("videoconvert", "vc"); | ||||
| 16 | m_encoder = gst_element_factory_make ("vp9enc", "my9enc"); | ||||
| 17 | m_queue = gst_element_factory_make("queue", "qu"); | ||||
| 18 | m_webmmux = gst_element_factory_make("webmmux", "mymux"); | ||||
| 19 | m_sink = gst_element_factory_make ("filesink" , NULL); | ||||
| 20 | m_timestamp = 0; | ||||
| 21 | if( !m_pipeline || | ||||
| 22 | !m_src || !m_filter1 || | ||||
| 23 | !m_encoder || /*!m_videoconvert ||*/ !m_webmmux || /*!m_queue ||*/ | ||||
| 24 | !m_sink ) { | ||||
| 25 | printf("Error creating pipeline elements!\n"); | ||||
| 26 | exit(2); | ||||
| 27 | } | ||||
| 28 | | ||||
| 29 | gst_bin_add_many( | ||||
| 30 | GST_BIN(m_pipeline), | ||||
| 31 | (GstElement*)m_src, | ||||
| 32 | m_filter1, | ||||
| 33 | m_videoconvert, | ||||
| 34 | m_encoder, | ||||
| 35 | m_queue, | ||||
| 36 | m_webmmux, | ||||
| 37 | m_sink, | ||||
| 38 | NULL); | ||||
| 39 | | ||||
| 40 | qDebug() << "width " << m_width << " height " << m_height; | ||||
| 41 | | ||||
| 42 | g_object_set (m_src, "format", GST_FORMAT_TIME, NULL); | ||||
| 43 | g_object_set( m_src, "is-live", true, NULL); | ||||
| 44 | GstCaps *filtercaps1 = gst_caps_new_simple ("video/x-raw", | ||||
| 45 | "format", G_TYPE_STRING, "RGBA", | ||||
| 46 | "width", G_TYPE_INT, m_width, | ||||
| 47 | "height", G_TYPE_INT, m_height, | ||||
| 48 | "framerate", GST_TYPE_FRACTION, 4, 1, | ||||
| 49 | NULL); | ||||
| 50 | g_object_set (G_OBJECT (m_filter1), "caps", filtercaps1, NULL); | ||||
| 51 | g_object_set (G_OBJECT (m_sink), "location", filename, NULL); | ||||
| 52 | | ||||
| 53 | g_assert( gst_element_link_many( | ||||
| 54 | (GstElement*)m_src, | ||||
| 55 | m_filter1, | ||||
| 56 | m_videoconvert, | ||||
| 57 | m_encoder, | ||||
| 58 | m_queue, | ||||
| 59 | m_webmmux, | ||||
| 60 | m_sink, | ||||
| 61 | NULL ) ); | ||||
| 62 | | ||||
| 63 | state_ret = gst_element_set_state((GstElement*)m_pipeline, GST_STATE_PLAYING); | ||||
| 64 | g_assert(state_ret == GST_STATE_CHANGE_ASYNC); | ||||
| 65 | } | ||||
| 66 | | ||||
| 67 | void Encoder::pushFrame(gpointer data, gsize size) | ||||
| 68 | { | ||||
| 69 | GstBuffer *buffer = gst_buffer_new_wrapped(data, size); //Actual databuffer | ||||
| 70 | GstFlowReturn ret; //Return value | ||||
| 71 | //Set frame timestamp | ||||
| 72 | GST_BUFFER_PTS (buffer) = m_timestamp; | ||||
| 73 | GST_BUFFER_DTS (buffer) = m_timestamp; | ||||
| 74 | GST_BUFFER_DURATION (buffer) = gst_util_uint64_scale_int ( GST_SECOND, 1,4); | ||||
| 75 | m_timestamp += GST_BUFFER_DURATION (buffer); | ||||
| 76 | ret = gst_app_src_push_buffer( m_src, buffer); //Push data into pipeline | ||||
| 77 | | ||||
| 78 | g_assert(ret == GST_FLOW_OK); | ||||
| 79 | qDebug() << "push frame"; | ||||
| 80 | } | ||||
| 81 | | ||||
| 82 | void Encoder::finish() | ||||
| 83 | { | ||||
| 84 | qDebug() << "finishe called"; | ||||
| 85 | //Declare end of stream | ||||
| 86 | gst_app_src_end_of_stream (GST_APP_SRC (m_src)); | ||||
| 87 | // Wait for EOS message | ||||
| 88 | GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(m_pipeline)); | ||||
| 89 | gst_bus_poll(bus, GST_MESSAGE_EOS, GST_CLOCK_TIME_NONE); | ||||
| 90 | | ||||
| 91 | qDebug() << "finished"; | ||||
| 92 | } | ||||
| 93 | No newline at end of file | ||||