1 /***************************************************************************
2                           gui_blackframes.cpp  -  description
3                              -------------------
4 
5             Detect black frames
6 
7 
8     copyright            : (C) 2002/2008 by mean
9     email                : fixounet@free.fr
10  ***************************************************************************/
11 
12 /***************************************************************************
13  *                                                                         *
14  *   This program is free software; you can redistribute it and/or modify  *
15  *   it under the terms of the GNU General Public License as published by  *
16  *   the Free Software Foundation; either version 2 of the License, or     *
17  *   (at your option) any later version.                                   *
18  *                                                                         *
19  ***************************************************************************/
20 
21 #include "ADM_cpp.h"
22 #include "avi_vars.h"
23 
24 #include <math.h>
25 
26 #include "DIA_fileSel.h"
27 #include "ADM_assert.h"
28 #include "prototype.h"
29 #include "audio_out.h"
30 #include "ADM_coreAudio.h"
31 #include "gui_action.hxx"
32 #include "gtkgui.h"
33 #include "DIA_coreToolkit.h"
34 #include "ADM_render/GUI_render.h"
35 #include "DIA_working.h"
36 #include "DIA_processing.h"
37 #include "ADM_commonUI/DIA_busy.h"
38 #include "ADM_commonUI/GUI_ui.h"
39 
40 #include "ADM_vidMisc.h"
41 #include "ADM_preview.h"
42 
43 
44 static const int  sliceOrder[8]={3,4,2,5,1,6,0,7};
45 /**
46         \fn sliceScanNotBlack
47         \brief The image is split into 8 slices, returns if the given slice is black or not
48 */
sliceScanNotBlack(int darkness,int maxnonb,int sliceNum,ADMImage * img)49 static int sliceScanNotBlack(int darkness, int maxnonb, int sliceNum,ADMImage *img)
50 {
51     uint32_t width = img->_width;
52     int       stride=img->GetPitch(PLANAR_Y);
53     uint32_t height = img->_height;
54     uint32_t sliceOffset = (stride * height)>>3 ;    // 1/8 of an image
55 
56     uint8_t *buff,*start;
57 
58     int cnt4=0;
59 
60     start=img->GetReadPtr(PLANAR_Y)+ sliceOffset*sliceNum;
61     buff=start+sliceOffset;
62 
63     while(--buff>start)
64     {
65       if(*buff > darkness )
66       {
67         cnt4++;
68         if(cnt4>=maxnonb)
69           return(1);
70       }
71     }
72     return(0);
73 
74 }
75 /**
76     \fn fastIsNotBlack
77     \brief Quickly check if the frame is black or not
78 */
fastIsNotBlack(int darkness,ADMImage * img)79 uint8_t  fastIsNotBlack(int darkness,ADMImage *img)
80 {
81 
82     uint32_t width = img->_width;
83     uint32_t height = img->_height;
84     uint32_t maxnonb=(width* height)>>8;
85 
86         maxnonb>>=3;
87         // Divide the screen in 8 part  : 0 1 2 3 4 5 6 7
88         // Scan 2 & 3 first, if still good, go on
89         for(uint32_t i=0;i<6;i++)
90         {
91                 if(sliceScanNotBlack(darkness,maxnonb,sliceOrder[i],img)) return 1;
92         }
93         // The slice 0 & 7 are particular and we admit twice as much
94         if(sliceScanNotBlack(darkness,maxnonb*2,0,img)) return 1;
95         if(sliceScanNotBlack(darkness,maxnonb*2,7,img)) return 1;
96 
97     return(0);
98 }
99 /**
100     \fn GUI_PrevBlackFrame
101     \brief lookup for a black frame
102 */
GUI_PrevBlackFrame(void)103 void GUI_PrevBlackFrame(void)
104 {
105     GUI_Error_HIG(QT_TRANSLATE_NOOP("blackframes", "BlackFrame"), QT_TRANSLATE_NOOP("blackframes", "This function is unsupported at the moment"));
106 }
107 
108 /**
109     \fn GUI_NextBlackFrame
110     \brief lookup for a black frame
111 */
GUI_NextBlackFrame(void)112 void GUI_NextBlackFrame(void)
113 {
114     if (playing)
115 		return;
116     if (! avifileinfo)
117        return;
118     const int darkness=40;
119     admPreview::deferDisplay(true);
120     ADMImage *rdr;
121 
122 //#warning set real fps
123 
124     // guess ~ number of frames
125     uint64_t duration=video_body->getVideoDuration();
126     uint64_t startTime=admPreview::getCurrentPts();
127     DIA_processingBase *work=createProcessing(QT_TRANSLATE_NOOP("blackframes", "Searching black frame.."),duration-startTime);
128 
129     uint32_t count=0;
130     while(1)
131     {
132         UI_purge();
133 
134         if(false==admPreview::nextPicture())
135                 break;
136         rdr=admPreview::getBuffer();
137         if(rdr->refType!=ADM_HW_NONE) // need to convert it to plain YV12
138         {
139             if(false==rdr->hwDownloadFromRef())
140             {
141                 ADM_warning("Cannot convert hw image to yv12\n");
142                 break;
143             }
144 
145         }
146         if(!fastIsNotBlack(darkness,rdr))
147         {
148                 break;
149         }
150         if(work->update(1,admPreview::getCurrentPts()-startTime))
151               break;
152     }
153     delete work;
154     admPreview::deferDisplay(false);
155     admPreview::samePicture();
156     GUI_setCurrentFrameAndTime();
157     return;
158 
159 }
160 
161 //EOF
162