~ubuntu-branches/ubuntu/karmic/recordmydesktop/karmic

« back to all changes in this revision

Viewing changes to src/load_cache.c

  • Committer: Bazaar Package Importer
  • Author(s): Alan Pope
  • Date: 2009-04-21 10:57:22 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20090421105722-w6l4gz958gva15wn
Tags: 0.3.8.1-0ubuntu1
* New upstream release (LP: #364674)
* debian/control: Fixed libjack0.100.0-dev dependancy
* debian/control: Fixed project home page

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************************************
2
 
*                            recordMyDesktop                                  *
3
 
*******************************************************************************
4
 
*                                                                             *
5
 
*            Copyright (C) 2006,2007,2008 John Varouhakis                     *
6
 
*                                                                             *
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
 
*                                                                             *
23
 
*                                                                             *
24
 
*   For further information contact me at johnvarouhakis@gmail.com            *
25
 
******************************************************************************/
26
 
 
27
 
 
28
 
#include <recordmydesktop.h>
29
 
 
30
 
void LoadBlock(unsigned char *dest,
31
 
               unsigned char *source,
32
 
               int blockno,
33
 
               int width,
34
 
               int height,
35
 
               int blockwidth){
36
 
    int j,
37
 
        block_i=blockno/(width/blockwidth),//place on the grid
38
 
        block_k=blockno%(width/blockwidth);
39
 
    for(j=0;j<blockwidth;j++)//we copy rows
40
 
        memcpy( &dest[(block_i*width+block_k)*blockwidth+j*width],
41
 
                &source[j*blockwidth],
42
 
                blockwidth);
43
 
}
44
 
 
45
 
//returns number of bytes
46
 
int ReadZF(void * buffer,size_t size,size_t nmemb,FILE *ucfp,gzFile *ifp){
47
 
    if((ifp!=NULL && ucfp!=NULL)||
48
 
       (ifp==NULL && ucfp==NULL))
49
 
        return -1;
50
 
    else if(ucfp!=NULL){
51
 
        return (size*fread(buffer,size,nmemb,ucfp));
52
 
    }
53
 
    else
54
 
        return gzread(ifp,buffer,size*nmemb);
55
 
}
56
 
 
57
 
int ReadFrame(CachedFrame *frame,FILE *ucfp,gzFile *ifp){
58
 
    int index_entry_size=sizeof(u_int32_t);
59
 
    if(frame->header->Ynum>0){
60
 
        if(ReadZF(frame->YBlocks,
61
 
                index_entry_size,
62
 
                frame->header->Ynum,
63
 
                ucfp,
64
 
                ifp)!=index_entry_size*frame->header->Ynum){
65
 
            return -1;
66
 
        }
67
 
    }
68
 
    if(frame->header->Unum>0){
69
 
        if(ReadZF(frame->UBlocks,
70
 
                index_entry_size,
71
 
                frame->header->Unum,
72
 
                ucfp,
73
 
                ifp)!=index_entry_size*frame->header->Unum){
74
 
            return -1;
75
 
        }
76
 
    }
77
 
    if(frame->header->Vnum>0){
78
 
        if(ReadZF(frame->VBlocks,
79
 
                index_entry_size,
80
 
                frame->header->Vnum,
81
 
                ucfp,
82
 
                ifp)!=index_entry_size*frame->header->Vnum){
83
 
            return -1;
84
 
        }
85
 
    }
86
 
    if(frame->header->Ynum>0){
87
 
        if(ReadZF(frame->YData,
88
 
                  Y_UNIT_BYTES,
89
 
                  frame->header->Ynum,
90
 
                  ucfp,
91
 
                  ifp)!=Y_UNIT_BYTES*frame->header->Ynum){
92
 
            return -2;
93
 
        }
94
 
    }
95
 
    if(frame->header->Unum>0){
96
 
        if(ReadZF(frame->UData,
97
 
                  UV_UNIT_BYTES,
98
 
                  frame->header->Unum,
99
 
                  ucfp,
100
 
                  ifp)!=UV_UNIT_BYTES*frame->header->Unum){
101
 
            return -2;
102
 
        }
103
 
    }
104
 
    if(frame->header->Vnum>0){
105
 
        if(ReadZF(frame->VData,
106
 
                  UV_UNIT_BYTES,
107
 
                  frame->header->Vnum,
108
 
                  ucfp,
109
 
                  ifp)!=UV_UNIT_BYTES*frame->header->Vnum){
110
 
            return -2;
111
 
        }
112
 
    }
113
 
    return 0;
114
 
}
115
 
 
116
 
void *LoadCache(ProgData *pdata){
117
 
 
118
 
    yuv_buffer *yuv=&pdata->enc_data->yuv;
119
 
    gzFile *ifp=NULL;
120
 
    FILE *ucfp=NULL;
121
 
    FILE *afp=pdata->cache_data->afp;
122
 
    FrameHeader fheader;
123
 
    CachedFrame frame;
124
 
    int j=0,
125
 
        nth_cache=1,
126
 
        audio_end=0,
127
 
        extra_frames=0,//total number of duplicated frames
128
 
        missing_frames=0,//if this is found >0 current run will not load
129
 
                        //a frame but it will proccess the previous
130
 
        thread_exit=0,//0 success, -1 couldn't find files,1 couldn't remove
131
 
        blocknum_x=pdata->enc_data->yuv.y_width/Y_UNIT_WIDTH,
132
 
        blocknum_y=pdata->enc_data->yuv.y_height/Y_UNIT_WIDTH,
133
 
        blockszy=Y_UNIT_BYTES,//size of y plane block in bytes
134
 
        blockszuv=UV_UNIT_BYTES;//size of u,v plane blocks in bytes
135
 
    signed char *sound_data=(signed char *)malloc(pdata->periodsize*
136
 
                                                  pdata->sound_framesize);
137
 
 
138
 
    u_int32_t YBlocks[(yuv->y_width*yuv->y_height)/Y_UNIT_BYTES],
139
 
              UBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES],
140
 
              VBlocks[(yuv->uv_width*yuv->uv_height)/UV_UNIT_BYTES];
141
 
    //we allocate the frame that we will use
142
 
    INIT_FRAME(&frame,&fheader,yuv,
143
 
                YBlocks,UBlocks,VBlocks);
144
 
    //and the we open our files
145
 
    if(!pdata->args.zerocompression){
146
 
        ifp=gzopen(pdata->cache_data->imgdata,"rb");
147
 
        if(ifp==NULL){
148
 
            thread_exit=-1;
149
 
            pthread_exit(&thread_exit);
150
 
        }
151
 
    }
152
 
    else{
153
 
        ucfp=fopen(pdata->cache_data->imgdata,"rb");
154
 
        if(ucfp==NULL){
155
 
            thread_exit=-1;
156
 
            pthread_exit(&thread_exit);
157
 
        }
158
 
    }
159
 
 
160
 
 
161
 
    if(!pdata->args.nosound){
162
 
        afp=fopen(pdata->cache_data->audiodata,"rb");
163
 
        if(afp==NULL){
164
 
            thread_exit=-1;
165
 
            pthread_exit(&thread_exit);
166
 
        }
167
 
    }
168
 
 
169
 
    //this will be used now to define if we proccess audio or video
170
 
    //on any given loop.
171
 
    pdata->avd=0;
172
 
    //If sound finishes first,we go on with the video.
173
 
    //If video ends we will do one more run to flush audio in the ogg file
174
 
    while(pdata->running){
175
 
        //video load and encoding
176
 
        if(pdata->avd<=0 || pdata->args.nosound || audio_end){
177
 
            if(missing_frames>0){
178
 
                extra_frames++;
179
 
                missing_frames--;
180
 
                SyncEncodeImageBuffer(pdata);
181
 
            }
182
 
            else if(((!pdata->args.zerocompression)&&
183
 
                     (gzread(ifp,frame.header,sizeof(FrameHeader))==
184
 
                      sizeof(FrameHeader) ))||
185
 
                    ((pdata->args.zerocompression)&&
186
 
                    (fread(frame.header,sizeof(FrameHeader),1,ucfp)==1))){
187
 
                //sync
188
 
                missing_frames+=frame.header->current_total-
189
 
                                (extra_frames+frame.header->frameno);
190
 
                if(frames_total)
191
 
                    fprintf(stdout,"\r[%d%%] ",
192
 
                    ((frame.header->frameno+extra_frames)*100)/frames_total);
193
 
                else
194
 
                    fprintf(stdout,"\r[%d frames rendered] ",
195
 
                            (frame.header->frameno+extra_frames));
196
 
                fflush(stdout);
197
 
                if( (frame.header->Ynum<=blocknum_x*blocknum_y) &&
198
 
                    (frame.header->Unum<=blocknum_x*blocknum_y) &&
199
 
                    (frame.header->Vnum<=blocknum_x*blocknum_y) &&
200
 
                    (!ReadFrame(&frame,
201
 
                                ((pdata->args.zerocompression)?ucfp:NULL),
202
 
                                ((pdata->args.zerocompression)?NULL:ifp)))
203
 
                        ){
204
 
                        //load the blocks for each buffer
205
 
                        if(frame.header->Ynum)
206
 
                            for(j=0;j<frame.header->Ynum;j++)
207
 
                                LoadBlock(  yuv->y,
208
 
                                            &frame.YData[j*blockszy],
209
 
                                            frame.YBlocks[j],
210
 
                                            yuv->y_width,
211
 
                                            yuv->y_height,
212
 
                                            Y_UNIT_WIDTH);
213
 
                        if(frame.header->Unum)
214
 
                            for(j=0;j<frame.header->Unum;j++)
215
 
                                LoadBlock(  yuv->u,
216
 
                                            &frame.UData[j*blockszuv],
217
 
                                            frame.UBlocks[j],
218
 
                                            yuv->uv_width,
219
 
                                            yuv->uv_height,
220
 
                                            UV_UNIT_WIDTH);
221
 
                        if(frame.header->Vnum)
222
 
                            for(j=0;j<frame.header->Vnum;j++)
223
 
                                LoadBlock(  yuv->v,
224
 
                                            &frame.VData[j*blockszuv],
225
 
                                            frame.VBlocks[j],
226
 
                                            yuv->uv_width,
227
 
                                            yuv->uv_height,
228
 
                                            UV_UNIT_WIDTH);
229
 
                        //encode. This is not made in a thread since
230
 
                        //now blocking is not a problem
231
 
                        //and this way sync problems
232
 
                        //can be avoided more easily.
233
 
                        SyncEncodeImageBuffer(pdata);
234
 
                }
235
 
                else{
236
 
                    raise(SIGINT);
237
 
                    continue;
238
 
                }
239
 
            }
240
 
            else{
241
 
                if(SwapCacheFilesRead(pdata->cache_data->imgdata,
242
 
                                      nth_cache,
243
 
                                      &ifp,
244
 
                                      &ucfp)){
245
 
                    raise(SIGINT);
246
 
                }
247
 
                else{
248
 
                    fprintf(stderr,"\t[Cache File %d]",nth_cache);
249
 
                    nth_cache++;
250
 
                }
251
 
                continue;
252
 
            }
253
 
        }
254
 
        //audio load and encoding
255
 
        else{
256
 
            if(!audio_end){
257
 
                int nbytes=fread(sound_data,1,pdata->periodsize*
258
 
                                 pdata->sound_framesize,afp);
259
 
                if(nbytes<=0)
260
 
                    audio_end=1;
261
 
                else
262
 
                    SyncEncodeSoundBuffer(pdata,sound_data);
263
 
            }
264
 
        }
265
 
    }
266
 
 
267
 
    pdata->v_encoding_clean=pdata->th_encoding_clean=1;
268
 
    pthread_mutex_lock(&pdata->theora_lib_mutex);
269
 
    pthread_cond_signal(&pdata->theora_lib_clean);
270
 
    pthread_mutex_unlock(&pdata->theora_lib_mutex);
271
 
    pthread_mutex_lock(&pdata->vorbis_lib_mutex);
272
 
    pthread_cond_signal(&pdata->vorbis_lib_clean);
273
 
    pthread_mutex_unlock(&pdata->vorbis_lib_mutex);
274
 
    fprintf(stdout,"\n");
275
 
    CLEAR_FRAME(&frame)
276
 
    free(sound_data);
277
 
 
278
 
    if(!pdata->args.nosound){
279
 
        fclose(afp);
280
 
    }
281
 
 
282
 
    pthread_exit(&thread_exit);
283
 
 
284
 
 
285
 
}
286