🌐 English

    Pipe API#

    Oasis Pipe supports Inter-Process Communication (IPC).

    It utilizes the oasis namespace.

    It is specialized for transmitting video or audio data. It is useful when writing video data to a v4l2loopback device.

    Oasis Pipe is not dependent on other Oasis components and can be used without oasis::initialize, allowing applications that do not use Oasis to also link with and use the liboasis_pipe.so library.

    Header File#

    OasisPipe.h

    Type Definitions#

    The data formats supported by Oasis Pipe are as follows. In the case of video, it is compatible with V4L2 formats.

    enum {
      kOasisPipeDataTypeUserData = 0,
      kOasisPipeDataTypeVideoBGRA,
      kOasisPipeDataTypeVideoARGB,
      kOasisPipeDataTypeVideoYUYV,
      kOasisPipeDataTypeVideoYVYU,
      kOasisPipeDataTypeVideoYUV420,
      kOasisPipeDataTypeVideoYVU420,
      kOasisPipeDataTypeVideoNV12,
      kOasisPipeDataTypeVideoNV21,
      kOasisPipeDataTypeAudioPCM16LE,
      kOasisPipeDataTypeAudioPCM16BE,
    
      //in case of the following types, width_or_sampling_rate, height_or_channels, stride_or_bits_per_sample are ignored.
      kOasisPipeDataTypeVideoH264,
      kOasisPipeDataTypeVideoH265,
      kOasisPipeDataTypeVideoVP8,
      kOasisPipeDataTypeVideoVP9,
      kOasisPipeDataTypeVideoMJPEG,
    };
    
    int32_t pipeDataTypeToV4l2Format ( int32_t data_type )
    OasisPipe.h
    Converts an Oasis pipe data type into a V4L2 format type.
    Parameters
    data_type  The Oasis pipe data type.
    Return Value
    The V4L2 format type. Returns -1 if it is not supported.

    The conversion maps as follows:

    From To
    kOasisPipeDataTypeVideoBGRA V4L2_PIX_FMT_ABGR32
    kOasisPipeDataTypeVideoARGB V4L2_PIX_FMT_ARGB32
    kOasisPipeDataTypeVideoYUYV V4L2_PIX_FMT_YUYV
    kOasisPipeDataTypeVideoYVYU V4L2_PIX_FMT_YYUV
    kOasisPipeDataTypeVideoYUV420 V4L2_PIX_FMT_YUV420
    kOasisPipeDataTypeVideoYVU420 V4L2_PIX_FMT_YVU420
    kOasisPipeDataTypeVideoNV12 V4L2_PIX_FMT_NV12
    kOasisPipeDataTypeVideoNV21 V4L2_PIX_FMT_NV21
    kOasisPipeDataTypeVideoH264 V4L2_PIX_FMT_H264
    kOasisPipeDataTypeVideoH265 V4L2_PIX_FMT_H265
    kOasisPipeDataTypeVideoVP8 V4L2_PIX_FMT_VP8
    kOasisPipeDataTypeVideoVP9 V4L2_PIX_FMT_VP9
    kOasisPipeDataTypeVideoMJPEG V4L2_PIX_FMT_MJPEG
    int32_t v4l2FormatToPipeDataType ( int32_t format )
    OasisPipe.h
    Converts a V4L2 format type into an Oasis pipe data type.
    Parameters
    format  The V4L2 format type.
    Return Value
    Returns the Oasis pipe data type. Returns -1 if it is not supported.

    The conversion maps as follows:

    From To
    V4L2_PIX_FMT_BGR32 kOasisPipeDataTypeVideoBGRA
    V4L2_PIX_FMT_ABGR32 kOasisPipeDataTypeVideoBGRA
    V4L2_PIX_FMT_RGB32 kOasisPipeDataTypeVideoARGB
    V4L2_PIX_FMT_ARGB32 kOasisPipeDataTypeVideoARGB
    V4L2_PIX_FMT_YUYV kOasisPipeDataTypeVideoYUYV
    V4L2_PIX_FMT_YYUV kOasisPipeDataTypeVideoYVYU
    V4L2_PIX_FMT_YUV420 kOasisPipeDataTypeVideoYUV420
    V4L2_PIX_FMT_YVU420 kOasisPipeDataTypeVideoYVU420
    V4L2_PIX_FMT_NV12 kOasisPipeDataTypeVideoNV12
    V4L2_PIX_FMT_NV21 kOasisPipeDataTypeVideoNV21
    V4L2_PIX_FMT_H264 kOasisPipeDataTypeVideoH264
    V4L2_PIX_FMT_H265 kOasisPipeDataTypeVideoH265
    V4L2_PIX_FMT_VP8 kOasisPipeDataTypeVideoVP8
    V4L2_PIX_FMT_VP9 kOasisPipeDataTypeVideoVP9
    V4L2_PIX_FMT_MJPEG kOasisPipeDataTypeVideoMJPEG

    Writer#

    OasisPipeWriterRef pipeWriterOpen ( const char * pipe_path )
    OasisPipe.h
    Creates a pipe writer object.
    Parameters
    pipe_path  The pipe path. If the path starts with /dev/video, it is considered a v4l2loopback device, and the writer object is created for the purpose of writing video data.
    Return Value
    Returns the pipe writer object on success. Returns nullptr on failure.
    int32_t pipeWriterClose ( OasisPipeWriterRef & pipe )
    OasisPipe.h
    Releases the pipe writer object.
    Parameters
    pipe  The pipe writer object.
    Return Value
    • 0: Success
    • -1: Failure
    ssize_t pipeWriterWrite ( const OasisPipeWriterRef & pipe , const void * data , size_t length , int32_t width_or_sampling_rate , int32_t height_or_channels , int32_t stride_or_bits_per_sample , int32_t data_type , uint32_t flags )
    OasisPipe.h
    Transmits data to the pipe.
    Parameters
    pipe  The pipe writer object.
    data  The data pointer.
    length  The data length. Measured in bytes.
    width_or_sampling_rate  Specifies the width value in the case of video data, or the sampling rate in the case of audio data. For user data, it is defined and used arbitrarily.
    height_or_channels  Specifies the height value in the case of video data, or the number of channels in the case of audio data. For user data, it is defined and used arbitrarily.
    stride_or_bits_per_sample  Specifies the width stride value in the case of video data, or the sample size in the case of audio data. For user data, it is defined and used arbitrarily.
    data_type  Specifies the pipe data type.
    flags  Specifies the flag values. Enter a value of 0.
    Return Value
    Returns the data length on success. Returns -1 on failure, and if an error callback function is registered, detailed information is delivered by invoking the callback function.
    void pipeWriterSetErrorCallback ( const OasisPipeWriterRef & pipe , std::function<void(int32_t, const void *, size_t, void *)> error_callback , void * user )
    OasisPipe.h
    Registers a callback function that is invoked when an error event occurs while writing.
    Parameters
    pipe  The pipe writer object.
    error_callback 
    user  The user data to be passed as a parameter to the callback function.

    The error event callback function is as follows:

    typedef  void  (*error_callback_) ( int32_t errno , const void * data , size_t length , void * user_data )
    OasisPipe.h
    Parameters
    errno  The errno value.
    data  The data pointer passed during the write call.
    length  The data length passed during the write call.
    user_data  The user data passed during callback registration.

    Reader#

    OasisPipeReaderRef pipeReaderOpen ( const char * pipe_path )
    OasisPipe.h
    Creates a pipe reader object.
    Parameters
    pipe_path  The pipe path.
    Return Value
    Returns the pipe reader object on success. Returns nullptr on failure.
    void pipeReaderSetCallback ( const OasisPipeReaderRef & pipe , std::function<void(const void *, size_t, int32_t, int32_t, int32_t, int32_t, uint32_t)> callback )
    OasisPipe.h
    Registers a callback function that is invoked when complete data has been read from the pipe.
    Parameters
    pipe  The pipe reader object.
    callback  Registers the read callback function.

    The type definition for the read callback function is as follows:

    typedef  void  (*callback) ( const void * data , size_t size , int32_t width_or_sampling_rate , int32_t height_or_channels , int32_t stride_or_bits_per_sample , int32_t data_type , uint32_t flags )
    OasisPipe.h
    Parameters
    data  The buffer pointer where the data is stored.
    size  The data length. Measured in bytes.
    width_or_sampling_rate  Indicates the width value in the case of video data, or the sampling rate in the case of audio data. For user data, it is defined and used arbitrarily.
    height_or_channels  Indicates the height value in the case of video data, or the number of channels in the case of audio data. For user data, it is defined and used arbitrarily.
    stride_or_bits_per_sample  Indicates the width stride value in the case of video data, or the sample size in the case of audio data. For user data, it is defined and used arbitrarily.
    data_type  The data type.
    flags  The flag value.
    int32_t pipeReaderClose ( OasisPipeReaderRef & pipe )
    OasisPipe.h
    Releases the pipe reader object.
    Parameters
    pipe  The pipe reader object.
    Return Value
    • 0: Success
    • -1: Failure

    Example#

    Below is an example where one process requests an OFFS format via a pipe to another process and receives the response via a pipe.

    The JsonCpp library is used for JSON processing.

    Command Requesting Process#

    Create the read and write pipes and register callbacks for each.

    OasisPipeReaderRef pipe_reader_ = pipeReaderOpen("/tmp/oasis-mon-res");
    pipeReaderSetCallback(pipe_reader_, std::bind(&onPipeCommandCompleted, _1, _2, _3, _4, _5, _6, _7));
    
    OasisPipeWriterRef pipe_writer_ = pipeWriterOpen("/tmp/oasis-mon-req");
    pipeWriterSetErrorCallback(pipe_writer_, std::bind(&onPipeCommandWriteError, _1, _2, _3, _4), nullptr);
    

    The read callback function:

    void onPipeCommandCompleted(const void *data, size_t length, int32_t width, int32_t height, int32_t stride, int32_t data_type, uint32_t flags)
    {
      std::string reply((const char*)data, (const char*)data+length);
    
      Json::Value json_reply;
      Json::Reader reader;
      bool parsing_ok = reader.parse(reply.c_str(), json_reply);
      if(!parsing_ok) {
        return;
      }
    
      if(json_reply.isMember("result")) {
        // Verifies the result.
        int32_t result = std::stoi(json_reply["result"].asString());
      }
    }
    

    The write error event callback function:

    void DashApp::onPipeCommandWriteError(int32_t error, const void *data, size_t length, void *user)
    {
    }
    

    Delivers the OFFS format command to the command executing process.

    Json::Value json_req;
    json_req["cmd"] = "format";
    
    Json::FastWriter fastWriter;
    std::string json_string = fastWriter.write(json_req);
    
    pipeWriterWrite(pipe_writer_, json_string.c_str(), json_string.length(), 0, 0, 0, 0, 0);
    

    Command Executing Process#

    Create the read and write pipes and register callbacks for each. The paths used in the command requesting process are switched and used.

    // Executes the command and delivers the result to the command requesting process.
    OasisPipeWriterRef writer = pipeWriterOpen("/tmp/oasis-mon-res");
    
    // Reads the command request message from the command requesting process.
    OasisPipeReaderRef reader = pipeReaderOpen("/tmp/oasis-mon-req");
    pipeReaderSetCallback(reader, std::bind(&onCommand, _1, _2, _3, _4, _5, _6, _7));
    

    The command reading callback function:

    static void onCommand(const void *data, size_t length, int32_t width, int32_t height, int32_t stride, int32_t data_type, uint32_t flags)
    {
      if(length == 0) {
        //nothing to do
        return;
      }
    
      std::string cmd((const char *)data, (const char *)data+length);
    
      Json::Value json_req;
      Json::Reader reader;
      bool parsing_ok = reader.parse(cmd.c_str(), json_req);
      if(!parsing_ok) {
        fprintf(stdout, "pipe req: json parsing error: %s\n", cmd.c_str());
        continue;
      }
    
      if(json_req.isMember("cmd") == false) {
        fprintf(stdout, "pipe req: \"cmd\" not found!: %s\n", cmd.c_str());
        continue;
      }
    
      std::string req_cmd = json_req["cmd"].asString();
      if(req_cmd == "format") {
        // Proceeds with formatting the file system.
        char shell_cmd[PATH_MAX];
        int32_t req_cmd_result = 0;
        sprintf(shell_cmd, "/usr/sbin/mkfs.offs /dev/mmcblk0p1 /etc/offs-format.cfg 32GB_DRV");
        err = runCommand(shell_cmd);
        if(err) {
          req_cmd_result = -err;
        }
    
        Json::Value json_reply;
    
        json_reply["result"] = std::to_string(req_cmd_result);
        json_reply["cmd"] = req_cmd;
    
        Json::FastWriter fastWriter;
        std::string json_string = fastWriter.write(json_reply);
    
        pipeWriterWrite(writer, json_string.c_str(), json_string.length(), 0, 0, 0, 0, 0);
      }
    }
    

    The function that executes the command using the popen function:

    #define MAXLINE 4096
    
    static int32_t runCommand(const char *shell_cmd)
    {
        char buff[MAXLINE];
        FILE *fp;
    
        fp = popen(shell_cmd, "r");
        if(fp == NULL) {
            fprintf(stderr, "\"%s\" popen error: %d(%s)\n", shell_cmd, errno, strerror(errno));
            return -errno;
        }
    
        while(fgets(buff, MAXLINE, fp) != NULL) {
            fprintf(stdout, "%s", buff);
            fflush(stdout);
        }
    
        return (int32_t)(int8_t)pclose(fp);
    }