90c9f6efefbabd99fca21a4da8792e4bfcd408be
[goodguy/history.git] / cinelerra-5.1 / cinelerra / libdv.C
1 /*
2  * Grabbing algorithm is from dvgrab
3  */
4
5 #include "bccmodels.h"
6 #include "libdv.h"
7
8 #include <pthread.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #ifdef USE_MMX
13 #include "mmx.h"
14 #endif
15
16
17 #define DV_WIDTH 720
18 #define DV_HEIGHT 576
19
20
21 static int dv_initted = 0;
22 static pthread_mutex_t dv_lock;
23
24 dv_t* dv_new()
25 {
26         dv_t *dv = (dv_t *)calloc(1, sizeof(dv_t));
27         if(!dv_initted)
28         {
29                 pthread_mutexattr_t attr;
30                 dv_initted = 1;
31 //              dv_init();
32                 pthread_mutexattr_init(&attr);
33                 pthread_mutex_init(&dv_lock, &attr);
34         }
35
36         dv->decoder = dv_decoder_new(0, 0, 0);
37         dv_set_error_log (dv->decoder, 0);
38         dv->decoder->quality = DV_QUALITY_BEST;
39         dv->decoder->prev_frame_decoded = 0;
40         dv->use_mmx = 1;
41         return dv;
42 }
43
44
45 int dv_delete(dv_t *dv)
46 {
47         int i;
48         if(dv->decoder)
49         {
50                 dv_decoder_free( dv->decoder );
51         }
52
53         if(dv->temp_video)
54                 free(dv->temp_video);
55
56         if(dv->temp_audio[0])
57         {
58                 for(i = 0; i < 4; i++)
59                         free(dv->temp_audio[i]);
60         }
61
62         if(dv->encoder)
63         {
64                 dv_encoder_free( dv->encoder );
65         }
66
67         free(dv);
68         return 0;
69 }
70
71 // Decodes BC_YUV422 only
72
73
74
75 int dv_read_video(dv_t *dv, 
76                 unsigned char **output_rows, 
77                 unsigned char *data, 
78                 long bytes,
79                 int color_model)
80 {
81         int i;
82         int pitches[3];
83         int use_temp = color_model != BC_YUV422;
84         unsigned char *pixels[3];
85
86 //printf("dv_read_video 1 %d\n", color_model);
87         pthread_mutex_lock(&dv_lock);
88         switch(bytes)
89         {
90                 case DV_PAL_SIZE:
91                         break;
92                 case DV_NTSC_SIZE:
93                         break;
94                 default:
95                         return 1;
96                         break;
97         }
98
99         if(data[0] != 0x1f) return 1;
100
101         pitches[0] = DV_WIDTH * 2;
102         pitches[1] = 0;
103         pitches[2] = 0;
104         pixels[1] = 0;
105         pixels[2] = 0;
106
107         dv_parse_header(dv->decoder, data);
108
109         if(!use_temp)
110         {
111 //printf("dv_read_video 1\n");
112                 pixels[0] = output_rows[0];
113                 dv_decode_full_frame(dv->decoder, 
114                         data, 
115                         e_dv_color_yuv, 
116                         output_rows, 
117                         pitches);
118 //printf("dv_read_video 2\n");
119         }
120         else
121         {
122                 unsigned char *temp_rows[DV_HEIGHT];
123                 if(!dv->temp_video)
124                         dv->temp_video = (unsigned char *)calloc(1, DV_WIDTH * DV_HEIGHT * 2);
125
126                 for(i = 0; i < DV_HEIGHT; i++)
127                 {
128                         temp_rows[i] = dv->temp_video + i * DV_WIDTH * 2;
129                 }
130
131                 pixels[0] = dv->temp_video;
132 //printf("dv_read_video 3 %p\n", data);
133                 dv_decode_full_frame(dv->decoder, 
134                         data, 
135                         e_dv_color_yuv, 
136                         pixels, 
137                         pitches);
138 //printf("dv_read_video 4\n");
139
140                 BC_CModels::transfer(output_rows, 
141                         temp_rows,
142                         output_rows[0],
143                         output_rows[1],
144                         output_rows[2],
145                         0,
146                         0,
147                         0,
148                         0, 
149                         0, 
150                         DV_WIDTH, 
151                         dv->decoder->height,
152                         0, 
153                         0, 
154                         DV_WIDTH, 
155                         dv->decoder->height,
156                         BC_YUV422, 
157                         color_model,
158                         0,
159                         DV_WIDTH,
160                         DV_WIDTH);
161         }
162         dv->decoder->prev_frame_decoded = 1;
163         pthread_mutex_unlock(&dv_lock);
164         return 0;
165 }
166
167
168
169
170
171
172 int dv_read_audio(dv_t *dv, 
173                 unsigned char *samples,
174                 unsigned char *data,
175                 long size,
176                 int channels,
177                 int bits)
178 {
179         int i, j;
180         short *samples_int16 = (short*)samples;
181         int samples_read;
182         if(channels > 4) channels = 4;
183
184 // For some reason someone had problems with libdv's maxmimum audio samples
185 #define MAX_AUDIO_SAMPLES 2048
186         if(!dv->temp_audio[0])
187         {
188                 for(i = 0; i < 4; i++)
189                         dv->temp_audio[i] = (int16_t*)calloc(1, sizeof(int16_t) * MAX_AUDIO_SAMPLES);
190         }
191
192         switch(size) {
193                 case DV_PAL_SIZE: break;
194                 case DV_NTSC_SIZE: break;
195                 default: return 0;
196         }
197
198         if(data[0] != 0x1f) return 0;
199
200         dv_parse_header(dv->decoder, data);
201         dv_decode_full_audio(dv->decoder, data, dv->temp_audio);
202         samples_read = dv->decoder->audio->samples_this_frame;
203
204         for(i = 0; i < channels; i++)
205         {
206                 for(j = 0; j < samples_read; j++)
207                 {
208                         samples_int16[i + j * channels] = dv->temp_audio[i][j];
209                         if(samples_int16[i + j * channels] == -0x8000)
210                                 samples_int16[i + j * channels] = 0;
211                 }
212         }
213
214
215
216
217
218
219         return samples_read;
220 }
221
222
223
224
225
226 // Encodes BC_YUV422 only
227
228 void dv_write_video(dv_t *dv,
229                 unsigned char *data,
230                 unsigned char **input_rows,
231                 int color_model,
232                 int norm)
233 {
234         int encode_dv_colormodel = 0;
235
236         if(!dv->encoder)
237         {
238                 dv->encoder = dv_encoder_new( 
239                         0,
240                         0,
241                         0);
242         }
243
244         switch( color_model )
245         {
246                 case BC_YUV422:
247                         encode_dv_colormodel = e_dv_color_yuv;
248                         break;
249                 case BC_RGB888:
250                         encode_dv_colormodel = e_dv_color_rgb;
251                         break;
252                 default:
253                         return;
254                         break;
255         }
256         dv->encoder->is16x9 = 0;
257         dv->encoder->vlc_encode_passes = 3;
258         dv->encoder->static_qno = 0;
259         dv->encoder->force_dct = DV_DCT_AUTO;
260         dv->encoder->isPAL = (norm == DV_PAL);
261         
262         dv_encode_full_frame( dv->encoder,
263                 input_rows, 
264                 (dv_color_space_t)encode_dv_colormodel, 
265                 data );
266 }
267
268
269
270 int dv_write_audio(dv_t *dv,
271                 unsigned char *data,
272                 unsigned char *input_samples,
273                 int max_samples,
274                 int channels,
275                 int bits,
276                 int rate,
277                 int norm)
278 {
279         int i, j;
280
281         if(!dv->encoder)
282         {
283                 dv->encoder = dv_encoder_new( 
284                         0,
285                         0,
286                         0 );
287         }
288         dv->encoder->isPAL = (norm == DV_PAL);
289
290
291 // Get sample count from a libdv function
292         int samples = dv_calculate_samples(dv->encoder, rate, dv->audio_frames);
293         dv->audio_frames++;
294
295         if(!dv->temp_audio[0])
296         {
297                 for(i = 0; i < 4; i++)
298                         dv->temp_audio[i] = (int16_t*)calloc(1, sizeof(int16_t) * MAX_AUDIO_SAMPLES);
299         }
300
301         for(i = 0; i < channels; i++)
302         {
303                 short *temp_audio = dv->temp_audio[i];
304                 short *input_channel = (short*)input_samples + i;
305                 for(j = 0; j < samples; j++)
306                 {
307                         temp_audio[j] = input_channel[j * channels];
308                 }
309         }
310
311
312         dv_encode_full_audio(dv->encoder, 
313                 dv->temp_audio,
314                 channels, 
315                 rate, 
316                 data);
317         return samples;
318 }
319
320