<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>JBCobb.net</title>
	<atom:link href="http://jbcobb.net/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://jbcobb.net</link>
	<description>Free software, the blues and life in the big city.</description>
	<pubDate>Sun, 15 Aug 2010 02:40:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.1</generator>
	<language>en</language>
			<item>
		<title>Of stupid moves that will lead to a better system, libfoundation and more&#8230;</title>
		<link>http://jbcobb.net/?p=497</link>
		<comments>http://jbcobb.net/?p=497#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:06:25 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[DVD Metabase]]></category>

		<category><![CDATA[EZRip]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[VOD]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=497</guid>
		<description><![CDATA[Greetings all. This is just a short update. I had intended to have more of the libfoundation stuff done when disaster struck. This disaster came in the form of administering one of our NAS units which served 2 terabytes of movies, documentaries, music and more. Our NAS units (the US Robotics 2TB modules; these things [...]]]></description>
			<content:encoded><![CDATA[<p>Greetings all. This is just a short update. I had intended to have more of the libfoundation stuff done when disaster struck. This disaster came in the form of administering one of our NAS units which served 2 terabytes of movies, documentaries, music and more. Our NAS units (the US Robotics 2TB modules; these things are rocks) allow access to them only by IP/hostname/MAC address combinations. The NAS that had been online the longest (6 years not counting a week in 2007 moving from Ventura to San Francisco and about 48 hours moving from there to here (Las Vegas)) had collected addresses from machines long-dead&#8230;<span id="more-497"></span>So one day after work I was way over-tired and instead of deleting an old user, I deleted the main share. D&#8217;oh.  Thus the deal now and has been for over a month that I have had every spare moment wrapped up in running 6 machines to re-rip the contents of the entire drive. As of this writing, I am about 45 percent done. This is taking a while because we realized that we did not have nearly as many discs in the database for DVD Metabase to help much with the task so now I have three machines going constantly scanning the discs, pain-stakingly labeling each track and submitting them to the database, then I have three more machines in the server room doing the actual transcoding and repopulating the NAS.</p>
<p>In any event we finally got around to getting some backup for our systems but up until now we had not found good method of backing up 6 terabytes of data. Well as luck would have it Seagate just put out a new FreeAgent external 3 TB HD for 250 dollars US. We looked a little more, almost bought a pair of them figuring 500 was a cheap date for backing up all of our stuff when Beth found Seagate 2TB models for $139 plus shipping. This meant we were able to get 6TB of backup for less than 420 bones! Thus while repopulating the NAS we have been able to back up the other two and once the movie NAS is done (again) we can back that up too.</p>
<p>This means however that while the process is a painful one, the database will have probably 20x the content that it has now. I look at this as a good thing. To show it off I mean to put up some kind of website demonstrating the metadata and the many uses to which it can be put.</p>
<p>So while this is going on, no work has been done on libfoundation for a while. I finished a prototype for the virtual memory core, XML configuration read/write libs, threading tools (thread class wrapper, read-write locks, scoped mutex classes), shared memory tools and a really good start on the IPC mechanism. Once this is done I will add in the component loading system and call that libfoundation 0.5 and publish that. Each subsystem will come with a demo app showing how to use it.</p>
<p>Until then, I am working for Bally from ~06:45 until 16:30 then coming home and working on this for usually another 4 hours a day, 12 plus hours on the weekends. The thing is, running that many machines doing transcoding generates a lot of heat and being in the desert, it is even now (21:00) 106 degrees F outside so you can imagine how hot it gets inside, even with AC.</p>
<p>I will post more when done&#8230;.</p>
<p>Me to you..</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=497</wfw:commentRss>
		</item>
		<item>
		<title>New subproject: libfoundation</title>
		<link>http://jbcobb.net/?p=495</link>
		<comments>http://jbcobb.net/?p=495#comments</comments>
		<pubDate>Sun, 09 May 2010 23:47:08 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=495</guid>
		<description><![CDATA[Greetings all;
As some or many of you know I have a lot of concurrently-running projects between DVD Metabase, Bitmimic, the parallel processing initiative and more. All of these projects use forms of IPC, multithreading, logging, configuration and so on. All of this stuff is already available at the low-level but when re-implementing these things errors [...]]]></description>
			<content:encoded><![CDATA[<p>Greetings all;</p>
<p>As some or many of you know I have a lot of concurrently-running projects between DVD Metabase, Bitmimic, the parallel processing initiative and more. All of these projects use forms of IPC, multithreading, logging, configuration and so on. All of this stuff is already available at the low-level but when re-implementing these things errors creep in but plus when coding it I get the case of Deja-Moo (I have coded this BS before). However when I am doing it I tend to be coding for a given employer and they tend to put their stamp of ownership on it.</p>
<p>Now however my employer has tasked me with no such endeavor plus as I am at the beginning of several larger projects, I find myself saying &#8220;Oh look: I will be needing an IPC system again or a template-less container or a mutex controller or&#8230;.&#8221;.</p>
<p>Hence, the creation of libfoundation.  I am going to recode all of this stuff one last time and publish it under a business/hacker friendly license so no one can take it away. More, it will be loosely-coupled to the point that I or anyone can use a subset of the functionality without recoding or sacrificing functionality.  In a strange twist though, if you need an IPC system that talks to a plugin loader which uses an XML configuration scheme (for example), this will work too.</p>
<p><span id="more-495"></span></p>
<p>This time however I intend to be a bit more proactive on things. My intention is to take what I have learned over the years in terms of best-practices and implement all of the tools that I seem to need over and over again&#8230;one&#8230;last&#8230;time. They will be published under the bsd or some business-friendly license so I can use them when and where I need to and not constantly feel like I am reinventing the wheel. More to the point though; while this is a single overall library, it is really a loosely-couple collection of sublibraries that I have found useful over the years. Another aspect of this code is that every single API call will be exercised in a demo app that will serve multiple purposes:</p>
<p>1. Aside from any printed documentation, the demo code will show how to use the API to accomplish a variety of purposes.</p>
<p>2. Because each demo app tests (or will) every API call, it is a simple matter to just run Valgrind against that in order to confirm that any given component isn&#8217;t causing memory-leaks, corruption, etc. Since this is a foundational layer, I expect stuff to be built upon it (well that is what *I* am going to do anyways) and since most of the stuff I have in mind is non-trivial to begin with, having a justified sense of confidence in your foundation is critical.</p>
<p>For much of what I intend to cover, Boost and other libs cover this as well but at least in the case of Boost not all of the low-level libraries are of the same and consistent maturity level.  Moreover, while each sublibrary can be used independently, they are as a rule designed to work together, hence the API for the XML configuration lib has the same feel as the data library or the socket library.</p>
<p>It is my intention to grow this over time as needs change. How best to describe this would be to say that if you are needing something upon which to build a multithreaded (but not necessarily), dynamic (but not necessarily), embedded (but not necessarily) distributed (but not necessarily) system, this will work. It uses as much or as little C++ as you want/need. For example, I have a variant (an &#8220;any&#8221; class) and a return code class (enforces the checking of return codes) that either uses templates and RTTI (thinner classes)  or I have the same thing as almost C-like versions, no templates/RTTI, resulting in heavier classes but fewer system constraints. Most systems always support all this but some embedded systems don&#8217;t.</p>
<p>Most of the classes/tools are like this. In version 1.0 (probably due soon the basic library will contain:</p>
<p>* Thread class</p>
<p>* Scoped mutex, scoped try mutex classes</p>
<p>* Wait condition classes</p>
<p>* XML configuration classes (translates an XML file to a C++ class)</p>
<p>* IPC class framework (easy server and client messaging)</p>
<p>* Template-less data containers</p>
<p>* Variant class (same class can be anything from a string to an int to a data block)</p>
<p>* Return code class (if you return this and the caller doesn&#8217;t check the return code it asserts)</p>
<p>* Reader/writer locks</p>
<p>* Dynamic component loading system.</p>
<p>* File or memory-based error logging system.</p>
<p>* Quick and reliable TCP/UDP socket server and client system</p>
<p>* Virtual memory system</p>
<p>* MD5 hashing system.</p>
<p>This is not all inclusive but will give you an idea of the kinds of tools that will be available.  The first cut of this will be Linux-only, built with autotools.  I expect to get to an alpha shortly which will probably not have everything in the first release but I gotta start somewhere&#8230;..</p>
<p>More to come.  Me to you&#8230;</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=495</wfw:commentRss>
		</item>
		<item>
		<title>CMake Wizard 2.3 (Maint. release)</title>
		<link>http://jbcobb.net/?p=492</link>
		<comments>http://jbcobb.net/?p=492#comments</comments>
		<pubDate>Sun, 21 Feb 2010 21:19:46 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[cmake]]></category>

		<category><![CDATA[gtk]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=492</guid>
		<description><![CDATA[Greetings all. This will just a be short post to provide CMake Wizard 2.3. This is just a maintenance release to cover some changes in GCC that have come out recently that prevented the generated projects from compiling. Essentially it is just the inclusion of stdio.h to the file to provide the macro EOF for [...]]]></description>
			<content:encoded><![CDATA[<p>Greetings all. This will just a be short post to provide CMake Wizard 2.3. This is just a maintenance release to cover some changes in GCC that have come out recently that prevented the generated projects from compiling. Essentially it is just the inclusion of stdio.h to the file to provide the macro EOF for the getopt stuff. I do have some other directions I want to take this (and some bug-fixes to cover edge-cases) but this will at least keep the project working for now. The link to the project is here:</p>
<p><a href="http://jbcobb.net/bin/cmwiz2.3.tar.gz">CMakeWizard 2.3</a></p>
<p><span id="more-492"></span></p>
<p>To install:</p>
<p>Untar this file in your home directory. It will create a folder called .cmwiz and put all of the template files and installation code into it. Look at the readme.txt file for final installation details (setting up symlinks, adding GTK support, etc).</p>
<p>When done creating a new project for hacking should be as simple as:</p>
<p>1. Create a folder in your development directory.</p>
<p>2. Change to that folder.</p>
<p>3. Run cmwiz</p>
<p>4. Answer the questions; if you are in a hurry the drunken-chicken path can be followed, resulting in a basic C++ project with getopt support, a main executable and a single shared library. The drunken-chicken path can be best described as simply hitting Enter over and over again to all queries (except for naming the project; this is kind of critical as many of the file names are derived from this) will result in a working project.</p>
<p>5. After the interview stage the CMake project is generated along with a C++ framework which is then compiled and linked, resulting in a working project in just a few seconds.</p>
<p>Enjoy and as usual, if you have any questions you can write to me at JeffC@JBCobb.net. This is still released under the GPL 3.0.</p>
<p>Me to you.</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=492</wfw:commentRss>
		</item>
		<item>
		<title>Microlog 1.1a</title>
		<link>http://jbcobb.net/?p=479</link>
		<comments>http://jbcobb.net/?p=479#comments</comments>
		<pubDate>Sat, 09 Jan 2010 03:34:10 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=479</guid>
		<description><![CDATA[Greetings. I have a couple of things to cover here so will get right to it.
1. Microlog 1.1a: It was pointed out to me that for all the tricks that it did, it was missing the basics of proritizing log message a la Info, Warning, Error. This has been fixed and is in the new [...]]]></description>
			<content:encoded><![CDATA[<p>Greetings. I have a couple of things to cover here so will get right to it.</p>
<p>1. Microlog 1.1a: It was pointed out to me that for all the tricks that it did, it was missing the basics of proritizing log message a la Info, Warning, Error. This has been fixed and is in the new code dump here:<br />
<a href="http://jbcobb.net/bin/microlog1.1a.tar.gz">Microlog 1.1a</a></p>
<p>Plus some forward-looking statements&#8230;</p>
<p><span id="more-479"></span></p>
<p>When you start a sabbatical like I have you think you have the eternity of time to get done what you want. Well now it seems that it is time for the sabbatical to end and for me to rejoin the ranks of the employed.. What this means is that my time will no longer be mine to use as I please. While I cannot put an exact time-frame on things, I am expecting things to be occupied within the next 45 days. This means I need to wrap up several projects PDQ. As for the main projects, here is where they are, were I think I can get in the time I have left and the abilities is each:</p>
<p>1 The BIG project. I have the micrologger done and 45% of the IPC system done. In some ways I wanted the IPC to be stand-alone for use is in other pojects but ran into the basic problem of: An IPC system needs someone to talk to and the module loaders need some way to communicate or they are not going to work well. So. While I was going to split the distributed project into IPC and module loading as separate projects, now I find that I must roll then into on. Consequently the next release of this will be the module loader along with the IPC system so the modules can intercommunicate. In other words the next release of this will contain both. An initial set of modules will be released to do the analysis outlined here , <a href="http://jbcobb.net/?p=373">The Problem</a>. Then as time goes forward I can just swap out the modules to make the string search smarter and I already have some ideas for that.  Once this is done. it will be a minor task enlisting armies of machines to do the analysis work and come up with better solutions faster, the point of the game. I have the IPC stuff coded and the module loading going in a separate project; need to meld the two and this part should be useful&#8230;</p>
<p>2. DVD Metabase: I am going to push out a new version to cover version 0.94 of Handbrake though I will be supporting version 9.3 (AVI + Xvid) for now. This will happen RSN. To be honest, the reliance on x264 and MP4 has has positive and some very negative impacts on the project.. Therefore the use of 94 will be there for those who want it and I will maintain a code-drop of 93 on my webserver for those who don&#8217;t.</p>
<p>3. The C++ version of EZRip and the plugins&#8230;.it is in progress, has some ups and downs and if I don&#8217;t get some help on this could take a while b/c I am getting some rather dodgy results from using libdvdread3. PM me offline for specifics.</p>
<p>4. I will probably be making some upgrades to CMakeWizard shortly since GCC 4.4 has produced some irregularities&#8230;I know what the fix is but not sure how to gracefully make it work with all versions&#8230;.meh.</p>
<p>All of this will be done in the next 30 days. No pressure&#8230;.</p>
<p>Me to you</p>
<p>JeffC</p>
<p>EDIT: I must have been seriously tired when I first posted this entry due to the mistakes involved&#8230;sorry folks, all should be well now&#8230;</p>
<p>J.</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=479</wfw:commentRss>
		</item>
		<item>
		<title>MicroLog 1.0a</title>
		<link>http://jbcobb.net/?p=457</link>
		<comments>http://jbcobb.net/?p=457#comments</comments>
		<pubDate>Thu, 03 Dec 2009 04:52:55 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Microlog]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=457</guid>
		<description><![CDATA[There are two things every programmer of multithreaded applications knows:
1. Logging is the simplest form of debugging for such systems.
2. The act of logging triggers context switches which changes the execution which in turn means the application behaves differently under debugging conditions than it does under normal conditions.
Often the application of #1 results in #2 [...]]]></description>
			<content:encoded><![CDATA[<p>There are two things every programmer of multithreaded applications knows:<br />
1. Logging is the simplest form of debugging for such systems.<br />
2. The act of logging triggers context switches which changes the execution which in turn means the application behaves differently under debugging conditions than it does under normal conditions.</p>
<p>Often the application of #1 results in #2 meaning the &#8220;bug&#8221; can go away or change in nature to the point where the original bug is no longer obvious. You can assume that you have the bug fixed yet as soon as you remove/disable the debug code and the bug can return or worse, uncover a completely new one.</p>
<p>Part of the reason for this is that writing to a log, socket or other place to store the log will cause the kernel to execute a context switch. This means that different threads will execute in a different order under debug conditions&#8230;this is what I call &#8220;the observer effect&#8221;: a watched program executes differently than one running in release mode.  This is even more noticeable when running it under GDB or Valgrind for example.  There are two ways to deal with this:</p>
<p><span id="more-457"></span></p>
<p>1. Force the context switches to happen the same way under both conditions.<br />
2. Reduce/eliminate the context switches incurred by the logging process itself.</p>
<p>While #1 is interesting and the subject of another project I have on the back-burner, #2 is the subject of this article. One way to achieve what we want is to defer all file IO until such a time that it no longer matters. This means storing the log-contents in memory which brings up another problem: if you have multiple threads of execution all attempting to write to the same object/data store, you have to gate access via synchronization tools such as the mutex or semaphore and that means blocking some threads while others work and that still brings about the dreaded artificially-induced context switches. One way around this is to give each thread its own area of memory to write to. However since 90% of logging messages are text this could quickly become a resource-hungry monster. This would be bad enough in a normal system but on an embedded system this would make such a method all but unusable.</p>
<p>One way around this is by tokenizing the log messages. If you look at most of your logs you will find most if not all of the messages follow a similar pattern, often with only a few bits of data being different.  A few examples of typical log messages reveal:</p>
<p>[11:50:34] Test Process 1: Starting test begin<br />
[11:50:34] Test Process 1: Locking resource mainQueue<br />
[11:50:34] Test Process 1: Unlocking resource mainQueue<br />
[11:50:34] Test Process 1: Sleeping for 1000<br />
[11:50:34] Test Process 1: HWEvent Mouse event<br />
[11:50:34] Test Process 1: Info Finishing task<br />
[11:50:34] Test Process 1: Warning low resources</p>
<p>If we look more closely at this we find four basic kinds of information:</p>
<p>1. Time stamp</p>
<p>2. Originator of the message</p>
<p>3. General text of the message</p>
<p>4. The message &#8220;payload&#8221; or specific data being conveyed.</p>
<p>In the entry: &#8220;[11:50:34] Test Process 1: Locking resource mainQueue&#8221;</p>
<p>1. The time stamp is obvious, in brackets</p>
<p>2. &#8220;Test Process 1&#8243; is the process originating the message</p>
<p>3. &#8220;Locking resource X&#8221; is the generalized text of the message and</p>
<p>4. &#8220;mainQueue&#8221; is the message payload</p>
<p>Total message consumption: ~56 bytes.</p>
<p>With the goals of reducing the chance of triggering a context switch and reducing the memory footprint of the message in mind I created a message token like so:</p>
<pre>typedef struct TBasicMsg
{
        time_t msgTime;// time of message
        mType msgType;// enumeration of message type
        payloadType plType;// enumeration of payload type
        basePayload basePL;// 16-byte payload
}basicMsg;</pre>
<p>The time_t time stamp is obvious. The message type is an enumeration of basic core messages:</p>
<pre>typedef enum {
    msgNone = 0,
    msgStart,
    msgStop,
    msgLockResource,
    msgUnlockResource,
    msgSleep,
    msgWake,
    msgWait,
    msgResume,</pre>
<p>&#8230; etc. Each of these corresponds to a full textual message or more accurately a message format string suitable for sprintf(), stored in an STL map in the server. For example, msgSleep may correspond to the string &#8220;Sleeping for %d seconds&#8221;.</p>
<p>The payload is simply up to 16 bytes of data. It could be four integers, 16 characters, 15 characters + a NULL, two doubles, etc. Exactly how that data block is interpreted is dictated by the payload type field, enumerated as so:</p>
<p>typedef enum {plEmbeddedChar = 0, plLUChar, plDouble1, plDouble2, plInt1, plInt2, plInt3, plInt4, plLong1, plLong2, plNone} payloadType;</p>
<p>Each of these corresponds to a union to easily translate the 16 byte block defined as:</p>
<pre>const short payloadSize = 16;
typedef struct TPayload
{
    char base[payloadSize];
}basePayload;</pre>
<p>The basePayload is then translated into a specific set of data through the use of a union. For example, plInt reflects:</p>
<pre>union intPayload
{
    basePayload core;
    int n1, n2, n3, n4;
};</pre>
<p>There are unions to translate this into various combinations of values such as doubles, integers, longs, short character arrays and so on.</p>
<p>Using this combination of elements, all messages can be contained in a single 28-byte block. The call to store such a message as &#8220;Sleeping for 10 seconds&#8221; would look like this at the client level:</p>
<pre>Log.logMsg(msgSleep, plInt1, Log.makePayload(1000));</pre>
<p>This call sends the message token about sleeping along with a payload type meaning a single integer.  The makePayload() overloaded function converts the single integer into a basePayload type and returns it. The whole thing is then added to a BasicMsg type along with the current timestamp and pushed into a memory slot provided by the server.</p>
<p><span style="text-decoration: underline;"><strong>The Bigger Picture:</strong></span></p>
<div id="attachment_474" class="wp-caption aligncenter" style="width: 241px"><a href="http://jbcobb.net/wp-content/uploads/2009/12/microlog.jpg"><img class="size-medium wp-image-474" title="microlog" src="http://jbcobb.net/wp-content/uploads/2009/12/microlog-231x300.jpg" alt="Overview of client/server relationship" width="231" height="300" /></a><p class="wp-caption-text">Overview of client/server relationship</p></div>
<p>The idea is that there is a single microlog &#8220;server&#8221; created and 1-n clients.  The server is never instantiated directly but rather by the first instance of the first client in the constructor:</p>
<pre>CMicroLog::CMicroLog(string strProcName, long lThreadID, string &amp;strLogName)
{
    // if server is not there, create
    if(ptrServer == NULL)
    {
        ptrServer = new CMLogServer(strLogName);
        nClients = 1;
    }
    else
    {
        nClients++;
    }</pre>
<p>ptrServer and nClients are both static members of the CMicroLog class. The first client instance created will build the server instance and the last one destroyed will delete the server:</p>
<pre>CMicroLog::~CMicroLog()
{
    // this should be wrapped in a lock
    nClients--;
    if( nClients == 0 )
    {
         cout &lt;&lt; "Deleting server..." &lt;&lt; endl;
         delete ptrServer;
    }
}</pre>
<p>When the destructor for the server is called, the stored byte-ranges for all client-generated messages are translated into textual equivalents and written to the filename strLogName.  Thus it makes a certain kind of sense to have a &#8220;control&#8221; client created so the log is not written before you are truly ready to exit.</p>
<p>Upon instantiation, after the server is created or the client count is updated, the client registers itself with the server through the registerLog() method:</p>
<pre>nBufSize = ptrServer-&gt;registerLog(strProcName, lThreadID, &amp;ptrMainBufStart);</pre>
<p>strProcName is the textual name of this process (ie &#8220;Database manager&#8221; or &#8220;Socket service&#8221;), lThreadID is a long that can store the actual ID or handle for that thread/process or an arbitrary number more meaningful to the debug process. Finally &amp;ptrMainBufStart is simply a reference to a pointer to a memory block managed by the server. On making this call the server sets aside a block of memory for direct use by this client that is the size of the basic message times MSG_BUF_SLOTS, currently 1024. This essentially sets up a circular queue managed by the server associated with this client. Each call by the client to logMsg() pushes the 28-byte block in the slot pointed to by ptrMainBuf (initialized to ptrMainBufStart, established by the server) and updates the value of ptrMainBuf. When ptrMainBuf reaches the end of the block it is reset to the beginning held by ptrMainBufStart. All pointer manipulation and memory writes are performed by the client. Since the client &#8220;owns&#8221; this zone, no synchronization is needed.</p>
<p>Finally when the last client is destroyed the server calls flushLog() which iterates through all allocated memory blocks, all valid (non-zero) messages are entered into an STL multimap, keyed on the time-stamp. This has the net effect of aggregating all messages from all registered clients in time-stamp order into a single list. For each message in the list, the payload is converted to a string and inserted into the message.  That list is then translated into textual messages and written to the log file.</p>
<p><span style="text-decoration: underline;"><strong>The Code:</strong></span></p>
<p>The link at the bottom of the article has the source code for the library (CMicroLog (client), CMlogServer (server) and mlog_main.cpp (test/demo application). Please note that in its current version it is very much alpha code and will probably see a lot of refinement and extension in the area of message variety and construction.  Consider this to be a proof of concept as much as anything. You will need the cross-platform make system CMake installed to build everything (apt-get install cmake).</p>
<p>Two notes on extending the system (and it is *meant* to be extended!):</p>
<p>1. If you want to extend the core message library, add the new message to the msgType enumeration in mlogmsgs.hpp and then add a string insertion into the msfDigest in mlog.cpp:CMlogserver::initMsgDigest().</p>
<p>2. There is an experimental extension type called auxMsgTypes in auxmsgs.hpp.  It is triggered by specifying msgAuxMsg in the logMsg() call, plLUChar in the payload type and then the desired auxMsgType in the overloaded CMicroLog::makePayload() call.</p>
<p>The test app can be run in two different ways:</p>
<p>1. mlog_test -t basic will run a single-threaded test to demonstrate core message building. All messages are written to singletest.log.</p>
<p>2. mlog_test -t multiple -n &lt;number of threads&gt; to test a multithreaded model. This will spin up &lt;number of threads&gt; threads, each of which will create a CMicroLog client and go through a series of sleep and wake periods at random intervals which in turn emits a number of log messages to the server. Once all of the threads are done the server will collate the messages into a single log and write it to multitest.log.</p>
<p>There are a lot of logging systems that are more complete and easier to use. The value this brings to the table is if you need to constrain the number of artificially triggered context switches and/or constrain the amount of memory consumed by the logging process.  If you want smaller circular queues, adjust the value of MSG_BUF_SLOTS in mlog.hpp. If you need to add more/different messages to the system or add custom payloads, edit mlogmsgs.hpp and mlog.cpp.</p>
<p>The main logging library is contained in libmlog.so.  The main logging code is in mlog.cpp/hpp. The message enums and unions are stored in mlogmshs.hpp and auxmsgs.hpp. The entire codebase is released under the GPL 3.0. Sorce Code is here:</p>
<p><a href="http://jbcobb.net/bin/microlog-1.0.a.tar.gz" target="_blank">microlog-1.0.a.tar.gz</a></p>
<p>Experiment and share your findings&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=457</wfw:commentRss>
		</item>
		<item>
		<title>A Video Interview Using Free Tools</title>
		<link>http://jbcobb.net/?p=442</link>
		<comments>http://jbcobb.net/?p=442#comments</comments>
		<pubDate>Wed, 11 Nov 2009 03:23:45 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=442</guid>
		<description><![CDATA[Man oh man have I had an experience. It stems largely from living in the Windows world when it was king (and therefore the only standard) and then moving to larger world of free software and real standards.  Like many in this down economy I am looking for work and in an effort to make [...]]]></description>
			<content:encoded><![CDATA[<p>Man oh man have I had an experience. It stems largely from living in the Windows world when it was king (and therefore the only standard) and then moving to larger world of free software and real standards.  Like many in this down economy I am looking for work and in an effort to make myself stand out and thought that a video resume might be a good way to do it.</p>
<p>This story is about how easy it is to do all of this using free tools and then to make it work under both Linux and Windows&#8230;.only this is not about Linux vs Windows. It is more of a case of Microsoft Internet Explorer vs the rest of the world&#8230;.</p>
<p><span id="more-442"></span></p>
<p>At first the general project sounded simple; dress in a suit, iterate the highlights of my resume on video, edit it to fit into a nice bite-sized format, convert it flash to save on my bandwidth and host it on my web site. Doing it all with free tools made things even nicer.</p>
<p>The Video:</p>
<p>In anticipation of needing to do some editing I broke the general &#8217;script&#8217; apart into four or five sections: An introduction, skills summary, early background, later background, current projects and closing. Then I went into my office with a shovel and cleaned out an area to film in. I used the so-handy <a title="RCA Small Wonder" href="http://www.mysmallwonder.com/" target="_blank">RCA Small Wonder</a> video camera to film with. These things are great; even without additional RAM, it can record up to 30 minutes of high-quality video or an hour at low-quality. When you get done filming you press a button on the side of the device and a USB port pops out; plug it into your Linux laptop and it appears as a camera or external drive and the files are already in .AVI containers. I went through all of the section four times so that I could cherry-pick the best ones. As you will see, I may be an excellent coder but I am nobodies movie star.</p>
<p>Processing:</p>
<p>The next step was to break apart the various video files and assemble the best parts into one continuous film. That task was relegated to my favourite video editor for idiots (me being an idiot at such things), AVIDemux (apt-get install avidemux). With this tool it was childs play to break them apart, preview the various elements and then &#8220;stack&#8221; them together into one video:</p>
<p><a href="http://jbcobb.net/wp-content/uploads/2009/11/avidemux.png"><img class="aligncenter size-medium wp-image-443" title="avidemux" src="http://jbcobb.net/wp-content/uploads/2009/11/avidemux-300x235.png" alt="" width="300" height="235" /></a></p>
<p>Once I chose the parts I wanted it was a simple matter of stacking them with successive calls to Append File (File -&gt; Append). When done, I simply saved the result to a file called interview1.avi. This was fine except for two things that should be apparent: 1. I am unemployed so funds are limited and 2. This file was 89 megs in length! I could see my bandwidth bills going through the roof, defeating the purpose of the exercise. That answer? The oft-despised but comparatively anorexic Flash medium but I had no experience at creating Flash videos! Oh what is an OSS dude to do? FFMpeg to the rescue but I was on the clock, having put it off all weekend and needed it for the following morning. A nice front-end for FFMpeg (and my new best friend) is WinFF (apt-get install winff):</p>
<p><a href="http://jbcobb.net/wp-content/uploads/2009/11/winff.png"><img class="aligncenter size-medium wp-image-444" title="winff" src="http://jbcobb.net/wp-content/uploads/2009/11/winff-300x300.png" alt="" width="300" height="300" /></a></p>
<p>WinFF is great; you point at the file you are starting with, choose from dozens of types of outputs and press Convert. It&#8217;s just that simple. I love it. Out pops interview2.flv at a slender 15 megs.</p>
<p>The Fun: Flash</p>
<p>At this point I somewhat stupidly assumed I was in the home stretch; the only thing that was to stretch was my ability to curse at inanimate objects and insanely rich billionaires. All I had to do was to embed the Flash video into my website which contained a page with my experience on it anyways and just sticking the file out there with an HREF anchor did the trick but it just started up and played with no way to stop or to pause the video&#8230;and made it look even more lame than it was. A little research revealed that you had to embed a Flash player on your website (or somewhere) to provide the VCR-like controls we are all accustomed to&#8230;and most were for &#8220;non-commercial&#8221; use only. Well job-hunting left me in a strange spot in that it would be non-commercial &#8230; until and unless it worked. Consquently I went out in a search for an open source Flash player and sure enough, the OSS world provides <a title="OS FLV Open Source Flash Player" href="http://osflash.org/" target="_blank">OSFLV</a>.</p>
<p>Creating the page:</p>
<p>First to set up the web page; I run WordPress on a spare box for my main site. Great product, BTW. In any event, OS FLV needed me to muck with elements of the HTML normally out of the reach of the common user so I just created a subdirectory under the main site called &#8216;interview&#8217; and from the OS FLV tarball I extracted the flash folder along with AC_RunActiveContent.js along with player.swf and put them all in the interview folder. To that I added the interview2.flv file, a snapshot from it called sample.png (AVIDemux provided this) which gives the Flash player an image to display when the video is not running. All that was left was the HTML to play it. Since I had it in a directory of it&#8217;s own, I fired up Bluefish HTML editor and created a default index.html file using the Quick Start wizard (I was definitely into the &#8220;why work when you don&#8217;t have to&#8221; mode at this point) and this is where the fun began. To get Flash to embed nicely on everything (regardless of platform) except Microsoft Internet Explorer, you need the embed tag:</p>
<pre>&lt;EMBED href="http://www/jbcobb.net/interview/interview2.flv"
quality=high bgcolor=#FFFFFF WIDTH="550" HEIGHT="400"  NAME="interview2" ALIGN=""
TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/gogetflashplayer"&gt;
&lt;/EMBED&gt;</pre>
<p>And to get it to work in IE you have to wrap all of *that* in an object tag from hell:</p>
<pre>&lt;object&gt; classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" type="application/x-shockwave-flash"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,16,0"
width='480' height='360' id='flvPlayer'&gt;
  &lt;param name='allowFullScreen' value='true'&gt;
  &lt;param name='movie' value="player.swf?movie=interview2.flv&amp;bgcolor=0x051615&amp;fgcolor=0x13ABEC&amp;
volume=90&amp;autoload=on&amp;autorewind=on&amp;clickurl=interview2.flv&amp;clicktarget=_self&amp;
postimage=sample.png"&gt;
 &lt;/object&gt;</pre>
<p>You can view the semi-finished product here:</p>
<p><a title="Five minute interview" href="http://jbcobb.net/interview" target="_blank">http://www/jbcobb.net/interview</a></p>
<p>At the end of the day this was pretty simple to do once you deal with the browser insanity. I did a lot of browser work years ago; I would have thought that Microsoft would have learned by now&#8230;.the thing is about any form of HTML/javascript/etc worked in Linux and only one in IE&#8230;.there was a time when it was the other way around&#8230;</p>
<p>Update 11 November 2009:</p>
<p>I added another similar section here: <a title="14 Things I can do" href="http://jbcobb.net/14_things/" target="_blank">jbcobb.net/14_things/</a>. Basically I thought the interview itself was pretty dry and I wanted an easy way to quickly outline some of the more interesting projects I have worked on or invented. Again using free tools I used Open Office.org Presentation tool to create a slideshow of the material, ran the slideshow under recordmydesktop (apt-get install grecordmydesktop), converted the file to .AVI with WinFF (see above), edited the cruft out of it, overlaid some background unobtrusive background music and saved. Then I used WinFF again to convert the video to Flash, I cloned the &#8216;interview&#8217; directory on my webserver, replaced the video payload with the new &#8216;14_things.flv&#8217; and updated the index.html file there to reflect that. Badda-bing we have a new video&#8230;</p>
<p>Me to you</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=442</wfw:commentRss>
		</item>
		<item>
		<title>New directions for DVD Metabase: development odds and ends&#8230;</title>
		<link>http://jbcobb.net/?p=409</link>
		<comments>http://jbcobb.net/?p=409#comments</comments>
		<pubDate>Fri, 09 Oct 2009 01:38:30 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[DVD Metabase]]></category>

		<category><![CDATA[EZRip]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[VOD]]></category>

		<category><![CDATA[C++]]></category>

		<category><![CDATA[cmake]]></category>

		<category><![CDATA[cross-platform]]></category>

		<category><![CDATA[mono]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=409</guid>
		<description><![CDATA[In this article:
* A new DVDMB C++ API
* To plug-in or not?
* To Mono or not?
* To Java or not?

Greetings all, JeffC here. While I am here in Las Vegas looking for work I have started to take EZRip/DVD Metabase into a few new directions. First, while there will *always* be a Python version of [...]]]></description>
			<content:encoded><![CDATA[<p>In this article:</p>
<p>* A new DVDMB C++ API</p>
<p>* To plug-in or not?</p>
<p>* To Mono or not?</p>
<p>* To Java or not?</p>
<p><span id="more-409"></span></p>
<p>Greetings all, JeffC here. While I am here in Las Vegas looking for work I have started to take EZRip/DVD Metabase into a few new directions. First, while there will *always* be a Python version of EZRip (and probably DVD Metabase), I have never made a secret of the fact that I have used the Python as a way of quick prototyping new project ideas.  Now after 5 years of development I have observed that for the most part the feature-set of the system has settled down. Also, while I see it as a useful rip tool in and of itself, I can also see uses as a component of a larger/different system, both on the rip side and the playback side, not to mention that holy grail of Netflix-like services, suggestions.</p>
<p>A C++ API&#8230;</p>
<p>One way to make this useful in other places is to wrap the core functionality in a plug-in-esque environment. As it is EZRip uses the following key services:</p>
<p>* Volname (collects the disc label, comes with Linux)</p>
<p>* XML-RPC (Web services architecture for performing transactions with the DVD Metabase server: Python)</p>
<p>* DVD scanning (collecting disc track, language and subtitle information, provided by lsdvd)</p>
<p>* DVD Disc hashing (calculating an MD5 hash of the disc contents for disc lookups, provided by disc_id from the libdvdread source)</p>
<p>To this end, I have started rewriting all of EZRip as a C++ project. With the exception of the rip engine itself (Handbrake in this case but more on that in a moment) all services will either use stock Linux libraries (libdvdread, libxmlrpc) or other open source libraries (SimpleINI). I am creating an interesting API that should allow other programmers to use these services however they wish.</p>
<p>So far I have readers/writers for the configuration file (which is now an INI-style affair), profile and filter files. On the XML-RPC side I have readers for doing a DVD lookup (supply a hash ID and get a main record plus a deque of 1-n track objects). On the DVD scanning side, I am still wrapping volname calls but intend to use libdvdread for that, a simple call that returns an MD5 hash based on a device path and am in the middle of sorting out the direct calls needed by libdvdread to perform the scanning job. So far I have that last bit collecting track, time duration and available audio track information; after fixing a few bugs and gathering the subtitle information, you should be able to pass in a device path and get back all of the information you need to do track processing.</p>
<p>All of this will be exposed via a well-documented API, allowing other developers to do disc lookups, retrieve DVD metadata, read and use filters and profiles and more, all by simply including a single shared library and a header file; no more screen scraping (woowoo)! As a proof of completeness of this, I will  be rewriting EZRip to use this API and make for a faster/more extensible rip tool. As a part of this I will be implementing the concept of a modular rip engine system so that you can easily apply the metadata lookup abilities to not only HandBrake but OGMRip and Mencoder as well. Currently the make system for it will be the ever-trusty cross-platform maker, CMake. I have a lot of years of experience with this and feel it to be a safe choice for this project.</p>
<p>The first version of this will be pretty much a work-alike of the existing system (with the exception of a different format for the configuration files, natch) but then things are going to get interesting. First, for the sake of my long-suffering wife I am going to create a GTK GUI-based version of this tool. While it won&#8217;t be anything terribly fancy, it should remove most of the rough-edges that the command line tool presented (like the interrogation in interactive mode).</p>
<p>The next step however may cause some consternation and indeed it has in my own mind as well. One of the larger debates (flame-wars) happening in the open-source community right now is over the use of Mono which is an open-source impelentation of the .NET framework and tools invented by&#8230;..Microsoft. One thing I have never made a secret of is the fact that I do in my professional work a lot of cross-platform development and so whenever I approach any non-trivial project, I do with with an eye towards that end. On the system side the only remaining non-neutral component is libdvdread and that will by then be sufficiently abstracted. Handbrake is already cross-platform. That pretty much leaves the presentation side of things which is one of the places where solid cross-platform development strategies totally live or totally die. Which brings us back to Mono.</p>
<p>To Mono or not to Mono?</p>
<p>As someone who has lived through Microsoft&#8217;s early and shamelessly anti-competitive years, I cannot say I would ever trust them.  I can see any number of ways they can screw over the open source community with .NET/Mono and not for a second do I think they would hesitate if given the chance. However I also have to say I am a pragmatist to an extent and since I started doing Windows coding back in the early 90&#8217;s and had to wrestle with the SDK of the time, I really appreciated the power and architecture of Delphi (and later Borland Builder). It just seems like GUI and component-based development done right. And guess who is behind the design of .NET at Microsoft? You guessed it: Anders Hejlsberg, creator of Delphi. This suddenly puts things in a whole new light. Frankly if all it presented was another way of doing cross-platform development, I would say the risk of working with Microsoft technologies was not worth the gain since there are several other (safer) ways of doing the same thing (wxWidgets, GTK, Java/SWING, etc). However if you have ever had to develop with Delphi/Borland Builder you would know this is absolutely NOT just another cross-platform solution.</p>
<p>It is with this mindset that I am even remotely consideging using Mono for the next evolution of this tool.  Yes I KNOW the Mono side will always be years behind the .NET side (regardless of what Miguel De Icaza would have you believe but then no developer with his or her salt believes anything he says anymore. Once he was a great developer but now he is a salesman, pure and simple. I don&#8217;t trust car salesmen either) and will never be feature-comparable. That said I am going to take a serious, non-biased look at the platform and if it seems safe enough and feature complete so I know it won&#8217;t be a total waste of my time, I will probably make a Mono version of the toolset and a GUI front-end for it. This however brings me to one last point on this&#8230;.</p>
<p>To plugin or not?</p>
<p>While I do have a few patents to my name, I still don&#8217;t like what it does to otherwise sane people. Lately the company Eolas has brought suit against the world + dog (as seen <a title="Eolas patent suits" href="http://www.betanews.com/article/Yahoo-Apple-Adobe-others-named-in-Eolas-patent-lawsuit-blitz/1254842259" target="_blank">here</a> ) for creating things with plugins or using a plug-in like architecture&#8230;people, *please*! This model of application design is not only the most flexible and sane way of applicaition development, it is OBVIOUS! This application (EZRip) will be no different but if Eolas gain any traction with their ridiculous claims, this may have to be revisited.</p>
<p>Another direction I might take this (mostly to scratch an intellectual itch) is to write a Java-based version of this. I see it as a way of taking a design I know well and using a variety of technologies to bring it to life. I figure in this way I can honestly determine if one technology or the other is worth spending my time on. You as a C++, .NET/Mono or Java fan what is the best tool for the job and their answer is predictable. This will be my way of walking a mile in someone else&#8217;s shoes&#8230;</p>
<p>Status:</p>
<p>Currently I have proof of concept code working with configuration, profile and filter files.</p>
<p>I have volname wrapped (popen) but intend to use libdvdread to get the volume label directly.</p>
<p>I have the DVD hashing code done as a library.</p>
<p>I have most of the DVD scanning code done but this needs lots of testing.</p>
<p>I have XML-RPC code done to interact with the back-end server @ jbcobb.net:8000. I still need to flesh out the code to do a disc submission and update existing records to complete this section.</p>
<p>Unless something comes up, I am expecting to have the C++ command-line version of this done within two weeks. I will publish all code at that time and under the GPL.</p>
<p>Until later then, me to you&#8230;</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=409</wfw:commentRss>
		</item>
		<item>
		<title>CMakeWizard 2.2 is released</title>
		<link>http://jbcobb.net/?p=392</link>
		<comments>http://jbcobb.net/?p=392#comments</comments>
		<pubDate>Wed, 12 Aug 2009 03:22:11 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<category><![CDATA[cmake]]></category>

		<category><![CDATA[coding]]></category>

		<category><![CDATA[gtk]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=392</guid>
		<description><![CDATA[CMakeWizard 2.0 is here.
Howdy. It has been a while since I have updated this handy development tool. In case you don&#8217;t know, CMakeWizard is a simple set of Python scripts and C++ templates for jump-starting development projects. In short, you can start with an empty folder, run the CMakeWizard script and in seconds have a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jbcobb.net/bin/cmwiz2.2.tar.gz" target="_blank">CMakeWizard</a> 2.0 is here.</p>
<p>Howdy. It has been a while since I have updated this handy development tool. In case you don&#8217;t know, CMakeWizard is a simple set of Python scripts and C++ templates for jump-starting development projects. In short, you can start with an empty folder, run the CMakeWizard script and in seconds have a complete if skeletal C++ project up and running. It can create a shared or static library and an optional executable to test it all. If you want POSIX thread support you can have that too, along with optional sample code so that you can be up and running in no time. Finally, after generating the proper CMake-based project, it creates the C++ source and builds everything to prove that it works.</p>
<p>Now it is even better; it has built-in GTK support&#8230;</p>
<p><span id="more-392"></span></p>
<p>Recently I had a need to get into GTK+ development and since I did not wish to spend all of my time fooling with the makefiles and such to support it, I decided to see if my CMakeWizard was extensible enough to support GTK. As it turned out, it was. When I initially wrote this wizard some time ago I intended for it to have this kind of extensibility and I am pleased to say that things worked out as I hoped.</p>
<p>New Functionality:</p>
<p>One thing that made GTK a little more difficult to work with was the dependency on pkg-config to find the proper libgtk2.0 headers and libraries. In order to build a typical GTK project you would need to do something like this:</p>
<p>gcc myfile.c -o mybin `pkg-config &#8211;cflags gtk+-2.0 &#8211;libs gtk+-2.0 `</p>
<p>As it turned out, in the development branch of CMake there was an extension that did the same thing called FindGTK2.cmake. In the default distribution there is a FindGTK.cmake but that is only geared towards finding and dealing with GTK 1.2, an outdated version of the library. You can use this new extension by simply copying the provided FindGTK2.cmake to your CMake Modules folder. I have included the necessary file in the CMakeWizard tarball. It allows one to create CMake project files like so:</p>
<p>FIND_PACKAGE(GTK2 2.6 REQUIRED gtk)<br />
IF(GTK2_FOUND)<br />
ADD_DEFINITIONS( -Wall -ggdb )<br />
INCLUDE_DIRECTORIES(${GTK2_INCLUDE_DIRS})<br />
ADD_LIBRARY( foo SHARED foo.cpp )<br />
ADD_EXECUTABLE(foo_test foo_main.cpp)<br />
TARGET_LINK_LIBRARIES(foo_test foo ${GTK2_LIBRARIES} )<br />
ENDIF(GTK2_FOUND)</p>
<p>This will lookup the right locations of the GTK libraries and headers and provide them via the variables GTK2_INCLUDE_DIRS and GTK2_LIBRARIES.</p>
<p>I have also extended the templating system to optionally generate a working minimal GTK GUI app, the venerable Hello World.</p>
<p>To use this just unpack the contents of the tarball to your home folder; it should create/overwrite a hidden folder called .cmwiz. If this is your initial installation, please read the readme file for finishing the installation.</p>
<p>Once installed the steps to go from absolute nothing to a working GTK GUI app are:</p>
<p>1. Create a new folder and cd into it:</p>
<p>mkdir gtktest &amp;&amp; cd gtktest</p>
<p>2. Run the CMakeWizard:</p>
<p>cmwiz</p>
<p>3. When asked if you want to generate a GTK project, say yes and accept all defaults. That is it. When it finishes running you will have a working GTK app that you can now extend to meet your needs. The entire session looks like this:</p>
<p>jeff@jeff-gate:~/dev/gtktest$ cmwiz<br />
CMakeWizard 2.2<br />
A CMake Project jumpstart script<br />
This script is published under the GPL.<br />
CMakeWizard will first ask you a few simple questions<br />
and generate a CMake-based project with source in<br />
the current directory. Finally the project will be built.</p>
<p>Answer the following questions or Ctrl-C to abort:<br />
Project name: gtktest<br />
Use GTK 2.0 (n): y<br />
NOTE: This depends on FindGTK2.cmake being in your modules folder to work<br />
Gen sample GTK code? (y):<br />
Should this build a library (y):<br />
Generate a shared library (y):<br />
Library source name:  (gtktest.cpp):<br />
Additional include directories:<br />
Use pthreads?<br />
Should this create a test harness (y):<br />
Test harness source (gtktest_main.cpp):<br />
CMakeLists.txt written<br />
&#8211; The C compiler identification is GNU<br />
&#8211; The CXX compiler identification is GNU<br />
&#8211; Check for working C compiler: /usr/bin/gcc<br />
&#8211; Check for working C compiler: /usr/bin/gcc &#8212; works<br />
&#8211; Detecting C compiler ABI info<br />
&#8211; Detecting C compiler ABI info - done<br />
&#8211; Check for working CXX compiler: /usr/bin/c++<br />
&#8211; Check for working CXX compiler: /usr/bin/c++ &#8212; works<br />
&#8211; Detecting CXX compiler ABI info<br />
&#8211; Detecting CXX compiler ABI info - done<br />
&#8211; Found GTK2_GTK: /usr/lib/libgtk-x11-2.0.so<br />
&#8211; Configuring done<br />
&#8211; Generating done<br />
&#8211; Build files have been written to: /home/jeff/dev/gtktest<br />
Scanning dependencies of target gtktest<br />
[ 50%] Building CXX object CMakeFiles/gtktest.dir/gtktest.cpp.o<br />
Linking CXX shared library libgtktest.so<br />
[ 50%] Built target gtktest<br />
Scanning dependencies of target gtktest_test<br />
[100%] Building CXX object CMakeFiles/gtktest_test.dir/gtktest_main.cpp.o<br />
Linking CXX executable gtktest_test<br />
[100%] Built target gtktest_test<br />
jeff@jeff-gate:~/dev/gtktest$</p>
<p>Running the generated binary (gtktest_test) yields the following:</p>
<div id="attachment_394" class="wp-caption alignnone" style="width: 279px"><a href="http://jbcobb.net/wp-content/uploads/2009/08/helloworld1.png"><img class="size-medium wp-image-394" title="helloworld1" src="http://jbcobb.net/wp-content/uploads/2009/08/helloworld1.png" alt="GTK Applet generated by CMakeWizard" width="269" height="154" /></a><p class="wp-caption-text">GTK Applet generated by CMakeWizard</p></div>
<p>Future directions:</p>
<p>As I learn more about Glade and how to automate that process, I will extend/modify this to use a more generic resource model. As-is, the GUI is pretty hard-coded, more a proof that it works than useful in an of itself. Obviously for any of this new functionality to work you need the proper GTK development libraries installed to begin with&#8230;.</p>
<p>Enjoy and as usual, any feedback is appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=392</wfw:commentRss>
		</item>
		<item>
		<title>Concurrent development challenge: The Problem (part 2)</title>
		<link>http://jbcobb.net/?p=373</link>
		<comments>http://jbcobb.net/?p=373#comments</comments>
		<pubDate>Wed, 15 Jul 2009 20:09:03 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[bitmimic]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=373</guid>
		<description><![CDATA[Hi Folks;
Waaaay back in 2007 I wrote about coming up with a new development model for dealing with todays multicore systems and larger than life problems. The stories are here, here, here and here. As of here I outlined a problem that would fit our needs in developing such a system. It was a problem [...]]]></description>
			<content:encoded><![CDATA[<p>Hi Folks;<br />
Waaaay back in 2007 I wrote about coming up with a new development model for dealing with todays multicore systems and larger than life problems. The stories are <a href="http://jbcobb.net/?p=12" target="_blank">here</a>, <a href="http://jbcobb.net/?p=13" target="_blank">here</a>, <a href="http://jbcobb.net/?p=345" target="_blank">here</a> and <a href="http://jbcobb.net/?p=13">here</a>. As of <a title="The problem" href="http://jbcobb.net/?p=15" target="_blank">here</a> I outlined a problem that would fit our needs in developing such a system. It was a problem that should tax a single-processor system to the point where it would be relatively inefficient to resolve yet had a tangible result. The first step was to create an non-efficient yet runnable program to illustrate the problem and act as a baseline. That is what this article represents.  You can read the original article or just take in the outline below:</p>
<p><span id="more-373"></span></p>
<p>1. There is nothing totally original in nature or created by man.</p>
<p>2. Anything that *is* considered unique could be decomposed until the uniqueness was gone and essentially all elements of the unique creation could be found in another &#8216;unique&#8217; creation.</p>
<p>3. In short, any supposedly unique creation was simply the re-assembling of other non-unique elements.</p>
<p>To prove this, I would take two supposedly unique items, lets call them target and source. The source would be some bit of digital work that is unique yet not copyrighted, hence in the public domain. In this case, I am using a JPG of my house:</p>
<p><a href="http://jbcobb.net/wp-content/uploads/2009/07/house.jpg"><img class="alignnone size-medium wp-image-374" title="house" src="http://jbcobb.net/wp-content/uploads/2009/07/house-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Not much to look at but will serve as our source. The target is a file that is supposedly completely different than the source. In this case, I am using a picture of my Epi Riviera guitar:</p>
<p><a href="http://jbcobb.net/wp-content/uploads/2009/07/epismall1.jpg"><img class="alignnone size-medium wp-image-375" title="epismall1" src="http://jbcobb.net/wp-content/uploads/2009/07/epismall1-168x300.jpg" alt="" width="168" height="300" /></a></p>
<p>The idea then is that even thought the two look nothing like each other, decompose the target picture into smaller and smaller byte strings and find those strings in the source. Once found, the offset and length of the byte string would be recorded to what I am calling a recipe file. The proof of success is then to take the source and the recipe file and completely (and faithfully) reconstruct the target file from scratch.</p>
<p>The application provided here, what I am calling Bitmimic does exactly that. It does a brute-force decomposition of the target file and finds the byte strings that match in the source file, recording the results in the recipe file. Note that it is intentional that no attempts at optimization of either the recipe file or the searching. The project linked at the end of the file will contain all of the source along with the two JPGs for testing. Feel free to test this with your own digital media. The JPG test will execute relatively quickly (10m for the deconstruction/recipe generation and seconds for the reconstruction); this was done to give you a feel that the system works. However to give the larger concurrent project something real to chew on, the Epi picture will take the place of the source and the target will be a 30 minute video, something like 190M in size. On a relatively recent machine it took 2 days to deconstruct an episode of a 30 minute show and something like 10m to reconstruct it.</p>
<p>About the software:</p>
<p>Bitmimic is written in basic C++ and constructed with CMake which should allow it to build under Windows, Mac and Linux. I do use getopt to grab the command line args but that should be the only platform-specific bit to the system.  The source and the target and memmapped and so are treated like memory blocks. As mentioned, there has intentionally been no effort put into optmimization of any kind. Since this problem was designed to serve as a test subject for a larger system for problem-solving I needed a worst-case baseline to use as a foundation. The idea is to use the larger problem-solving mechanism to split the work up between processes and even machines on a network to resolve the recipe file in record time.</p>
<p>To make the system just:</p>
<p>cmake .</p>
<p>and then</p>
<p>make</p>
<p>To use the program to break up the Epi picture using the house picture you would:</p>
<p>jeff@jeffhpdev:~/dev/bitmimic$ ./bitmimic -a -r epirecipe.dat -d ./house.JPG -s ./epismall1.jpg</p>
<p>Parameters were:</p>
<p>-a = analyze (as opposed to build)</p>
<p>-r = name of recipe file to generate</p>
<p>-d = data file file to use</p>
<p>-s = source file to analyze</p>
<p>Two other command line args I could have used were:</p>
<p>-l = Open this text file and read each file listed therein. The system would spot check each data file listed and select the one with the longest byte-strings from the source. This is good if you want to check a list of JPGs (in this case) to the find ones that have the longest naturally occurring matches. The result is a smaller recipe file.</p>
<p>-D = root directory of files listed in the file with the -l option. For example, all my jpg candidates were in a directory called home/jeff/data; the library file referenced with the -l option was simply the output of ls *.jpg ../library.dat. The whole line would then be:</p>
<p>./bitmimic -a -d &lt;path to library file&gt; -l -D /home/jeff/data/ -r recipe.dat -s epismall1.jpg.</p>
<p>This would iterate through all files listed in the file library.dat, pick 5 spots to check in the source file and see how long the discovered byte-strings were in each file. The file with the largest score would be used as the actual data file.</p>
<p>To then reconstruct the original file you would:</p>
<p>jeff@jeffhpdev:~/dev/bitmimic$ ./bitmimic -b -d ./house.JPG -t epinew.jpg -r epirecipe.dat</p>
<p>-b means to build -t from recipe in -r using -d as a data source.</p>
<div id="attachment_390" class="wp-caption alignnone" style="width: 178px"><a href="http://jbcobb.net/wp-content/uploads/2009/07/epinew.jpg"><img class="size-medium wp-image-390" title="epinew" src="http://jbcobb.net/wp-content/uploads/2009/07/epinew-168x300.jpg" alt="output of program" width="168" height="300" /></a><p class="wp-caption-text">output of program</p></div>
<p>And there you have it. A few notes about this:</p>
<p>1. In the example the target file (epismall1.jpg) is 54K. The data file of the house is 1.5M.</p>
<p>2. In this exact scenario the analysis bit took just over 8 minutes to process.</p>
<p>3. The generated recipe file is 212K.</p>
<p>Challenges to the system:</p>
<p>There are two primary things that the larger system shall attempt to resolve:</p>
<p>1. Recipe file size. Right now it is just a text of offsets and byte ranges. LOTS could be done to mitigate this, many having nothing to do with parallel processing such as making it a binary file, smarter recording of repeating byte-patterns and so on. However one of the things that could seriously help all of this and still be a result of massive CPU power is finding longer byte strings. Most are in the 2-3 byte range which means more entries and a longer recipe file. By having multiple processes searching on different data files for the longer byte strings could help with this. This may however be at odds with the second thing the larger system will try to resolve:</p>
<p>2. Faster execution. If smaller recipe files were not a concern, having process/machine A break up the search and spread it amongst machines/processes B-n it would obviously accomplish the overall search many times faster.</p>
<p>All of this will require some specialized IPC along with some serious thought which I am applying to the problem right now and will be the subject of future articles. As a side note however, I have just moved to a serious HOT climate and am finding it hard to do more than a few hours per day since our AC is borked. It will happen, just on my own schedule. No one is paying me for this so it gets done when it gets done.</p>
<p>All of that said, it is interesting being able to recreate any piece of data from any other piece of data when you have none of the original data available (in it&#8217;s original form that is). I have used that same JPG of my guitar to generate everything from other JPGs to hour-long videos and everything inbetween.  However as a computationally intensive problem this is perfect for the larger system which I hope to present soon as it develops/the weather cools/I get the air fixed in our home. It&#8217;s going to be a great ride though.</p>
<p>The code here is simple but I encourage people to experiment with it; it will be much much more when it &#8220;grows up&#8221;.</p>
<p>The code for the sample is <a href="http://jbcobb.net/bin/bitmimic_0.1a.tar.gz">here</a>.</p>
<p>Me to you,</p>
<p>JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=373</wfw:commentRss>
		</item>
		<item>
		<title>FOSS: Freedom to explore, create and avoid intellectual speed-bumps</title>
		<link>http://jbcobb.net/?p=356</link>
		<comments>http://jbcobb.net/?p=356#comments</comments>
		<pubDate>Thu, 21 May 2009 17:31:17 +0000</pubDate>
		<dc:creator>JeffC</dc:creator>
		
		<category><![CDATA[DVD Metabase]]></category>

		<category><![CDATA[EZRip]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[VOD]]></category>

		<guid isPermaLink="false">http://jbcobb.net/?p=356</guid>
		<description><![CDATA[This article is a profile on experiences I have had while being an administrator of an open source project. While some aspects of this have been published before, recent work in the world of proprietary software has highlighted in my mind a few of the more powerful aspects of living in a FOSS world that [...]]]></description>
			<content:encoded><![CDATA[<p>This article is a profile on experiences I have had while being an administrator of an open source project. While some aspects of this have been published before, recent work in the world of proprietary software has highlighted in my mind a few of the more powerful aspects of living in a FOSS world that I am sure the proprietary software makers would prefer you not to embrace.</p>
<p><span id="more-356"></span></p>
<p><strong>First, the project: DVD Metabase.</strong></p>
<p>DVD Metabase is a collection of tools that does some things for myself and at least 300+ other like-minded individuals with Home Theater PC (HTPC) environments that you probably cannot find anywhere else. While the feature-list of DVD Metabase is lengthy, one of the keystone features is the idea of hashing or creating a unique checksum of your commercial DVD, looking up that checksum in a database and if found, returning a host of metadata about the disc to the calling application. What is this good for or actually mean to you? Well, if you integrate this with your DVD media extractor what you get is something that can rip titles with proper names to your hard disc for later viewing.</p>
<p>Here is a real-world example:</p>
<p>Take the DVD version of the scifi epic Total Recall (great Philip K. Dick story, iffy Schwarzenegger vehicle), insert the disc into your PC to prepare it for your HTPC and even with some bits of intelligence your ripped files will look like this:<br />
<code><br />
./total_recall<br />
|-- features<br />
|   |-- total_recall_features_03.avi<br />
|   |-- total_recall_features_05.avi<br />
|   `-- total_recall_features_07.avi<br />
|-- total_recall01.avi<br />
`-- total_recall_02.avi</code></p>
<p>1 directory, 5 files</p>
<p>Now the same disc when run with the DVD Metabase-enhanced tools. First the disc hashed with tools from libdvdread and we get:</p>
<p>7c4673a5a32cb10588dd635218857542</p>
<p>Then that hash is submitted to the database and we get back:<br />
<code><br />
jeff@jeffhpdev:~/dvdmetabase$ ./chkdisc.py<br />
connecting to ... http://jbcobb.net:8000<br />
doing record search...<br />
converting to a string...<br />
total_recall|7c4673a5a32cb10588dd635218857542|unkid<br />
Title found:  total_recall<br />
Disc ID:  7c4673a5a32cb10588dd635218857542<br />
5 tracks found:<br />
[tracknumber]-type:title<br />
[01]-m:total_recall<br />
[02]-x:featurette<br />
[03]-x:visions_of_mars<br />
[05]-x:storyboards<br />
[07]-x:trailer</code></p>
<p>We (and by extension our rip tools) know that track one is the main feature, named &#8220;total recall&#8221;  and that tracks 2,3,5,7 are all extra features (Featurette, Visions of Mars, Storyboards and the trailer). This allows our rip tools to rip the files to a disc tree that looks like the following:</p>
<p><code><br />
jeff@jeffhpdev:~/dvdmetabase/rips$ tree ./total_recall<br />
./total_recall<br />
|-- features<br />
|   |-- featurette.avi<br />
|   |-- storyboards.avi<br />
|   |-- trailer.avi<br />
|   `-- visions_of_mars.avi<br />
`-- total_recall.avi</code></p>
<p>Quite the difference, no? It gets even better with episodic television DVDs:</p>
<p>Disc 3 of the seventh season of Crime Scene Investigation:<br />
<code><br />
jeff@jeffhpdev:~/dvdmetabase/rips$ tree ./dvd_video/<br />
./dvd_video/<br />
|-- dvd_video_01.avi<br />
|-- dvd_video_02.avi<br />
|-- dvd_video_03.avi<br />
`-- dvd_video_04.avi<br />
</code><br />
becomes:<br />
<code><br />
jeff@jeffhpdev:~/dvdmetabase/rips$ tree ./csi_season7_disc3/<br />
./csi_season7_disc3/<br />
|-- 09_living_legend.avi<br />
|-- 10_loco_motives.avi<br />
|-- 11_leaving_las_vegas.avi<br />
`-- 12_sweet_jane.avi</code></p>
<p>0 directories, 4 files<br />
jeff@jeffhpdev:~/dvdmetabase/rips$</p>
<p>Even better. If this were the only feature of such a system it would be cool enough but the metadata can also include things like links to trailers, web-based content, advanced rip settings and more. The ripper itself can automatically select specific audio and/or subtitle tracks so if the disc is in a language you don&#8217;t understand, your preferred audio track is selected and if that is not present, the correct subtitle track is selected. Different track types (movie, show, cartoon, etc) can have specialized rip quality settings applied. A great number of features can be configured.</p>
<p>Since a system like this is only as useful as the data sitting behind it, I created a public XML-RPC service that I host on a spare Linux box here at Casa Cobb (http://jbcobb.net:8000). Authorized users can scan unknown discs, fill out a simple submission form and update the central server so that others can benefit from this work.</p>
<p>This entire system was built with free software:</p>
<p>Front-end:</p>
<p>Ripper: Handbrake (http://handbrake.fr/)</p>
<p>Hashing code (http://freshmeat.net/projects/libdvdread/)</p>
<p>Python (http://python.org)</p>
<p>Back-end:</p>
<p>Sqlite (http://sqlite.org)</p>
<p>Python (http://python.org)</p>
<p>XML-RPC (http://xml-rpc.org)</p>
<p>Project host (https://sourceforge.net/projects/dvdmetabase/)<br />
<strong><br />
The point of the article:</strong></p>
<p>The project itself is useful and powerful when used properly. However the point is that much of this would not have been as easy and in some cases possible with only proprietary software. Creating this costed nothing; the only on-going costs are my bandwidth fees. With proprietary tools I would need to have bought a server version of Windows, a client version of Windows, a Python development environment (to get the same IDE-abilities I get with Dr. Python), I would have to have developed the hashing algorithm from scratch and more.</p>
<p>This was brought to mind lately when I had to fulfil a contract for a client that needed to support 32 and 64-bit Windows with C++ and AutoCAD. First, to fully support the needed environments I would need two versions of Windows (Linux: 0$), two specific versions of the C++ compiler (32/64, 2005 and 2008 at $200 each) (Linux C++ compiler for all platforms: 0$) and of course AutoCAD ($$$; if you have to ask, you cannot afford it). Granted there are no versions of AutoCAD for Linux but there ARE DWF-compliant CAD programs for Linux (QCAD for one). As you can see you are paying a toll at each step of the toolchain.</p>
<blockquote><p>It is enough to make you go running for GCC and embrace it with open arms. If I had to develop my projects using Microsoft tools, the project would probably never have gotten off the ground. With proprietary tools and environments you keep hitting what I call intellectual speed bumps&#8230;with FOSS if you want to see how something works, you just *look*. If you need a tool to get a job done, you just install it and not give it another thought. With proprietary tools you have to find it, make sure you can afford it, wait for it to arrive if electronic delivery is not an option, get it installed and dance around with DRM just to get into your project. By the time you get your tools installed, your competitor that uses FOSS tools is probably delivering milestone 1 at the very least&#8230;</p></blockquote>
<p>It is times like these that FOSS feels like a comfortable old sweater. The pragmatist in me says I will continue to have to wrestle with proprietary tools as time goes on but every single experience like this ensures that every project where I need to get something done and done quickly and right the first time will be done with FOSS tools, no question about it.</p>
<p>Me to you.<br />
JeffC</p>
]]></content:encoded>
			<wfw:commentRss>http://jbcobb.net/?feed=rss2&amp;p=356</wfw:commentRss>
		</item>
	</channel>
</rss>
