r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / libdv.c
blob3f1e87c59e3cc25b82cb65924930e08c8cf94d65
1 /*
2 * Grabbing algorithm is from dvgrab
3 */
5 #include "colormodels.h"
6 #include "libdv.h"
8 #include <pthread.h>
9 #include <stdio.h>
10 #include <string.h>
12 #ifdef USE_MMX
13 #include "mmx.h"
14 #endif
17 #define DV_WIDTH 720
18 #define DV_HEIGHT 576
21 static int dv_initted = 0;
22 static pthread_mutex_t dv_lock;
24 dv_t* dv_new()
26 dv_t *dv = calloc(1, sizeof(dv_t));
27 if(!dv_initted)
29 pthread_mutexattr_t attr;
30 dv_initted = 1;
31 // dv_init();
32 pthread_mutexattr_init(&attr);
33 pthread_mutex_init(&dv_lock, &attr);
36 dv->decoder = dv_decoder_new(0, 0, 0);
37 dv->decoder->quality = dv->decoder->video->quality;
38 dv->decoder->prev_frame_decoded = 0;
39 dv->use_mmx = 1;
40 return dv;
44 int dv_delete(dv_t *dv)
46 int i;
47 if(dv->decoder)
49 dv_decoder_free( dv->decoder );
52 if(dv->temp_video)
53 free(dv->temp_video);
55 if(dv->temp_audio[0])
57 for(i = 0; i < 4; i++)
58 free(dv->temp_audio[i]);
61 if(dv->encoder)
63 dv_encoder_free( dv->encoder );
66 free(dv);
67 return 0;
70 // Decodes BC_YUV422 only
74 int dv_read_video(dv_t *dv,
75 unsigned char **output_rows,
76 unsigned char *data,
77 long bytes,
78 int color_model)
80 int dif = 0;
81 int lost_coeffs = 0;
82 long offset = 0;
83 int isPAL = 0;
84 int is61834 = 0;
85 int numDIFseq;
86 int ds;
87 int i, v, b, m;
88 dv_block_t *bl;
89 long mb_offset;
90 dv_sample_t sampling;
91 dv_macroblock_t *mb;
92 int pixel_size;
93 int pitches[3];
94 int use_temp = color_model != BC_YUV422;
95 unsigned char *pixels[3];
97 //printf("dv_read_video 1 %d\n", color_model);
98 pthread_mutex_lock(&dv_lock);
99 switch(bytes)
101 case DV_PAL_SIZE:
102 break;
103 case DV_NTSC_SIZE:
104 break;
105 default:
106 return 1;
107 break;
110 if(data[0] != 0x1f) return 1;
112 pitches[0] = DV_WIDTH * 2;
113 pitches[1] = 0;
114 pitches[2] = 0;
115 pixels[1] = 0;
116 pixels[2] = 0;
118 dv_parse_header(dv->decoder, data);
120 if(!use_temp)
122 //printf("dv_read_video 1\n");
123 pixels[0] = output_rows[0];
124 dv_decode_full_frame(dv->decoder,
125 data,
126 e_dv_color_yuv,
127 output_rows,
128 pitches);
129 //printf("dv_read_video 2\n");
131 else
133 unsigned char *temp_rows[DV_HEIGHT];
134 if(!dv->temp_video)
135 dv->temp_video = calloc(1, DV_WIDTH * DV_HEIGHT * 2);
137 for(i = 0; i < DV_HEIGHT; i++)
139 temp_rows[i] = dv->temp_video + i * DV_WIDTH * 2;
142 pixels[0] = dv->temp_video;
143 //printf("dv_read_video 3 %p\n", data);
144 dv_decode_full_frame(dv->decoder,
145 data,
146 e_dv_color_yuv,
147 pixels,
148 pitches);
149 //printf("dv_read_video 4\n");
151 cmodel_transfer(output_rows,
152 temp_rows,
153 output_rows[0],
154 output_rows[1],
155 output_rows[2],
161 DV_WIDTH,
162 dv->decoder->height,
165 DV_WIDTH,
166 dv->decoder->height,
167 BC_YUV422,
168 color_model,
170 DV_WIDTH,
171 DV_WIDTH);
173 dv->decoder->prev_frame_decoded = 1;
174 pthread_mutex_unlock(&dv_lock);
175 return 0;
183 int dv_read_audio(dv_t *dv,
184 unsigned char *samples,
185 unsigned char *data,
186 long size,
187 int channels,
188 int bits)
190 long current_position;
191 int norm;
192 int i, j;
193 int audio_bytes;
194 short *samples_int16 = (short*)samples;
195 int samples_read;
196 if(channels > 4) channels = 4;
198 // For some reason someone had problems with libdv's maxmimum audio samples
199 #define MAX_AUDIO_SAMPLES 2048
200 if(!dv->temp_audio[0])
202 for(i = 0; i < 4; i++)
203 dv->temp_audio[i] = calloc(1, sizeof(int16_t) * MAX_AUDIO_SAMPLES);
206 switch(size)
208 case DV_PAL_SIZE:
209 norm = DV_PAL;
210 break;
211 case DV_NTSC_SIZE:
212 norm = DV_NTSC;
213 break;
214 default:
215 return 0;
216 break;
219 if(data[0] != 0x1f) return 0;
221 dv_parse_header(dv->decoder, data);
222 dv_decode_full_audio(dv->decoder, data, dv->temp_audio);
223 samples_read = dv->decoder->audio->samples_this_frame;
225 for(i = 0; i < channels; i++)
227 for(j = 0; j < samples_read; j++)
229 samples_int16[i + j * channels] = dv->temp_audio[i][j];
230 if(samples_int16[i + j * channels] == -0x8000)
231 samples_int16[i + j * channels] = 0;
240 return samples_read;
247 // Encodes BC_YUV422 only
249 void dv_write_video(dv_t *dv,
250 unsigned char *data,
251 unsigned char **input_rows,
252 int color_model,
253 int norm)
255 dv_color_space_t encode_dv_colormodel = 0;
257 if(!dv->encoder)
259 dv->encoder = dv_encoder_new(
265 switch( color_model )
267 case BC_YUV422:
268 encode_dv_colormodel = e_dv_color_yuv;
269 break;
270 case BC_RGB888:
271 encode_dv_colormodel = e_dv_color_rgb;
272 break;
273 default:
274 return;
275 break;
277 dv->encoder->is16x9 = 0;
278 dv->encoder->vlc_encode_passes = 3;
279 dv->encoder->static_qno = 0;
280 dv->encoder->force_dct = DV_DCT_AUTO;
281 dv->encoder->isPAL = (norm == DV_PAL);
283 dv_encode_full_frame( dv->encoder,
284 input_rows,
285 encode_dv_colormodel,
286 data );
291 int dv_write_audio(dv_t *dv,
292 unsigned char *data,
293 unsigned char *input_samples,
294 int max_samples,
295 int channels,
296 int bits,
297 int rate,
298 int norm)
300 int i, j;
302 if(!dv->encoder)
304 dv->encoder = dv_encoder_new(
307 0 );
309 dv->encoder->isPAL = (norm == DV_PAL);
312 // Get sample count from a libdv function
313 int samples = dv_calculate_samples(dv->encoder, rate, dv->audio_frames);
314 dv->audio_frames++;
316 if(!dv->temp_audio[0])
318 for(i = 0; i < 4; i++)
319 dv->temp_audio[i] = calloc(1, sizeof(int16_t) * MAX_AUDIO_SAMPLES);
322 for(i = 0; i < channels; i++)
324 short *temp_audio = dv->temp_audio[i];
325 short *input_channel = (short*)input_samples + i;
326 for(j = 0; j < samples; j++)
328 temp_audio[j] = input_channel[j * channels];
333 dv_encode_full_audio(dv->encoder,
334 dv->temp_audio,
335 channels,
336 rate,
337 data);
338 return samples;