Pages

Friday, December 17, 2010

Nature is beautiful

I finally learned how to take 'close-up' photos with my camera. I always wanted to take such photos but then dint know how to do that. How silly i was !! Sony W35 (and other similar cams) come with a feature called the 'Macro' mode which lets you point at some object and shoot it. You can shoot objects which are about 2mm away !!

Few images below, more to follow.


Friday, November 19, 2010

Scheduling torrent downloads using Vuze

In this post, let me explain how you can schedule your torrent downloads using torrent client called 'Vuze' formerly called as 'Azerus'. Most of us have broadband connections that allow free download during certain hours of the day. In my case, my BSNL broadband connection allows me free downloads between 2AM to 8AM. It was practically impossible for me to stay awake till 2 in the night and start the download. So when i searched the internet for clients that allow scheduling of downloads, i came across 'Vuze' along with speed scheduler.

1. Download and install the torrent client from http://www.vuze.com/. The installation is fairly easy and straight forward.

2. Start Vuze and select the 'Installation Wizard' from the 'Plugins' option in the 'Tools' menu as shown below.



3. In the dialog box that opens up, Choose 'By list from SourceForge.net'. Ensure that you are connected to the internet :). Click next.



4. Choose 'Speed Scheduler' from the options and then press 'Next' and then 'Finish'



5. The following dialog box will appear if the installation is complete properly.


6. You can find 'Speed Scheduler' in the 'Plugins' menu. Open it and you can schedule downloads as shown below.



The green tick indicates the schedule that is currently active.

Hope you guys find it useful and happy downloading :)

Sunday, November 7, 2010

Tomatoes

A dozen tomatoes on a wooden table gracefully illuminated by natural sunlight. Photo taken with my Sony Cybershot W35, One of my favorite pic

Monday, October 25, 2010

FPDF

This article explains how you can create pdf documents in PHP. While I searched google for 'php + pdf', I found so many libraries that one can use. The one that looked simple to use was FPDF.

All you need to do is copy the php files that come along with the FPDF download and paste them in your php 'include' folder and refer to the package in your code.

This is a simple example.

<?php
require('fpdf.php');

$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$pdf->Output();
?>

As shown in the example above, it is relatively simple to use the library. You can find the tutorials here.

You can create some complex pdfs such as the following,

A calender : Soruce Code Demo
A tree : Source Code Demo
Javascript support : Source Code Demo

You can find more such samples here. I hope you guys find it useful.

Sunday, October 10, 2010

Installing Ubuntu using Wubi

I have published this article today (10.10.10) to coincide with the release of 'Maverick Meerkat'

What do we normally do with PCs or laptops at home?

  • View Photos
  • Watch Movies
  • Listen to Music
  • Browse the Internet
  • Play Games
And in very rare cases, work with MS Office or do some random programming

The fact is, we dont need Windows Vista or Windows 7 to do the things mentioned above. Windows Vista/7 takes up a lot of RAM and is damn slow in starting up. And we invariably end of using a pirated version of windows which is always prone to virus attacks. For so many years I wanted to work with an linux operating system, but i was always scared of the installation process. I was scared that I might accidentally format one of my hard disks.

About an year ago, I got to know about Wubi from a colleague of mine. Wubi is nothing but an easy way to install Ubuntu on your personal computer. If you want to try out Ubuntu on your PC for a short period of time, Wubi is your best choice. Wubi installs Ubuntu on your PC as just another application on windows, but actually it installs an OS itself in your PC. That is how easy the whole installation is. Shown below is the snapshot of the installation screen.



It does look that simple, it really does. Choose any drive in your PC where you have sufficient amount of free space. I would suggest to choose 10GB as the installation size. Once you click on Install, it takes about 3-4 mts for Ubuntu to get installed. You need to reboot once and you will be shown with an option to load Ubuntu during the boot process. And thats it !! There you are, a new, stable and fast OS installed in your PC in absolutely no time.

It might take couple of days to get started with Ubuntu.You are not presented with the old problem of mounting the hard disks and USB drives of previous years. Everything is already done for you. The OS comes with pre-installed software that cover up all your basic needs.

Now, let us look at the pros and cons

Pros
  • Stable, Secure, Fast Operating system - you dont need to worry about virus attacks
  • No need to burn CDs. The iso is sufficient for the installation.
  • 100% Free
  • All basic software already installed
  • An alternate way to recover files if your Windows OS is infected by virus
  • Free upgrade of the OS available every 6 months.
  • Online repository of free software available.
  • Good forums available to answer all your queries and a very activity community.

Cons
  • Ubuntu installed using Wubi is not as fast as it can be. To get the full speed of an OS, you need to install it using the traditional procedure.
  • By default, Ubuntu does not support mp3 and other audio/video formats. This is done to avoid legal issues. To overcome this, you need to install VLC or install unrestricted-audio-packages from the online repository.
  • You might face some problems if you have graphic cards installed. This problem however has been fixed from Ubuntu 9.10 (Karmic Koala)
  • Few of your special keys in your keyboard might not work. For instance, your wifi-enable or bleutooth-enable key might not work on the keyboard. Workaround is to boot up the OS with those features already enabled.
If you guys face any problem in the installation or in using the OS, you can contact me at rmnforever@gmail.com or post your queries at Ubuntu forums

Saturday, September 25, 2010

FFMpeg - Using Libavcodec in your program


This will be my second post on ffmpeg. The first post was on building ffmpeg on windows using mingw.
In this post, we will see how you can use those libraries in your application and decode movie files. I am taking dranger's first tutorial as the source and I will build it using Visual C++ 6.0. You can find the source code here.

This post has been published in CodeProject.com. You can view it here. The Codeproject image appearing in this post will indicate that the articles are also present in CodeProject.

Explanation of the code

Opening the video file

// Register all formats and codecs
av_register_all();

// Open video file
if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
return -1; // Couldn't open file

// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return -1; // Couldn't find stream information

// Dump information about file onto standard error
dump_format(pFormatCtx, 0, argv[1], 0);

First, we initialize ffmpeg by calling 'av_register_all()' at the starting of the program. This registers all supported formats and codecs.
Next we open the video file using av_open_input_file(). The first parameter is the pointer to the 'AVFormatContext' which we will use in our program to refer to the video file. The second parameter is the name of the file to be opened. The last three parameters are for file format, buffer size, and format options. By setting it to NULL and 0, libavformat detects and fills values on it own.
We dump information about the input file using 'dump_format()'

Opening the decoder

videoStream=-1;
for(i=0; inb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
  videoStream=i;
  break;
}
if(videoStream==-1)
return -1;
pCodecCtx=pFormatCtx->streams[videoStream]->codec;

We loop through the list of streams present in the input file to locate the 'video' stream present in it. The file can typically contain one or more audio/video streams in it. Once a video stream is located, we extract the codec type of the video stream. This codec type will be used to initialize the decode as shown below. avcoded_find_decoder accepts the codec id (obtained from the video file) as input and returns a pointer of type 'AVCodec'. The codec is then open by making a call to 'avcodec_open()'

pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1;
}
if(avcodec_open(pCodecCtx, pCodec)<0)
return -1;

Allocating buffers for decoding

numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,  pCodecCtx->width, pCodecCtx->height);

This part of the code is fairly elementary. We calculate the size of the buffer required, allocate a temporary buffer using malloc

Decoding frames

i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
if(packet.stream_index==videoStream) {
  avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); 
  if(frameFinished) {
  img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
                (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
                pCodecCtx->height);

if(++i<=5)
  SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,
        i);
  }
}

Well, this is the part of the code that excites me the most, decoding the frames :) You read frames the file using av_read_frame. This function returns a non-zero positive value if the file has not reached its end. After receiving a packet, we first check if it is a video packet. We pass the CodecContext, Packet data and size as the input to the function. If decoding of the packet is successful, the 'pFrame' pointer points to decoded data. Success or failure of the decoding process is indicated by the 'frameFinished'. If it fails, the value will be '0'. We then convert the data from YUV to RBG format so that we can write to the file. I guess, by default, the decoded data is of type YUV.

Cleanup

av_free(buffer);
av_free(pFrameRGB);
av_free(pFrame);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);

This is the part of the code i normally hate. But any mistake in this part will result in memory leaks or run time exceptions. So we will release all the allocated buffers and frames using av_free(). We will also close the codecontext and file using avcodec_close() and av_close_input_file() respectively.

Steps to build the application
  1. Create a win32 console application using Visual C++. Let us name it 'ffmpeg'.
  2. Create a folder named 'Libraries' and copy the following library files (avcodec.lib, avformat.lib, avutil.lib) to that folder. 
  3. Add 'tutorial1.c' to the project.
  4. Open the 'Project Settings' dialog box and in the C++ tab, choose the 'Preprocessor' option. In the 'Additional Include Directories', add the folder where the ffmpeg header files are present. (ex: C:\ffmpeg) 
  5. Navigate to the 'Link' tab in the project settings dialog and choose 'Input' as category. Add the following libraries to the 'Object/Library modules' text box : avformat.lib avcodec.lib avutil.lib. Add 'libraries' to the 'Additional Library path' text box.
  6. Build the application and you should be able to build it without any problem.
I hope to write on more post on encoding data using FFmpeg. That will complete the cycle.

Sunday, September 12, 2010

Mr. Fern - Close up

This is my first post on photography. This photo was taken with a kodak digital camera. The photo came up better than I thought.



Friday, September 3, 2010

Windows service using C

For a very long time I did not know what a windows service was. When I came to what it was, I thought I had learnt something important far too late. As they say, 'It is better to be late then never at all' ;) For people who don't know what a service is, A service is a console application that runs in the background and performs tasks that don't require user interaction. The Windows NT/2000/XP operating systems offer special support for service programs. The installed services can be configured through the Services applet, available from the Control Panel in Windows NT or from Control Panel | Administrative Tools in Windows 2000/XP. Services can be configured to start automatically when operating system starts, so you dont have to start each of them manually after a system reboot

Writing a windows service and installing on windows was a lot easier than I thought. This blog will explain how to write a simple windows service using C and install it.

A window's service program contains 3 parts,
  1. Main function
  2. Windows Service's Main function
  3. Control Handler function

The main function does nothing but lists the services that this program contains.
The program contain any number of services, the list must be terminated with a NULL entry into the list.

The Window's Service main is the entry point for your service.  This function should accomplish 3 things. It must set the appropriate status of the service using SetServiceStatus. The argument to the function is a SERVICE_STATUS. This function should register the controlhandler function for this service. The functionality of the control handler will be explained below. And finally, this function should not exit. If it does, the service will move to a 'STOPPED' state in the services applet.An ideal way of implementing this is using a while loop which checks for the state of the service status variable. (shown below).

The control handler handles the request to the service such as stopping it. Stopping the service can be triggered from the services applet. All cleanup code that the service must execute while exiting must be written here.

Sample Program,  SampleWindowsService.cpp

#include
#define SLEEP_TIME 5000

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void  ServiceMain(int argc, char** argv);
void  ControlHandler(DWORD request);

void main()
{
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    // Start the control dispatcher thread for our service
    StartServiceCtrlDispatcher(ServiceTable); 
}

void ServiceMain(int argc, char** argv)
{
    int error;

    ServiceStatus.dwServiceType        = SERVICE_WIN32;
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted   =  SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint         = 0;
    ServiceStatus.dwWaitHint           = 0;

    hStatus = RegisterServiceCtrlHandler(
        "MemoryStatus",
        (LPHANDLER_FUNCTION)ControlHandler);


    if (hStatus == (SERVICE_STATUS_HANDLE)0)
    {
        // Registering Control Handler failed
        return;
    } 

    // We report the running status to SCM.
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus (hStatus, &ServiceStatus);

    MEMORYSTATUS memory;
    // The worker loop of a service
    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        Sleep(SLEEP_TIME);
    }
    return;
}

// Control handler function
void ControlHandler(DWORD request)
{
    switch(request)
    {
        case SERVICE_CONTROL_STOP:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
            SetServiceStatus (hStatus, &ServiceStatus);
            return;

        case SERVICE_CONTROL_SHUTDOWN:
            ServiceStatus.dwWin32ExitCode = 0;
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
            SetServiceStatus (hStatus, &ServiceStatus);
            return;
       
        default:
            break;
    }

    // Report current status
    SetServiceStatus (hStatus,  &ServiceStatus);

    return;
}

To install this service on your operating system, you'll need to use the SC.EXE executable, which comes with the Win32 Platform SDK tools. You will use this utility to install and remove the service. The other control operations will be done through the Services applet.
Here is the command-line to install your windows service:

sc create SampleWindowsService binpath= 
c:\MyServices\SampleWindowsService.exe
 
To remove the service from the system, execute the following command:

sc delete SampleWindowsService

Specify the delete option and the service name. The service will be marked for deletion and will be completely removed after the next restart.

Friday, August 20, 2010

TeamViewer - Remote Access to PCs

Now that we have friends and family geographically placed in different locations, there arises situation where you need to help some one with an installation or configure some software in the PC. Previous ways of doing it included sending mails with detailed steps and snapshots to do the job or guiding them over phone while they perform the job. This however does not work all the time. I started searching for software that would let me remotely access PCs and control them and I came across Team Viewer.

The software is relatively easy to install and use. I had no problems in the installation or the usage. There is very minimal latency involved while you remotely access the PC. It has few nice features such as chat & file transfer.

The entire steps involved are explained here.

Other software that you can use are GotoMeeting, GotoMyPC.  Teamviewer is totally free for non-commercial usage, which is good enough for us. There are trial versions available for GotoMeeting and GotoMyPC over a short period of time. Hope you guys find it useful !!

Friday, August 6, 2010

Googe Chart API

Recently I wanted to develop a tool that would show graphs on a web page. As I searched more and more, I began to understand that it was not easy as I though it would be.

I tried to display a bar chart using javascripts (cnxLABS). It worked fine, but then it was quite clumsy.
I stumbled upon JPGraph. These guys support so many different types of charts. Quite handy and easy to include it in your code. Rendering doesn't look sharp though.

PChart just looked cool on the site, but i was not able to include it in my project and run it. I just got too many errors. If any one out there was able to use it successfully in your project, please let me know :)



Finally, I decided to use Google Chart API. Simply awesome. Easy to include in your project and the rendering is just smooth and pleasing. The disadvantage, though, is you need to be connected to the internet to display charts in your web page. This will not be acceptable in certain cases. The Google Code Playground makes your easier in building charts. Most of the charts are interactive, which makes the experience better.




Sample code to display a pie chart

function drawVisualization() 
{
// Create and populate the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'Task');
data.addColumn('number', 'Hours per Day');
data.addRows(5);
data.setValue(0, 0, 'Work');
data.setValue(0, 1, 11);
data.setValue(1, 0, 'Eat');
data.setValue(1, 1, 2);
data.setValue(2, 0, 'Commute');
data.setValue(2, 1, 2);
data.setValue(3, 0, 'Watch TV');
data.setValue(3, 1, 2);
data.setValue(4, 0, 'Sleep');
data.setValue(4, 1, 7);

// Create and draw the visualization.
new google.visualization.PieChart(document.getElementById('visualization')).
draw(data, {title:"So, how was your day?"});
}

Happy Charting :)

Thursday, July 29, 2010

FFMpeg - Building on Windows

FFMpeg is probably the most widely used Encoder/Decoder library. It helps you when are working in a project that involves video processing. As with any open source project, it has very limited documentation. An article by by Martin Böhme (Using libavformat and libavcodec) and Stephen Dranger (FFmpeg and SDL Tutorial) were the only good articles available around. Apart from this, you might need to look into OutputExample.c that comes with the FFMpeg source code. I had a very hard time trying to learn from these tutorials and use 'libavcodec' library in my programs.This has been my prime motivating factor to start this blog.

The first thing about Open Source projects is, they dont distribute binaries. They distribute only the source code. So it makes your life harder to understand to download the source code, setup the build environment and then take a build. This process, though, is inevitable. If you really wish to skip the building process and get only a build, you can get them here. (P.S. these builds are outdated. If you plan to use it in your commercial application, you might need to search for an LGPL build. Else you will end up in FFMpeg's Hall of Shame)

Let's start with the build process. :)

Stuff to Download
  1. Download MinGW from here.
  2. Download MSYS from here.
  3. Download updated bash for MSYS from here.
  4. Get the latest snapshot of ffmpeg from here

Installing MinGW
  1. Click 'Next'
  2. Choose 'Download and Install' and click 'Next'
  3. Click 'I Agree'
  4. Choose 'Current' and then 'Next'
  5. Choose 'MinGW base tools' and 'MinGW Make'
  6. Choose Destination folder as 'C:\MinGW'
  7. Click 'Install'. The download will take some time and then will complete the installation.
  8. Click 'Next' and then 'Finish' to complete the installation.
Installing MinSys
  1. Click 'Yes'
  2. Click 'Next'
  3. Agree to the license agreement by clicking 'Yes'
  4. Click 'Next'
  5. Choose 'C:\msys\1.0' as destination folder and click 'Next'. Click 'Yes' to create a directory if not already there
  6. 'Installation for i386 based CPUs' should be selected, Click 'Next'
  7. Click 'Next' and then 'Install'
  8. The command window that opens will ask if you wish to continue with post install, type 'y'and press enter.
  9. Type 'y' and press enter when it asks if you have MinGW installed.
  10. Type 'C:/mingw' when it asks for your MinGW installation. (without quotes)
  11. Type 'y' when if it asks for adding mount bindings.
  12. Press enter and then Click 'Finish' to complete the installation.
Building FFMpeg
  1. Extract CoreUtils to a folder. Copy the contents in the extracted 'bin' folder to "C:\msys\1.0\bin"
  2. Extract the ffmpeg sources. I’ll assume you’ve extracted them to c:\work\ffmpeg .
  3. Open MSYS and navigate to C:\work\ffmpeg
  4. Type "./configure --enable-memalign-hack --enable-shared" and press Enter. --enable-memalign-hack is to specify that you need windows binaries and --enable-shared is to specify to build 'libavcodec.dll' and 'libavformat.dll'
  5. By default, it is an LGPL build. You need specify -enable-gpl. For more info on command line arguments, type ./configure --help
  6. Type 'make' and press 'Enter'
And there you have it, your ffmpeg binaries are ready to be used.

I have personally verified all the above mentioned steps, but then you may face problems during the whole process. The following links might of use in that case.

Installing MSYS
http://www.transana.org/developers/setup/AudioExtract/MSYS-Win.htm

Building ffmpeg on windows
http://www.gooli.org/blog/building-ffmpeg-for-windows-with-msys-and-mingw/
http://www.ffmpeg.org/general.html#SEC20

Building FFMpeg on linux is fairly easy. I have not tried building it on other platforms.

Wednesday, July 28, 2010

WAMP : Windows - Apache - MySQL - PHP


I have been using phptriad 2.2.1 on Windows for a very long time. It just made my work so easy. The combination of PHP, MySQL and Apache is extremely powerful when you need to quickly develop web pages.

Unfortunately, there were no newer versions of the triad available on the internet, and therefore I was not able to work with PHP5. As I searched for alternative solutions, I came across WAMP Server.

The WAMP Server looks a compact solution. The features (upgrade, opening up localhost, PHPMyAdmin) available in the System Tray menu make your life lot easier. For people who used the 'htdocs' folder to copy your PHP scripts, you must create a folder in the 'www' directory and paste your code in there.

Let us Explore

It was 10 years back that I wrote my first 'Hello World' program in C and the world of software programming has fascinated me ever since.

I have come across various software, open source tools, languages which I find useful in my day to day work. Few of those have been easy to learn and use, while others have not been easy. This blog is my effort to write a bit about the stuff that I learn. A good friend of mine recently said, 'Knowledge multiplies when shared'. Hope you guys find it useful too.

Cheers !!