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