YARP
Yet Another Robot Platform
MjpegStream.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include "MjpegStream.h"
8#include "MjpegLogComponent.h"
9
10#include <yarp/sig/Image.h>
12
13#include <cstdio>
14#include <cstring>
15
16using namespace yarp::os;
17using namespace yarp::sig;
18
20 if (remaining==0) {
21 if (phase==1) {
22 phase = 2;
23 cursor = (char*)(img.getRawImage());
24 remaining = img.getRawImageSize();
25 } else if (phase==3) {
26 phase = 4;
27 cursor = nullptr;
28 remaining = blobHeader.blobLen;
29 } else {
30 phase = 0;
31 }
32 }
33 while (phase==0 && delegate->getInputStream().isOk()) {
34 std::string s;
35 do {
36 s = delegate->getInputStream().readLine();
37 yCTrace(MJPEGCARRIER, "Read \"%s\"", s.c_str());
38 } while ((s.length()==0||s[0]!='-') && delegate->getInputStream().isOk());
39 s = delegate->getInputStream().readLine();
40 if (s!="Content-Type: image/jpeg") {
41 if (!delegate->getInputStream().isOk()) {
42 break;
43 }
44 yCWarning(MJPEGCARRIER, "Unknown content type - \"%s\"", s.c_str());
45 continue;
46 }
47 yCTrace(MJPEGCARRIER, "Read content type - \"%s\"", s.c_str());
48
49 s = delegate->getInputStream().readLine();
50 yCTrace(MJPEGCARRIER, "Read content length - \"%s\"", s.c_str());
51 Bottle b(s);
52 if (b.get(0).asString()!="Content-Length:") {
53 if (!delegate->getInputStream().isOk()) {
54 break;
55 }
56 yCWarning(MJPEGCARRIER, "Expected Content-Length: got - \"%s\"", b.get(0).asString().c_str());
57 continue;
58 }
59 int len = b.get(1).asInt32();
60 yCTrace(MJPEGCARRIER, "Length is \"%d\"", len);
61 do {
62 s = delegate->getInputStream().readLine();
63 yCTrace(MJPEGCARRIER, "Read \"%s\"", s.c_str());
64 } while (s.length()>0);
65 if (autocompress) {
66 cimg.allocate(len);
67 delegate->getInputStream().readFull(cimg.bytes());
68 if (!decompression.decompress(cimg.bytes(), img)) {
69 if (delegate->getInputStream().isOk()) {
70 yCError(MJPEGCARRIER, "Skipping a problematic JPEG frame");
71 }
72 }
73 imgHeader.setFromImage(img);
74 phase = 1;
75 cursor = (char*)(&imgHeader);
76 remaining = sizeof(imgHeader);
77 } else {
78 // User wants us to pass on jpeg bytes, without compressing.
79 // This can save time if not every frame will be used.
80
81 // We pass on the information in bottle-blob-compatible format.
82 phase = 3;
83 blobHeader.init(len);
84 cursor = (char*)(&blobHeader);
85 remaining = sizeof(blobHeader);
86 }
87 }
88
89 if (remaining>0) {
90 int allow = remaining;
91 if ((int)b.length()<allow) {
92 allow = b.length();
93 }
94 if (cursor!=nullptr) {
95 memcpy(b.get(),cursor,allow);
96 cursor+=allow;
97 remaining-=allow;
98 yCTrace(MJPEGCARRIER, "returning %d bytes", allow);
99 return allow;
100 } else {
101 int result = delegate->getInputStream().read(b);
102 yCTrace(MJPEGCARRIER, "Read %d bytes", result);
103 if (result>0) {
104 remaining-=result;
105 yCTrace(MJPEGCARRIER, "%d bytes of meat", result);
106 return result;
107 }
108 }
109 }
110 return -1;
111}
112
113
114void MjpegStream::write(const Bytes& b) {
115 delegate->getOutputStream().write(b);
116}
const yarp::os::LogComponent & MJPEGCARRIER()
bool decompress(const yarp::os::Bytes &data, yarp::sig::FlexImage &image)
void write(const yarp::os::Bytes &b) override
Write a block of bytes to the stream.
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:64
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:246
A simple abstraction for a block of bytes.
Definition: Bytes.h:24
size_t length() const
Definition: Bytes.cpp:22
const char * get() const
Definition: Bytes.cpp:27
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:20
yarp::conf::ssize_t readFull(Bytes &b)
Keep reading until buffer is full.
Definition: InputStream.cpp:96
std::string readLine(const char terminal='\n', bool *success=nullptr)
Read a block of text terminated with a specific marker (or EOF).
Definition: InputStream.cpp:54
const Bytes & bytes() const
void allocate(size_t len)
Makes a data block of the specified length that will be deleted if this object is destroyed.
virtual void write(char ch)
Write a single byte to the stream.
virtual InputStream & getInputStream()=0
Get an InputStream to read from.
virtual OutputStream & getOutputStream()=0
Get an OutputStream to write to.
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:204
virtual std::string asString() const
Get string value.
Definition: Value.cpp:234
void setFromImage(const Image &image)
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:542
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
Definition: Image.cpp:551
#define yCError(component,...)
Definition: LogComponent.h:213
#define yCTrace(component,...)
Definition: LogComponent.h:84
#define yCWarning(component,...)
Definition: LogComponent.h:192
::ssize_t ssize_t
Definition: numeric.h:86
An interface to the operating system, including Port based communication.