0

I wanted to create multithreading mjpeg streaming in c++, and I succeded with single thread, but when I try to start the "stream" function in a separate thread or using std::async (I thought async was better than create a thread in this case), I don't understand why, it doesn't work. That function, seems not to start in other thread. Please can you help me? Thanks

streamer.cpp

#include "streamer.h"
#include <cstring>
#include <sys/types.h>
#include <unistd.h>
#include <future>

void Streamer::stream(int socket)
{
    std::string image, buffer;
    int check = send(socket, header.c_str(), header.size(), MSG_NOSIGNAL);
    while (check > 0)
    {
        image = camera->getFrameInByteArray();
        buffer = "--boundary\r\n"
                 "Content-Type: image/jpeg\r\n"
                 "Content-Length: " + std::to_string(image.size()) + "\r\n\r\n" + image;
        check = send(socket, buffer.c_str(), buffer.size(), MSG_NOSIGNAL);
    }
    close(socket);
}

void Streamer::start() {    
    bindChannel();
    listen(socketFileDescriptor, 5);
    socklen_t clientLenght = sizeof(clientAddress);
    while(1) {
        newSocketFileDescriptor = accept(socketFileDescriptor, (struct sockaddr *) &clientAddress, &clientLenght);
        if (newSocketFileDescriptor < 0)
            error("Error accepting request");

        /*If I do this, I can't serve more than one request*/
        std::async(std::launch::async, &Streamer::stream, this, newSocketFileDescriptor);

    }
    close(socketFileDescriptor);
}

void Streamer::error(std::string msg){...}

void Streamer::bindChannel(){...}

Streamer::~Streamer(){...}

Streamer::Streamer(int port, int cameraAddress){...}

EDIT:

I tried to define as static and modify stream() function in this way:

void Streamer::stream(Camera &cam, int socket)
{
    std::string head =  "HTTP/1.1 200 OK\r\n"
                        "Connection: close\r\n"
                        "Max-Age: 0\r\n"
                        "Expires: 0\r\n"
                        "Cache-Control: no-cache, private\r\n"
                        "Pragma: no-cache\r\n"
                        "Content-Type: multipart/x-mixed-replace;boundary=--boundary\r\n\r\n";

    std::string image, buffer;
    int check = send(socket, head.c_str(), head.size(), MSG_NOSIGNAL);
    while (check > 0)
    {
        image = cam.getFrameInByteArray();
        buffer = "--boundary\r\n"
                 "Content-Type: image/jpeg\r\n"
                 "Content-Length: " + std::to_string(image.size()) + "\r\n\r\n" + image;
        check = send(socket, buffer.c_str(), buffer.size(), MSG_NOSIGNAL);
    }
    close(socket);
}

and I tried these:

//std::thread{Streamer::stream, std::ref(*camera), newSocketFileDescriptor}.detach();
//auto f = std::async(std::launch::async, Streamer::stream, std::ref(*camera), newSocketFileDescriptor);
//std::async(std::launch::async, Streamer::stream, std::ref(*camera), newSocketFileDescriptor);

In all cases I can serve only one request at a time

Sam
  • 263
  • 2
  • 12
  • You seem to have left out the code you claim you tried. We're not mind readers, we can't tell you why what you tried doesn't work unless we can see what you tried *first*. – WhozCraig Sep 02 '17 at 12:35
  • You should do this: auto future_value = std::async(std::launch::async, &Streamer::stream, this, newSocketFileDescriptor); then it will execute in a separate thread else it will execute synchronously – Asesh Sep 02 '17 at 12:54
  • Ok, sorry I edited the code. – Sam Sep 02 '17 at 12:55
  • @Sam Did you try doing so? That should solve your problem – Asesh Sep 02 '17 at 13:10
  • @Asesh Yes sorry it doesn't work. I think problem is that resources used in stream() function cannot be used more than one time at the same time, so now I wrote stream() as static method, passing Camera object as parameters so that it can call the function getFrameInByteArray() from the parameter without using "camera" that is an object in the class Streamer. – Sam Sep 02 '17 at 13:19
  • 2
    I suppose You have to read https://stackoverflow.com/questions/23455104/why-is-the-destructor-of-a-future-returned-from-stdasync-blocking – Artemy Vysotsky Sep 02 '17 at 13:19
  • Ok, I just solved it myself. I don't know why, but I changed socket family to PF_INET and used a detached thread with that static method and it works. Thanks and sorry. – Sam Sep 02 '17 at 21:06

0 Answers0