Posts Tagged - C++

Crossplatform C++ Arch detection

You can simply get current arch usign following code, where on windows can be used GetNativeSystemInfo() and on macos and linux uname() function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
std::string GetOSArch()
{
#ifdef CPK_OS_WIN
    SYSTEM_INFO info;
    GetNativeSystemInfo(&info);
    switch (info.wProcessorArchitecture) {
        case PROCESSOR_ARCHITECTURE_AMD64:
            return "x86_64";
        case PROCESSOR_ARCHITECTURE_INTEL:
            return "x86";
        case PROCESSOR_ARCHITECTURE_IA64:
            return "ia64";
    };
#endif
#if defined(CPK_OS_LINUX) || defined(CPK_OS_MACOS)
    long ret = -1;
    struct utsname u;

    if (ret == -1)
        ret = uname(&u);
    if (ret != -1) {
        if (strlen(u.machine) == 4 && u.machine[0] == 'i'
                && u.machine[2] == '8' && u.machine[3] == '6')
            return std::string("x86");
        if (strcmp(u.machine, "amd64") == 0) // Solaris
            return std::string("x86_64");

        return std::string(u.machine);
    }
#endif
    return "";
}

OS detection can be done for example on cmake side or with other definition like __WIN32:

1
2
3
4
5
6
7
8
9
if(WIN32)
    add_definitions(-DCPK_OS_WIN)
else()
    if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
        add_definitions(-DCPK_OS_MACOS)
    else()
        add_definitions(-DCPK_OS_LINUX)
    endif()
endif()

Read More

Missmatch of libstd++ library / _zst28__throw_bad_array_new_lengthv error

For example you install new compiler or MinGW C++ and you met error of _zst28__throw_bad_array_new_lengthv after compile time. You can verify you compiler with simple example:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <vector>

using namespace std;
int main(void)
{
    vector <int> a = {2, 0, 1}; // problem line
    cout << "hellow world";
    return 0;
}

If you still get error on such simple example you have system libstd++ missmatch. Your system is taking this library from some other part of the system (NOT from compiler directory) of the %PATH% location. Edit you PATH variable and make compiler directory (for example: c:\mingw64\bin) to be ABOVE the problematic one. Or with other words: compiler directory must have more priority. Very popular problematic place is git - C:\Git\mingw64\bin, move it to the end of %PATH%.

The error must go away.

Read More

GStreamer H264/MP4 decoding C/C++ basics and encoding/decoding buffers manipulations

Exploring GStreamer and pipelines

Before proceeding to code review, let’s look at what we can do without it. GStreamer includes useful utilities to work with, in particular:

  • gst-inspect-1.0 will allow you to see a list of available codecs and modules, so you can immediately see what will do with it and select a set of filters and codecs.
  • gst-launch-1.0 allows you to start any pipeline. GStreamer uses a decoding scheme where a stream passes through different components in series, from source to sink output. You can choose anything as a source: a file, a device, the output (sink) also may be a file, a screen, network outputs, and protocols (like RTP).

Simple example of using gst-launch-1.0 to connect elements and play audio:

1
gst-launch-1.0 filesrc location=/path/to/file.ogg ! decodebin ! alsasink
How to sink and src works

Filesrc will open file, decodebin - decode it, and alsasink will output audio.

Another more complex example of playing an mp4 file:

1
gst-launch-1.0 filesrc location=file.mp4 ! qtdemux ! h264parse ! avdec_h264 ! videoconvert ! autovideosink

The input accepts the mp4 file, which goes through the mp4 demuxer — qtdemux, then through the h264 parser, then through the decoder, the converter, and finally, the output.

You can replace autovideosink with filesink with a file parameter and output the decoded stream directly to the file.

Programming an application with GStreamer C/C++ API. Let’s try to decode

Now when we know how to use gst-launch-1.0, we are doing the same thing within our application. The principle remains the same: we are building in a decoding pipeline, but now we are using the GStreamer library and glib-events.

We will consider a live example of H264 decoding.

Initialization of the GStreamer application takes place once with the help of

1
gst_init (NULL, NULL);

Read More

Android NDK AAC decoder ADTS alignment

After a long thought, I finally decided to switch my blog articles to english, and continue to give some rare and mostly unintresting info in free form. And today we will talk more about Android, NDK and some undocumentated video/audio functionality, maybe will discover some new knowlage about AAC and maybe it will help your own problem, like it was for me. In a focus of this acrticle is Android AAC decoder, and a little detail how the decoding in android working behind NDK documentation.

AMediaCodec using steps

First let take a very very surface look how to start decoding using NDK:

  1. Create AMediaCodec using codec name.
  2. Configure AMediaCodec via AMediaCodec_configure.
  3. Ctart decoding AMediaCodec_start.
  4. Give a buffer using AMediaCodec_getInputBuffer.
  5. Back buffer with AMediaCodec_queueInputBuffer.
  6. Repeat while you have an buffer ;).

Looks very simple, and work good as well. I can end this article in this place, but I don’t tell you nothing about buffer requirenments and other stuffs, and in NDK/SDK also all simple like that. So what going on behind this android decoding? What if you getting some error with your buffer, or you don’t have sound in some rare cases? How the Android decoder works like, let take a look at AAC audio decoder as example. Let’s begin from simple.

Android AAC decoder architecture

As you see on this bad jpeg picture :) Android have different implementation of AAC decoders as OMX components. But that’s not all, beside some software implemetation on some platforms existed hardware implementation, like on Broadcom chips. Keep at mind, and will transport to SoftAAC2 decoder. Let take a look deeper.

Read More

Send Ctrl+C event to any Windows window

In some cases you want close the window on windows with ctrl+c combination, or invoke event for different reasons. On windows you can make such small program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
 int pid = atoi( argv[1] );
 printf("kill in console %d", pid);

 FreeConsole();
 if (AttachConsole(pid))
 {
     SetConsoleCtrlHandler(NULL, true);
     GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
     FreeConsole();
     SetConsoleCtrlHandler(NULL, false);
 }


 return 0;
}

As argument you can pass a pid or the window proccess. (You can get it via system monitor).

Read More