While there’s nothing much to write about the encoder itself (it should be released and forgotten soon), it’s worth recording down how some magic numbers in the code (those not coming from the specification) were obtained. Spoiler: it’s mostly statistics and gut feeling.
(more…)
Author Archive
rv4enc: magic numbers
Tuesday, May 16th, 2023rv4enc: probably done
Saturday, May 13th, 2023In one of the previous posts I said that this encoder will likely keep me occupied for a long time. Considering how bad was that estimation I must be a programmer.
Anyway, there were four main issues to be resolved: compatibility with the reference player, B-frame selection and performing motion estimation for interpolated macroblocks in them, and rate control.
I gave up on the compatibility. The reference player is unwieldy and I’d rather not run it at all let alone debug it. Nowadays the majority of players use my decoder anyway and the produced videos seem to play fine with it.
The question of motion vector search for interpolated macroblocks was discusses in the previous post. The solution is there but it slows down encoding by several times. As a side note, by omitting intra 4×4 mode in B-frames I’ve got a significant speed-up (ten to thirty percent depending on quantiser) so I decided to keep it this way by default.
The last two issues were resolved with the same trick: estimating frame complexity. This is done in a relatively simple way: calculate SATD (sum of absolute values of Hadamard-transformed block) of the differences between current and some previous frame with motion compensation applied. For speed reasons you can downsample those frames and use a simpler motion search (like with pixel-precision only). And then you can use calculated value to estimate some frame properties.
For example, if the difference between frames 0 and 1 is about the same as the difference between frames 1 and 2 then frame 1 should probably be coded as B-frame. I’ve implemented it as a simple dynamic frame selector that allows one B-frame between reference frames (it can be extended to allow several B-frames but I didn’t bother) and it improved coding compared to the fixed frame order.
Additionally there seems to be a correlation between frame complexity and output frame size (also depending on the quantiser of course). So I reworked rate control system to rely on those factors to select the quantiser for I- and P-frames (adjusting them if the predicted and the actual sizes differ too much). B-frames simply use P-frame quantiser plus constant offset. The system seems to work rather well except that it tends to assign too high quantisers for some frames, resulting in rather crisp I-frame followed by more and more blurry frames.
I suppose I’ll play with it for a week or two, hopefully improving it a bit, and then I shall commit it and move to something else.
P.S. the main goal of NihAV
is to provide me with a playground for learning and testing new ideas. If it becomes useful beside that, that’s a bonus (for example, I’m mostly using nihav-sndplay
to play audio nowadays). So RealVideo 4 encoder has served its purpose by allowing me to play more with various concepts related to B-frames and rate control (plus there were some other tricks). Even if its output makes RealPlayer hang, even if it’s slow—that does not matter much as I’m not going to use it myself and nobody else is going to use it either (VP6 encoder had some initial burst of interest from some people but none afterwards, and nobody cares about RV4 from the start).
Now the challenge is to find myself an interesting task, because most of the tasks I can think about involve improving some encoder or decoder or—shudder—writing a MOV/MP4 muxer. Oh well, I hope I’ll come with something regardless.
rv4enc: B-frame experiments
Saturday, May 6th, 2023As I mentioned in the previous post, one of the problems is to find a good motion vector for B-frame interpolated macroblock. Since I had nothing better to do I’ve decided to try motion vector search in the same style as the usual motion estimation: start from the candidate motion vector pair and try adjusting both vectors using diamond pattern (since it’s the simplest one).
The results are not exciting: while it slightly improves PSNR and reduces file size (on lower quantisers), encoding time explodes. My 17-second 320×240 test clip encoded with quant=16
and two B-frames between I/P-frames takes 40 seconds without that option and 136 seconds with it. And while average PSNR improves from 38.0446 to 38.0521, the size decreases from 1511843 bytes to 1507224.
That’s the law of diminishing returns in action. Of course it can be made significantly faster by e.g. using pre-interpolated set of reference frames but why bother in this case? I’ve put this under an option (i.e. be satisfied with the initial guess or try to search for a better pair of motion vectors) but I doubt anybody will ever use it (the same applies to the whole encoder as well).
rv4enc: somewhat working
Wednesday, May 3rd, 2023I’ve finally managed to implement more or less working RealVideo 4 encoder with all the main features (yeah, I’m also surprised that I’ve got to this stage this fast). As usual, it’s small details that will take a lot of time to make them decent let alone good.
So, what can my encoder actually do now? It can encode video with I/P/B-frames using provided order, it can encode all possible macroblock types and has some kind of rate control.
What it does not have then? First of all, I don’t know yet how it would fare with the original RealPlayer (I also need to modify RMVB muxer to output improper B-frame timestamps and maybe write the additional streaming-related information). Then there’s a question of having a proper rate control. And finally there are a lot of questions related to B-frames.
Currently my rate control is implemented as a system that keeps statistics on how large is on average an encoded frame for a given frame type and quantiser and tries to find the best fitting quantiser. If there’s still no statistics (or not enough of it) I resort to a simpler quantiser guessing, adjusting quantiser depending on how different are the projected and actual frame sizes. Of course it can be tuned to behave better (the question is how though). And I’m not going to touch the two-pass encoding (theoretically it’s rather simple—you log various encoder information in the first pass and use it to select quantisers better in the second part; in practice it means messing with text data and doing additional guesstimates, so pass).
With B-frames there are two main issues to deal with: which frames to select and how to perform motion estimation. I read the first can be achieved by performing motion compensation against neighbouring frames and calculating SATD (often done on scaled-down frames to be faster). The second question is how to search for a bidirectional block vectors. Currently I have a very simple approach: I search for a forward and backward motion vectors independently and check which combination of them works the best. I suspect there may be an approach specifically for weighted bi-directional search but I could not find anything (and I’m not desperate enough to dive into the codebase of MPEG-4 ASP/AVC encoders).
And finally there’s the whole question of quality. I suspect that my encoder is far from being good because it should not merely transform-quantise-code blocks but also perform some masking (i.e. set some higher-frequency coefficients to zero instead of hoping that they’ll be quantised to zero).
So this will be long and boring work…
A quick look at a watery game video format
Monday, April 24th, 2023As you can guess, my work on Real Video 4 encoder goes so well that I’d rather look at virtually anything else.
Probably some of you are aware of Tex Murphy game series (maybe not even just Mike) and I got reminded of an existence of The Pandora Directive game that supposedly has a lot of videos in it, so I downloaded a demo and decided to explore it a bit.
Game data is packed into extremely simple archive format (just the number of offsets and the offsets) so you need to know what archives to look into (hint: the larger ones).
So what about videos? They start with H2O
magic (hence me calling it a watery format) and contain video frames and audio data (in an embedded WAV file). The video compression is both nothing special and somewhat original: it’s Huffman-compressed RLE. Video frame can contain several chunks, first there’s a Huffman tree description, then palette data and finally there’s compressed RLE data. The originality lies in the details: Huffman coding is often used to code single bytes while here single symbol represents both run length and value (also IIUC zero value signals skips), additionally the data is stored as the list of symbols for each codeword length. I don’t think I’ve seen anywhere neither RLE+Huffman used in such manner nor such tree description format.
This was a fun distraction even if I don’t care about the game series (I tried playing their other games like Countdown and Amazon: Guardians of Eden but the interface was too clunky and the action sequences were too annoying). It’s always nice to see some originality in video coding even if it is nothing advanced.
rv4enc: limping forward
Tuesday, April 18th, 2023So far there’s not much to write about: I’ve dealt with the second most annoying thing (writing coefficients) and now my encoder can produce a valid stream of I- and P-frames. Probably it’s a good place to define a road map though.
First of all, there’s still the most annoying thing pending—in-loop filtering. And I can’t reuse that much code from the decoder since it was written back in the day when my knowledge of Rust was even less than now, so I have to partly rewrite some of the parts to make them fit my current approaches to the interfaces (that means a lot of DSP functions among other things). At least it can be disabled for now but I’ll have to return to it sooner or later.
Then there’s 4×4 intra prediction mode still waiting to be implemented. Again, I know how to pick the good enough prediction modes, it’s context-dependent coding of those modes that is going to be annoying.
Another thing missing is estimating the number of bits required to encode a single block. There are about five codebooks involved and those are selected depending on macroblock type, quantiser, coefficient block type (luma, chroma or luma DCs) and the global set index. I guess I’ll resort to gathering statistics for all possible coding modes and seeing if I can make some heuristic estimation out of it. And there’s still a task of selecting the best coding set for a slice…
After all that it will be mostly B-frame related things left to implement. I also need to make sure the muxer will write them out properly (for historical reasons in that case it mangles the timestamp to be last frame timestamp plus one). That’s not counting all possible enhancements like deciding the frame type for coding. Most likely I’ll be annoyed by it and keep the fixed coding order instead.
There are too many things to do and considering my pace it may keep me busy for a good part of the year—I mean a large part of a calender year, the current date is still February 24.
Starting yet another failure of an encoder
Thursday, April 6th, 2023As anybody could’ve guessed from Cook encoder, I’d not want to stop on that and do some video encoder to accompany it. So here I declare that I’m starting working on RealVideo 4 encoder (again, making it public should prevent me from chickening out).
I can salvage up some parts from my VP7 encoder but there are several things that make it different enough from it (beside the bitstream coding): slices and B-frames. Historically RealMedia packets are limited to 64kB and they should not contain partial slices (grouping several slices or even frames in the packet is fine though), so the frame should be split during coding. And while Duck codecs re-invent B-frames to make them still be coded in sequence, RealVideo 4 has honest B-frames that should be reordered before encoding.
So while the core is pretty straightforward (try different coding modes for each macroblock, pick the best one, write bitstream), it gives me enough opportunity to try different aspects of H.264 encoding that I had no reason to care about previously. Maybe I’ll try to see if automatic frame type selection makes sense, maybe I’ll experiment with more advanced motion search algorithms, maybe I’ll try better heuristics for e.g. quantiser selection.
There should be a lot to keep me occupied (but I expect to spend even more time on evading that task for the lack of inspiration or a sheer amount of work to do demotivating me).
Staying neutral
Friday, March 31st, 2023Back in the day this quote from Futurama could be seen only at its face value: something only a paranoid jingoistic moron would say. Nowadays we see how the organisations and countries with neutral status use it mostly as an excuse to avoid responsibility for their acts.
Let’s start with various international organisations. Various international sports federations and the IOC say they’re outside politics and welcome money participants from all countries. All while forgetting that accepting participants from the countries that violate their principles of fair sportsmanship is going against those principles (“to oppose any political or commercial abuse of sport” from the Olympic Charter sounds especially ironic). And we have the ICRC that is in theory should act as a neutral mediator between fighting parties. In practice it has destroyed its reputation by not willing to organise anything for Ukraine (I can understand that they could not organise green corridors for Ukrainians because russians were against that but not performing their duties by visiting Ukrainian POWs in russia and essentially participating in war crimes by supporting russian deportation centres—that I cannot neither understand nor forgive). I suspect than in both cases corruption is at play: a dictatorship can always offer money or “gifts” that law-abiding democratic countries can’t.
And of course there’s Useless Nations organisation (still officially called United Nations by mistake). Considering how russia ignores its General Assembly decisions without any repercussions one should wonder about its usefulness already. And then they (as well as certain other international organisations “for all good against everything bad”) release reports blaming both parties: russia for aggression and Ukraine for defending itself. Including the latest scandal with russian “orthodox” church (FSB patriarchy)—it does not matter that in every church and monastery in Ukraine they occupy (in both senses) there were found stashes of russian propaganda, weapons and often russian agents in hiding; it does not matter how the church officials and lower clergy still repeat russian propaganda theses and act against Ukraine—the church is obviously a neutral organisation and should be treated as such.
On the same note, even individuals who repeat the same things about how both parties are wrong and you should stay neutral invoke only disgust in me. In the best case they’re idiots who listen to russian propaganda, in the worst case they’re narcissists who believe only they can be right and the rest of the world is stupid and wrong (place the current Pope into a category you see fit).
Now to the countries with neutral or “neutral” status. Often such country stays neutral because it is too small and cannot afford to anger its neighbours. The classic example of that would be Switzerland (just ignore its army regularly invading Liechtenstein during trainings), Sweden or Israel. Finland remained neutral for a sadder reason: it found out how useless were those alliances for defending it against Soviet aggression (similarly there was a joke in the beginning on 2022 that if russia would invade Poland or Estonia then NATO would react by excluding that country from the alliance). And we also see “neutral” Hungary and China. Let’s take a closer look at all those countries.
Switzerland started out as a small poor country that had fears of being invaded by its stronger neighbours—which happened only once, in Napoleon times (and because of their connections Swiss ended up with more territory when the war was over; those who try to mention Austrian invasion should look first who those Habsburgs were). Nevertheless they decided to remain heavily armed neutrals so that they don’t get involved in wars themselves and when an invader comes a good deal of the population will fight those armies in the mountains (having mountains is a good bonus to defence indeed). That’s why they have the law against transferring their weapons and munitions to the countries in the state of war (I can respect that. Update: after reading this article I’m inclined to re-evaluate their neutrality as to “do whatever we want as long as it does not anger powerful countries much”). In the same time they used their neutral status to conduct unscrupulous trade with all countries of the world (especially during WWII) and to get a reputation of a banking safe haven. But thanks to the pressure from the USA and various data leaks from its own banks it is no longer so. Hopefully in the future the country will survive and prosper on its high-tech chocolate industry and other respectable businesses instead of keeping stolen goods and money from dictators all around the world (just see this list to understand why one of their major banks went belly-up and may take another one with it).
And now to Israel. This is somehow an inverted Switzerland—a unitary state created more or less as a safe haven for a certain nation, it has constant tensions with its neighbours but remains neutral because it does not want its citizens (and potential ones) living in other countries to be harmed (a noble goal really). So in the beginning of the war they remained neutral because they did not want russia to get vengeful and supply a neighbouring terrorist state with something that will harm Israel. russia responded to this with various anti-Semitic statements and actions (read about the Sokhnut court case) and went to arm Iran anyway. Also it helps that the current government is very pro-russian and acts in rather russian ways (see their recent laws and the heavily-opposed legal reform; just another case why you should not have politicians serve indefinitely long terms). Here the neutral status is used to evade certain actions and also to evade responsibility for the other actions. Though the way it goes either the current government will be kicked out or they’ll lose international support.
Let’s move to really neutral countries like Sweden. In XX century it let Norway free after it decided to dissolve the union and the only war-like act during WWI was occupation of Åland that was more of a territorial dispute that was settled more or less peacefully (between Sweden and Finland, the other parties involved were not so nice). During WWII Sweden had to yield to pressure from Germany (like letting its troops pass through Northern Sweden—which those troops regretted doing) but in general it remained neutral because of its usefulness (like the iron ore and products from it) that would be lost in case of occupation. The current war made Sweden reconsider their position and it has finally applied for NATO membership.
And now for another NATO applicant, Finland. It has been suffering from the same problem as Ukraine—bordering with russia. In the first half of XX century it had been constantly struggling to keep its territory and sovereignty from Soviet Union (and the League of Nations proved out to be as useful as UN now, only Sweden and Norway helped it at that time plus some political manoeuvring). That’s why after 1945 it remained neutral but the recent events proved that if you border with russia and you’re not large enough then russia will try to occupy you. So Finland reconsidered its status as well.
Temporarily Occupied West Taiwan (or China for short) is a country that declares itself to be neutral while it semi-openly supports russia (and does not do that in the open because of the fear of sanctions). To which russia repays with its usual ingratitude: just three days after Xi Jinping visited it and had his roadmap for peace accepted there there’s a claim that they’ll go against it by threatening the world with their nukes and nuclear proliferation. This is a poster case of neutrality used as an excuse to do whatever they want since they’re not restricted by some political alliance.
And finally there’s a country that conveniently forgets about its treaties and alliances and proclaims itself neutral to do business with sanctioned countries. Of course I’m talking about Hungary. It’s the country that constantly blocks EU and NATO decisions either because it was paid for that (that’s why the amount of EU sanctions against russian oligarchs and entities is much lower than it should be) or because they want to have a bargaining chip (EU sanctions and other unanimous decisions again and blocking NATO membership for Finland, Sweden and Ukraine are good examples of that). And when I said they forget about previous treaties at their convenience I meant their claims about increasing trade with Iran (despite EU sanctions) or not honouring the indictments from the International Criminal Court because the (signed and ratified) Rome Statute “is not integrated into our legal system”. I believe somebody should help them become truly neutral by kicking them out from both EU and NATO. In the recent news though it’s reported that russia has added them to their list of unfriendly countries. Looks like there’s a common pattern in dealing with russia.
I probably should’ve mentioned Austria here as it was made a neutral country after 1945 but considering how it turned into serving russian interests I don’t see it showing any new aspects of “neutrality” and thus contributing to the discussion.
In conclusion I want to say that there are three different kinds of neutrality that different countries (organisations, people) often mix and pass for another kind: “don’t touch me” neutrality, “I can do whatever I want” neutrality and “you can’t make me do it” neutrality. The first kind is essentially a country staying aside and remaining not involved in any wars so that other countries do not have a reason to invade it either; sadly this works well only for countries with good defence (and not for Ukraine). The second kind is when you claim to be neutral in order not to have any restrictions on dealing with all other possible parties (it works only so well as you can withstand sanctions and pressure i.e. China has better chances doing that than Switzerland). The third kind is complementary to the second kind and the same reasoning applies.
So next time you hear claims about somebody or something staying neutral and not wanting to leave anybody or anything behind, ask yourself about the real goal of that neutrality (hint: there are dirty money involved quite often in this case).
The disturbing similarities between France and russia
Saturday, March 11th, 2023Dedicated to yet another piece of news about French company deciding to increase its business presence in russia instead of leaving the “market”.
In general I enjoy learning a bit about various foreign languages but I never had a desire to learn French language and when asked why I always answered that I know russian language already. But with the time I saw many more common things between France and russia than their language policy. This year of 1939 (will it end already?) brought even more examples of russia behaving like France and the French Empire(s) of old. Which makes me wonder if it is a certain type of country and what makes it such.
To me it looks the root of all problems is that both countries grew too large in territory, incorporating different nations in the process and relying too much on the central power (come to think about it, Temporarily Occupied West Taiwan comes to mind as well). The only way they could keep it going was to create “single nation”, by means of the cultural or physical genocide if required, and stealing the history while at it.
Below I’ll try to group things that are similar in the both countries by category.
History.
Both countries originated as the outskirts of some larger country that were overrun by the invaders. As the result they ended up as something semi-fictional: why do you think territory formerly known as Gallia (and proud of Galls) is called after some Bavarians (and IIRC it even had a war with them over the name, so one ended as France and another one as Franconia)? Similarly why a country in a place originally inhabited by Finno-Ugric people, where only the nobility was of Slavic origin (with their blood heavily diluted by Mongols) would boast their completely Slavic lineage (forgetting about all those Finno-Ugric, Turkic and Caucasian nations living on the majority of its territory)? And of course both countries claimed the title of the One True Heir of Roman Empire. Let’s skip most of the Medieval history, remarking only such details as St. Bartholomew’s Day massacre and the genocide of Novgorod Republic, and move to the more modern days. The French Revolution (the first and most famous one)—and the revolutionary terror of course—set the standard of how to do such things (which russia copied later). It’s worth noting that for the majority of XXth century France and russia remained friends: first the Entente, after WWII France willingly returned to the Soviet Union people who fled russia even before USSR was created (or it was russian territory at all), then (after France decided to leave NATO) Soviet-French friendship prospered (to the point possible by the foundational principles of Soviet Union), even now the French president tries hard to be russian advocate (the same can be said about Germany but despite some common things the countries were not similar throughout the majority of the history).
Country structure.
I notice that both countries occupy a large territory but despite that a significant part of the population lives in the metropolitan area of the capital: about one fifth for France, and one seventh for russia (for comparison, for Germany, Ukraine or Kazakhstan those numbers are below one tenth). Additionally the capitals in both countries are considered to be the only place to live (in case of russia their former capital is regarded in the same way too) and locals (whose ancestors probably lived far away from that capital) sneeze down at all those newcomers who don’t live in the capital and don’t speak the capital dialect either. Then there’s the whole question of the empire…
The main difference here is that russia was never good at maintaining overseas colonies (Fort Ross and Alaska were sold and the pirate nest of Septinsular Republic could not be hold) so it resorted to occupying and controlling neighbouring countries. For example, during Soviet times Mongolia was controlled by the Irkutsk division of The Party. Maybe that’s why they always wanted more oceanic ports.
France, on the other hand, had its colonies all around the world and keeps some of them under the name of overseas departments. For more exquisite things there’s Andorra. And of course there are “military advisors” in various African countries (former French colonies by coincidence). Now that France does not want or can’t maintain its presence, those are withdrawn and are usually replaced by the troops of the infamous russian military company (hopefully it’ll find its end at Bakhmut soon).
And finally, if you think that russia is the only country that tried to create puppet republics in Europe in order to annex them later you’d be wrong. When in 1945 several countries agreed to occupy parts of Germany in order to make it a decent civilised country, USSR almost immediately made its zone of responsibility into a socialistic puppet state that had been the best friends to its end and even after that (see Angela Merkel). France, meanwhile, tried to pull a similar trick with Saarland. They tried to convert Saar Protectorate into a puppet People’s Republic of Saarland but (since they could not falsify elections) the result was unfavourable for them and in 1957 Saarland joined Germany for good. Considering how Saarland plays about the same role as Donetsk and Luhansk regions in Ukraine it’s hard not to see parallels to russia’s actions in 2014 and 2018.
Language and cultural policies.
Here I’m not going to talk about the influence of the for-export version of the country culture (writers, composers, ballet and so on) on other nations but rather what they did inside their own territory.
I observe the same approach: cultural genocide and forcing the One True Language. russia did that to many of its colonised nations, see Ems decree as one of such example (I’ve been there recently BTW and spat and the bust of Alexander II installed in the local park). Nobody talks about France in this aspect but it did rather well to eliminate Occitan and Basque languages from its territory (and if you think what Basques have to do with it—learn about the history of Gascony fist). Similarly it forced French as the first language in the schools—unlike, say, British Empire where people could learn their native language first and English later. As the result many people from “former” French colonies speak perfect French while people from British Commonwealth have all kinds of accents and dialects.
Of course (in both countries) you have language chauvinism extended past beyond that when they refuse to learn and speak the language of any other country (one philologist who emigrated from USSR once said that the purpose of studying foreign languages there was mostly to incite hate to that language). And now both countries have laws for protecting their language purity against foreign influences too.
Another aspect of such language chauvinism is demanding to support their language on the state level (you might’ve heard about the situation in Canada where exists essentially a language police from a certain province that checks that all inscriptions in this predominantly English-speaking country have translations in French next to it in the same size; and of course even the most liberal russians demand the same from any country they take residence in).
And the last thing about the language is its writing complexity. By that I mean the fact that there’s not a very strong connection between the way the words are written and spoken (to the point where sometimes you need to know the context in order to pronounce the word properly). And reforms are often met with hard resistance (see France, 2016 or russia, 1918) probably because they cherish the elite status of the language and do not want to make it more available to the common folk. There are other languages with similar characteristics, but in case of English it was essentially arbitrarily picked from various dialects (of several languages) for printing convenience (i.e. it was not something forced by a government) and people curse William Caxton to this day; in case of Chinese it’s used to hide the fact that different parts of the country speak different languages so if they don’t write in the same way they would be completely disconnected (which goes against the imperial narrative of a single Han nation); in case of Japanese it’s mostly a consequence of adapting Chinese writing system for their language that is built on very different principles (it has a completely different grammar and mostly different lexis even if it has a good share of Chinese loanwords); and Hebrew as a Semitic language has little regard for vowels so they’re omitted where possible and usually indicated in full only in the texts for children and the religious texts. In either case it’s not done just to make scribes feel more important.
I could also mention how they all like to overlook the fact that a good deal of their famous people and inventions have a different origin (starting with that guy from freshly conquered Italian territory by the name of Napoleone Buonaparte or the famous russian explorer from Danemark Vitus Bering) but IMO that’s pretty normal when you’re building a unified empire based on a single culture forced onto everybody as the mean of unification. A certain country in the East comes to mind as well with its Uyghur re-education camps.
And when I talk about cultural genocide I mean not only forcing the master language and culture onto the colonised nations but also destroying (or at least hiding) the remnants of native civilisation so that the nations won’t get wrong ideas. In Soviet Union the representatives of state security always accompanied archaeological expeditions and denied publishing the findings if they were contradicting the state narratives (for example, the real age of Trypillia or Carpathian settlements as they undermined the narrative about russians being the oldest nation). Similarly I read a story over two decades ago that in French Indochina the explorers discovered an impressive city or temple complex (was it Angkor Wat?) that was kept in obscurity so it would not inspire any national liberation movements and it was effectively rediscovered in 1960s or so.
Cruelty.
Here’s a quote from Mark Twain:
Yet even France rose at last — and would have retired to its warren again quite contented with a cuff and a bonbon if the foolish King had offered them, but it was not his style to do the needful thing at the needful time, so the chance went by. Then the nation cast its rabbit skin and put on its other national garment, the tiger skin; being closely pressed by Europe in arms, it went a step further and asserted its manhood, and was doubtless surprised to find how much it had of it. Napoleon, the great foreigner, brought the people’s soldiership up to the last summit of perfection; and when he got ready he dressed the nation in their rabbit skins again and put his foot on their necks, and they glorified him for it. Napoleon III accommodated them in the same way, to their vast satisfaction.
The same largely applies to russians as well: they never had real uprisings against the sovereign, only protests addressed to him (the only real uprisings were started by other nations, like Ukrainians or Bashkorts) but when they were allowed to display their repressed feelings we got East Prussia in 1945 or Yahidne, Mariupol’ or Izyum this year. And if you look at russians they’re meekly going to war if they can’t avoid it and their relatives blame Ukraine for their subsequent deaths (instead of the führer who sent them there to die).
And if you look at what historical figures russians worship and despise, they mostly worship tyrants who oppressed them and wasted them in countless wars and despise rulers who tried to have more peaceful and liberal politics (because it was usually a sign of them being weak). I don’t know much about the French but considering the Penguin Island novel I expect about the same. At least nowadays they have strikes to vent off their negative feelings…
Conclusions
As I mentioned in the beginning, I suspect there’s a reason why both countries have acted similarly throughout the ages. Maybe it was the absolute power of the monarch and the abundance of initial territories, maybe it was something else. For example, British Empire grew up a lot thanks to the private initiative (names like Cecil Rhodes or East India Company come to mind immediately); USA (with such “unincorporated territories” as Puerto Rico or American Samoa) seem to retain its satellites a lot thanks to the fact that it’s better to be part of USA and get involved in its economic processes—and for the rest there’s U.S. Navy (which reminds me a lot of Roman Empire). With russia it was the opposite—the conquered countries tried hard to get independent from it (all of the Baltic states immediately and Ukraine, even if it took it more years after 1991 to realize why). French colonies are known to have been treated some of the worst (not as bad as Belgian king’s and later simply Belgian Congo though)—Haiti is the poorest country of Americas and I urge you to compare how many of the world poorest countries are former French colonies.
So it is no wonder that the countries with similar mindset would keep doing business together as long as the public opinion permits. At least France seems to improve albeit slowly while I see only two realistic ways for russia—balkanisation or turning into another North Korea. In either case maybe the future historians will explain what was wrong with both countries and why they went different ways eventually.
NihAV: towards RealMedia encoding support
Friday, March 10th, 2023Since I have nothing better to do with my life, I’ve decided to add a rudimentary support for encoding into RealMedia. I’ve written a somewhat working RMVB muxer (it lacks logical stream support that is used to describe the streaming capabilities, it also has some quirks in audio and video support but it seems to produce something that other players understand) and now I’ve made a Cook audio encoder as well.
Somebody who knows me knows that I fail spectacularly at writing non-trivial lossy audio encoders but luckily here we have a format which even I can’t botch much. It is based on parametric bit-allocation derived from band energies. So all it takes is to perform slightly modified MDCT, calculate band energies, convert them to scale factors, perform bit allocation based on them, pack band contents depending on band categories and adjust the categories until all bands fit the frame. All of these steps are well-defined (including the order in which bands should be adjusted) so making it all work is rather trivial. But what about determining the frame size and coupling mode?
As it turns out, RealMedia supports only certain codec profiles (or “flavors” in its terminology), so Cook has about 32 different flavours defined for different combinations of sample rates, number of channels and bitrates. And each flavour has an internally bitrate parameters (frame size and which coupling parameters to use) for each channel pair so you just pick a fitting profile and go on with it. In theory it’s possible to add a custom profile but it’s not worth the hassle IMO.
And now here are some fun facts about it. Apparently there are three internal revisions of the codec: the original version for RealMedia G2, version 2 for RealMedia 8 and multichannel encoder (introduced in RealMedia 10, when they’ve switched to AAC already). Version 2 is the one supporting joint-stereo coding. The codec is based on G.722.1 (the predecessor of CELT even if Xiph folks keep denying that) but, because Cook frames are 256-1024 samples instead of fixed 320-sample frames, they’ve introduced gains to adjust better for volume changes inside the frame (but I haven’t bothered implementing that part). That is probably the biggest principal change in the format (not counting the different frame sizes and joint stereo support in the version 2). And finally I should probably mention that there are some flavours with the same bitrate that differ by the frequency range and where the joint stereo part starts (some of those are called “high response music” whatever that means).
Time to move to the video encoder…