All Blog Entries

All blog entries, ordered from most recent. Entry count: 1198.

Warning! Some information on this page is older than 6 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

Pages: > 1 ... 22 23 24 25 26 ... 150 >

# How to quickly convert MKV to MP4 file using VLC?

Fri
22
Jan 2016

Do you have a video in MKV file and you can't open it because some program (like Sony Vegas Pro) doesn't support this format? If so, you probably wonder how to convert it into some different format. I just discovered a way to do this.

Important update 2020-03-22: I found another way to quickly remux MKV to MP4 using OBS Studio. This is a free and open source app intended mostly for video recording and streaming. The feature we need can be found in menu File > Remux Recordings.

To understand this method, first you need to know that media file formats are just containers (for example, MKV is Matroska). Each format encapsulates a set of streams, usually one video and one audio stream. Now, each stream is encoded using some specific codec. There may be various codecs used, but for the file I needed to convert, Media Player Classic (my favorite movie player, installed with K-Lite Codec Pack) shows following information after selecting File > Properties:

Type: Matroska
Video: MPEG4 Video (H264) 720x400 25fps [V: English [eng] (h264 main L4.0, yuv420p, 720x400) [default]]
Audio: AAC 44100Hz stereo [A: aac lc, 44100 Hz, stereo [default]]

MPEG4 Video is the same codec that may be used with MP4 file format! It means we could convert ("repack") the file to just different container format, rewriting streams as-is without actually converting video or audio - which should be very fast (converting a long movie takes only few seconds) and wouldn't cause any quality loss.

To do that, I used VLC media player. This program has its own set of codecs for many video and audio formats, so it doesn't depend on codecs installed in Windows. The player is actually just an overlay on top of a powerful library that can also do different things, like streaming video over network (that's probably where the company name "VideoLAN" comes from) or convert files.

So to convert an MKV file to MP4:

  1. Run "VLC media player".
  2. From main menu select "Media" > "Convert / Save...".
  3. On "File" tab, click "Add..." button.
  4. Choose you MKV file. After that, it should be added to the list. (Alternatively, you can drag&drop a file into the list.)
  5. Click "Convert/Save" button.
  6. Select Profile: "Video - H.264 + MP3 (MP4)".
  7. Click on the icon button that has hint: "Edit selected profile".
  8. On "Encapsulation" tab, leave "MP4/MOV" selected.
  9. On "Video codec" tab, check both "Video" and "Keep original video track".
  10. On "Audio codec" tab, similarly select both "Audio" and "Keep original audio track".
  11. Click "Save" button.
  12. In "Destination" selection, click "Browse" button to select directory and file name for you destination MP4 file.
  13. Click "Start" button.
  14. Observe progress bar in the main window as file is converted.
  15. After that, my VLC (version 2.2.1) seems to hang in an infinite loop so I have to kill it using system "Task Manager", but it doesn't matter - the destination file is already created.

Comments | #video Share

# ID3D11Device::CreateTexture2D: pInitialData[0].SysMemPitch cannot be 0

Sat
09
Jan 2016

The concept of "stride" or "pitch" - a step (in bytes) to be taken to proceed to next element of a data structure - is brilliant, because it gives great flexibility. In 3D graphics for example, explicitly specified number of bytes between vertices in a vertex buffer or rows in a texture can be:

  1. Equal to exact size of vertex structure or texture row, when these entries are laid out next to each other.
  2. Greater, so additional padding can exist at the end of each entry or entries can be interleaved with some other data to be skipped in particular case.
  3. Zero, so that the same single entry will be read over and over.

This is a theory, because I just discovered that option 3 doesn't work in Direct3D 11 when passing pInitialData to created texture. I cannot see any reason why specifying D3D11_SUBRESOURCE_DATA::SysMemPitch == 0 should be considered invalid, other than trying to save developer from possibly unintended mistake. I think it is actually pretty useful for initializing a texture with the same data in each row, so it would be enough to allocate and fill the data for just one row, instead of full texture. And still, following code fails on call to CreateTexture2D:

CD3D11_TEXTURE2D_DESC textureDesc = CD3D11_TEXTURE2D_DESC(
    TEXTURE_FORMAT, // format
    (UINT)TEXTURE_SIZE.x, // width
    (UINT)TEXTURE_SIZE.y, // height
    1, // arraySize
    1, // mipLevels
    D3D11_BIND_SHADER_RESOURCE, // bindFlags
    D3D11_USAGE_DYNAMIC, // usage
    D3D11_CPU_ACCESS_WRITE); // cpuaccessFlags
std::vector<uint32_t> initialTextureRow(TEXTURE_SIZE.x);
ZeroMemory(&initialTextureRow[0], TEXTURE_SIZE.x * sizeof(uint32_t));
D3D11_SUBRESOURCE_DATA textureInitialData = {
    &initialTextureRow[0], // pSysMem
    0, // SysMemPitch
    0 }; // SysMemSlicePitch
ID3D11Texture2D *texture = nullptr;
ERR_GUARD_DIRECTX( m_Dev->CreateTexture2D(&textureDesc, &textureInitialData, &texture) );

DirectX debug layer reports error:

D3D11 ERROR: ID3D11Device::CreateTexture2D: pInitialData[0].SysMemPitch cannot be 0 [ STATE_CREATION ERROR #100: CREATETEXTURE2D_INVALIDINITIALDATA]

Dear Microsoft: Why? :)

Comments | #directx Share

# Funny quotes from Twitter - Part 2

Fri
18
Dec 2015

Some time ago I published my list of Funny quotes from Twitter - Part 1. As I read Twitter regularly, I would like to share some new funny (and sometimes serious) quotes that I liked recently, again mostly about programming.

my solution runs in O(my god) time

We're about 5 years away from dumping the games and just buying the trailers

Programming is a constant exercise in remembering how stupid you really are. (@ramyhg)

Problem statement = goals + constraints

As technology advances, rendering time remains constant. (Blinn's Law)

First Law of Software Quality:
e = mc^2
errors = (more code)^2

We used to leak kilobytes, then megs, then even gigs. Now, we leak EC2 instances. Someday, we'll leak entire datacenters.

Why did a DBA suddenly quit his career and become a DJ? Because he DROPed the base! (@astarasikov)

if Apple's graphics API for small phone GPUs was called "metal", does that make the desktop version "heavy metal"?

Programming is like writing a book... except if you miss out a single comma on page 126 the whole thing makes no damn sense.

You likely have to get management approval for a $500 expense... but you can call a 1-hr meeting with 20 people and no one notices.

"I've set the wedding date. I've not asked her out yet." - how software projects are managed.

Compiler devs, I'm not sure how to break this to you, but SSA is ass backwards. (@rygorous)

My hope is that if I use enough encapsulation, no one will find out that I have no idea what I’m doing :D (@BenNadel)

Just because RAM stands for Random Access Memory doesn't mean you should strive to access memory randomly. (@domipheus)

THE GUIDFATHER (annoyed): I'll make him an offer he can't reuse. (@rygorous)

What's up? Answer: up is a static const vector3 (@_Humus_)

Programming is like sex: It may give some concrete results, but that is not why we do it. #stroustrup (@samanismael)

What do you say to a Linux user? Nothing, their sound card doesn't work.

"You had one job," said the work stealing scheduler "but now it's mine.".

When .NET developers are fired they put their stuff in a box, even though boxing is generally discouraged in that space.

'Fancy algorithms are slow when n is small, and n is usually small.' -- Rob Pike (@CompSciFact)

User interface is like a joke, if you have to explain it, it's not that good.

Unfortunately, Accidental Complexity is often where the fun is for many developers. (@cyriux)

Objects are data structures with functions. Closures are functions with data.

My girlfriend says she needs time and distance. Is she calculating velocity?

an important question: if one wants to grows a binary tree, does one put a 1 or a 0 in the soil? (@logicalerror)

- "What do we want?" - "Now!" - "When do we want it?" - "Fewer race conditions!" (@wellendonner)

Tetris is a game about technical debt (@JeremyGrosser)

"Immutable objects are always tread safe." -- Brian Goetz

I don't think any profession makes you feel as stupid as programming. Yes, computer, you WERE right. I am sorry. (@JJcoolkl)

"Nobody wins a data race." -- Pablo Halpern #cppcon

Videogames have a unique way of combining all the risks of a creative endeavor with all the risks of software engineering.

The year is "2027". Strings are the only remaining data type. (@velartrill)

A programmer with a hammer will find most problems sufficiently nail-like. (@TimSweeneyEpic)

Debugging is like being the detective in a crime movie where you are also the murderer. (@fortes)

Comments | #humor Share

# PrintStream 2.0 - Polymorphic Printf

Sat
05
Dec 2015

Almost 4 years ago I shared a code snippet: CPrintStream - Polymorphic Printf. I recently came back to this code and decided to improve it in many ways. It is now more clean, efficient, and supports Unicode character set.

I created MISC repository on my GitHub for the purpose of such small code snippets and added new version of my code there, as:

GitHub sawickiap / MISC / PrintStream

Description:

A hierarchy of classes that represent abstract concept of a text-based stream that can be printed into, using methods like print(const char* str), printf(const char* format, ....) etc. Derived classes offer printing to console (standard output), to file, to memory buffer and more.

Comments | #c++ Share

# type_safe_ptr - Idea for Type-Safe void* Pointer

Sat
21
Nov 2015

I was thinking recently about passing raw data pointers (like void* or char*), which we have to do sometimes in C++. Is there any way to check if the type that we cast it to is the same as the type of last assigned value? I came up with an idea of implementing a "smart pointer" class using RTTI (specifically typeof operator) to store type information next to the actual pointer. Example usage:

int i = 123;
type_safe_ptr ptr{&i};
int j = *ptr.get_typed<int>(); // OK
float f = *ptr.get_typed<float>(); // Error

Initially I wanted to store pointer to const type_info struct returned by typeid operator, and it seems to work in Visual Studio 2015, but language standard defines the object returned by typeid as temporary, so it is not formally correct. Finally I decided to store typeid(T).hash_code(). You can find my implementation of classes type_safe_ptr and type_safe_const_ptr in file: type_safe_ptr.hpp. Here is example tesing program:

#include <cstdio>
#include "type_safe_ptr.hpp"

int main()
{
    type_safe_ptr ptr1;
    // ptr1 is null.
    assert(!ptr1);
    assert(ptr1.get() == nullptr);

    int i = 123;
    type_safe_ptr ptr2{&i};
    // ptr2 is pointer to int.
    assert(*ptr2.get_typed<int>() == 123);
    // It would activate assert inside type_safe_ptr.get_typed, because ptr2 is int not float.
    //assert(*ptr2.get_typed<float>() == 123.f);

    struct STest { int i; } obj;
    // itr2 is now pointer to STest.
    ptr2 = &obj;
    ptr2.get_typed<STest>()->i = 124;
    assert(obj.i == 124);
    // It would activate assert inside type_safe_ptr.get_typed, because ptr2 is now STest not int.
    //assert(*ptr2.get_typed<int>() == 123);
    
    type_safe_const_ptr cptr = type_safe_const_ptr(ptr2);
    // cptr is pointer to const STest.
    assert(cptr.get_typed<STest>()->i == 124);

    const int* constIntPtr = &i;
    cptr.reset(constIntPtr);
    // cptr is now pointer to const int.
    assert(*cptr.get_typed<int>() == 123);
}

Some issues and open question regarding my solution are:

Final question is, whether this whole idea of "type-checking void* smart pointer" makes any sense? I am not sure about that, but anyway it was a funny experiment :)

Comments | #c++ #visual studio Share

# The Virtual Reality of Code

Wed
11
Nov 2015

In my opinion, coding is a virtual reality with its own set of rules unlike in the physical world. In physical world, each thing has its specific location at the moment, things don't appear or disappear instantly, we have laws of energy and mass conservation. Inside a computer, we have data in memory (which is actually linear - 1D) and processors, processes and threads executing instructions of a program over time.

I have been trying for years to imagine some nice way editing or at least visualizing code, which would be more convenient (and look more attractive) than the text representation we all use. I am unsuccessful, because even if we render some nice looking depiction of a function code, its instructions, conditions and loops, drawing all the connections with variables and functions that this code uses would clutter the image too much. It's just like this virtual world doesn't fit into a 2D or 3D world.



Movie depiction of computer programs is often visually attractive, but far from being practical. This one comes from "Hackers" movie.

Of course there are ways of explaining a computer program on a diagram, e.g. entity diagrams or UML notation. I think that electrical diagrams are something in between. Electrical devices end up as physical things, but on a diagram, the shape, size and position of specific elements doesn't match how they will be arranged on a PCB. Logical representation and electrical connections between them is the only thing that matters.

Today it occured to me that this virtual reality of code also has "dimensions", in its own sense. It's evident when learning programming.

1. First, one has to understand control flow - that the processor executes subsequent instructions of the program over time and that there can be jumps caused by conditions, loops, function calls and returns. It's called dynamic aspect of the code. It can be depicted e.g. by UML sequence diagram or activity diagram.

I still remember my colleague at university who couldn't understand this. What's obvious to every programmer, was a great mystery to him as first year's computer science student. He thought that when there is a function above main(), instructions of that function are executed first and then instructions of the main function. He just couldn't imagine the concept of calling one function from the other and returning from it.

2. Then, there is so called static aspect - data structures and objects that are in memory at given moment in time. This involves understanding that objects can be created in one place and destroyed in another place and at later time, that there may be a collection of multiple objects (arrays, lists, trees, graphs and other data structures), objects may be connected to one another (the concept of pointers or references). Various relationships are possible, like one-to-one and one-to-many. In object-oriented methodologies, there is another layer of depth here, as there are classes and interfaces (with inheritance, composition etc.) and there are actual objects in memory that are instances of these classes. It can be depicted for example by entity diagram or UML class diagram.

3. Finally, one has to learn about version control systems that store history of the code. This adds another dimension to all the above, as over successive commits, developers make changes to the code - its structure and the way it works, including format of data structures it uses. Branches and merges add even more complexity to it. GUI apps for version control systems offer some way of visualizing this, whether it's showing a timeline with commits ("History") or showing who and when commited each line of a file ("Blame").

There is even more to it. Source is organized into files and directories, which may be more or less related to the structure of contained code. Multithreading (and coprocessing e.g. with GPU, SIMD, and all kinds of parallel programming) complicates imagining (and especially debugging!) control flow of the program. Program binaries and data may be distributed into multiple programs and machines that have to communicate.

It fascinates me how software is so multidimensional in its own way, while so flat at the same time (after all, computer memory is linear). I believe that becoming a programmer is all about learning how to imagine, navigate and create stuff in this virtual reality.

Comments | #philosophy #software engineering Share

# Poznań Game Arena + Game Industry Conference 2015

Mon
19
Oct 2015

Last weekend Poznań Game Arena together with Game Industry Conference (former ZTG - Zjazd Twórców Gier) took place in Poznań, Poland. I have been there, just like in previous years and I liked it a lot. PGA is advertised as "biggest multimedia and entertainment event in this region of Europe." There were multiple halls filled with exhibitors of various kinds, of course all related to gaming. Lots of gaming hardware have been shown, as well as T-shirts and other fan accessories. I had an opportunity to try Oculus Rift and Samsung Gear VR. Samsung's product seems to have higher resolution, but bigger lag between accelerometer and displayed image. Unfortunately I didn't try HTC Vive (the queue was too long), while they say it is the best of all virtual reality solutions. There was also one hall dedicated to indie games, with lots of productions available to play and discuss with their creators.

While PGA was targeted mostly to gaming fans, game developers gathered in the same time and place for GIC, which consisted of almost 100 talks, panels, workshops and other activities. Industry professionals talked about their games, academics showed their research, enthusiasts discussed their ideas and prototypes... Traditionally, most of the topics were not technical, but rather related to game design or business. Well, most games are made in Unity these days anyway, so probably there is not need to discuss quirks of DirectX or OpenGL for an average game developer. But I still believe that the opportunity for expanding knowledge beyond everyday work, for networking, catching new ideas and getting motivation boost make such events worth attending.

Comments | #events Share

# Direct3D 12 - Watch out for non-uniform resource index!

Mon
28
Sep 2015

DirectX 12 allows us to use arrays of resources (descriptor tables) and refer to them from a shader code by an index. The index can be constant or variable. But there is a big trap waiting for shader developers doing that! Microsoft just updated their public documentation in this regard (see Resource Binding in HLSL), so now I can talk about it.

In D3D12, resource index is expected to be uniform (scalar) by default. It means the index, even if dynamic, should be the same across whole draw call (all vertices/pixels/etc.). For example, it can be a result of some calculations, which depend on parameters coming from a constant buffer. Example code:

Texture2D<float4> textures[16] : register(t0);
SamplerState samp : register(s0);
struct SConstantBuffer
{
    uint MaterialId;
};
ConstantBuffer<SConstantBuffer> cb : register(b0);

float4 PS(
    in float2 texCoords : TEXCOORD0 ) : SV_Target
{
    uint materialId = cb.MaterialId;
    return textures[materialId].Sample(samp, texCoords);
}

Why is it this way? That is because on low level, GPU-s are made of SIMD processors. Each of its small processors executes shader instructions over multiple "SIMD threads" (or "warps", or "wavefronts", however you call them), not a single (scalar) value. Because of that, knowing that the resource index will always be the same on all SIMD threads can result in some optimizations and more efficient execution.

Resource indices in Direct3D 12 actually can be non-uniform (divergent) - different in every vertex/pixel/etc., like when they are result of some calculations based on vertex attributes or pixel position. But they must be then surrounded by a special, "pseudo"-function in HLSL, called NonUniformResourceIndex. For example:

Texture2D<float4> textures[16] : register(t0);
SamplerState samp : register(s0);

float4 PS(
    in float2 texCoords : TEXCOORD0,
    in uint materialId : MATERIAL_ID ) : SV_Target
{
    return textures[NonUniformResourceIndex(materialId)].Sample(samp, texCoords);
}

This may look a bit unintuitive, so I expect many developers will make the mistake and omit this function. If you use a non-uniform value as resource index, but forget to mark it with NonUniformResourceIndex, HLSL compiler probably won't warn you about it. It may even work in some cases and on some GPU-s, while it will give invalid (undefined) results on others. So similarly to the issue with reduced precision in normalize/length operations in GLSL, this is a thing to be careful with when coding your shaders in HLSL using new Shader Model 5.1.

Update 2023-10-05: I recommend a follow-up article I've written 5 years later: "Which Values Are Scalar in a Shader?". It explains the topic in more details and also introduces differentiation between values that are uniform across the entire draw call or compute dispatch (constant) versus uniform in a single wave (scalar).

Update 2025-07-30: For debugging related issues on AMD GPUs, see also my later article: "Debugging AMD-Specific Issues with Driver Experiments Tool"

Comments | #directx Share

Pages: > 1 ... 22 23 24 25 26 ... 150 >

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2026