YARP
Yet Another Robot Platform
H264Stream.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include "H264Stream.h"
10 #include "H264LogComponent.h"
11 
12 #include <yarp/os/LogStream.h>
13 #include <yarp/sig/Image.h>
15 
16 #include <cstdio>
17 #include <cstring>
18 
19 
20 //#define debug_time 1
21 
22 #ifdef debug_time
23  #include <yarp/os/Time.h>
24  #define DBG_TIME_PERIOD_PRINTS 10 //10 sec
25 #endif
26 
27 
28 using namespace yarp::os;
29 using namespace yarp::sig;
30 using namespace std;
31 
33  delegate(nullptr),
34  blobHeader{0,0,0},
35  phase(0),
36  cursor(nullptr),
37  remaining(0),
38  decoder(nullptr),
39  cfg(config)
40 {}
41 
43 {
44  delete decoder;
45  delete delegate;
46 }
47 
48 
49 
51 {
52  delegate = stream;
53  if(nullptr == delegate)
54  {
55  return false;
56  }
57  return true;
58 }
59 
61 {
62  decoder = new H264Decoder(this->cfg);
63  decoder->init();
64  decoder->start();
65 }
66 
68 {
69  return *this;
70 }
71 
73 {
74  return *this;
75 }
76 
77 //using yarp::os::OutputStream::write;
78 
79 
80 //using yarp::os::InputStream::read;
81 
82 bool H264Stream::setReadEnvelopeCallback(InputStream::readEnvelopeCallbackType callback, void* data)
83 {
84  return true;
85 }
86 
88 {
89 
90 #ifdef debug_time
91  static bool isFirst = true;
92  double start_time = Time::now();
93  double start_timeCopy;
94  double end_time=0;
95  static double last_call;
96  static double sumOf_timeBetweenCalls=0;
97 
98  static double sumOf_timeOnMutex = 0;
99  static double sumOf_timeOfCopyPerPahse[5] ={0};
100  static uint32_t count=0;
101  static uint32_t countPerPhase[5]={0};
102  #define MAX_COUNT 100
103 
104 
105  if(isFirst)
106  {
107  last_call = start_time;
108  isFirst = false;
109  }
110  else
111  {
112  sumOf_timeBetweenCalls+=(start_time -last_call);
113  last_call = start_time;
114  }
115 
116 
117 #endif
118 
119  if (remaining==0)
120  {
121  if (phase==1)
122  {
123  phase = 2;
124  cursor = (char*)(img.getRawImage());
125  remaining = img.getRawImageSize();
126  } else if (phase==3)
127  {
128  phase = 4;
129  cursor = nullptr;
130  remaining = blobHeader.blobLen;
131  } else
132  {
133  phase = 0;
134  }
135  }
136  while (phase==0)
137  {
138  decoder->mutex.lock();
139  int len = 0;
140  if(decoder->newFrameIsAvailable())
141  {
142  ImageOf<PixelRgb> & img_dec = decoder->getLastFrame();
143  img.copy(img_dec);
144  len = decoder->getLastFrameSize();
145  decoder->mutex.unlock();
146  #ifdef debug_time
147  end_time = Time::now();
148  sumOf_timeOnMutex +=(end_time - start_time);
149  count++;
150  if(count>=MAX_COUNT)
151  {
153  "STREAM On %d times: timeOnMutex is long %.6f sec",
154  MAX_COUNT, (sumOf_timeOnMutex/MAX_COUNT) );
155  for(int x=0; x<5; x++)
156  {
158  "STREAM: phase:%d, count=%u, time=%.6f sec",
159  x,
160  countPerPhase[x],
161  ((countPerPhase[x]==0) ? 0: sumOf_timeOfCopyPerPahse[x]/countPerPhase[x]) );
162  countPerPhase[x] = 0;
163  sumOf_timeOfCopyPerPahse[x] = 0;
164  }
165  yCDebug(H264CARRIER, "sleep=%.6f", sumOf_timeBetweenCalls/count);
167  count = 0;
168  isFirst = true;
169  sumOf_timeOnMutex = 0;
170  sumOf_timeBetweenCalls = 0;
171  }
172  #endif
173 
174  }
175  else
176  {
177  yCTrace(H264CARRIER, "h264Stream::read has been called but no frame is available!!");
178  phase = 0;
179  remaining = 0;
180  cursor = nullptr;
181  decoder->setReq();
182  decoder->mutex.unlock();
183  decoder->semaphore.waitWithTimeout(1);
184  return 0;
185  }
186 
187  yCTrace(H264CARRIER, "Length is \"%d\"", len);
188 
189  imgHeader.setFromImage(img);
190  phase = 1;
191  cursor = (char*)(&imgHeader);
192  remaining = sizeof(imgHeader);
193  }
194 
195  if (remaining>0)
196  {
197  size_t allow = remaining;
198  if (b.length()<allow)
199  {
200  allow = b.length();
201  }
202  if (cursor!=nullptr)
203  {
204  #ifdef debug_time
205  start_timeCopy = Time::now();
206  #endif
207  memcpy(b.get(),cursor,allow);
208  cursor+=allow;
209  remaining-=allow;
210  yCDebug(H264CARRIER, "returning %zd bytes", allow);
211  #ifdef debug_time
212  end_time = Time::now();
213  sumOf_timeOfCopyPerPahse[phase] +=(end_time - start_timeCopy);
214  countPerPhase[phase]++;
215  #endif
216  return allow;
217  } else
218  {
219  yarp::conf::ssize_t result = delegate->getInputStream().read(b);
220  yCTrace(H264CARRIER, "Read %zu bytes", result);
221  if (result>0)
222  {
223  remaining-=result;
224  yCTrace(H264CARRIER, "%zu bytes of meat", result);
225  return result;
226  }
227  }
228  }
229  return -1;
230 }
231 
232 
233 void H264Stream::write(const Bytes& b)
234 {
235  delegate->getOutputStream().write(b);
236 }
LogStream.h
H264Stream.h
H264Decoder::getLastFrameSize
int getLastFrameSize()
Definition: H264Decoder.cpp:525
ImageNetworkHeader.h
yarp::sig
Signal processing.
Definition: Image.h:25
H264Decoder::start
bool start()
Definition: H264Decoder.cpp:483
H264Decoder::setReq
void setReq()
Definition: H264Decoder.cpp:531
yarp::os::OutputStream
Simple specification of the minimum functions needed from output streams.
Definition: OutputStream.h:25
yarp::sig::ImageNetworkHeader::setFromImage
void setFromImage(const Image &image)
Definition: ImageNetworkHeader.h:58
H264Stream::~H264Stream
virtual ~H264Stream()
Definition: H264Stream.cpp:42
yarp::os::Time::now
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
yarp::sig::ImageOf< PixelRgb >
H264Stream::getInputStream
InputStream & getInputStream() override
Get an InputStream to read from.
Definition: H264Stream.cpp:67
yarp::os::Bytes::get
const char * get() const
Definition: Bytes.cpp:30
h264Decoder_cfgParamters
Definition: H264Decoder.h:17
yarp::os::Bytes::length
size_t length() const
Definition: Bytes.cpp:25
H264Stream::H264Stream
H264Stream(h264Decoder_cfgParamters &config)
Definition: H264Stream.cpp:32
H264Decoder::mutex
std::mutex mutex
Definition: H264Decoder.h:44
yarp::conf::ssize_t
::ssize_t ssize_t
Definition: numeric.h:60
H264LogComponent.h
yarp::os::impl::DgramTwoWayStream
A stream abstraction for datagram communication.
Definition: DgramTwoWayStream.h:40
yarp::wire_rep_utils::BlobNetworkHeader::blobLen
yarp::os::NetInt32 blobLen
Definition: BlobNetworkHeader.h:26
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
H264Stream::start
void start()
Definition: H264Stream.cpp:60
Image.h
H264Decoder::init
bool init()
Definition: H264Decoder.cpp:456
H264Stream::write
void write(const yarp::os::Bytes &b) override
Write a block of bytes to the stream.
Definition: H264Stream.cpp:233
H264Stream::getOutputStream
OutputStream & getOutputStream() override
Get an OutputStream to write to.
Definition: H264Stream.cpp:72
yarp::os::InputStream::read
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:23
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yCDebug
#define yCDebug(component,...)
Definition: LogComponent.h:112
H264Stream::setReadEnvelopeCallback
bool setReadEnvelopeCallback(InputStream::readEnvelopeCallbackType callback, void *data) override
Definition: H264Stream.cpp:82
H264Decoder
Definition: H264Decoder.h:38
Time.h
yarp::os::Semaphore::waitWithTimeout
bool waitWithTimeout(double timeoutInSeconds)
Try to decrement the counter, even if we must wait - but don't wait forever.
Definition: Semaphore.cpp:104
yCTrace
#define yCTrace(component,...)
Definition: LogComponent.h:88
H264Stream::setStream
bool setStream(yarp::os::impl::DgramTwoWayStream *stream)
Definition: H264Stream.cpp:50
yarp::os::InputStream
Simple specification of the minimum functions needed from input streams.
Definition: InputStream.h:29
H264CARRIER
const yarp::os::LogComponent & H264CARRIER()
Definition: H264LogComponent.cpp:16
H264Decoder::newFrameIsAvailable
bool newFrameIsAvailable()
Definition: H264Decoder.cpp:519
H264Decoder::getLastFrame
yarp::sig::ImageOf< yarp::sig::PixelRgb > & getLastFrame()
Definition: H264Decoder.cpp:511
H264Decoder::semaphore
yarp::os::Semaphore semaphore
Definition: H264Decoder.h:45