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