[mmap] partial revert of 8cef8db4 to disable using mmap file reader
[videoplayer.git] / yuvReaderMmap.cpp
blob23ecf41f0a5bd1bef6f21b7976496f887b5d0327
1 /* ***** BEGIN LICENSE BLOCK *****
3 * The MIT License
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
23 * THE SOFTWARE.
25 * ***** END LICENSE BLOCK ***** */
27 #include <QtGui>
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <sstream>
35 #ifdef Q_OS_UNIX
36 #include <unistd.h>
37 #include <sys/mman.h>
38 #endif
40 #ifdef Q_OS_MAC
41 #define lseek64 lseek
42 #define off64_t off_t
43 #define mmap64 mmap
44 #endif
46 #include "yuvReaderMmap.h"
47 #include "stats.h"
49 #define DEBUG 0
51 YUVReaderMmap::YUVReaderMmap(FrameQueue& frameQ) :
52 ReaderInterface(frameQ)
54 randomAccess = true;
57 void YUVReaderMmap::setForceFileType(bool f)
59 forceFileType = f;
62 void YUVReaderMmap::setFileType(const QString &t)
64 fileType = t;
67 void YUVReaderMmap::setVideoWidth(int w)
69 videoWidth = w;
72 void YUVReaderMmap::setVideoHeight(int h)
74 videoHeight = h;
77 void YUVReaderMmap::setFileName(const QString &fn)
79 fileName = fn;
80 QFileInfo info(fileName);
82 if (DEBUG)
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());
88 perror("OPEN");
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());
96 firstFrameNum = 0;
98 if (type == "16p0") {
99 videoFormat = VideoData::V16P0;
100 lastFrameNum = info.size() / ((videoWidth * videoHeight * 3 * 2) / 2);
101 lastFrameNum--;
104 if (type == "16p2") {
105 videoFormat = VideoData::V16P2;
106 lastFrameNum = info.size() / (videoWidth * videoHeight * 2 * 2);
107 lastFrameNum--;
110 if (type == "16p4") {
111 videoFormat = VideoData::V16P4;
112 lastFrameNum = info.size() / (videoWidth * videoHeight * 3 * 2);
113 lastFrameNum--;
116 if (type == "420p") {
117 videoFormat = VideoData::V8P0;
118 lastFrameNum = info.size() / ((videoWidth * videoHeight * 3) / 2);
119 lastFrameNum--;
122 if (type == "422p") {
123 videoFormat = VideoData::V8P2;
124 lastFrameNum = info.size() / (videoWidth * videoHeight * 2);
125 lastFrameNum--;
128 if (type == "444p") {
129 videoFormat = VideoData::V8P4;
130 lastFrameNum = info.size() / (videoWidth * videoHeight * 3);
131 lastFrameNum--;
134 if (type == "i420") {
135 videoFormat = VideoData::V8P0;
136 lastFrameNum = info.size() / ((videoWidth * videoHeight * 3) / 2);
137 lastFrameNum--;
140 if (type == "yv12") {
141 videoFormat = VideoData::YV12;
142 lastFrameNum = info.size() / ((videoWidth * videoHeight * 3) / 2);
143 lastFrameNum--;
146 if (type == "uyvy") {
147 videoFormat = VideoData::UYVY;
148 lastFrameNum = info.size() / (videoWidth * videoHeight * 2);
149 lastFrameNum--;
152 if (type == "v216") {
153 videoFormat = VideoData::V216;
154 lastFrameNum = info.size() / (videoWidth * videoHeight * 4);
155 lastFrameNum--;
158 if (type == "v210") {
159 videoFormat = VideoData::V210;
160 lastFrameNum = info.size() / ((videoWidth * videoHeight * 2 * 4) / 3);
161 lastFrameNum--;
165 Stats &stat = Stats::getInstance();
166 std::stringstream ss;
168 ss.str("");
169 ss << videoWidth;
170 stat.addStat("YUVReader (mmap)", "VideoWidth", ss.str());
172 ss.str("");
173 ss << videoHeight;
174 stat.addStat("YUVReader (mmap)", "VideoHeight", ss.str());
176 ss.str("");
177 ss << firstFrameNum;
178 stat.addStat("YUVReader (mmap)", "FirstFrame", ss.str());
180 ss.str("");
181 ss << lastFrameNum;
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);
194 if (DEBUG)
195 printf("Getting frame number %d\n", frameNumber);
197 //deal with frame number wrapping
198 if (frameNumber < 0) {
199 frameNumber *= -1;
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);
211 dst = frame;
213 //calculate offset
214 off64_t offset = (off_t)dst->dataSize * (off_t)frameNumber; //seek to the wanted frame
216 //read
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;
227 ss.str("");
228 ss << readtime << "ms";
229 stat.addStat("YUVReader (mmap)", "Read", ss.str());
231 ss.str("");
232 int rate = (dst->dataSize) / (readtime * 1024);
233 ss << rate << " MB/s";
234 stat.addStat("YUVReader (mmap)", "Peak Rate", ss.str());
236 ss.str("");
237 int avgrate = (dst->dataSize) / ((readtime + idletime) * 1024);
238 ss << avgrate << "MB/s";
239 stat.addStat("YUVReader (mmap)", "Avg Rate", ss.str());