1 /* ***** BEGIN LICENSE BLOCK *****
5 * Copyright (c) 2008 BBC Research
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * ***** END LICENSE BLOCK ***** */
30 #include <sys/types.h>
46 #include "yuvReaderMmap.h"
51 YUVReaderMmap::YUVReaderMmap(FrameQueue
& frameQ
) :
52 ReaderInterface(frameQ
)
57 void YUVReaderMmap::setForceFileType(bool f
)
62 void YUVReaderMmap::setFileType(const QString
&t
)
67 void YUVReaderMmap::setVideoWidth(int w
)
72 void YUVReaderMmap::setVideoHeight(int h
)
77 void YUVReaderMmap::setFileName(const QString
&fn
)
80 QFileInfo
info(fileName
);
83 printf("Opening file %s\n", fileName
.toLatin1().data());
84 fd
= open(fileName
.toLatin1().data(), O_RDONLY
);
86 if (fd
< 0 && DEBUG
== 1) {
87 printf("[%s]\n", fileName
.toLatin1().data());
91 base_ptr
= (char *)mmap64(0, info
.size(), PROT_READ
, MAP_PRIVATE
, fd
, 0);
93 QString type
= forceFileType
? fileType
.toLower() : info
.suffix().toLower();
94 printf("Playing file with type %s\n", type
.toLatin1().data());
99 videoFormat
= VideoData::V16P0
;
100 lastFrameNum
= info
.size() / ((videoWidth
* videoHeight
* 3 * 2) / 2);
104 if (type
== "16p2") {
105 videoFormat
= VideoData::V16P2
;
106 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 2 * 2);
110 if (type
== "16p4") {
111 videoFormat
= VideoData::V16P4
;
112 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 3 * 2);
116 if (type
== "420p") {
117 videoFormat
= VideoData::V8P0
;
118 lastFrameNum
= info
.size() / ((videoWidth
* videoHeight
* 3) / 2);
122 if (type
== "422p") {
123 videoFormat
= VideoData::V8P2
;
124 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 2);
128 if (type
== "444p") {
129 videoFormat
= VideoData::V8P4
;
130 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 3);
134 if (type
== "i420") {
135 videoFormat
= VideoData::V8P0
;
136 lastFrameNum
= info
.size() / ((videoWidth
* videoHeight
* 3) / 2);
140 if (type
== "yv12") {
141 videoFormat
= VideoData::YV12
;
142 lastFrameNum
= info
.size() / ((videoWidth
* videoHeight
* 3) / 2);
146 if (type
== "uyvy") {
147 videoFormat
= VideoData::UYVY
;
148 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 2);
152 if (type
== "v216") {
153 videoFormat
= VideoData::V216
;
154 lastFrameNum
= info
.size() / (videoWidth
* videoHeight
* 4);
158 if (type
== "v210") {
159 videoFormat
= VideoData::V210
;
160 lastFrameNum
= info
.size() / ((videoWidth
* videoHeight
* 2 * 4) / 3);
165 Stats
&stat
= Stats::getInstance();
166 std::stringstream ss
;
170 stat
.addStat("YUVReader (mmap)", "VideoWidth", ss
.str());
174 stat
.addStat("YUVReader (mmap)", "VideoHeight", ss
.str());
178 stat
.addStat("YUVReader (mmap)", "FirstFrame", ss
.str());
182 stat
.addStat("YUVReader (mmap)", "LastFrame", ss
.str());
184 stat
.addStat("YUVReader (mmap)", "VideoFormat", type
.toLatin1().data());
188 //called from the frame queue controller to get frame data for display
189 void YUVReaderMmap::pullFrame(int frameNumber
, VideoData
*& dst
)
191 VideoData
* frame
= frameQueue
.allocateFrame();
192 frame
->resize(videoWidth
, videoHeight
, videoFormat
);
195 printf("Getting frame number %d\n", frameNumber
);
197 //deal with frame number wrapping
198 if (frameNumber
< 0) {
200 frameNumber
%= (lastFrameNum
+ 1);
201 frameNumber
= lastFrameNum
- frameNumber
;
204 if (frameNumber
> lastFrameNum
)
205 frameNumber
%= (lastFrameNum
+ 1);
207 //set frame number and first/last flags
208 frame
->frameNum
= frameNumber
;
209 frame
->isFirstFrame
= (frameNumber
== firstFrameNum
);
210 frame
->isLastFrame
= (frameNumber
== lastFrameNum
);
214 off64_t offset
= (off_t
)dst
->dataSize
* (off_t
)frameNumber
; //seek to the wanted frame
217 int idletime
= timer
.restart();
219 memcpy(dst
->data
, base_ptr
+ offset
, dst
->dataSize
);
221 int readtime
= timer
.restart();
224 Stats
&stat
= Stats::getInstance();
225 std::stringstream ss
;
228 ss
<< readtime
<< "ms";
229 stat
.addStat("YUVReader (mmap)", "Read", ss
.str());
232 int rate
= (dst
->dataSize
) / (readtime
* 1024);
233 ss
<< rate
<< " MB/s";
234 stat
.addStat("YUVReader (mmap)", "Peak Rate", ss
.str());
237 int avgrate
= (dst
->dataSize
) / ((readtime
+ idletime
) * 1024);
238 ss
<< avgrate
<< "MB/s";
239 stat
.addStat("YUVReader (mmap)", "Avg Rate", ss
.str());