January 2016

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

21:17
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.

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

17:07
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

STAT NO AD
[Stat] [STAT NO AD] [Download] [Dropbox] [pub] [Mirror]
Copyright © 2004-2017