StreamDecoderImageProvider.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package VisionX::ArmarXObjects::StreamDecoderImageProvider
17 * @author Mirko Waechter ( mirko dot waechter at kit dot edu )
18 * @date 2016
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <Image/ByteImage.h>
26using namespace armarx;
27
28void
30{
32 usingProxy(getProperty<std::string>("UsedStreamProvider").getValue());
33 usingTopic(getProperty<std::string>("imageStreamTopicName").getValue());
34 numberImages = 0;
35
36 avcodec_register_all();
37 av_init_packet(&m_packet);
38 m_decoder = avcodec_find_decoder(AV_CODEC_ID_H264);
39 if (!m_decoder)
40 {
41 ARMARX_ERROR << ("Can't find H264 decoder!");
42 }
43 m_decoderContext = avcodec_alloc_context3(m_decoder);
44
45 if (m_decoder->capabilities & AV_CODEC_CAP_TRUNCATED)
46 {
47 m_decoderContext->flags |= AV_CODEC_FLAG_TRUNCATED;
48 }
49
50
51 //we can receive truncated frames
52 m_decoderContext->flags2 |= AV_CODEC_FLAG2_CHUNKS;
53 m_decoderContext->thread_count =
54 4; //TODO: random value. May be changing can make decoding faster
55
56 AVDictionary* dictionary = nullptr;
57 if (avcodec_open2(m_decoderContext, m_decoder, &dictionary) < 0)
58 {
59 ARMARX_ERROR << "Could not open decoder";
60 }
61 ARMARX_INFO << "H264 Decoder successfully opened";
62
63 //m_picture = avcodec_alloc_frame();
64 m_picture = av_frame_alloc();
65}
66
67void
69{
70 std::unique_lock lock(decodedImageMutex);
71 ppDecodedImages = new CByteImage*[numberImages];
72
74 getProperty<std::string>("UsedStreamProvider").getValue());
75 // codec = streamProvider->getCodecType();
76 numberImages = streamProvider->getNumberOfImages();
78 int imgWidth, imgHeight, imgType;
79 streamProvider->getImageInformation(imgWidth, imgHeight, imgType);
80 ARMARX_INFO << "number of Images: " << numberImages;
81 for (int i = 0; i < numberImages; i++)
82 {
83 ppDecodedImages[i] = new CByteImage(imgWidth, imgHeight, CByteImage::eRGB24);
84 }
85 pCombinedDecodedImage = new CByteImage(imgWidth, imgHeight * numberImages, CByteImage::eRGB24);
86 setImageFormat(visionx::ImageDimension(imgWidth, imgHeight), visionx::eRgb);
87 ImageProvider::onConnectComponent();
88}
89
90void
92{
93 std::unique_lock lock(decodedImageMutex);
95 pCombinedDecodedImage = nullptr;
97 {
98 for (int i = 0; i < numberImages; i++)
99 {
100 delete ppDecodedImages[i];
101 }
102
103 delete[] ppDecodedImages;
104 ppDecodedImages = nullptr;
105 }
106}
107
108void
112
119
120void
122 Ice::Long imageTimestamp,
123 const Ice::Current&)
124{
125 std::unique_lock lock(streamDecodeMutex);
126 m_packet.size = chunk.size();
127 m_packet.data = const_cast<Ice::Byte*>(chunk.data());
128 // ARMARX_INFO << "H264Decoder: received encoded frame with framesize " << enc_frame.size();
129
130 while (m_packet.size > 0)
131 {
132 int got_picture;
133#pragma GCC diagnostic push
134#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
135 int len = avcodec_decode_video2(m_decoderContext, m_picture, &got_picture, &m_packet);
136#pragma GCC diagnostic pop
137 if (len < 0)
138 {
139 std::string err("Decoding error");
140 ARMARX_ERROR << err;
141 return;
142 }
143 if (got_picture)
144 {
145 ARMARX_DEBUG << deactivateSpam(1) << "H264Decoder: frame decoded!";
146 // std::vector<unsigned char> result;
147 // this->storePicture(result);
148
149 if (m_picture->format == AV_PIX_FMT_YUV420P)
150 {
151
152 // QImage frame_img = QImage(width, height, QImage::Format_RGB888);
153 m_swsCtx = sws_getCachedContext(m_swsCtx,
154 m_picture->width,
155 m_picture->height,
156 AV_PIX_FMT_YUV420P,
157 m_picture->width,
158 m_picture->height,
159 AV_PIX_FMT_RGB24,
160 SWS_GAUSS,
161 NULL,
162 NULL,
163 NULL);
164 std::unique_lock lock(decodedImageMutex);
165
166 uint8_t* dstSlice[] = {pCombinedDecodedImage->pixels};
167 int dstStride = m_picture->width * 3;
168 if (sws_scale(m_swsCtx,
169 m_picture->data,
170 m_picture->linesize,
171 0,
172 m_picture->height,
173 dstSlice,
174 &dstStride) != m_picture->height)
175 {
176 ARMARX_INFO << "SCALING FAILED!";
177 return;
178 }
179 for (int i = 0; i < numberImages; ++i)
180 {
181 size_t imageByteSize = ppDecodedImages[i]->width * ppDecodedImages[i]->height *
182 ppDecodedImages[i]->bytesPerPixel;
183 // if(ppInputImages[i]->type != CByteImage::eRGB24)
184 // {
185 // ::ImageProcessor::ConvertImage(imageProviderInfo, eRgb,)
186 // }
187 memcpy(ppDecodedImages[i]->pixels,
188 pCombinedDecodedImage->pixels + i * imageByteSize,
189 imageByteSize);
190 }
191 updateTimestamp(imageTimestamp);
193 // ARMARX_INFO << "New decoded image!";
194 }
195 else
196 {
197 ARMARX_INFO << "Other format: " << m_picture->format;
198 }
199
200 // emit newDecodedFrame(frame_img);
201 // }
202 // else if (m_picture->format == PIX_FMT_RGB32)
203 // {
204 // QImage img = QImage(result.data(), m_picture->width, m_picture->height, QImage::Format_RGB32);
205 // ARMARX_INFO << "New decoded image!";
206 // emit newDecodedFrame(img);
207 // }
208 // else if (m_picture->format == AV_PIX_FMT_RGB24)
209 // {
210 // QImage img = QImage(result.data(), m_picture->width, m_picture->height, QImage::Format_RGB888);
211 // ARMARX_INFO << "New decoded image!";
212 // emit newDecodedFrame(img);
213 // }
214 // else
215 // {
216 // std::string err = std::string( "Unsupported pixel format! Can't create QImage!");
217 // ARMARX_INFO << err;
218 // emit criticalError( err );
219 // return false;
220 // }
221 }
222 m_packet.size -= len;
223 m_packet.data += len;
224 }
225}
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void reportNewStreamData(const Stream::DataChunk &chunk, Ice::Long imageTimestamp, const Ice::Current &) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
Pure virtual hook for the subclass.
void onInitImageProvider() override
This is called when the Component::onInitComponent() is called.
void onExitImageProvider() override
This is called when the Component::onExitComponent() setup is called.
void updateTimestamp(Ice::Long timestamp, bool threadSafe=true)
Updates the timestamp of the currently captured image.
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
void provideImages(void **inputBuffers, const IceUtil::Time &imageTimestamp=IceUtil::Time())
send images raw.
void setNumberImages(int numberImages)
Sets the number of images on each capture.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.