Hi All,
I am trying to make simple encoding application which takes yuv input and provides ".H264" output, using gstreamer APIs, which runs on AM572x evm. I just want to do a static file operation for now. Meaning, it takes "YUV" inputs from file and dumps "H264" output to another file.
I do not want to use gst-launch binary, and command line interface.
I want to make my own application, which uses gstreamer APIs and ducati plugin, so that we can also use the IVA co-processor capabilities. But, I am facing few issues in creating g-streamer pipeline and setting encoder properties.
Please find attached application code.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/time.h> #include <unistd.h> #include <gst/gst.h> #define ERR -1 #define SUCCESS 0 typedef struct pipeline_ele { int status; GstElement *pipeline; }pipeline_ele; void show_help(void) { printf("Application Usage: \n"); printf("./gsttestencoder -i <input filename> -o <output filename> \n"); printf("<input filename> = YUV format raw file \n"); printf("<output filename> = .H264 filename along with path \n"); } void src_pad_added_cb(GstElement *element, GstPad *pad, void *data) { GstElement *parse = GST_ELEMENT (data); GstPad *srcPad = NULL; char *thename = GST_PAD_NAME (pad); printf("pad added: %s\n", thename); srcPad = gst_element_get_static_pad(parse, "source"); gst_pad_link(pad, srcPad); gst_object_unref(srcPad); } pipeline_ele* create_pipeline(char *src_filename, char *dst_filename) { GstElement *source = NULL; GstElement *encode = NULL; GstElement *sink = NULL; GstCaps *encodeCaps = NULL; pipeline_ele *element = NULL; const char *enc_name; element = (pipeline_ele *)malloc(sizeof(pipeline_ele)); if(NULL == element) { printf("Can not allocate memory..\n"); return; } if((NULL == src_filename) || (NULL == dst_filename)) { printf("Invalid argument to create pipeline function\n"); element->status = ERR; return element; } enc_name = "ducatih264enc"; element->pipeline = gst_pipeline_new("encoding-pipeline"); source = gst_element_factory_make("filesrc", "source"); if(!source) { printf("Error in creating source element\n"); element->status = ERR; return element; } encode = gst_element_factory_make(enc_name, "encode"); if(!encode) { printf("Error in creating encoding element\n"); element->status = ERR; return element; } printf("Destination filename: %s\n", dst_filename); sink = gst_element_factory_make("filedst", "sink"); if(!sink) { printf("Error in creating sink element\n"); element->status = ERR; return element; } #if 0 sinkpad = gst_element_get_compatible_pad(); if(NULL == sinkpad) { printf("Unable to allocate sink pad\n"); } sinkCaps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "NV12", "width", G_TYPE_INT, "720", "height", G_TYPE_INT, "480", "framerate", GST_TYPE_FRACTION, "30", 1, NULL); if(NULL == sinkCaps) { printf("Set sink capabilities failed\n"); } #endif //g_object_set((G_OBJECT)sinkpad, "caps", sinkCaps, NULL); encodeCaps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "YUV2", "width", G_TYPE_INT, "1024", "height", G_TYPE_INT, "768", "stream-format", G_TYPE_STRING, "byte-stream", "alignment", G_TYPE_STRING, "au", "profile", G_TYPE_STRING, "baseline", NULL); if(NULL == encodeCaps) { printf("Unable to set encoder capabilities\n"); } /* setting parameters to encoder object */ g_object_set(G_OBJECT (encode), "caps", encodeCaps, NULL); g_object_set(G_OBJECT (source), "location", src_filename, NULL); g_object_set(G_OBJECT (sink), "location", dst_filename, NULL); gst_caps_unref (encodeCaps); #if 0 gst_bin_add_many(GST_BIN (element->pipeline), source, encode, sink, NULL); gst_element_link_many(source, NULL); gst_element_link_many(encode, sink, NULL); #endif #if 0 if(!g_signal_connect(encode, "pad-added", G_CALLBACK(sinkpad), (void *)encode)) { printf("Can not connect sink pad added\n"); } #endif if(!g_signal_connect(source, "pad-added", G_CALLBACK(src_pad_added_cb), (void *)encode)) { printf("Can not connect source pad added\n"); } element->status = SUCCESS; return element; } int main(int argc, char *argv []) { GstElement *p; pipeline_ele *pipe_element = NULL; pipe_element = (pipeline_ele *)malloc(sizeof(pipeline_ele)); if(NULL == pipe_element) { printf("Failed to allocate memory for pipeline structure\n"); return 1; } memset(pipe_element, 0x00, sizeof(pipeline_ele)); gst_init(&argc, &argv); //initialize g-streamer engine if((argc < 2) || (0 == strcmp(argv[1],"--help")) || (0 == strcmp(argv[1], "-h"))) { show_help(); return 1; } pipe_element = create_pipeline(argv[1], argv[2]); if(ERR == pipe_element->status) { printf("Gstreamer pipeline creation failed\n"); return 1; } gst_object_unref(pipe_element->pipeline); if(NULL != pipe_element) { free(pipe_element); pipe_element = NULL; } sleep(1); return 0; }
This code shows me error, while creating "sink" element.
It shows me error that "object class 'GstDucatiH264Enc' has no property named 'caps'". Please guide me on how I can set encoder properties with ducati plugin. Also guide me if, I have made any mistakes in pipeline creation.
Please help me on this.
Thanks,
Krinali Shah