Commit 8cfa787e authored by Nicolas Michon's avatar Nicolas Michon

Changes for correct ms2 integration

parent b019155c
SmartWireless GmbH & Co. KG
\ No newline at end of file
SmartWireless GmbH & Co. KG
Belledonne Communications SARL
......@@ -30,6 +30,7 @@
#include "h264helper.hpp"
#include "utils.hpp"
using namespace h264camera;
using namespace std::chrono_literals;
......@@ -111,17 +112,27 @@ void State::captureLoop() {
while (mRunning) {
if (ms_video_starter_need_i_frame(&mVideoStarter,
mFilter->ticker->time) ||
ms_iframe_requests_limiter_iframe_requested(
&mIFrameLimiter, mFilter->ticker->time)) {
mDevice->xuResetIFrame();
ms_iframe_requests_limiter_notify_iframe_sent(&mIFrameLimiter,
mFilter->ticker->time);
mFilter->ticker->time) ||
ms_iframe_requests_limiter_iframe_requested(
&mIFrameLimiter,
mFilter->ticker->time)) {
mDevice->xuResetIFrame();
ms_iframe_requests_limiter_notify_iframe_sent(&mIFrameLimiter,
mFilter->ticker->time);
}
if (auto frame = mDevice->dequeue(200ms)) {
separate_h264_nalus(frame, &mNalus);
mDevice->queue(frame->index);
MSQueue *nalus = getMSQueue();
separate_h264_nalus(frame, nalus);
mCaptureMutex.lock();
if (!ms_queue_empty(nalus)) {
mNalusQueue.push(nalus);
} else {
mAvailableNalus.push(nalus);
}
mCaptureMutex.unlock();
mDevice->queue(frame->index);
} else {
bctbx_warning("Timeout when waiting for a new frame");
}
......@@ -137,11 +148,9 @@ void State::captureLoop() {
void State::preprocess() {
assert(mDevice);
ms_queue_init(&mNalus);
mPacker = rfc3984_new_with_factory(mFilter->factory);
rfc3984_set_mode(mPacker, 1);
ms_video_starter_init(&mVideoStarter);
ms_iframe_requests_limiter_init(&mIFrameLimiter, 1000);
......@@ -152,8 +161,17 @@ void State::process() {
// rtp uses a 90 kHz clockrate for video
auto timestamp = mFilter->ticker->time * 90;
if (!ms_queue_empty(&mNalus)) {
rfc3984_pack(mPacker, &mNalus, mFilter->outputs[0], timestamp);
if (mCaptureMutex.try_lock()) {
while (!mNalusQueue.empty()) {
MSQueue *nalus = mNalusQueue.front();
if (!ms_queue_empty(nalus)) {
rfc3984_pack(mPacker, nalus, mFilter->outputs[0], timestamp);
}
mNalusQueue.pop();
ms_queue_flush(nalus);
mAvailableNalus.push(nalus);
}
mCaptureMutex.unlock();
}
}
......@@ -164,7 +182,31 @@ void State::postprocess() {
rfc3984_destroy(mPacker);
ms_queue_flush(&mNalus);
while (!mNalusQueue.empty()) {
MSQueue *nalus = mNalusQueue.front();
ms_queue_flush(nalus);
delete nalus;
mNalusQueue.pop();
}
while (!mAvailableNalus.empty()) {
MSQueue *nalus = mAvailableNalus.front();
ms_queue_flush(nalus);
delete nalus;
mAvailableNalus.pop();
}
}
MSQueue *State::getMSQueue() {
MSQueue *queue;
if (!mAvailableNalus.empty()) {
queue = mAvailableNalus.front();
mAvailableNalus.pop();
} else {
queue = new MSQueue();
ms_queue_init(queue);
}
return queue;
}
const MSVideoConfiguration *State::videoConfList() {
......@@ -228,14 +270,6 @@ static MSFilterMethod filter_method_table[] = {
enc_support->supported = (enc_support->pixfmt == MS_H264);
return enc_support->pixfmt ? 0 : -1;
}},
{MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST,
[](MSFilter *f, void *arg) -> int {
bctbx_debug("Filter method: MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST");
auto state = State::from(f);
auto vconfs = static_cast<const MSVideoConfiguration **>(arg);
*vconfs = state->videoConfList();
return 0;
}},
{MS_VIDEO_ENCODER_GET_CONFIGURATION,
[](MSFilter *f, void *arg) -> int {
auto state = State::from(f);
......@@ -295,23 +329,6 @@ static MSFilterMethod filter_method_table[] = {
*accelerated = true;
return 0;
}},
{MS_FILTER_GET_VIDEO_SIZE,
[](MSFilter *f, void *arg) -> int {
bctbx_debug("Filter method: MS_FILTER_GET_VIDEO_SIZE");
auto state = State::from(f);
auto vsize = static_cast<MSVideoSize *>(arg);
*vsize = state->videoConf().vsize;
return 0;
}},
{MS_FILTER_GET_FPS,
[](MSFilter *f, void *arg) -> int {
bctbx_debug("Filter method: MS_FILTER_GET_FPS");
auto state = State::from(f);
auto fps = static_cast<float *>(arg);
*fps = state->videoConf().fps;
return 0;
}},
{0, nullptr}};
// Struct with all filter related callbacks and information. It is
......
......@@ -20,13 +20,15 @@
#include <array>
#include <atomic>
#include <memory>
#include <string>
#include <queue>
#include <mutex>
#include <thread>
#include <mediastreamer2/mscodecutils.h>
#include <mediastreamer2/msfilter.h>
#include <mediastreamer2/msvideo.h>
#include <mediastreamer2/rfc3984.h>
#include <memory>
#include <string>
#include <thread>
namespace h264camera {
class Usb100W04H;
......@@ -76,6 +78,7 @@ public:
private:
void captureLoop();
MSQueue *getMSQueue();
MSFilter *mFilter{nullptr};
/// The camera device. It will be set by the create_reader call in the
......@@ -85,11 +88,14 @@ private:
MSVideoConfiguration mVideoConf;
std::thread mCaptureThread;
std::mutex mCaptureMutex;
// The capture loop will stop, if this is false.
std::atomic<bool> mRunning{false};
// The capture loop will restart after exit, if this is true.
std::atomic<bool> mReconfigure{true};
MSQueue mNalus;
std::queue<MSQueue *> mNalusQueue;
std::queue<MSQueue *> mAvailableNalus;
Rfc3984Context *mPacker{nullptr};
MSVideoStarter mVideoStarter;
MSIFrameRequestsLimiterCtx mIFrameLimiter;
......
......@@ -23,24 +23,6 @@
namespace mselph264 {
extern MSFilterDesc filter_description;
extern MSWebCamDesc camera_description;
// Mediastream2 will only tell there is codec support, if both encoder and
// decoder filters are registered.
MSFilterDesc fake_h264_decoder = {
MS_FILTER_PLUGIN_ID /*id*/,
"h264_fake_decoder" /*name*/,
"H.264 fake decoder to claim H264 support" /*text*/,
MS_FILTER_DECODER /*category*/,
"H264" /*enc_fmt*/,
1 /*ninputs*/,
0 /*noutputs*/,
nullptr /*init*/,
nullptr /*preprocess*/,
nullptr /*process*/,
nullptr /*postprocess*/,
nullptr /*uninit*/,
nullptr, /*methods*/
0 /*flags*/};
} // namespace mselph264
// This function is automatically called by Mediastreamer2. The
......@@ -51,7 +33,6 @@ extern "C" void libmselph264_init(MSFactory *factory) {
// bctbx_set_log_level(BCTBX_LOG_DOMAIN, BCTBX_LOG_DEBUG);
assert(factory);
ms_factory_register_filter(factory, &mselph264::filter_description);
ms_factory_register_filter(factory, &mselph264::fake_h264_decoder);
auto cam_manager = ms_factory_get_web_cam_manager(factory);
assert(cam_manager);
ms_web_cam_manager_register_desc(cam_manager, &mselph264::camera_description);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment