YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
ffmpegPortmonitor.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
15// Local imports
16#include "ffmpegPortmonitor.h"
17#include "constants.h"
18// YARP imports
20#include <yarp/os/Time.h>
21#include <yarp/sig/all.h>
22// Standard imports
23#include <cstring>
24#include <cmath>
25#include <algorithm>
26#include <iostream>
27#include <sstream>
28#include <mutex>
29#include <iomanip>
30
31// Ffmpeg imports
32extern "C" {
33 #include <libavcodec/avcodec.h>
34 #include <libavutil/opt.h>
35 #include <libavutil/imgutils.h>
36 #include <libavformat/avformat.h>
37 #include <libswscale/swscale.h>
38}
39
40using namespace yarp::os;
41using namespace yarp::sig;
42
43namespace {
45 "yarp.carrier.portmonitor.image_compression_ffmpeg",
49 nullptr)
50
51void split(const std::string& s, char delim, std::vector<std::string>& elements)
52{
53 std::istringstream iss(s);
54 std::string item;
55 while (std::getline(iss, item, delim))
56 {
57 elements.push_back(item);
58 }
59}
60} // anonymous namespace
61
62// As per version 5.1.2 of ffmpeg, there seem to be race conditions between sws_scale and
63// sws_freeContext even when called from different instances on different threads.
64// We use a static mutex to prevent segmentation faults when connecting two port monitors
65// to the same sender or receiver.
66static std::mutex instances_mutex;
67
69{
70 // Check if this is sender or not
71 senderSide = (options.find("sender_side").asBool());
72 printStatistics = false;
78
79 // Parse command line parameters and set them into global variable "paramsMap"
80 std::string str = options.find("carrier").asString();
81 int frameRate = 15;
83 return false;
84 }
85
86 // Prepare codec context
87 if (codecContext == NULL) {
89 } else {
90 yCError(FFMPEGMONITOR, "Codec context is already allocated");
91 return false;
92 }
93 if (!codecContext) {
94 yCError(FFMPEGMONITOR, "Could not allocate video codec context");
95 return false;
96 }
97
98 if (!codec->pix_fmts)
99 {
100 yCWarning(FFMPEGMONITOR, "The specified codec (%s) has unknown available pixel formats. There might be visualization issues.", codec->name);
101 }
102 else
103 {
104 std::stringstream pixelFormatList;
105 bool found = false;
106 size_t i = 0;
107 AVPixelFormat test = codec->pix_fmts[i];
108
109 if (test == AV_PIX_FMT_NONE)
110 {
111 yCError(FFMPEGMONITOR, "The specified codec (%s) has no available pixel format.", codec->name);
112 return false;
113 }
114
115 pixelFormatList << test;
116 while (test != AV_PIX_FMT_NONE)
117 {
118 if (test == pixelFormat)
119 {
120 found = true;
121 break;
122 }
123 ++i;
124 test = codec->pix_fmts[i];
125
126 if (test != AV_PIX_FMT_NONE)
127 {
128 pixelFormatList << ", " << test;
129 }
130 }
131
132 if (!found)
133 {
135
137 {
138 yCError(FFMPEGMONITOR, "The specified codec (%s) is not compatible with the default pixel format AV_PIX_FMT_YUV420P (code %d). "
139 "Try specifying the suggested pixel format of the codec with the option \"pixel_format.%d\". "
140 "The available pixel formats are %s.",
142 }
143 else
144 {
145 yCError(FFMPEGMONITOR, "The specified codec (%s) is not compatible with the specified pixel format (code %d). "
146 "The available pixel formats are as follows %s (suggested = %d).",
147 codec->name, pixelFormat, pixelFormatList.str().c_str(), suggestedFormat);
148 }
149 return false;
150 }
151 }
152
153 firstTime = true;
154
155 // Set time base parameter
156 codecContext->time_base.num = 1;
157 codecContext->time_base.den = frameRate;
158 // Set command line params
159 if (setCommandLineParams() == -1) {
160 return false;
161 }
162
163 return true;
164}
165
167{
168 paramsMap.clear();
169
170 // Check if codec context is freeable, if yes free it.
171 if (codecContext != NULL) {
172#if LIBAVCODEC_VERSION_MAJOR < 61
173 // See https://github.com/FFmpeg/FFmpeg/blob/n7.0/libavcodec/avcodec.h#L2381-L2384
175#endif
178 }
179}
180
182{
183 yCTrace(FFMPEGMONITOR, "setparam");
184 return false;
185}
186
188{
189 yCTrace(FFMPEGMONITOR, "getparam");
190 return false;
191}
192
194{
195 if (senderSide) {
196 // If sender side
197 yCTrace(FFMPEGMONITOR, "accept - sender");
198 // Try to cast the Thing into an Image
199 Image* img = thing.cast_as< Image >();
200 // If cast fails, try to cast the Thing into a Bottle
201 if(img == nullptr) {
202 Bottle* bt = thing.cast_as<Bottle>();
203 // If cast fails, return error
204 if (bt == nullptr) {
205 yCError(FFMPEGMONITOR, "Expected type Image or Bottle in sender side, but got wrong data type!");
206 return false;
207 }
208 }
209 }
210 else {
211 // If receiver side
212 yCTrace(FFMPEGMONITOR, "accept - receiver");
213 // Try to cast the Thing into a Bottle
214 Bottle* bt = thing.cast_as<Bottle>();
215 // If cast fails, return error
216 if(bt == nullptr){
217 yCError(FFMPEGMONITOR, "Expected type Bottle in receiver side, but got wrong data type!");
218 return false;
219 }
220 }
221 return true;
222}
223
225{
226 double now = yarp::os::Time::now();
227 const double printInterval = 5.0;
228
229 if (statisticsCounter < 0)
230 {
231 previousFrameTime = now;
234 }
235 else
236 {
237 size_t outputData{0};
238 inputBottle.toBinary(&outputData);
239 double dt = now - previousFrameTime;
240 double bandwidth = outputData * 8 / dt /1000;
245
246 }
248 {
251 std::stringstream bandwidthString, lagString;
252 bandwidthString << std::fixed << std::setprecision(2) << bandwidthRunningAverage;
253 lagString << std::fixed << std::setprecision(3) << lagRunningAverage * 1000;
254 yCInfo(FFMPEGMONITOR, "Statistics: current bandwidth %s kb/s, codec computational time %s ms",
255 bandwidthString.str().c_str(), lagString.str().c_str());
256 }
257}
258
260{
261 double startTime = yarp::os::Time::now();
262 if (senderSide) {
263 bool success = true;
264 yCTrace(FFMPEGMONITOR, "update - sender");
265 // Cast Thing into an Image
266 Image* img = thing.cast_as< Image >();
267
268 if (img == nullptr) {
269 Bottle* bot = thing.cast_as<Bottle>();
271 {
272 yCError(FFMPEGMONITOR, "The input type is a Bottle, but it cannot be copied to an Image");
273 success = false;
274 }
275 img = &imageBottleBuffer;
276 }
277
278 // Allocate memory for packet
280 if (packet == NULL) {
281 yCError(FFMPEGMONITOR, "Error in packet allocation");
282 success = false;
283 }
284
285 // Call compress function
286 if (success && compress(img, packet) != 0) {
287 yCError(FFMPEGMONITOR, "Error in compression");
288 success = false;
289 }
290
291 // Insert compressed image into a Bottle to be sent
292 data.clear();
293
294 int successCode = success ? 1 : 0;
296 data.addInt32(img->width());
297 data.addInt32(img->height());
298 data.addInt32(img->getPixelCode());
299 data.addInt32(img->getPixelSize());
300
301 if (success) { // If compression was successful, insert also compressed data
302 // Packet
303 Value p(packet, sizeof(*packet));
304 data.add(p);
305 // Packet data
306 Value d(packet->data, packet->size);
307 data.add(d);
308 // Buffer size
309 data.addInt32(packet->buf->size);
310 // Buffer data
311 Value bd(packet->buf->data, packet->buf->size);
312 data.add(bd);
313
314 // Side data elements
315 for (int i = 0; i < packet->side_data_elems; i++) {
316 data.addInt32(packet->side_data[i].size);
317 data.addInt32(packet->side_data[i].type);
318 Value sd(packet->side_data[i].data, packet->side_data[i].size);
319 data.add(sd);
320 }
321 }
322
323 if (printStatistics)
324 {
326 }
327
329 // Free the memory allocated for the packet
331 }
332 else {
333
334 yCTrace(FFMPEGMONITOR, "update - receiver");
335 // Cast the Thin as a Bottle
337 // Fill the final image with zeros
338 imageOut.zero();
339 // Extract decompression data from the Bottle
340 int width = compressedBottle->get(1).asInt32();
341 int height = compressedBottle->get(2).asInt32();
342 int pixelCode = compressedBottle->get(3).asInt32();
343 int pixelSize = compressedBottle->get(4).asInt32();
344 // Set information into final image
345
347 {
350 imageOut.resize(width, height);
351 }
352 else
353 {
354 yCError(FFMPEGMONITOR, "Invalid input pixel code");
355 }
356
357 // Check if compression was successful
358 if (compressedBottle->get(0).asInt32() == 1) {
359 bool success = true;
360 // Get compressed image from Bottle
361 AVPacket* tmp = (AVPacket*) compressedBottle->get(5).asBlob();
362 // Allocate memory for packet
364 // Set all packet parameters
365 packet->dts = tmp->dts;
366 packet->duration = tmp->duration;
367 packet->flags = tmp->flags;
368 packet->pos = tmp->pos;
369 packet->pts = tmp->pts;
370 packet->side_data_elems = 0;
371 packet->stream_index = tmp->stream_index;
372 packet->size = tmp->size;
373 // Image data
374 packet->data = (uint8_t *) compressedBottle->get(6).asBlob();
375 // Buffer data
376 packet->buf = av_buffer_create((uint8_t *) compressedBottle->get(8).asBlob(),
377 compressedBottle->get(7).asInt32(), av_buffer_default_free,
378 nullptr, AV_BUFFER_FLAG_READONLY);
379
380 // Packet side data
381 for (int i = 0; i < tmp->side_data_elems; i++) {
382
384 (AVPacketSideDataType) compressedBottle->get(10).asInt32(), // Type
385 (uint8_t *) compressedBottle->get(11).asBlob(), // Data
386 compressedBottle->get(9).asInt32()); // Size
387 if (ret < 0) {
388 success = false;
389 break;
390 }
391 }
392
393 // Call to decompress function
394 if (success && decompress(packet, width, height, pixelCode) != 0) {
395 yCError(FFMPEGMONITOR, "Error in decompression");
396 }
397
398 if (printStatistics)
399 {
401 }
402
403 // Free memory allocated for side data and packet
404 av_freep(&packet->side_data);
406
407 }
408
410
411 }
412 return th;
413}
414
416
417 yCTrace(FFMPEGMONITOR, "compress");
420
421 // Get width and height
422 int w = img->width();
423 int h = img->height();
424
425 // Allocate video frame for original frames
427 if (startFrame == NULL) {
428 yCError(FFMPEGMONITOR, "Cannot allocate starting frame!");
429 return -1;
430 }
431
432 // Allocate a video frame for end frame
434 if (endFrame == NULL) {
435 yCError(FFMPEGMONITOR, "Cannot allocate end frame!");
437 return -1;
438 }
439
440 // Allocate space into start frame to contain data
441 int success = av_image_alloc(startFrame->data, startFrame->linesize,
442 w, h,
444
445 if (success < 0) {
446 yCError(FFMPEGMONITOR, "Cannot allocate starting frame buffer!");
449 return -1;
450 }
451
452 // Set Image data into AVFrame
453 startFrame->linesize[0] = img->getRowSize();
454 // Free old pointer (because we will use the buffer contained into img)
455 av_freep(&startFrame->data[0]);
456 startFrame->data[0] = img->getRawImage();
457 startFrame->height = h;
458 startFrame->width = w;
460
461 // Allocate memory for end frame data
462 success = av_image_alloc(endFrame->data, endFrame->linesize,
463 w, h, pixelFormat, 16);
464
465 if (success < 0) {
466 yCError(FFMPEGMONITOR, "Cannot allocate end frame buffer!");
469 return -1;
470 }
471
472 // Set end frame parameters
473 endFrame->height = h;
474 endFrame->width = w;
475 endFrame->format = pixelFormat;
476
477 {
478 std::lock_guard<std::mutex> lock(instances_mutex);
479
480 // Convert the image from start format into end format
481 static struct SwsContext *img_convert_ctx;
482
483 // Allocate context for conversion
486 w, h,
489 NULL, NULL, NULL);
490 if (img_convert_ctx == NULL) {
491 yCError(FFMPEGMONITOR, "Cannot initialize pixel format conversion context!");
492 av_freep(&endFrame->data[0]);
495 return -1;
496 }
497
498 // Perform conversion
499 int ret = sws_scale(img_convert_ctx, startFrame->data, startFrame->linesize, 0,
500 h, endFrame->data, endFrame->linesize);
501
502 if (ret < 0) {
503 yCError(FFMPEGMONITOR, "Could not convert pixel format!");
505 av_freep(&endFrame->data[0]);
508 return -1;
509 }
510
511 if (firstTime) {
512 // If this is the first compression
513
514 // Set codec context parameters
515 codecContext->width = w;
516 codecContext->height = h;
517 codecContext->pix_fmt = pixelFormat;
518
519 // Open codec
521 if (ret < 0) {
522 yCError(FFMPEGMONITOR, "Could not open codec");
524 av_freep(&endFrame->data[0]);
527 return -1;
528 }
529 firstTime = false;
530 }
531
532 // Set presentation timestamp
533#if LIBAVCODEC_VERSION_MAJOR >= 61
534 // See https://github.com/FFmpeg/FFmpeg/commit/6b6f7db81932f94876ff4bcfd2da0582b8ab897e
535 endFrame->pts = codecContext->frame_num;
536#else
537 endFrame->pts = codecContext->frame_number;
538#endif
539
540 // Send image frame to codec
542 if (ret < 0) {
543 yCError(FFMPEGMONITOR, "Error sending a frame for encoding");
545 av_freep(&endFrame->data[0]);
548 return -1;
549 }
550
551 // Receive compressed data into packet
554 av_freep(&endFrame->data[0]);
557
558
559 if (ret == AVERROR(EAGAIN)) {
560 // Not enough data
561 yCError(FFMPEGMONITOR, "Error EAGAIN");
562 return -1;
563 } else if (ret == AVERROR_EOF) {
564 // End of file reached
565 yCError(FFMPEGMONITOR, "Error EOF");
566 return -1;
567 } else if (ret < 0) {
568 yCError(FFMPEGMONITOR, "Error during encoding");
569 return -1;
570 }
571 }
572
573 return 0;
574}
575
577
578 yCTrace(FFMPEGMONITOR, "decompress");
581
582 if (firstTime) {
583 // If this is the first decompression
584
585 // Set codec context parameters
586 codecContext->width = w;
587 codecContext->height = h;
588 codecContext->pix_fmt = pixelFormat;
589
590 // Open codec
592 if (ret < 0) {
593 yCError(FFMPEGMONITOR, "Could not open codec");
594 return -1;
595 }
596 firstTime = false;
597 }
598
599 // Allocate video frame
601 if (startFrame == NULL) {
602 yCError(FFMPEGMONITOR, "Could not allocate start frame!");
603 return -1;
604 }
605
606 // Send compressed packet to codec
608 if (ret < 0) {
609 yCError(FFMPEGMONITOR, "Error sending a frame for decoding");
611 return -1;
612 }
613
614 // Receive decompressed image into an AVFrame
616 if (ret == AVERROR(EAGAIN)) {
617 // No enough data
618 yCError(FFMPEGMONITOR, "Error EAGAIN");
620 return -1;
621 }
622 else if (ret == AVERROR_EOF) {
623 // End of file reached
624 yCError(FFMPEGMONITOR, "Error EOF");
626 return -1;
627 }
628 else if (ret < 0) {
629 yCError(FFMPEGMONITOR, "Error during decoding");
631 return -1;
632 }
633
634 // Allocate a video frame for end frame
636 if (endFrame == NULL) {
637 yCError(FFMPEGMONITOR, "Could not allocate start frame!");
639 return -1;
640 }
641
642 // Allocate memory into end frame to contain data
643 int success = av_image_alloc(endFrame->data, endFrame->linesize,
644 w, h,
646
647 if (success < 0) {
648 yCError(FFMPEGMONITOR, "Error allocating end frame buffer!");
651 return -1;
652 }
653
654 // Set end frame parameters
655 endFrame->height = h;
656 endFrame->width = w;
658
659 {
660 std::lock_guard<std::mutex> lock(instances_mutex);
661
662 // Convert the image into RGB format
663 static struct SwsContext *img_convert_ctx;
664
665 // Allocate conversion context
668 w, h,
671 NULL, NULL, NULL);
672 if (img_convert_ctx == NULL) {
673 yCError(FFMPEGMONITOR, "Cannot initialize the pixel format conversion context!");
674 av_freep(&endFrame->data[0]);
677 return -1;
678 }
679
680 // Perform conversion
681 ret = sws_scale(img_convert_ctx, startFrame->data, startFrame->linesize, 0,
682 h, endFrame->data, endFrame->linesize);
683
684 if (ret < 0) {
685 yCError(FFMPEGMONITOR, "Could not convert pixel format!");
686 av_freep(&endFrame->data[0]);
690 return -1;
691 }
692
693 // Copy decompressed data from end frame to imageOut
694 memcpy(imageOut.getRawImage(), endFrame->data[0], success);
695
696 // Free allocated memory
697 av_freep(&endFrame->data[0]);
701 }
702
703 return 0;
704
705}
706
708
709 std::vector<std::string> parameters;
710 // Split command line string using '+' delimiter
711 split(carrierString, '+', parameters);
712
713 bool standardCodec = false;
714 bool customEnc = false;
715 bool customDec = false;
716
717 // Iterate over result strings
718 for (std::string& param: parameters) {
719
720 // Skip YARP initial parameters
722 continue;
723 }
724
725 // If there is no '.', the param is bad formatted, return error
726 auto pointPosition = param.find('.');
727 if (pointPosition == std::string::npos) {
728 yCError(FFMPEGMONITOR, "Error while parsing parameter %s. Missing '.'!", param.c_str());
729 return false;
730 }
731
732 // Otherwise, separate key and value
733 std::string paramKey = param.substr(0, pointPosition);
734 std::string paramValue = param.substr(pointPosition + 1, param.length());
735
736 // Parsing codec
738
739 if (customEnc || customDec)
740 {
741 yCError(FFMPEGMONITOR, "Cannot set both %s and %s/%s together.",
745 codecOut = nullptr;
746 return false;
747 }
748
749 bool found = false;
750 // Iterate over codecs command line possibilities
751 for (size_t i = 0; i < FFMPEGPORTMONITOR_CL_CODECS.size(); i++) {
752 // If found
754 // Set codec id basing on codec command line name
756 // Find encoder/decoder
757 if (senderSide) {
759 } else {
761 }
762
763 if (!codecOut) {
764 yCError(FFMPEGMONITOR, "Can't find codec %s", paramValue.c_str());
765 codecOut = nullptr;
766 return false;
767 }
768
769 standardCodec = true;
770 found = true;
771 break;
772 }
773 }
774
775 // If not found, unrecognized codec, return error
776 if (!found) {
777 yCError(FFMPEGMONITOR, "Unrecognized codec: %s", paramValue.c_str());
778 return false;
779 }
780
781 continue; //avoid to add this parameter to paramsMap
782 }
784 {
785 if (!senderSide)
786 {
787 customEnc = true;
788 continue; //The custom encoder need to be set on the sender side only. Later we check that the custom decoder has been set too.
789 }
790
791 if (standardCodec)
792 {
793 yCError(FFMPEGMONITOR, "Cannot set both %s and %s/%s together.",
797 codecOut = nullptr;
798 return false;
799 }
800
801
803
804 if (!codecOut) {
805 yCError(FFMPEGMONITOR, "Can't find encoder %s", paramValue.c_str());
806 codecOut = nullptr;
807 return false;
808 }
809
810 customEnc = true;
811 continue; //avoid to add this parameter to paramsMap
812 }
814 {
815 if (senderSide)
816 {
817 customDec = true;
818 continue; //The custom decoder need to be set on the receiver side only. Later we check that the custom encoder has been set too.
819 }
820
821 if (standardCodec)
822 {
823 yCError(FFMPEGMONITOR, "Cannot set both %s and %s/%s together.",
827 codecOut = nullptr;
828 return false;
829 }
830
832
833 if (!codecOut) {
834 yCError(FFMPEGMONITOR, "Can't find decoder %s", paramValue.c_str());
835 codecOut = nullptr;
836 return false;
837 }
838
839 customDec = true;
840 continue; //avoid to add this parameter to paramsMap
841 }
843 {
844 pixelFormatOut = static_cast<AVPixelFormat>(std::atoi(paramValue.c_str()));
845 continue; //avoid to add this parameter to paramsMap
846 }
848 {
849 frameRate = std::atoi(paramValue.c_str());
850 continue; //avoid to add this parameter to paramsMap
851 }
853 {
854 printStatistics = std::atoi(paramValue.c_str());
855 continue; //avoid to add this parameter to paramsMap
856 }
857
858 // Save param into params map
859 paramsMap.insert( std::pair<std::string, std::string>(paramKey, paramValue) );
860 }
861
862 if (!standardCodec && !customEnc && !customDec)
863 {
864 // Set default codec
866 if (senderSide) {
868 } else {
870 }
871
872 if (!codecOut) {
873 yCError(FFMPEGMONITOR, "Can't find default codec (mpeg2video).");
874 return false;
875 }
876 }
877
878 if (customEnc && !customDec)
879 {
880 yCError(FFMPEGMONITOR, "A custom encoder has been specified, but not a custom decoder.");
881 return false;
882 }
883
884 if (!customEnc && customDec)
885 {
886 yCError(FFMPEGMONITOR, "A custom decoder has been specified, but not a custom encoder.");
887 return false;
888 }
889
890 return true;
891
892}
893
895
896 // Iterate over all saved parameters
897 for (auto const& x : paramsMap) {
898
899 // Get key and value
900 std::string key = x.first;
901 std::string value = x.second;
902
903 // Try to set this pair (key, value) into codec context (global parameters).
904 int globalError = av_opt_set(codecContext, key.c_str(), value.c_str(), 0);
905 // Try to set this pair (key, value) into codec context -> priv data (parameters that are specific for a codec).
906 int privError = av_opt_set(codecContext->priv_data, key.c_str(), value.c_str(), 0);
907
908 // If the param exists, but the value is out of range
910 yCError(FFMPEGMONITOR, "Parameter out of range: %s", key.c_str());
911 return -1;
912 }
913 // If the param exists, but the value is invalid
914 else if (globalError == AVERROR(EINVAL) || privError == AVERROR(EINVAL)) {
915 yCError(FFMPEGMONITOR, "Invalid value for parameter: %s", key.c_str());
916 return -1;
917 }
918 // If the param doesn't exists (we check only in sender side because some parameters doesn't exist in the decoders)
920 yCError(FFMPEGMONITOR, "Parameter not found: %s", key.c_str());
921 return -1;
922 }
923
924 }
925 return 0;
926}
@ VOCAB_PIXEL_INVALID
Definition Image.h:41
bool ret
void updateStatistics(yarp::os::Bottle &inputBottle, double currentLag)
Print some network statistics.
yarp::sig::FlexImage imageOut
The final decompressed image that will be sent to the original destination.
int statisticsCounter
Utility counter for printing statistics.
int compress(yarp::sig::Image *img, AVPacket *pkt)
This function performs all the compression actions on the incoming Image and saves the resulting comp...
AVPixelFormat pixelFormat
Ffmpeg pixel format.
bool getParamsFromCommandLine(std::string carrierString, const AVCodec *&codecOut, AVPixelFormat &pixelFormatOut, int &frameRate)
This function parses the command line parameters from a string containing the entire command used to ...
bool accept(yarp::os::Things &thing) override
This function is used by the port monitor to decide if an incoming packet can be accepted (it tries t...
int setCommandLineParams()
This function iterates over the attribute paramsMap and sets all the specified parameters into the at...
bool firstTime
Boolean variable used to check if the current call to the "compression" (or "decompression") function...
yarp::sig::Image imageBottleBuffer
The final decompressed image that will be sent to the original destination.
yarp::os::Things & update(yarp::os::Things &thing) override
This function is the one that manipulates the incoming packet.
yarp::os::Bottle data
The bottle that is filled with compressed image and all the information needed for decompression (it ...
const AVCodec * codec
Ffmpeg structure containing all codec information needed for compression / decompression.
double lagRunningAverage
Variable storing the current lag for statistics.
double previousFrameTime
Seconds since epoch of the previous frame;.
yarp::os::Things th
The object returned by the "update" function; it can be a yarp::os::Bottle (sender side) or a yarp::s...
bool printStatistics
Boolean variable used to check whether the bandwidth statistics should be printed.
bool senderSide
Boolean variable that tells if the current execution is in sender side or not.
bool create(const yarp::os::Property &options) override
This function is called when the object is created and it is used to initialize all its attributes.
bool setparam(const yarp::os::Property &params) override
This will be called when the portmonitor carrier parameters are set via YARP admin port.
bool getparam(yarp::os::Property &params) override
This will be called when the portmonitor carrier parameters are requested via YARP admin port.
int decompress(AVPacket *pkt, int w, int h, int pixelCode)
This function decompresses the incoming AVPacket passed as parameter and saves decompressed data into...
double previousStatisticPrintTime
Utility variable to store the time in which the last time the statistics have been printed.
std::map< std::string, std::string > paramsMap
Structure that maps every parameter inserted from command line into its value (both as strings).
void destroy(void) override
This function is called when the execution is terminated and the object is destroyed.
AVCodecContext * codecContext
Ffmpeg structure containing all codec context information needed for compression / decompression.
double bandwidthRunningAverage
Variable storing the current bandwidth average for statistics.
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition Bottle.cpp:309
void clear()
Empties the bottle of any objects it contains.
Definition Bottle.cpp:121
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition Bottle.cpp:140
A mini-server for performing network communication in the background.
static LogCallback printCallback()
Get current print callback.
Definition Log.cpp:873
static LogType minimumPrintLevel()
Get current minimum print level.
Definition Log.cpp:833
@ LogTypeReserved
Definition Log.h:98
static bool copyPortable(const PortWriter &writer, PortReader &reader)
Copy one portable to another, via writing and reading.
Definition Portable.cpp:16
A class for storing options and configuration information.
Definition Property.h:33
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Base class for generic things.
Definition Things.h:18
T * cast_as()
Definition Things.h:53
void setPortWriter(yarp::os::PortWriter *writer)
Set the reference to a PortWriter object.
Definition Things.cpp:26
A single value (typically within a Bottle).
Definition Value.h:43
virtual bool asBool() const
Get boolean value.
Definition Value.cpp:186
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
void setPixelCode(int imgPixelCode)
Definition Image.h:366
void setPixelSize(size_t imgPixelSize)
Definition Image.h:371
Base class for storing images.
Definition Image.h:79
size_t width() const
Gets width of image in pixels.
Definition Image.h:171
size_t getRowSize() const
Size of the underlying image buffer rows.
Definition Image.h:197
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition Image.cpp:479
virtual size_t getPixelSize() const
Gets pixel size in memory in bytes.
Definition Image.cpp:385
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition Image.cpp:402
void zero()
Set all pixels to 0.
Definition Image.cpp:395
size_t height() const
Gets height of image in pixels.
Definition Image.h:177
virtual int getPixelCode() const
Gets pixel type identifier.
Definition Image.cpp:390
File containing constans used in FfmpegPortmonitor.cpp.
static const std::vector< std::string > FFMPEGPORTMONITOR_IGNORE_PARAMS
This vector contains all parameters that have to be ignored while parsing command line string.
Definition constants.h:34
static const std::string FFMPEGPORTMONITOR_CL_CODEC_KEY
This string is the "key" value for the codec parameter.
Definition constants.h:48
static const std::string FFMPEGPORTMONITOR_CL_CUSTOM_DEC_KEY
This string is the "key" value for the custom decoder parameter.
Definition constants.h:70
static const std::vector< std::string > FFMPEGPORTMONITOR_CL_CODECS
This vector contains the only accepted values for the command line parameter "codec".
Definition constants.h:54
static std::map< int, int > FFMPEGPORTMONITOR_PIXELMAP
This structure maps YARP pixel format codec into Ffmpeg pixel format codes.
Definition constants.h:104
static const std::string FFMPEGPORTMONITOR_CL_PIXEL_FORMAT_KEY
This string is the "key" value for the pixel format parameter.
Definition constants.h:76
static const std::string FFMPEGPORTMONITOR_CL_CUSTOM_ENC_KEY
This string is the "key" value for the custom encoder parameter.
Definition constants.h:64
static const std::vector< int > FFMPEGPORTMONITOR_CODE_CODECS
This vector contains the codec ids corresponding to the codecs of the FFMPEGPORTMONITOR_CL_CODECS vec...
Definition constants.h:94
static const std::string FFMPEGPORTMONITOR_CL_FRAME_RATE_KEY
This string is the "key" value for the frame rate parameter.
Definition constants.h:82
static const std::string FFMPEGPORTMONITOR_CL_PRINT_STATISTICS_KEY
This string is the "key" value to enable the print statistics.
Definition constants.h:88
static AVPixelFormat FFMPEGPORTMONITOR_DEFAULT_PIXEL_FORMAT
Default pixel format to be used within ffmpeg.
Definition constants.h:116
static std::mutex instances_mutex
Header file of FfmpegPortmonitor: a port monitor for video compression/decompression.
#define yCInfo(component,...)
#define yCError(component,...)
#define yCTrace(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
STL namespace.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition Time.cpp:121
An interface to the operating system, including Port based communication.