Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions app/videonative/src/main/cpp/VideoPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,15 @@ void VideoPlayer::processQueue()
}
if (!naluQueue.empty())
{
NALU nalu = naluQueue.front();
if (framerate == 0)
{
if (latestDecodingInfo.currentFPS <= 0)
{
continue;
}
const bool is_h265 = naluQueue.front().is_h265;
if (MP4E_STATUS_OK !=
mp4_h26x_write_init(
&mp4wr, mux, latestVideoRatio.width, latestVideoRatio.height, nalu.IS_H265_PACKET))
mp4_h26x_write_init(&mp4wr, mux, latestVideoRatio.width, latestVideoRatio.height, is_h265))
{
__android_log_print(ANDROID_LOG_DEBUG, TAG, "error: mp4_h26x_write_init failed");
}
Expand All @@ -82,12 +81,13 @@ void VideoPlayer::processQueue()
framerate,
latestVideoRatio.width,
latestVideoRatio.height,
nalu.IS_H265_PACKET);
is_h265);
}
DvrNalu nalu = std::move(naluQueue.front());
naluQueue.pop();
lock.unlock();
// Process the NALU
auto res = mp4_h26x_write_nal(&mp4wr, nalu.getData(), nalu.getSize(), 90000 / framerate);
auto res = mp4_h26x_write_nal(&mp4wr, nalu.data.data(), (int) nalu.data.size(), 90000 / framerate);
if (MP4E_STATUS_OK != res)
{
__android_log_print(ANDROID_LOG_DEBUG, TAG, "mp4_h26x_write_nal failed with %d", res);
Expand Down Expand Up @@ -144,11 +144,9 @@ void VideoPlayer::onNewNALU(const NALU& nalu)
{
return;
}
// Copy data to write if from a different thread.
uint8_t* m_data_copy = new uint8_t[nalu.getSize()];
memcpy(m_data_copy, nalu.getData(), nalu.getSize());
NALU nalu_(m_data_copy, nalu.getSize(), nalu.IS_H265_PACKET);
enqueueNALU(nalu_);
// The writer thread outlives this call, so hand it an owning copy.
enqueueNALU(DvrNalu{std::vector<uint8_t>(nalu.getData(), nalu.getData() + nalu.getSize()),
nalu.IS_H265_PACKET});
}

void VideoPlayer::setVideoSurface(JNIEnv* env, jobject surface, jint i)
Expand Down
17 changes: 14 additions & 3 deletions app/videonative/src/main/cpp/VideoPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <stdio.h>
#include <fstream>
#include <queue>
#include <utility>
#include <vector>
#include "AudioDecoder.h"
#include "BufferedPacketQueue.h"
#include "UdpReceiver.h"
Expand Down Expand Up @@ -74,21 +76,30 @@ class VideoPlayer
H26XParser mParser;
BufferedPacketQueue mBufferedPacketQueueVideo, mBufferedPacketQueueAudio;

// A NALU is a non-owning view onto the parser's buffer (see NALU.hpp), which is
// reused for the next packet. The DVR writer runs on its own thread, so what gets
// handed over has to own its bytes.
struct DvrNalu
{
std::vector<uint8_t> data;
bool is_h265 = false;
};

// DVR attributes
int dvr_fd;
std::queue<NALU> naluQueue;
std::queue<DvrNalu> naluQueue;
std::mutex mtx;
std::condition_variable cv;
bool stopFlag = false;
std::thread processingThread;
int dvr_mp4_fragmentation = 0;
uint64_t last_dvr_write = 0;

void enqueueNALU(const NALU& nalu)
void enqueueNALU(DvrNalu&& nalu)
{
{
std::lock_guard<std::mutex> lock(mtx);
naluQueue.push(nalu);
naluQueue.push(std::move(nalu));
}
cv.notify_one();
}
Expand Down