1 /*  dvbcut
2     Copyright (c) 2005 Sven Over <svenover@svenover.de>
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 /* $Id$ */
20 
21 #include "imageprovider.h"
22 #include "mpgfile.h"
23 #include "avframe.h"
24 #include "busyindicator.h"
25 
imageprovider(mpgfile & mpg,busyindicator * bi,bool unscaled,double factor,int cachesize)26 imageprovider::imageprovider(mpgfile &mpg, busyindicator *bi, bool unscaled, double factor, int cachesize) :
27     RTTI(IMAGEPROVIDER_STANDARD), m(mpg), maxcachedframes(cachesize), viewscalefactor(factor),
28     busyind(bi)
29   {
30   if (unscaled)
31     RTTI=IMAGEPROVIDER_UNSCALED;
32   }
33 
34 
~imageprovider()35 imageprovider::~imageprovider()
36   {
37   if (busyind)
38     delete busyind;
39   }
40 
41 
shrinkcache(int free)42 void imageprovider::shrinkcache(int free)
43   {
44   int keep=maxcachedframes;
45   if (free>0)
46     keep-=free;
47 
48   std::list<framecacheitem>::iterator it=framecache.begin();
49   for(int i=0;i<keep&&it!=framecache.end();++it,++i)
50     ;
51 
52   while(it!=framecache.end())
53     it=framecache.erase(it);
54   }
55 
getimage(int picture,bool decodeallgop)56 QImage imageprovider::getimage(int picture, bool decodeallgop)
57   {
58   if (picture < 0 || picture >= m.getpictures())
59     return QImage();
60 
61   for (std::list<framecacheitem>::iterator it = framecache.begin(); it != framecache.end(); ++it)
62     if (it->first == picture) {
63       framecache.push_front(*it);
64       framecache.erase(it);
65       return framecache.front().second;
66       }
67 
68   if (busyind)
69     busyind->setbusy(true);
70   shrinkcache(1);
71 
72   decodepicture(picture,decodeallgop);
73   if (busyind)
74     busyind->setbusy(false);
75 
76   for (std::list<framecacheitem>::iterator it = framecache.begin(); it != framecache.end(); ++it)
77     if (it->first == picture) {
78       framecache.push_front(*it);
79       framecache.erase(it);
80       return framecache.front().second;
81       }
82 
83   return QImage();
84   }
85 
decodepicture(int picture,bool decodeallgop)86 void imageprovider::decodepicture(int picture, bool decodeallgop)
87   {
88   std::list<avframe*> framelist;
89   int startpic=m.lastiframe(picture);
90   m.decodegop(startpic,decodeallgop?-1:(picture+1),framelist);
91 
92   for (std::list<avframe*>::iterator it=framelist.begin();it!=framelist.end();++it) {
93     framecache.push_front(framecacheitem(startpic++,(*it)->getqimage(RTTI!=IMAGEPROVIDER_UNSCALED,viewscalefactor)));
94     delete *it;
95     }
96   }
97