#include "chroma_subsampler.h"
-#include <string>
#include <movit/util.h>
+#include <string>
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
2.0f, 0.0f
};
glCreateBuffers(1, &vbo);
- glNamedBufferData(vbo, sizeof(vertices), vertices, GL_STATIC_DRAW);
+ glNamedBufferData(vbo, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
- GLint position_attrib = 0; // Hard-coded in every vertex shader.
+ GLint position_attrib = 0; // Hard-coded in every vertex shader.
glEnableVertexArrayAttrib(vao, position_attrib);
glVertexAttribPointer(position_attrib, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glProgramUniform2f(cbcr_program, uniform_chroma_offset_0, -1.0f / width, 0.0f);
glProgramUniform2f(cbcr_program, uniform_chroma_offset_1, -0.0f / width, 0.0f);
- glViewport(0, 0, width/2, height);
+ glViewport(0, 0, width / 2, height);
fbos.render_to(cb_tex, cr_tex);
glBindVertexArray(vao);
#ifndef _CHROMA_SUBSAMPLER_H
#define _CHROMA_SUBSAMPLER_H 1
-#include <epoxy/gl.h>
-
#include "flow.h"
+#include <epoxy/gl.h>
+
class ChromaSubsampler {
public:
ChromaSubsampler();
+#include "clip_list.h"
+
#include "mainwindow.h"
+#include "timebase.h"
+#include "ui_mainwindow.h"
#include <math.h>
#include <string>
#include <vector>
-#include "clip_list.h"
-#include "timebase.h"
-#include "ui_mainwindow.h"
-
using namespace std;
string pts_to_string(int64_t pts)
return buf;
}
-int ClipList::rowCount(const QModelIndex &parent) const {
- if (parent.isValid()) return 0;
+int ClipList::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
return clips.size();
}
-int PlayList::rowCount(const QModelIndex &parent) const {
- if (parent.isValid()) return 0;
+int PlayList::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
return clips.size();
}
-int ClipList::columnCount(const QModelIndex &parent) const {
- if (parent.isValid()) return 0;
+int ClipList::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
return int(Column::NUM_COLUMNS);
}
-int PlayList::columnCount(const QModelIndex &parent) const {
- if (parent.isValid()) return 0;
+int PlayList::columnCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
return int(Column::NUM_COLUMNS);
}
-QVariant ClipList::data(const QModelIndex &parent, int role) const {
+QVariant ClipList::data(const QModelIndex &parent, int role) const
+{
if (!parent.isValid())
return QVariant();
const int row = parent.row(), column = parent.column();
}
}
-QVariant PlayList::data(const QModelIndex &parent, int role) const {
+QVariant PlayList::data(const QModelIndex &parent, int role) const
+{
if (!parent.isValid())
return QVariant();
const int row = parent.row(), column = parent.column();
}
}
-QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role) const {
+QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role) const
+{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation != Qt::Horizontal)
}
}
-QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role) const {
+QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role) const
+{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation != Qt::Horizontal)
beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
rotate(clips.begin() + first - 1, clips.begin() + first, clips.begin() + last + 1);
} else {
- beginMoveRows(QModelIndex(), first, last, QModelIndex(), first + (last-first+1) + 1);
+ beginMoveRows(QModelIndex(), first, last, QModelIndex(), first + (last - first + 1) + 1);
first = clips.size() - first - 1;
last = clips.size() - last - 1;
rotate(clips.rbegin() + last - 1, clips.rbegin() + last, clips.rbegin() + first + 1);
#ifndef _CLIP_LIST_H
#define _CLIP_LIST_H 1
-#include <QAbstractTableModel>
+#include "defs.h"
+#include "state.pb.h"
+#include <QAbstractTableModel>
#include <stdint.h>
-
-#include <vector>
#include <string>
-
-#include "defs.h"
-#include "state.pb.h"
+#include <vector>
struct Clip {
int64_t pts_in = -1, pts_out = -1; // pts_in is inclusive, pts_out is exclusive.
public:
ClipProxy(Clip &clip, DataChangedReceiver *clip_list, size_t row)
: clip(clip), clip_list(clip_list), row(row) {}
- ~ClipProxy() {
+ ~ClipProxy()
+ {
if (clip_list != nullptr) {
clip_list->emit_data_changed(row);
}
-#include <stdio.h>
-
-#include <string>
-
#include <QGL>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QSurface>
#include <QSurfaceFormat>
+#include <stdio.h>
+#include <string>
QGLWidget *global_share_widget = nullptr;
}
sqlite3_stmt *stmt;
- ret = sqlite3_prepare(db, "INSERT INTO state VALUES (?)", -1, &stmt, 0);
+ ret = sqlite3_prepare(db, "INSERT INTO state VALUES (?)", -1, &stmt, 0);
if (ret != SQLITE_OK) {
fprintf(stderr, "INSERT prepare: %s\n", sqlite3_errmsg(db));
exit(1);
#define DB_H 1
#include "state.pb.h"
+
#include <sqlite3.h>
class DB {
#include "disk_space_estimator.h"
+#include "timebase.h"
+
+#include <memory>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/statfs.h>
-#include <memory>
-
-#include "timebase.h"
DiskSpaceEstimator::DiskSpaceEstimator(DiskSpaceEstimator::callback_t callback)
: callback(callback)
//
// The bitrate is measured over a simple 30-second sliding window.
-#include <stdint.h>
-#include <sys/types.h>
+#include "timebase.h"
+
#include <deque>
#include <functional>
+#include <stdint.h>
#include <string>
+#include <sys/types.h>
-#include "timebase.h"
-
-class DiskSpaceEstimator
-{
+class DiskSpaceEstimator {
public:
typedef std::function<void(off_t free_bytes, double estimated_seconds_left)> callback_t;
DiskSpaceEstimator(callback_t callback);
// Evaluate a .flo file against ground truth,
// outputting the average end-point error.
-#include <assert.h>
-#include <stdio.h>
+#include "util.h"
+#include <assert.h>
#include <memory>
-
-#include "util.h"
+#include <stdio.h>
using namespace std;
#define NO_SDL_GLEXT 1
-#include <epoxy/gl.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
#include "flow.h"
+
#include "gpu_timers.h"
#include "util.h"
#include <algorithm>
+#include <assert.h>
#include <deque>
-#include <memory>
+#include <epoxy/gl.h>
#include <map>
+#include <memory>
#include <stack>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
#include <vector>
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
}
if (ret == 0) {
fprintf(stderr, "Short read when trying to read %d bytes from %s\n",
- size, filename.c_str());
+ size, filename.c_str());
exit(1);
}
fclose(fp);
return str;
}
-
GLuint compile_shader(const string &shader_src, GLenum type)
{
GLuint obj = glCreateShader(type);
- const GLchar* source[] = { shader_src.data() };
+ const GLchar *source[] = { shader_src.data() };
const GLint length[] = { (GLint)shader_src.size() };
glShaderSource(obj, 1, source, length);
glCompileShader(obj);
// in-between frames. The main user interface is the DISComputeFlow and Interpolate
// classes (also GrayscaleConversion can be useful).
-#include <stdint.h>
-#include <epoxy/gl.h>
#include <array>
+#include <epoxy/gl.h>
#include <map>
#include <mutex>
-#include <vector>
+#include <stdint.h>
#include <utility>
+#include <vector>
class ScopedTimer;
std::map<std::array<GLuint, num_elements>, GLuint> fbos;
};
-
// Same, but with a depth texture.
template<size_t num_elements>
class PersistentFBOSetWithDepth {
// after use.
GLuint exec(GLuint tex, FlowDirection flow_direction, ResizeStrategy resize_strategy);
- void release_texture(GLuint tex) {
+ void release_texture(GLuint tex)
+ {
pool.release_texture(tex);
}
// two-layer RGBA8 texture with mipmaps (unless flow_level == 0).
std::pair<GLuint, GLuint> exec(GLuint image_tex, GLuint gray_tex, GLuint bidirectional_flow_tex, GLuint width, GLuint height, float alpha);
- void release_texture(GLuint tex) {
+ void release_texture(GLuint tex)
+ {
pool.release_texture(tex);
}
#define NO_SDL_GLEXT 1
-#include <epoxy/gl.h>
+#include "flow.h"
+#include "gpu_timers.h"
+#include "util.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_error.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_mouse.h>
#include <SDL2/SDL_video.h>
-
-#include <assert.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include "flow.h"
-#include "gpu_timers.h"
-#include "util.h"
-
#include <algorithm>
+#include <assert.h>
#include <deque>
-#include <memory>
+#include <epoxy/gl.h>
+#include <getopt.h>
#include <map>
+#include <memory>
#include <stack>
+#include <stdio.h>
+#include <unistd.h>
#include <vector>
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
int main(int argc, char **argv)
{
- static const option long_options[] = {
+ static const option long_options[] = {
{ "smoothness-relative-weight", required_argument, 0, 's' }, // alpha.
{ "intensity-relative-weight", required_argument, 0, 'i' }, // delta.
{ "gradient-relative-weight", required_argument, 0, 'g' }, // gamma.
-#include <epoxy/gl.h>
-
#include "gpu_timers.h"
+#include <epoxy/gl.h>
+
using namespace std;
bool enable_timing = false;
size_t num_subtimers = 0;
GLint64 sum_subtimers = 0;
for (size_t j = i + 1; j < timers.size() && timers[j].level > timers[i].level; ++j) {
- if (timers[j].level != timers[i].level + 1) continue;
+ if (timers[j].level != timers[i].level + 1)
+ continue;
++num_subtimers;
sum_subtimers += find_elapsed(timers[j].query);
}
#ifndef _GPU_TIMERS_H
#define _GPU_TIMERS_H 1
+#include <epoxy/gl.h>
#include <string>
#include <utility>
#include <vector>
-#include <epoxy/gl.h>
-
extern bool enable_timing;
extern bool detailed_timing;
extern bool in_warmup;
#include <assert.h>
#include <byteswap.h>
#include <endian.h>
+#include <memory>
#include <microhttpd.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
-#include <memory>
extern "C" {
#include <libavutil/avutil.h>
}
int HTTPD::answer_to_connection(MHD_Connection *connection,
const char *url, const char *method,
- const char *version, const char *upload_data,
- size_t *upload_data_size, void **con_cls)
+ const char *version, const char *upload_data,
+ size_t *upload_data_size, void **con_cls)
{
// See if the URL ends in “.metacube”.
HTTPD::Stream::Framing framing;
ssize_t HTTPD::Stream::reader_callback(uint64_t pos, char *buf, size_t max)
{
unique_lock<mutex> lock(buffer_mutex);
- has_buffered_data.wait(lock, [this]{ return should_quit || !buffered_data.empty(); });
+ has_buffered_data.wait(lock, [this] { return should_quit || !buffered_data.empty(); });
if (should_quit) {
return 0;
}
buffered_data.emplace_back((char *)&packet, sizeof(packet));
}
- has_buffered_data.notify_all();
+ has_buffered_data.notify_all();
}
void HTTPD::Stream::stop()
// A class dealing with stream output to HTTP.
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/types.h>
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <set>
+#include <stddef.h>
+#include <stdint.h>
#include <string>
+#include <sys/types.h>
#include <unordered_map>
#include <utility>
~HTTPD();
// Should be called before start().
- void set_header(const std::string &data) {
+ void set_header(const std::string &data)
+ {
header = data;
}
NO_CORS_POLICY,
ALLOW_ALL_ORIGINS
};
- void add_endpoint(const std::string &url, const EndpointCallback &callback, CORSPolicy cors_policy) {
+ void add_endpoint(const std::string &url, const EndpointCallback &callback, CORSPolicy cors_policy)
+ {
endpoints[url] = Endpoint{ callback, cors_policy };
}
void start(int port);
void stop();
void add_data(const char *buf, size_t size, bool keyframe, int64_t time, AVRational timebase);
- int64_t get_num_connected_clients() const {
+ int64_t get_num_connected_clients() const
+ {
return metric_num_connected_clients.load();
}
#include "jpeg_frame_view.h"
-#include <jpeglib.h>
-#include <stdint.h>
-#include <unistd.h>
+#include "defs.h"
+#include "post_to_main_thread.h"
+#include "video_stream.h"
+#include "ycbcr_converter.h"
+#include <QMouseEvent>
+#include <QScreen>
#include <atomic>
#include <condition_variable>
#include <deque>
+#include <jpeglib.h>
+#include <movit/init.h>
+#include <movit/resource_pool.h>
+#include <movit/util.h>
#include <mutex>
+#include <stdint.h>
#include <thread>
+#include <unistd.h>
#include <utility>
-#include <QMouseEvent>
-#include <QScreen>
-
-#include <movit/resource_pool.h>
-#include <movit/init.h>
-#include <movit/util.h>
-
-#include "defs.h"
-#include "post_to_main_thread.h"
+// Must come after the Qt stuff.
#include "vaapi_jpeg_decoder.h"
-#include "video_stream.h"
-#include "ycbcr_converter.h"
using namespace movit;
using namespace std;
jpeg_read_raw_data(&dinfo, data, v_mcu_size);
}
- (void) jpeg_finish_decompress(&dinfo);
+ (void)jpeg_finish_decompress(&dinfo);
jpeg_destroy_decompress(&dinfo);
fclose(fp);
any_pending_decodes.wait(lock, [] {
return !pending_decodes.empty() || should_quit.load();
});
- if (should_quit.load()) break;
+ if (should_quit.load())
+ break;
decode = pending_decodes.front();
pending_decodes.pop_front();
cache_updated.wait(lock, [id] {
return cache.count(id) != 0 || should_quit.load();
});
- if (should_quit.load()) break;
+ if (should_quit.load())
+ break;
found_in_cache = true; // Don't count it as a decode.
auto it = cache.find(id);
}
JPEGFrameView::JPEGFrameView(QWidget *parent)
- : QGLWidget(parent, global_share_widget) {
+ : QGLWidget(parent, global_share_widget)
+{
}
void JPEGFrameView::setFrame(unsigned stream_idx, int64_t pts, bool interpolated, int secondary_stream_idx, int64_t secondary_pts, float fade_alpha)
namespace {
-
} // namespace
void JPEGFrameView::setDecodedFrame(shared_ptr<Frame> frame, shared_ptr<Frame> secondary_frame, float fade_alpha)
#ifndef _JPEG_FRAME_VIEW_H
#define _JPEG_FRAME_VIEW_H 1
-#include <epoxy/gl.h>
-#include <QGLWidget>
-
-#include <stdint.h>
+#include "jpeg_frame.h"
+#include "ycbcr_converter.h"
+#include <QGLWidget>
+#include <epoxy/gl.h>
+#include <memory>
#include <movit/effect_chain.h>
#include <movit/flat_input.h>
#include <movit/mix_effect.h>
#include <movit/ycbcr_input.h>
-
-#include <memory>
+#include <stdint.h>
#include <thread>
-#include "jpeg_frame.h"
-#include "ycbcr_converter.h"
-
struct JPEGID {
unsigned stream_idx;
int64_t pts;
#include <assert.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
#include <atomic>
#include <chrono>
#include <condition_variable>
+#include <dirent.h>
#include <memory>
#include <mutex>
+#include <stdint.h>
+#include <stdio.h>
#include <string>
+#include <sys/types.h>
#include <thread>
#include <vector>
#include <libavformat/avformat.h>
}
-#include <QApplication>
-
-#include <movit/init.h>
-#include <movit/util.h>
-
#include "clip_list.h"
#include "context.h"
#include "defs.h"
#include "disk_space_estimator.h"
-#include "mainwindow.h"
#include "ffmpeg_raii.h"
#include "httpd.h"
+#include "mainwindow.h"
#include "player.h"
#include "post_to_main_thread.h"
#include "ref_counted_gl_sync.h"
#include "ui_mainwindow.h"
#include "vaapi_jpeg_decoder.h"
+#include <QApplication>
+#include <movit/init.h>
+#include <movit/util.h>
+
using namespace std;
using namespace std::chrono;
#include "timebase.h"
#include "ui_mainwindow.h"
-#include <future>
-#include <string>
-#include <vector>
-
#include <QMouseEvent>
-#include <QWheelEvent>
#include <QShortcut>
#include <QTimer>
-
+#include <QWheelEvent>
+#include <future>
#include <sqlite3.h>
+#include <string>
+#include <vector>
using namespace std;
using namespace std::placeholders;
void MainWindow::preview_clicked()
{
- if (cliplist_clips->empty()) return;
+ if (cliplist_clips->empty())
+ return;
QItemSelectionModel *selected = ui->clip_list->selectionModel();
if (!selected->hasSelection()) {
void MainWindow::play_clicked()
{
- if (playlist_clips->empty()) return;
+ if (playlist_clips->empty())
+ return;
QItemSelectionModel *selected = ui->playlist->selectionModel();
int row;
double remaining = total_length - played_this_clip;
for (int row = playlist_clips->get_currently_playing() + 1; row < int(playlist_clips->size()); ++row) {
const Clip clip = *playlist_clips->clip(row);
- remaining += double(clip.pts_out - clip.pts_in) / TIMEBASE / 0.5; // FIXME: stop hardcoding speed.
+ remaining += double(clip.pts_out - clip.pts_in) / TIMEBASE / 0.5; // FIXME: stop hardcoding speed.
}
int remaining_ms = lrint(remaining * 1e3);
}
int column = destination->columnAt(mouse->x());
int row = destination->rowAt(mouse->y());
- if (column == -1 || row == -1) return false;
+ if (column == -1 || row == -1)
+ return false;
if (type == SCRUBBING_CLIP_LIST) {
if (ClipList::Column(column) == ClipList::Column::IN) {
{
if (rounding == LAST_BEFORE) {
lock_guard<mutex> lock(frame_mu);
- if (frames[stream_idx].empty()) return;
+ if (frames[stream_idx].empty())
+ return;
auto it = lower_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts);
if (it != frames[stream_idx].end()) {
pts = *it;
} else {
assert(rounding == FIRST_AT_OR_AFTER);
lock_guard<mutex> lock(frame_mu);
- if (frames[stream_idx].empty()) return;
+ if (frames[stream_idx].empty())
+ return;
auto it = upper_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts - 1);
if (it != frames[stream_idx].end()) {
pts = *it;
std::string label = buf;
- post_to_main_thread([this, label]{
- disk_free_label->setText(QString::fromStdString(label));
- ui->menuBar->setCornerWidget(disk_free_label); // Need to set this again for the sizing to get right.
- });
+ post_to_main_thread([this, label] {
+ disk_free_label->setText(QString::fromStdString(label));
+ ui->menuBar->setCornerWidget(disk_free_label); // Need to set this again for the sizing to get right.
+ });
}
void MainWindow::exit_triggered()
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include <QLabel>
-#include <QMainWindow>
-
#include "clip_list.h"
#include "db.h"
#include "state.pb.h"
+#include <QLabel>
+#include <QMainWindow>
+#include <stdbool.h>
+#include <sys/types.h>
+
namespace Ui {
class MainWindow;
} // namespace Ui
class Player;
-class MainWindow : public QMainWindow
-{
+class MainWindow : public QMainWindow {
Q_OBJECT
public:
extern MainWindow *global_mainwindow;
#endif
-
-#include <cstdint>
#include <algorithm>
#include <assert.h>
+#include <cstdint>
#if __SSE2__
#include <immintrin.h>
#endif
assert(((limit - src) % 64) == 0);
#if __AVX2__
- const __m256i * __restrict in = (const __m256i *)src;
- __m256i * __restrict out1 = (__m256i *)dest1;
- __m256i * __restrict out2 = (__m256i *)dest2;
+ const __m256i *__restrict in = (const __m256i *)src;
+ __m256i *__restrict out1 = (__m256i *)dest1;
+ __m256i *__restrict out2 = (__m256i *)dest2;
__m256i shuffle_cw = _mm256_set_epi8(
15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0,
#include "mux.h"
+#include <algorithm>
#include <assert.h>
+#include <mutex>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <algorithm>
-#include <mutex>
#include <string>
#include <utility>
#include <vector>
lock_guard<mutex> lock(mu);
if (write_strategy == WriteStrategy::WRITE_BACKGROUND) {
packet_queue.push_back(QueuedPacket{ av_packet_clone(&pkt_copy), pts });
- if (plug_count == 0) packet_queue_ready.notify_all();
+ if (plug_count == 0)
+ packet_queue_ready.notify_all();
} else if (plug_count > 0) {
packet_queue.push_back(QueuedPacket{ av_packet_clone(&pkt_copy), pts });
} else {
-#include <algorithm>
-#include <chrono>
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-#include <vector>
-
-#include <stdio.h>
-
-#include <movit/util.h>
+#include "player.h"
#include "clip_list.h"
#include "context.h"
#include "httpd.h"
#include "jpeg_frame_view.h"
#include "mux.h"
-#include "player.h"
#include "timebase.h"
#include "video_stream.h"
+#include <algorithm>
+#include <chrono>
+#include <condition_variable>
+#include <movit/util.h>
+#include <mutex>
+#include <stdio.h>
+#include <thread>
+#include <vector>
+
using namespace std;
using namespace std::chrono;
video_stream.reset(new VideoStream);
video_stream->start();
}
-
+
check_error();
constexpr double output_framerate = 60000.0 / 1001.0; // FIXME: make configurable
// Wait until we're supposed to play something.
{
unique_lock<mutex> lock(queue_state_mu);
- clip_ready = new_clip_changed.wait_for(lock, milliseconds(100), [this]{
+ clip_ready = new_clip_changed.wait_for(lock, milliseconds(100), [this] {
return new_clip_ready && current_clip.pts_in != -1;
});
new_clip_ready = false;
void Player::override_angle(unsigned stream_idx)
{
- // Corner case: If a new clip is waiting to be played, change its stream and then we're done.
+ // Corner case: If a new clip is waiting to be played, change its stream and then we're done.
{
unique_lock<mutex> lock(queue_state_mu);
if (new_clip_ready) {
}
pts_out = current_clip.pts_out;
}
-
+
lock_guard<mutex> lock(frame_mu);
auto it = upper_bound(frames[stream_idx].begin(), frames[stream_idx].end(), pts_out);
if (it == frames[stream_idx].end()) {
public:
RefCountedGLsync() {}
- RefCountedGLsync(GLenum condition, GLbitfield flags)
+ RefCountedGLsync(GLenum condition, GLbitfield flags)
: RefCountedGLsyncBase(locked_glFenceSync(condition, flags), glDeleteSync) {}
private:
-#include <assert.h>
-#include <stdio.h>
+#include "util.h"
+#include <assert.h>
#include <memory>
-
-#include "util.h"
+#include <stdio.h>
using namespace std;
#ifndef _UTIL_H
#define _UTIL_H 1
-#include <math.h>
-#include <stdint.h>
#include <algorithm>
+#include <math.h>
#include <memory>
+#include <stdint.h>
struct Vec2 {
float du, dv;
{
float angle = atan2(dv, du);
float magnitude = std::min(hypot(du, dv) / 20.0, 1.0);
-
+
// HSV to RGB (from Wikipedia). Saturation is 1.
float c = magnitude;
float h = (angle + M_PI) * 6.0 / (2.0 * M_PI);
float X = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
float r = 0.0f, g = 0.0f, b = 0.0f;
if (h <= 1.0f) {
- r = c; g = X;
+ r = c;
+ g = X;
} else if (h <= 2.0f) {
- r = X; g = c;
+ r = X;
+ g = c;
} else if (h <= 3.0f) {
- g = c; b = X;
+ g = c;
+ b = X;
} else if (h <= 4.0f) {
- g = X; b = c;
+ g = X;
+ b = c;
} else if (h <= 5.0f) {
- r = X; b = c;
+ r = X;
+ b = c;
} else if (h <= 6.0f) {
- r = c; b = X;
+ r = c;
+ b = X;
} else {
// h is NaN, so black is fine.
}
float m = magnitude - c;
- r += m; g += m; b += m;
+ r += m;
+ g += m;
+ b += m;
r = std::max(std::min(r, 1.0f), 0.0f);
g = std::max(std::min(g, 1.0f), 0.0f);
b = std::max(std::min(b, 1.0f), 0.0f);
#include "vaapi_jpeg_decoder.h"
+#include "jpeg_frame.h"
+#include "memcpy_interleaved.h"
+
#include <X11/Xlib.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <jpeglib.h>
+#include <list>
+#include <mutex>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <string>
#include <unistd.h>
#include <va/va.h>
#include <va/va_drm.h>
#include <va/va_x11.h>
-#include <list>
-#include <mutex>
-#include <string>
-
-#include "jpeg_frame.h"
-#include "memcpy_interleaved.h"
-
using namespace std;
static unique_ptr<VADisplayWithCleanup> va_dpy;
static VAConfigID config_id;
static VAImageFormat uyvy_format;
bool vaapi_jpeg_decoding_usable = false;
-
+
struct VAResources {
unsigned width, height;
VASurfaceID surface;
public:
ReleaseVAResources(const VAResources &resources)
: resources(resources) {}
- ~ReleaseVAResources() {
+ ~ReleaseVAResources()
+ {
if (!committed) {
release_va_resources(resources);
}
{
unique_ptr<VADisplayWithCleanup> va_dpy = va_open_display(va_display);
if (va_dpy == nullptr) {
- if (error) *error = "Opening VA display failed";
+ if (error)
+ *error = "Opening VA display failed";
return nullptr;
}
int major_ver, minor_ver;
if (va_status != VA_STATUS_SUCCESS) {
char buf[256];
snprintf(buf, sizeof(buf), "vaInitialize() failed with status %d\n", va_status);
- if (error != nullptr) *error = buf;
+ if (error != nullptr)
+ *error = buf;
return nullptr;
}
int num_entrypoints = vaMaxNumEntrypoints(va_dpy->va_dpy);
unique_ptr<VAEntrypoint[]> entrypoints(new VAEntrypoint[num_entrypoints]);
if (entrypoints == nullptr) {
- if (error != nullptr) *error = "Failed to allocate memory for VA entry points";
+ if (error != nullptr)
+ *error = "Failed to allocate memory for VA entry points";
return nullptr;
}
return va_dpy;
}
- if (error != nullptr) *error = "Can't find VAEntrypointVLD for the JPEG profile";
+ if (error != nullptr)
+ *error = "Can't find VAEntrypointVLD for the JPEG profile";
return nullptr;
}
memset(&parms, 0, sizeof(parms));
parms.slice_data_size = str.size();
parms.slice_data_offset = 0;
- parms.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
+ parms.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
parms.slice_horizontal_position = 0;
parms.slice_vertical_position = 0;
for (int component_idx = 0; component_idx < dinfo.num_components; ++component_idx) {
parms.components[component_idx].dc_table_selector = comp->dc_tbl_no;
parms.components[component_idx].ac_table_selector = comp->ac_tbl_no;
if (parms.components[component_idx].dc_table_selector > 1 ||
- parms.components[component_idx].ac_table_selector > 1) {
+ parms.components[component_idx].ac_table_selector > 1) {
fprintf(stderr, "Uses too many Huffman tables\n");
return nullptr;
}
#define _VAAPI_JPEG_DECODER_H 1
#include <X11/Xlib.h>
-#include <va/va.h>
-
-#include <string>
#include <memory>
+#include <string>
+#include <va/va.h>
struct Frame;
-
+
struct VADisplayWithCleanup {
~VADisplayWithCleanup();
std::shared_ptr<Frame> decode_jpeg_vaapi(const std::string &filename);
extern bool vaapi_jpeg_decoding_usable;
-
+
#endif // !defined(_VAAPI_JPEG_DECODER_H)
#include <libavformat/avio.h>
}
-#include <jpeglib.h>
-#include <unistd.h>
-
#include "chroma_subsampler.h"
#include "context.h"
#include "flow.h"
#include "ycbcr_converter.h"
#include <epoxy/glx.h>
+#include <jpeglib.h>
+#include <unistd.h>
using namespace std;
for (unsigned y = 0; y < height; y += 8) {
for (unsigned yy = 0; yy < 8; ++yy) {
yptr[yy] = const_cast<JSAMPROW>(&y_data[(y + yy) * width]);
- cbptr[yy] = const_cast<JSAMPROW>(&cb_data[(y + yy) * width/2]);
- crptr[yy] = const_cast<JSAMPROW>(&cr_data[(y + yy) * width/2]);
+ cbptr[yy] = const_cast<JSAMPROW>(&cb_data[(y + yy) * width / 2]);
+ crptr[yy] = const_cast<JSAMPROW>(&cr_data[(y + yy) * width / 2]);
}
jpeg_write_raw_data(&cinfo, data, /*num_lines=*/8);
check_error();
glNamedBufferStorage(resource.pbo, width * height * 4, nullptr, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
check_error();
- resource.pbo_contents = glMapNamedBufferRange(resource.pbo, 0, width * height * 4, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
+ resource.pbo_contents = glMapNamedBufferRange(resource.pbo, 0, width * height * 4, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT);
interpolate_resources.push_back(resource);
}
qf.type = QueuedFrame::ORIGINAL;
qf.output_pts = output_pts;
qf.stream_idx = stream_idx;
- qf.input_first_pts = input_pts;
+ qf.input_first_pts = input_pts;
unique_lock<mutex> lock(queue_lock);
frame_queue.push_back(qf);
chroma_subsampler->subsample_chroma(qf.cbcr_tex, 1280, 720, resources.cb_tex, resources.cr_tex);
}
-
// We could have released qf.flow_tex here, but to make sure we don't cause a stall
// when trying to reuse it for the next frame, we can just as well hold on to it
// and release it only when the readback is done.
}
return buf_size;
}
-
#ifndef _VIDEO_STREAM_H
#define _VIDEO_STREAM_H 1
-#include <stdint.h>
#include <epoxy/gl.h>
+#include <stdint.h>
extern "C" {
#include <libavformat/avio.h>
}
+#include "jpeg_frame_view.h"
+#include "ref_counted_gl_sync.h"
+
#include <condition_variable>
#include <deque>
-#include <mutex>
-#include <string>
-#include <thread>
-
#include <movit/effect_chain.h>
#include <movit/mix_effect.h>
#include <movit/ycbcr_input.h>
-
-#include "jpeg_frame_view.h"
-#include "ref_counted_gl_sync.h"
+#include <mutex>
+#include <string>
+#include <thread>
class ChromaSubsampler;
class DISComputeFlow;
void schedule_original_frame(int64_t output_pts, unsigned stream_idx, int64_t input_pts);
void schedule_faded_frame(int64_t output_pts, unsigned stream_idx, int64_t input_pts, int secondary_stream_idx, int64_t secondary_input_pts, float fade_alpha);
- void schedule_interpolated_frame(int64_t output_pts, unsigned stream_idx, int64_t input_first_pts, int64_t input_second_pts, float alpha, int secondary_stream_idx = -1, int64_t secondary_inputs_pts = -1, float fade_alpha = 0.0f); // -1 = no secondary frame.
+ void schedule_interpolated_frame(int64_t output_pts, unsigned stream_idx, int64_t input_first_pts, int64_t input_second_pts, float alpha, int secondary_stream_idx = -1, int64_t secondary_inputs_pts = -1, float fade_alpha = 0.0f); // -1 = no secondary frame.
void schedule_refresh_frame(int64_t output_pts);
private:
-
void encode_thread_func();
std::thread encode_thread;
int64_t output_pts;
enum Type { ORIGINAL, FADED, INTERPOLATED, FADED_INTERPOLATED } type;
unsigned stream_idx;
- int64_t input_first_pts; // The only pts for original frames.
+ int64_t input_first_pts; // The only pts for original frames.
// For fades only (including fades against interpolated frames).
int secondary_stream_idx = -1;
// Visualize a .flo file.
-#include <assert.h>
-#include <stdio.h>
+#include "util.h"
+#include <assert.h>
#include <memory>
-
-#include "util.h"
+#include <stdio.h>
using namespace std;
#include "ycbcr_converter.h"
+#include "jpeg_frame.h"
+
#include <movit/mix_effect.h>
#include <movit/ycbcr_input.h>
-#include "jpeg_frame.h"
-
using namespace std;
using namespace movit;
#ifndef _YCBCR_CONVERTER_H
#define _YCBCR_CONVERTER_H 1
-#include <memory>
-
#include <epoxy/gl.h>
+#include <memory>
#include <movit/ycbcr_input.h>
namespace movit {
// TODO: make private
void setup_input_for_frame(std::shared_ptr<Frame> frame, const movit::YCbCrFormat &ycbcr_format, movit::YCbCrInput *input);
-#endif // !defined(_YCBCR_CONVERTER_H)
+#endif // !defined(_YCBCR_CONVERTER_H)