Saturday, July 21, 2012

Video Player Using Qt Embedded

Cross compiling Qt Embedded:

Buildroot provide the easiest way to cross compile Qt Embedded for arm platform. Buildroot can be downloaded here.

configure buildroot to cross compile the Qt for arm platform, make sure to enable this in .config file of buildroot

BR2_arm=y
BR2_generic_arm=y
BR2_ARM_TYPE="GENERIC_ARM"
BR2_ARM_EABI=y
BR2_ARCH="arm"
BR2_ENDIAN="LITTLE"
BR2_GCC_TARGET_ABI="aapcs-linux"

Dependency packages for creating video player,

  • Qt.
  • Phonon packages.
  • gstreamer packages.


Modifications to be done on .conf files of Qt package:-

Modify qws.conf  file content like,

 QT                     += core gui network phonon

qws.conf file path  "/home/hussain/buildroot-2012.05/output/build/qt-4.8.2/mkspecs/common"

Modify  linux.conf file content like,

QMAKE_INCDIR_QT       = /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/include
QMAKE_LIBDIR_QT       = /home/hussain/buildroot-2012.05/output/target/usr/lib
QMAKE_MOC             = /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/bin/moc
QMAKE_UIC             = /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/bin/uic

linux.conf file path  "/home/hussain/buildroot-2012.05/output/build/qt-4.8.2/mkspecs/common"

Compilation steps:-

  •  /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/bin/qmake -project
  •  /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/bin/qmake -spec /home/hussain/buildroot-2012.05/output/build/qt-4.8.2/mkspecs/qws/linux-arm-g++ -r
  • make
  • ./media_player <path of videos folder>  -qws
source can be downloaded from here.









Thursday, March 29, 2012

Gdb remote debugging

Gdb remote debugging :  

Gdb cross compilation: 

Gdb source can be download from here 
extract the source,
   $ tar -xvf gdb-7.4.tar.gz
enter into the gdbserver folder,
   $ cd gdb-7.4/gdb/gdbserver
cross compiling the gdbserver, make sure that arm toolchain should be in binany path.
   $ CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-linux
    $ make
copy the gdbserver binary to the target machine.
   

Cross compiling the application:


   $ arm-none-linux-gnueabi-gcc -g test.c -o test
transfer the binary to the target machine

Running gdb server in target:


   # gdbserver :2345 ./test
output is like,
     Process ./test created, pid = 57
     Listening on port 2345

Running gdb in host machine:

   $ arm-none-linux-gnueabi-gdb ./test
after gdt prompt appers, 
   (gdb) set sysroot /path/to/rootfs
   (gdb) set solib-search-path /path/to/arm/toolchain/lib
example toolchain path is like,
"/home/abdul/em_linux/arm-2011.09/arm-none-linux-gnueabi/libc/lib"
   (gdb) target remote 192.168.1.2:2345
replace the ipaddress with target ipaddress
   (gdb) b main
 after this we can step through and debug the application in remote machine.

Tuesday, February 14, 2012

command line mp3 player using gstreamer

Gstreamer is an opensource multimedia framework which is widely using in various multimedia application.
It comes with bunch of codes, mux , demux etc.,
Below diagram shows how to build the pipeline using variuos plugins(in our case pipeline built for mp3 audio playing)

 
Compilation steps :

gcc player.c -o player $(pkg-config --cflags --libs gstreamer-0.10)

Run command:

./player <folder containing mp3 files>

 source code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <gst/gst.h>
#include <glib.h>
#include <pthread.h>

int flag=TRUE;

void play(char *song);
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data);

static gboolean
cb_print_position (GstElement *pipeline);

int check_mp3(char *name)
{
    char buf[4];
    int i;

    while(*name != '\0')
        name++;
    name = name - 3;
    for(i=0;i<3;i++){
        buf[i] = *name;
        name++;
    }
    buf[i]='\0';
    return strcmp(buf,"mp3");
}

int main(int argc,char *argv[])
{
    DIR *dir;
    struct dirent *dent;
    char buf[PATH_MAX];

    if(argc != 2)
    {
        printf("Usage: ./player <mp3_songs_folder>\n");
        exit(EXIT_FAILURE);
    }
   
    if(!(dir = opendir(argv[1])))
    {
        perror("opendir()");
        exit(EXIT_FAILURE);
    }

    while((dent = readdir(dir)))
    {
        if(!check_mp3(dent->d_name)){
            snprintf(buf,PATH_MAX,"%s/%s",argv[1],dent->d_name);
            g_print("Playing :- %s\n",dent->d_name);
            play(buf);
           
        }
    }
    return 0;
}

static gboolean
cb_print_position (GstElement *pipeline)
{
    GstFormat fmt = GST_FORMAT_TIME;
    gint64 pos, len;

    if (gst_element_query_position (pipeline, &fmt, &pos)
        && gst_element_query_duration (pipeline, &fmt, &len)) {
        g_print ("Time: %lld,%lld\r",
             (long long int) pos,(long long int)len);
    }

    if(flag == TRUE)
        return TRUE;
    else
    {
        flag = TRUE;
        return FALSE;
    }
}


void play(char *song)
{
    GMainLoop *loop;
    GstElement *pipeline,*filesrc,*mad,*audioconvert,*autoaudiosink;
    GstBus *bus;
   
    gst_init(NULL,NULL);
    loop = g_main_loop_new(NULL,FALSE);
   
    pipeline = gst_pipeline_new("mp3_player");
   
    filesrc = gst_element_factory_make("filesrc","filesrc");
    mad = gst_element_factory_make("mad","mad");
    audioconvert  = gst_element_factory_make("audioconvert","audioconvert");
    autoaudiosink = gst_element_factory_make("autoaudiosink","autoaudiosink");

    g_object_set(G_OBJECT(filesrc),"location",song,NULL);
   
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    gst_bin_add_many(GST_BIN(pipeline),filesrc,mad,audioconvert,autoaudiosink,NULL);
    gst_element_link_many(filesrc,mad,audioconvert,autoaudiosink,NULL);
   
    gst_element_set_state(pipeline,GST_STATE_PLAYING);
   
    g_timeout_add (200, (GSourceFunc) cb_print_position, pipeline);
    g_main_loop_run(loop);
    gst_element_set_state(pipeline,GST_STATE_NULL);
    gst_object_unref(pipeline);
}

static gboolean bus_call(GstBus *bus,GstMessage *msg,gpointer data)
{
    GMainLoop *loop = (GMainLoop *) data;

    switch (GST_MESSAGE_TYPE (msg)) {

    case GST_MESSAGE_EOS:
        g_print ("\nEnd of stream\n");
        g_main_loop_quit (loop);
        flag=FALSE;
        break;

    case GST_MESSAGE_ERROR: {
        gchar  *debug;
        GError *error;

        gst_message_parse_error (msg, &error, &debug);
        g_free (debug);

        g_printerr ("Error: %s\n", error->message);
        g_error_free (error);

        g_main_loop_quit (loop);
        break;
    }
    default:
        break;
    }

    return TRUE;
}