[cvs] / xvidcore / vfw / src / status.c Repository:
ViewVC logotype

Diff of /xvidcore/vfw/src/status.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Tue Jun 10 10:07:03 2003 UTC revision 1.1.2.5, Fri Jan 23 13:27:59 2004 UTC
# Line 0  Line 1 
1    /******************************************************************************
2     *
3     * XviD Video-for-Windows Frontend
4     * Quantizer histogram and encoding status window
5     *
6     * Copyright (C) 2003 Peter Ross <pross@xvid.org>
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21     *
22     * $Id$
23     *
24     *****************************************************************************/
25    
26    
27    #include <windows.h>
28    #include <stdio.h>
29    
30    #include "resource.h"
31    #include "codec.h"
32    #include "status.h"
33    
34    #include "debug.h"
35    
36    
37    #define CLR_BG                  0
38    #define CLR_FG                  1
39    #define CLR_QUANT_I             2
40    #define CLR_QUANT_P             3
41    #define CLR_QUANT_B             4
42    
43    static void set_bic(RGBQUAD * rgb, int index, int r, int g, int b)
44    {
45            rgb[index].rgbRed = r;
46            rgb[index].rgbGreen = g;
47            rgb[index].rgbBlue = b;
48    }
49    
50    /*
51            draw graph into buffer
52    */
53    static void draw_graph(status_t *s)
54    {
55            unsigned int i,j;
56    
57            memset(s->buffer, CLR_BG, s->width*s->stride);
58    
59            for (j=0; j<s->height; j++)
60            for (i=0; i<31; i++)
61                    s->buffer[ j*s->stride + i*s->width31 ] = CLR_FG;
62    
63            if (s->count[0]>0) {
64                    for (i=0; i<31; i++) {
65                            /* i-vops */
66                            unsigned int j_height = (s->height-s->tm.tmHeight)*s->quant[0][i]/s->max_quant_frames;
67                            if (j_height==0 && s->quant[0][i]>0) j_height=1;
68    
69                            for(j=0; j < j_height; j++) {
70                                    memset(s->buffer + (s->tm.tmHeight+j)*s->stride + i*s->width31 + 1,
71                                                    CLR_QUANT_I, s->width31-1);
72                            }
73                            /* p/s-vops */
74                            j_height += (s->height-s->tm.tmHeight)*s->quant[1][i]/s->max_quant_frames;
75                            if (j_height==0 && s->quant[1][i]>0) j_height=1;
76    
77                            for(; j < j_height; j++) {
78                                    memset(s->buffer + (s->tm.tmHeight+j)*s->stride + i*s->width31 + 1,
79                                                    CLR_QUANT_P, s->width31-1);
80                            }
81                            /* b-vops */
82                            j_height += (s->height-s->tm.tmHeight)*s->quant[2][i]/s->max_quant_frames;
83                            if (j_height==0 && s->quant[2][i]>0) j_height=1;
84    
85                            for(; j < j_height; j++) {
86                                    memset(s->buffer + (s->tm.tmHeight+j)*s->stride + i*s->width31 + 1,
87                                                    CLR_QUANT_B, s->width31-1);
88                            }
89                    }
90            }
91    }
92    
93    
94    static const char * number[31] = {
95            "1", "2", "3", "4", "5", "6", "7", "8", "9",
96            "0","1","2","3","4","5","6","7","8","9",
97            "0","1","2","3","4","5","6","7","8","9",
98            "0","1"
99    };
100    
101    static double
102    avg_quant(int quants[31], int min, int max, char* buf)
103    {
104            int i, sum = 0, count = 0;
105            for (i = min; i <= max && i > 0; i++) {
106                    sum += i*quants[i-1];
107                    count += quants[i-1];
108            }
109    
110            if (count != 0) {
111                    double avg = (double)sum/(double)count;
112                    sprintf(buf, "%.2f", avg);
113                    return avg;
114            } else {
115                    buf[0] = 0;
116                    return 0.0;
117            }
118    }
119    
120    /* status window proc handlder */
121    
122    static BOOL CALLBACK status_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
123    {
124            status_t * s = (status_t*)GetWindowLong(hDlg, GWL_USERDATA);
125    
126            switch (uMsg)
127            {
128            case WM_INITDIALOG :
129                    SetWindowLong(hDlg, GWL_USERDATA, lParam);
130                    s = (status_t*)lParam;
131    
132                    s->hGraph = GetDlgItem(hDlg, IDC_STATUS_GRAPH);
133                    s->hDc = GetDC(s->hGraph);
134                    {
135                            RECT rect;
136                            GetWindowRect(s->hGraph, &rect);
137                            s->width = rect.right - rect.left;
138                            s->height = rect.bottom - rect.top;
139                    }
140                    s->width31 = s->width/31;
141                    s->stride = (s->width/4+1)*4;
142    
143                    s->buffer = malloc(s->width * s->stride);
144    
145                    s->bi = malloc(sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD));
146                    memset(s->bi, 0, sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD));
147    
148                    s->bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
149                    s->bi->bmiHeader.biWidth  = s->stride;
150                    s->bi->bmiHeader.biHeight = s->height;
151                    s->bi->bmiHeader.biPlanes = 1;
152                    s->bi->bmiHeader.biBitCount = 8;
153                    s->bi->bmiHeader.biCompression = BI_RGB;
154    
155                    set_bic(s->bi->bmiColors, CLR_BG,          0,   0,   0);
156                    set_bic(s->bi->bmiColors, CLR_FG,        128, 128, 128);
157                    set_bic(s->bi->bmiColors, CLR_QUANT_I,  255, 0,   0);
158                    set_bic(s->bi->bmiColors, CLR_QUANT_P,  0, 0,   255);
159                    set_bic(s->bi->bmiColors, CLR_QUANT_B,  0, 192,   0);
160    
161                    SelectObject(s->hDc, GetStockObject(DEFAULT_GUI_FONT));
162                    SetBkColor(s->hDc, *(DWORD*)&s->bi->bmiColors[CLR_BG]);
163                    SetTextColor(s->hDc, *(DWORD*)&s->bi->bmiColors[CLR_FG]);
164                    GetTextMetrics(s->hDc, &s->tm);
165    
166                    draw_graph(s);
167                    SetTimer(hDlg, IDC_STATUS_GRAPH, 1000, NULL);   /* 1 second */
168                    break;
169    
170            case WM_DESTROY :
171                    free(s->buffer);
172                    free(s->bi);
173                    KillTimer(hDlg, IDC_STATUS_GRAPH);
174                    s->hDlg = NULL;
175                    break;
176    
177            case WM_DRAWITEM :
178                    if (wParam==IDC_STATUS_GRAPH) {
179                            int i;
180    
181                            /* copy buffer into dc */
182                            SetDIBitsToDevice(s->hDc,
183                                    0, 0, s->width, s->height,
184                                    0, 0, 0, s->height,
185                                    s->buffer, s->bi, DIB_RGB_COLORS);
186    
187                            SetTextAlign(s->hDc, GetTextAlign(s->hDc)|TA_CENTER);
188    
189                            for (i=0; i<31; i++) {
190                                    TextOut(s->hDc, i*s->width31 + s->width/62,
191                                            s->height-s->tm.tmHeight, number[i], strlen(number[i]));
192                            }
193                    }
194                    break;
195    
196            case WM_TIMER :
197                    if (wParam==IDC_STATUS_GRAPH) {
198                            double avg_q; char buf[16];
199    
200                            SetDlgItemInt(hDlg, IDC_STATUS_I_NUM, (unsigned int)s->count[1], FALSE);
201                            SetDlgItemInt(hDlg, IDC_STATUS_P_NUM, (unsigned int)s->count[2], FALSE);
202                            SetDlgItemInt(hDlg, IDC_STATUS_B_NUM, (unsigned int)s->count[3], FALSE);
203                            SetDlgItemInt(hDlg, IDC_STATUS_NUM, (unsigned int)s->count[0], FALSE);
204    
205                            SetDlgItemInt(hDlg, IDC_STATUS_IQ_MIN, s->min_quant[1], FALSE);
206                            SetDlgItemInt(hDlg, IDC_STATUS_IQ_MAX, s->max_quant[1], FALSE);
207                            SetDlgItemInt(hDlg, IDC_STATUS_PQ_MIN, s->min_quant[2], FALSE);
208                            SetDlgItemInt(hDlg, IDC_STATUS_PQ_MAX, s->max_quant[2], FALSE);
209                            SetDlgItemInt(hDlg, IDC_STATUS_BQ_MIN, s->min_quant[3], FALSE);
210                            SetDlgItemInt(hDlg, IDC_STATUS_BQ_MAX, s->max_quant[3], FALSE);
211                            SetDlgItemInt(hDlg, IDC_STATUS_Q_MIN, s->min_quant[0], FALSE);
212                            SetDlgItemInt(hDlg, IDC_STATUS_Q_MAX, s->max_quant[0], FALSE);
213    
214                            SetDlgItemInt(hDlg, IDC_STATUS_IL_MIN, s->min_length[1], FALSE);
215                            SetDlgItemInt(hDlg, IDC_STATUS_IL_MAX, s->max_length[1], FALSE);
216                            if (s->count[1]>0)
217                                    SetDlgItemInt(hDlg, IDC_STATUS_IL_AVG, (unsigned int)(s->tot_length[1]/s->count[1]), FALSE);
218                            else
219                                    SetDlgItemInt(hDlg, IDC_STATUS_IL_AVG, 0, FALSE);
220                            SetDlgItemInt(hDlg, IDC_STATUS_IL_TOT, (unsigned int)(s->tot_length[1]/1024), FALSE);
221                            SetDlgItemInt(hDlg, IDC_STATUS_PL_MIN, s->min_length[2], FALSE);
222                            SetDlgItemInt(hDlg, IDC_STATUS_PL_MAX, s->max_length[2], FALSE);
223                            if (s->count[2]>0)
224                                    SetDlgItemInt(hDlg, IDC_STATUS_PL_AVG, (unsigned int)(s->tot_length[2]/s->count[2]), FALSE);
225                            else
226                                    SetDlgItemInt(hDlg, IDC_STATUS_PL_AVG, 0, FALSE);
227                            SetDlgItemInt(hDlg, IDC_STATUS_PL_TOT, (unsigned int)(s->tot_length[2]/1024), FALSE);
228                            SetDlgItemInt(hDlg, IDC_STATUS_BL_MIN, s->min_length[3], FALSE);
229                            SetDlgItemInt(hDlg, IDC_STATUS_BL_MAX, s->max_length[3], FALSE);
230                            if (s->count[3]>0)
231                                    SetDlgItemInt(hDlg, IDC_STATUS_BL_AVG, (unsigned int)(s->tot_length[3]/s->count[3]), FALSE);
232                            else
233                                    SetDlgItemInt(hDlg, IDC_STATUS_BL_AVG, 0, FALSE);
234                            SetDlgItemInt(hDlg, IDC_STATUS_BL_TOT, (unsigned int)(s->tot_length[3]/1024), FALSE);
235                            SetDlgItemInt(hDlg, IDC_STATUS_L_MIN, s->min_length[0], FALSE);
236                            SetDlgItemInt(hDlg, IDC_STATUS_L_MAX, s->max_length[0], FALSE);
237                            if (s->count[0]>0)
238                                    SetDlgItemInt(hDlg, IDC_STATUS_L_AVG, (int)(s->tot_length[0]/s->count[0]), FALSE);
239                            else
240                                    SetDlgItemInt(hDlg, IDC_STATUS_L_AVG, 0, FALSE);
241                            SetDlgItemInt(hDlg, IDC_STATUS_L_TOT, (unsigned int)(s->tot_length[0]/1024), FALSE);
242    
243                            if (s->count[0]>0) {
244                                    uint64_t kbits = 8*s->tot_length[0]/1000;
245                                    double secs = (double)s->count[0]/s->fps;
246                               SetDlgItemInt(hDlg, IDC_STATUS_KBPS, (int)(kbits/secs), FALSE);
247                            }else{
248                                    SetDlgItemInt(hDlg, IDC_STATUS_KBPS, 0, FALSE);
249                            }
250    
251                            avg_q = avg_quant(s->quant[0], s->min_quant[1], s->max_quant[1], buf) * s->count[1];
252                            SetDlgItemText(hDlg, IDC_STATUS_IQ_AVG, buf);
253    
254                            avg_q += avg_quant(s->quant[1], s->min_quant[2], s->max_quant[2], buf) * s->count[2];
255                            SetDlgItemText(hDlg, IDC_STATUS_PQ_AVG, buf);
256    
257                            avg_q += avg_quant(s->quant[2], s->min_quant[3], s->max_quant[3], buf) * s->count[3];
258                            SetDlgItemText(hDlg, IDC_STATUS_BQ_AVG, buf);
259    
260                            if (s->count[0] != 0) avg_q /= (double)s->count[0];
261                            sprintf(buf, "%.2f", avg_q);
262                            SetDlgItemText(hDlg, IDC_STATUS_Q_AVG, buf);
263    
264                            draw_graph(s);
265                            InvalidateRect(s->hGraph, NULL, FALSE);
266                    }
267                    break;
268    
269            case WM_COMMAND :
270                    if (LOWORD(wParam)==IDCANCEL) {
271                            DestroyWindow(hDlg);
272                    }
273                    break;
274    
275            default :
276                    return FALSE;
277            }
278    
279            return TRUE;
280    }
281    
282    
283    /* destroy status window
284       (however if the auto-close box is unchecked, dont destroy) */
285    
286    void status_destroy(status_t *s)
287    {
288            if (s->hDlg && IsDlgButtonChecked(s->hDlg,IDC_STATUS_DESTROY)==BST_CHECKED) {
289                    DestroyWindow(s->hDlg);
290            }
291    }
292    
293    
294    /* destroy status window, alwasys */
295    
296    void status_destroy_always(status_t *s)
297    {
298            if (s->hDlg) {
299                    DestroyWindow(s->hDlg);
300            }
301    }
302    
303    
304    /* create status window */
305    void status_create(status_t * s, unsigned int fps_inc, unsigned int fps_base)
306    {
307            int i;
308    
309            s->fps = fps_base/fps_inc;
310    
311            memset(s->quant[0], 0, 31*sizeof(int));
312            memset(s->quant[1], 0, 31*sizeof(int));
313            memset(s->quant[2], 0, 31*sizeof(int));
314            s->max_quant_frames = 0;
315            for (i=0; i<4; i++) {
316                    s->count[i] = 0;
317                    s->min_quant[i] = s->max_quant[i] = 0;
318                    s->min_length[i] = s->max_length[i] = 0;
319                    s->tot_length[i] = 0;
320            }
321    
322            s->hDlg = CreateDialogParam(g_hInst,
323                                                            MAKEINTRESOURCE(IDD_STATUS),
324                                                            GetDesktopWindow(),
325                                                            status_proc, (LPARAM)s);
326    
327            ShowWindow(s->hDlg, SW_SHOW);
328    }
329    
330    static char
331    type2char(int type)
332    {
333            if (type==XVID_TYPE_IVOP)
334                    return 'I';
335            if (type==XVID_TYPE_PVOP)
336                    return 'P';
337            if (type==XVID_TYPE_BVOP)
338                    return 'B';
339            return 'S';
340    }
341    
342    static void
343    status_debugoutput(status_t *s, int type, int length, int quant)
344    {
345            if (s->hDlg && IsDlgButtonChecked(s->hDlg,IDC_SHOWINTERNALS)==BST_CHECKED) {
346                    LRESULT litem;
347                    char buf[128];
348                    sprintf(buf, "[%6d] ->%c  q:%2d (%6d b)",
349                                    (unsigned int)(s->count[0]), type2char(type), quant, length);
350    
351                    SendDlgItemMessage (s->hDlg,IDC_DEBUGOUTPUT, LB_ADDSTRING, 0, (LPARAM)(LPSTR)buf);
352    
353                    litem = SendDlgItemMessage (s->hDlg, IDC_DEBUGOUTPUT, LB_GETCOUNT, 0, 0L);
354    
355                    if (litem > 12)
356                            litem = SendDlgItemMessage (s->hDlg,IDC_DEBUGOUTPUT, LB_DELETESTRING, 0, 0L);
357    
358                    SendDlgItemMessage(s->hDlg,IDC_DEBUGOUTPUT, LB_SETCURSEL, (WORD)(litem-1), 0L);
359            }
360    }
361    
362    /* feed stats info into the window */
363    void status_update(status_t *s, int type, int length, int quant)
364    {
365            s->count[0]++;
366            s->count[type]++;
367    
368            status_debugoutput(s, type, length, quant);
369    
370            if (type == 4) type = 2; /* XVID_TYPE_SVOP to XVID_TYPE_PVOP */
371    
372            if (s->min_quant[0]==0 || quant<s->min_quant[0]) s->min_quant[0] = quant;
373            if (s->max_quant[0]==0 || quant>s->max_quant[0]) s->max_quant[0] = quant;
374            if (s->min_quant[type]==0 || quant<s->min_quant[type]) s->min_quant[type] = quant;
375            if (s->max_quant[type]==0|| quant>s->max_quant[type]) s->max_quant[type] = quant;
376    
377            s->quant[type-1][quant-1]++;
378            if (s->quant[0][quant-1] + s->quant[1][quant-1] + s->quant[2][quant-1] > s->max_quant_frames)
379                    s->max_quant_frames = s->quant[0][quant-1] + s->quant[1][quant-1] + s->quant[2][quant-1];
380    
381            if (s->min_length[0]==0 || length<s->min_length[0]) s->min_length[0] = length;
382            if (s->max_length[0]==0 || length>s->max_length[0]) s->max_length[0] = length;
383            if (s->min_length[type]==0 || length<s->min_length[type]) s->min_length[type] = length;
384            if (s->max_length[type]==0|| length>s->max_length[type]) s->max_length[type] = length;
385            s->tot_length[0] += length;
386            s->tot_length[type] += length;
387    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.5

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4