-
Notifications
You must be signed in to change notification settings - Fork 429
Expand file tree
/
Copy pathplaylistItemCompressedVideo.h
More file actions
203 lines (169 loc) · 9.29 KB
/
Copy pathplaylistItemCompressedVideo.h
File metadata and controls
203 lines (169 loc) · 9.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* This file is part of YUView - The YUV player with advanced analytics toolset
* <https://github.com/IENT/YUView>
* Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*
* You must obey the GNU General Public License in all respects for all
* of the code used other than OpenSSL. If you modify file(s) with this
* exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do
* so, delete this exception statement from your version. If you delete
* this exception statement from all source files in the program, then
* also delete it here.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/Typedef.h>
#include <decoder/decoderBase.h>
#include <filesource/FileSourceFFmpegFile.h>
#include <parser/ParserAnnexB.h>
#include <statistics/StatisticUIHandler.h>
#include <statistics/StatisticsData.h>
#include <ui_playlistItemCompressedFile.h>
#include "playlistItemWithVideo.h"
/* This playlist item encapsulates all compressed video sequences.
* We can read the data from a plain binary file (we support various raw annexB formats) or we can
* use ffmpeg to read from a container. For decoding, a range of different decoders is available.
*/
class playlistItemCompressedVideo : public playlistItemWithVideo
{
Q_OBJECT
public:
/* The default constructor requires the user to set a name that will be displayed in the
* treeWidget and provide a pointer to the widget stack for the properties panels. The constructor
* will then call addPropertiesWidget to add the custom properties panel. 'displayComponent'
* initializes the component to display (reconstruction/prediction/residual/trCoeff).
*/
playlistItemCompressedVideo(const QString & fileName,
int displayComponent = 0,
InputFormat input = InputFormat::Invalid,
decoder::DecoderEngine decoder = decoder::DecoderEngine::Invalid);
// Save the compressed file element to the given XML structure.
virtual void savePlaylist(QDomElement &root, const QDir &playlistDir) const override;
// Create a new playlistItemHEVCFile from the playlist file entry. Return nullptr if parsing
// failed.
static playlistItemCompressedVideo *
newPlaylistItemCompressedVideo(const YUViewDomElement &root, const QString &playlistFilePath);
// Return the info title and info list to be shown in the fileInfo groupBox.
virtual InfoData getInfo() const override;
virtual void infoListButtonPressed(int buttonID) override;
// Draw the compressed item using the given painter and zoom factor.
virtual void
drawItem(QPainter *painter, int frameIdx, double zoomFactor, bool drawRawData) override;
// Return the source (YUV and statistics) values under the given pixel position.
virtual ValuePairListSets getPixelValues(const QPoint &pixelPos, int frameIdx) override;
virtual bool canBeUsedInProcessing() const override { return true; }
// Add the file type filters and the extensions of files that we can load.
static void getSupportedFileExtensions(QStringList &allExtensions, QStringList &filters);
// ----- Detection of source/file change events -----
virtual bool isSourceChanged() override
{ /* TODO */
return false;
}
virtual void reloadItemSource() override;
virtual void updateSettings() override
{ /* TODO loadingDecoder->updateFileWatchSetting(); statSource.updateSettings(); */
}
// Do we need to load the given frame first?
virtual ItemLoadingState needsLoading(int frameIdx, bool loadRawData) override;
// Load the frame in the video item. Emit SignalItemChanged(true,false) when done.
virtual void
loadFrame(int frameIdx, bool playing, bool loadRawData, bool emitSignals = true) override;
// Is an image currently being loaded?
virtual bool isLoading() const override { return isFrameLoading; }
virtual bool isLoadingDoubleBuffer() const override { return isFrameLoadingDoubleBuffer; }
// Cache the frame with the given index.
// For all compressed items, a mutex must be locked when caching a frame (only one frame can be
// cached at a time because we only have one decoder).
void cacheFrame(int idx, bool testMode) override;
// We only have one caching decoder so it is better if only one thread caches frames from this
// item. This way, the frames will always be cached in the right order and no unnecessary decoding
// is performed.
virtual int cachingThreadLimit() override { return 1; }
InputFormat getInputFormat() const { return this->inputFormat; }
protected:
virtual void createPropertiesWidget() override;
// We allocate two decoder: One for loading images in the foreground and one for caching in the
// background. This is better if random access and linear decoding (caching) is performed at the
// same time.
std::unique_ptr<decoder::decoderBase> loadingDecoder;
std::unique_ptr<decoder::decoderBase> cachingDecoder;
// When opening the file, we will fill this list with the possible decoders
std::vector<decoder::DecoderEngine> possibleDecoders;
// The actual type of the decoder
decoder::DecoderEngine decoderEngine{decoder::DecoderEngine::Invalid};
// Delete existing decoders and allocate decoders for the type "decoderEngineType"
bool allocateDecoder(int displayComponent = 0);
// In order to parse raw annexB files, we need a file reader (that can read NAL units)
// and a parser that can understand what the NAL units mean. We open the file source twice (once
// for interactive loading, once for the background caching). The parser is only needed once and
// can be used for both loading and caching tasks.
std::unique_ptr<FileSourceAnnexBFile> inputFileAnnexBLoading;
std::unique_ptr<FileSourceAnnexBFile> inputFileAnnexBCaching;
std::unique_ptr<parser::ParserAnnexB> inputFileAnnexBParser;
// When reading annex B data using the FileSourceAnnexBFile::getFrameData function, we need to
// count how many frames we already read.
int readAnnexBFrameCounterCodingOrder{-1};
// Which type is the input?
InputFormat inputFormat;
FFmpeg::AVCodecIDWrapper ffmpegCodec;
// For FFMpeg files we don't need a reader to parse them. But if the container contains a
// supported format, we can read the NAL units from the compressed file.
std::unique_ptr<FileSourceFFmpegFile> inputFileFFmpegLoading;
std::unique_ptr<FileSourceFFmpegFile> inputFileFFmpegCaching;
// Is the loadFrame function currently loading?
bool isFrameLoading{};
bool isFrameLoadingDoubleBuffer{};
// Only cache one frame at a time. Caching should also always be done in display order of the
// frames.
// TODO: Could we somehow make shure that caching is always performed in display order?
QMutex cachingMutex;
stats::StatisticUIHandler statisticsUIHandler;
stats::StatisticsData statisticsData;
void fillStatisticList();
void loadStatistics(int frameIdx);
SafeUi<Ui::playlistItemCompressedFile_Widget> ui;
// The current frame index of the decoders (interactive/caching)
int currentFrameIdx[2]{-1, -1};
// Seek the input file to the given position, reset the decoder and prepare it to start decoding
// from the given position.
void seekToPosition(int seekToFrame, int64_t seekToDTS, bool caching);
// For certain decoders (FFmpeg or HM), pushing data may fail. The decoder may or may not switch
// to retrieveing mode. In this case, we must re-push the packet for which pushing failed.
bool repushData{};
// Besides the normal stats (error / no error) this item might be able to parse the file but not
// to decode it.
void setDecodingError(QString err)
{
infoText = err;
decodingEnabled = false;
}
bool decodingEnabled{};
// If the bitstream is invalid (for example it was cut at a position that it should not be cut
// at), we might be unable to decode some of the frames at the end of the sequence.
int decodingNotPossibleAfter{-1};
private slots:
// Load the raw (YUV or RGN) data for the given frame index from file. This slot is called by the
// videoHandler if the frame that is requested to be drawn has not been loaded yet.
virtual void loadRawData(int frameIdx, bool forceDecodingNow);
void updateStatSource(bool bRedraw) { emit SignalItemChanged(bRedraw, RECACHE_NONE); }
void displaySignalComboBoxChanged(int idx);
void decoderComboxBoxChanged(int idx);
};