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