• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ossia / score / 35742451820

22 Sep 2026 02:44PM UTC coverage: 40.337% (+0.3%) from 40.008%
35742451820

push

github

jcelerier
gfx: name DirectShow camera formats by codec, and widen the subtypes

A compressed pin carries no pixel format, so CameraSettings holds
AV_PIX_FMT_NONE for it and av_get_pix_fmt_name answers nullptr. The device
list's description built its name from that with only MJPEG special-cased,
which left every other compressed codec assigning a null pointer to a
std::string. Gfx::cameraFormatName names a format from its codec when it has
no layout and from its layout otherwise, and neither lookup is used
unchecked.

The compressed half of the subtype decision now goes to the fourcc -> codec
table FFmpeg maintains for RIFF/AVI, which is what ffmpeg's own dshow device
resolves a pin through, rather than the six-entry list it replaces. H.264's
eight spellings, DV's five, VP8/VP9/AV1, MPEG-4/DIVX/Xvid, H.263, JPEG 2000,
v210 and the lossless card codecs all arrive from there. The layout table is
consulted first, so a fourcc it names stays raw even where that table calls
it a codec -- Y41P, which we unpack.

What that table lacks and DirectShow emits is listed alongside it: H.265 in
both spellings in the wild (UVC cameras label the pin 'H265', OBS and the LAV
filters 'HEVC'), the CFCC/IJPG/TVMJ/WAKE/Plum Motion-JPEG fourccs from
dshow.h, and MDVF. A camera whose only pin is H.265 had no format to offer
at all.

The raw table gains the aliases FFmpeg's own raw table carries, so a pin
spelt any of them resolves to the layout we offer it under: HDYC (the UYVY
capture cards present), the other packed 4:2:2 spellings, the planar AVI
ones, YUV9, Y411 and 'Y16 '.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QnTb3Zd2ctRWoTs5wMtoiC

51 of 52 new or added lines in 3 files covered. (98.08%)

8408 existing lines in 137 files now uncovered.

119310 of 295781 relevant lines covered (40.34%)

112391.58 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

12.28
/src/plugins/score-plugin-library/Library/ProcessTreeView.cpp
1
#include "ProcessTreeView.hpp"
2

3
#include <Library/PresetListView.hpp>
4

5
#include <score/widgets/Pixmap.hpp>
6
#if defined(__EMSCRIPTEN__)
7
#include <score/widgets/ItemViewDrag.hpp>
8

9
#include <QStyleOptionViewItem>
10
#endif
11

12
#include <QDrag>
13
#include <QGuiApplication>
14
#include <QMimeData>
15
#include <QMouseEvent>
16
#include <QSortFilterProxyModel>
17

18
#include <wobjectimpl.h>
19

20
W_OBJECT_IMPL(Library::ProcessTreeView)
49,472✔
21
W_OBJECT_IMPL(Library::PresetListView)
36,507✔
22
namespace Library
23
{
24
Library::ProcessData* ProcessTreeView::dataFromViewIndex(QModelIndex idx)
×
25
{
26
  SCORE_ASSERT(idx.isValid());
×
27
  auto proxy = (QSortFilterProxyModel*)this->model();
×
28
  auto model_idx = proxy->mapToSource(idx);
×
29
  auto data = reinterpret_cast<TreeNode<ProcessData>*>(model_idx.internalPointer());
×
30
  return data;
×
31
}
32

UNCOV
33
void ProcessTreeView::reselect()
×
34
{
UNCOV
35
  if(auto* sm = selectionModel(); sm && !sm->selectedIndexes().isEmpty())
×
36
  {
UNCOV
37
    if(auto* data = dataFromViewIndex(sm->selectedIndexes().front()))
×
38
    {
UNCOV
39
      selected(*data);
×
UNCOV
40
      return;
×
41
    }
42
  }
×
43
  selected({});
×
UNCOV
44
}
×
45

46
void ProcessTreeView::selectionChanged(
1,122✔
47
    const QItemSelection& sel, const QItemSelection& desel)
48
{
49
  setDropIndicatorShown(true);
1,122✔
50

51
  if(!sel.isEmpty())
1,122✔
52
  {
53
    // guard against transient null internalPointer from async scan rebuild
54
    if(auto* data = dataFromViewIndex(sel.indexes().front()))
×
55
      selected(*data);
×
UNCOV
56
  }
×
57
  else if(desel.size() > 0)
1,122✔
58
  {
59
    selected({});
×
60
  }
×
61
}
1,122✔
62

UNCOV
63
QModelIndexList ProcessTreeView::selectedDraggableIndexes() const
×
64
{
65
  QModelIndexList indexes = selectedIndexes();
×
UNCOV
66
  auto m = QTreeView::model();
×
UNCOV
67
  auto isNotDragEnabled = [m](const QModelIndex& index) {
×
UNCOV
68
    return !(m->flags(index) & Qt::ItemIsDragEnabled);
×
69
  };
UNCOV
70
  indexes.erase(
×
71
      std::remove_if(indexes.begin(), indexes.end(), isNotDragEnabled), indexes.end());
×
72
  return indexes;
×
73
}
×
74

75
void ProcessTreeView::startDrag(Qt::DropActions)
×
76
{
UNCOV
77
  QModelIndexList indexes = selectedDraggableIndexes();
×
UNCOV
78
  if(indexes.count() == 1)
×
79
  {
80
    // auto proxy = (QSortFilterProxyModel*)this->model();
81
    // auto model_idx = proxy->mapFromSource(indexes.first());
82

83
    // QMimeData* data = proxy->mimeData(QModelIndexList{model_idx});
UNCOV
84
    QMimeData* data = QTreeView::model()->mimeData(indexes);
×
UNCOV
85
    if(!data)
×
UNCOV
86
      return;
×
87

88
    QDrag* drag = new QDrag(this);
×
89
    drag->setMimeData(data);
×
90
    /*
91
    auto p =
92
    score::get_pixmap(QStringLiteral(":/icons/cursor_process_audio.png"));
93
    drag->setDragCursor(p, Qt::CopyAction);
94
    drag->setDragCursor(p, Qt::MoveAction);
95
    */
96
#if defined(__EMSCRIPTEN__)
97
    QStyleOptionViewItem opt;
98
    initViewItemOption(&opt);
99
    score::setItemViewDragPixmap(*drag, *this, opt, indexes);
100
#endif
101
    drag->exec();
×
102
  }
×
103
}
×
104

105
void ProcessTreeView::mouseDoubleClickEvent(QMouseEvent* event)
×
106
{
107
  auto index = indexAt(event->pos());
×
UNCOV
108
  if(index.isValid())
×
109
  {
110
    // guard against transient null internalPointer from async scan rebuild
UNCOV
111
    auto data = dataFromViewIndex(index);
×
UNCOV
112
    if(data && data->key != UuidKey<Process::ProcessModel>{})
×
113
    {
UNCOV
114
      doubleClicked(*data);
×
UNCOV
115
      event->accept();
×
UNCOV
116
      return;
×
117
    }
UNCOV
118
  }
×
UNCOV
119
  QTreeView::mouseDoubleClickEvent(event);
×
UNCOV
120
}
×
121

122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc