1 /*
2 * dv.c
3 *
4 * Copyright (C) Charles 'Buck' Krasic - November 2000
5 *
6 * This file is part of libdv, a free DV (IEC 61834/SMPTE 314M)
7 * codec.
8 *
9 * libdv is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser Public License as published by
11 * the Free Software Foundation; either version 2.1, or (at your
12 * option) any later version.
13 *
14 * libdv is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser Public License
20 * along with libdv; see the file COPYING. If not, write to
21 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 * The libdv homepage is http://libdv.sourceforge.net/.
24 */
25
26 /** @file
27 * @ingroup decoder
28 * @brief Implementation for @link decoder DV Decoder @endlink
29 */
30
31 /** @weakgroup decoder DV Decoder
32 *
33 * This is the toplevel module of the \c liddv decoder.
34 *
35 * @{
36 */
37
38 #if HAVE_CONFIG_H
39 # include <config.h>
40 #endif
41
42 #include <string.h>
43
44 #if _WIN32
45 #include "dv_win32_pthread.h"
46 #else
47 #include <pthread.h>
48 #endif
49
50 #include "dv.h"
51 #include "encode.h"
52 #include "util.h"
53 #include "audio.h"
54 #include "idct_248.h"
55 #include "quant.h"
56 #include "weighting.h"
57 #include "vlc.h"
58 #include "parse.h"
59 #include "place.h"
60 #include "rgb.h"
61 #include "YUY2.h"
62 #include "YV12.h"
63 #if ARCH_X86 || ARCH_X86_64
64 #include "mmx.h"
65 #endif
66
67 #if YUV_420_USE_YV12
68 #define DV_MB420_YUV(a,b,c) dv_mb420_YV12 (a,b,c)
69 #define DV_MB420_YUV_MMX(a,b,c,d,e) dv_mb420_YV12_mmx(a,b,c,d,e)
70 #else
71 #define DV_MB420_YUV(a,b,c) dv_mb420_YUY2 (a,b,c)
72 #define DV_MB420_YUV_MMX(a,b,c,d,e) dv_mb420_YUY2_mmx(a,b,c,d,e)
73 #endif
74
75 #define MIN(a,b) ((a)<(b)?(a):(b))
76 #define MAX(a,b) ((a)<(b)?(b):(a))
77
78 int dv_use_mmx;
79
80 #if HAVE_LIBPOPT
81 static void
dv_decoder_popt_callback(poptContext con,enum poptCallbackReason reason,const struct poptOption * opt,const char * arg,const void * data)82 dv_decoder_popt_callback(poptContext con, enum poptCallbackReason reason,
83 const struct poptOption * opt, const char * arg, const void * data)
84 {
85 dv_decoder_t *decoder = (dv_decoder_t *)data;
86
87 if((decoder->arg_video_system < 0) || (decoder->arg_video_system > 3)) {
88 dv_opt_usage(con, decoder->option_table, DV_DECODER_OPT_SYSTEM);
89 } /* if */
90
91 } /* dv_decoder_popt_callback */
92 #endif /* HAVE_LIBPOPT */
93
94 dv_decoder_t *
dv_decoder_new(int add_ntsc_setup,int clamp_luma,int clamp_chroma)95 dv_decoder_new(int add_ntsc_setup, int clamp_luma, int clamp_chroma) {
96 dv_decoder_t *result;
97
98 result = (dv_decoder_t *)calloc(1,sizeof(dv_decoder_t));
99 if(!result) goto no_mem;
100
101 result->add_ntsc_setup = FALSE;
102 result->clamp_luma = clamp_luma;
103 result->clamp_chroma = clamp_chroma;
104 dv_init(clamp_luma, clamp_chroma);
105
106 result->video = dv_video_new();
107 if(!result->video) goto no_video;
108 result->video->dv_decoder = result;
109
110 result->audio = dv_audio_new();
111 if(!result->audio) goto no_audio;
112 result->audio->dv_decoder = result;
113
114 dv_set_error_log (result, stderr);
115 dv_set_audio_correction (result, DV_AUDIO_CORRECT_AVERAGE);
116 #if HAVE_LIBPOPT
117 result->option_table[DV_DECODER_OPT_SYSTEM] = (struct poptOption) {
118 longName: "video-system",
119 shortName: 'V',
120 argInfo: POPT_ARG_INT,
121 descrip: "video standard:"
122 "0=autoselect [default],"
123 " 1=525/60 4:1:1 (NTSC),"
124 " 2=625/50 4:2:0 (PAL,IEC 61834 DV),"
125 " 3=625/50 4:1:1 (PAL,SMPTE 314M DV)",
126 argDescrip: "(0|1|2|3)",
127 arg: &result->arg_video_system,
128 }; /* system */
129
130 result->option_table[DV_DECODER_OPT_VIDEO_INCLUDE] = (struct poptOption) {
131 argInfo: POPT_ARG_INCLUDE_TABLE,
132 descrip: "Video decode options",
133 arg: &result->video->option_table[0],
134 }; /* video include */
135
136 result->option_table[DV_DECODER_OPT_AUDIO_INCLUDE] = (struct poptOption) {
137 argInfo: POPT_ARG_INCLUDE_TABLE,
138 descrip: "Audio decode options",
139 arg: result->audio->option_table,
140 }; /* audio include */
141
142 result->option_table[DV_DECODER_OPT_CALLBACK] = (struct poptOption){
143 argInfo: POPT_ARG_CALLBACK|POPT_CBFLAG_POST,
144 arg: dv_decoder_popt_callback,
145 descrip: (char *)result, /* data passed to callback */
146 }; /* callback */
147
148 #endif /* HAVE_LIBPOPT */
149
150 return(result);
151
152 no_audio:
153 free(result->video);
154 no_video:
155 free(result);
156 result=NULL;
157 no_mem:
158 return(result);
159 } /* dv_decoder_new */
160
161
162 void
dv_decoder_free(dv_decoder_t * decoder)163 dv_decoder_free( dv_decoder_t *decoder)
164 {
165 if (decoder != NULL) {
166 if (decoder->audio != NULL) free(decoder->audio);
167 if (decoder->video != NULL) free(decoder->video);
168 free(decoder);
169 }
170 } /* dv_decoder_free */
171
172
173 void
dv_init(int clamp_luma,int clamp_chroma)174 dv_init(int clamp_luma, int clamp_chroma) {
175 static int done=FALSE;
176 if(done) goto init_done;
177 #if ARCH_X86
178 dv_use_mmx = mmx_ok();
179 #endif
180
181 /* decoder */
182 _dv_weight_init();
183 _dv_dct_init();
184 dv_dct_248_init();
185 dv_construct_vlc_table();
186 dv_parse_init();
187 dv_place_init();
188 dv_quant_init();
189 dv_rgb_init(clamp_luma, clamp_chroma);
190 dv_YUY2_init(clamp_luma, clamp_chroma);
191 dv_YV12_init(clamp_luma, clamp_chroma);
192
193 /* encoder */
194 _dv_init_vlc_test_lookup();
195 _dv_init_vlc_encode_lookup();
196 _dv_init_qno_start();
197 _dv_prepare_reorder_tables();
198
199 done=TRUE;
200 init_done:
201 return;
202 } /* dv_init */
203
204
205 void
dv_reconfigure(int clamp_luma,int clamp_chroma)206 dv_reconfigure(int clamp_luma, int clamp_chroma) {
207 dv_rgb_init( clamp_luma, clamp_chroma);
208 dv_YUY2_init( clamp_luma, clamp_chroma);
209 dv_YV12_init( clamp_luma, clamp_chroma);
210 } /* dv_reconfigure */
211
212
213 static inline void
dv_decode_macroblock(dv_decoder_t * dv,dv_macroblock_t * mb,unsigned int quality)214 dv_decode_macroblock(dv_decoder_t *dv, dv_macroblock_t *mb, unsigned int quality) {
215 int i;
216 for (i=0;
217 i<((quality & DV_QUALITY_COLOR) ? 6 : 4);
218 i++) {
219 if (mb->b[i].dct_mode == DV_DCT_248) {
220 dv_248_coeff_t co248[64];
221
222 _dv_quant_248_inverse (mb->b[i].coeffs, mb->qno, mb->b[i].class_no, co248);
223 dv_idct_248 (co248, mb->b[i].coeffs);
224 } else {
225 #if ARCH_X86
226 _dv_quant_88_inverse_x86(mb->b[i].coeffs,mb->qno,mb->b[i].class_no);
227 _dv_idct_88(mb->b[i].coeffs);
228 #elif ARCH_X86_64
229 _dv_quant_88_inverse_x86_64(mb->b[i].coeffs,mb->qno,mb->b[i].class_no);
230 _dv_idct_88(mb->b[i].coeffs);
231 #else /* ARCH_X86 */
232 _dv_quant_88_inverse(mb->b[i].coeffs,mb->qno,mb->b[i].class_no);
233 _dv_weight_88_inverse(mb->b[i].coeffs);
234 _dv_idct_88(mb->b[i].coeffs);
235 #endif /* ARCH_X86 */
236 } /* else */
237 } /* for b */
238 } /* dv_decode_macroblock */
239
240 void
dv_decode_video_segment(dv_decoder_t * dv,dv_videosegment_t * seg,unsigned int quality)241 dv_decode_video_segment(dv_decoder_t *dv, dv_videosegment_t *seg, unsigned int quality) {
242 dv_macroblock_t *mb;
243 dv_block_t *bl;
244 int m, b;
245 for (m=0,mb = seg->mb;
246 m<5;
247 m++,mb++) {
248 for (b=0,bl = mb->b;
249 b<((quality & DV_QUALITY_COLOR) ? 6 : 4);
250 b++,bl++) {
251 if (bl->dct_mode == DV_DCT_248) {
252 dv_248_coeff_t co248[64];
253
254 _dv_quant_248_inverse (mb->b[b].coeffs, mb->qno, mb->b[b].class_no, co248);
255 dv_idct_248 (co248, mb->b[b].coeffs);
256 } else {
257 #if ARCH_X86
258 _dv_quant_88_inverse_x86(bl->coeffs,mb->qno,bl->class_no);
259 _dv_weight_88_inverse(bl->coeffs);
260 _dv_idct_88(bl->coeffs);
261 #elif ARCH_X86_64
262 _dv_quant_88_inverse_x86_64(bl->coeffs,mb->qno,bl->class_no);
263 _dv_weight_88_inverse(bl->coeffs);
264 _dv_idct_88(bl->coeffs);
265 #else /* ARCH_X86 */
266 _dv_quant_88_inverse(bl->coeffs,mb->qno,bl->class_no);
267 _dv_weight_88_inverse(bl->coeffs);
268 _dv_idct_88(bl->coeffs);
269 #endif /* ARCH_X86 */
270 } /* else */
271 } /* for b */
272 } /* for mb */
273 } /* dv_decode_video_segment */
274
275 static inline void
dv_render_macroblock_rgb(dv_decoder_t * dv,dv_macroblock_t * mb,uint8_t ** pixels,int * pitches)276 dv_render_macroblock_rgb(dv_decoder_t *dv, dv_macroblock_t *mb, uint8_t **pixels, int *pitches ) {
277 if(dv->sampling == e_dv_sample_411) {
278 if(mb->x >= 704) {
279 dv_mb411_right_rgb(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 16x16 */
280 } else {
281 dv_mb411_rgb(mb, pixels, pitches, dv->add_ntsc_setup);
282 } /* else */
283 } else {
284 dv_mb420_rgb(mb, pixels, pitches);
285 } /* else */
286 } /* dv_render_macroblock_rgb */
287
288 void
dv_render_video_segment_rgb(dv_decoder_t * dv,dv_videosegment_t * seg,uint8_t ** pixels,int * pitches)289 dv_render_video_segment_rgb(dv_decoder_t *dv, dv_videosegment_t *seg, uint8_t **pixels, int *pitches ) {
290 dv_macroblock_t *mb;
291 int m;
292 for (m=0,mb = seg->mb;
293 m<5;
294 m++,mb++) {
295 if(dv->sampling == e_dv_sample_411) {
296 if(mb->x >= 704) {
297 dv_mb411_right_rgb(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 16x16 */
298 } else {
299 dv_mb411_rgb(mb, pixels, pitches, dv->add_ntsc_setup);
300 } /* else */
301 } else {
302 dv_mb420_rgb(mb, pixels, pitches);
303 } /* else */
304 } /* for */
305 } /* dv_render_video_segment_rgb */
306
307 static inline void
dv_render_macroblock_bgr0(dv_decoder_t * dv,dv_macroblock_t * mb,uint8_t ** pixels,int * pitches)308 dv_render_macroblock_bgr0(dv_decoder_t *dv, dv_macroblock_t *mb, uint8_t **pixels, int *pitches ) {
309 if(dv->sampling == e_dv_sample_411) {
310 if(mb->x >= 704) {
311 dv_mb411_right_bgr0(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 16x16 */
312 } else {
313 dv_mb411_bgr0(mb, pixels, pitches, dv->add_ntsc_setup);
314 } /* else */
315 } else {
316 dv_mb420_bgr0(mb, pixels, pitches);
317 } /* else */
318 } /* dv_render_macroblock_bgr0 */
319
320 void
dv_render_video_segment_bgr0(dv_decoder_t * dv,dv_videosegment_t * seg,uint8_t ** pixels,int * pitches)321 dv_render_video_segment_bgr0(dv_decoder_t *dv, dv_videosegment_t *seg, uint8_t **pixels, int *pitches ) {
322 dv_macroblock_t *mb;
323 int m;
324 for (m=0,mb = seg->mb;
325 m<5;
326 m++,mb++) {
327 if(dv->sampling == e_dv_sample_411) {
328 if(mb->x >= 704) {
329 dv_mb411_right_bgr0(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 16x16 */
330 } else {
331 dv_mb411_bgr0(mb, pixels, pitches, dv->add_ntsc_setup);
332 } /* else */
333 } else {
334 dv_mb420_bgr0(mb, pixels, pitches);
335 } /* else */
336 } /* for */
337 } /* dv_render_video_segment_bgr0 */
338
339 #if ARCH_X86 || ARCH_X86_64
340
341 static inline void
dv_render_macroblock_yuv(dv_decoder_t * dv,dv_macroblock_t * mb,uint8_t ** pixels,int * pitches)342 dv_render_macroblock_yuv(dv_decoder_t *dv, dv_macroblock_t *mb, uint8_t **pixels, int *pitches) {
343 if(dv_use_mmx) {
344 if(dv->sampling == e_dv_sample_411) {
345 if(mb->x >= 704) {
346 dv_mb411_right_YUY2_mmx(mb, pixels, pitches,
347 dv->add_ntsc_setup, dv->clamp_luma, dv->clamp_chroma); /* Right edge are 420! */
348 } else {
349 dv_mb411_YUY2_mmx(mb, pixels, pitches,
350 dv->add_ntsc_setup, dv->clamp_luma, dv->clamp_chroma);
351 } /* else */
352 } else {
353 DV_MB420_YUV_MMX(mb, pixels, pitches, dv->clamp_luma, dv->clamp_chroma);
354 } /* else */
355 } else {
356 if(dv->sampling == e_dv_sample_411) {
357 if(mb->x >= 704) {
358 dv_mb411_right_YUY2(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 420! */
359 } else {
360 dv_mb411_YUY2(mb, pixels, pitches, dv->add_ntsc_setup);
361 } /* else */
362 } else {
363 DV_MB420_YUV(mb, pixels, pitches);
364 } /* else */
365 } /* else */
366 } /* dv_render_macroblock_yuv */
367
368 void
dv_render_video_segment_yuv(dv_decoder_t * dv,dv_videosegment_t * seg,uint8_t ** pixels,int * pitches)369 dv_render_video_segment_yuv(dv_decoder_t *dv, dv_videosegment_t *seg, uint8_t **pixels, int *pitches) {
370 dv_macroblock_t *mb;
371 int m;
372 for (m=0,mb = seg->mb;
373 m<5;
374 m++,mb++) {
375 if(dv_use_mmx) {
376 if(dv->sampling == e_dv_sample_411) {
377 if(mb->x >= 704) {
378 dv_mb411_right_YUY2_mmx(mb, pixels, pitches,
379 dv->add_ntsc_setup, dv->clamp_luma, dv->clamp_chroma); /* Right edge are 420! */
380 } else {
381 dv_mb411_YUY2_mmx(mb, pixels, pitches,
382 dv->add_ntsc_setup, dv->clamp_luma, dv->clamp_chroma);
383 } /* else */
384 } else {
385 DV_MB420_YUV_MMX(mb, pixels, pitches, dv->clamp_luma, dv->clamp_chroma);
386 } /* else */
387 } else {
388 if(dv->sampling == e_dv_sample_411) {
389 if(mb->x >= 704) {
390 dv_mb411_right_YUY2(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 420! */
391 } else {
392 dv_mb411_YUY2(mb, pixels, pitches, dv->add_ntsc_setup);
393 } /* else */
394 } else {
395 DV_MB420_YUV(mb, pixels, pitches);
396 } /* else */
397 } /* else */
398 } /* for */
399 } /* dv_render_video_segment_yuv */
400
401 #else /* ARCH_X86 */
402
403 static inline void
dv_render_macroblock_yuv(dv_decoder_t * dv,dv_macroblock_t * mb,uint8_t ** pixels,int * pitches)404 dv_render_macroblock_yuv(dv_decoder_t *dv, dv_macroblock_t *mb, uint8_t **pixels, int *pitches) {
405 if(dv->sampling == e_dv_sample_411) {
406 if(mb->x >= 704) {
407 dv_mb411_right_YUY2(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 420! */
408 } else {
409 dv_mb411_YUY2(mb, pixels, pitches, dv->add_ntsc_setup);
410 } /* else */
411 } else {
412 DV_MB420_YUV(mb, pixels, pitches);
413 } /* else */
414 } /* dv_render_macroblock_yuv */
415
416 void
dv_render_video_segment_yuv(dv_decoder_t * dv,dv_videosegment_t * seg,uint8_t ** pixels,int * pitches)417 dv_render_video_segment_yuv(dv_decoder_t *dv, dv_videosegment_t *seg, uint8_t **pixels, int *pitches) {
418 dv_macroblock_t *mb;
419 int m;
420 for (m=0,mb = seg->mb;
421 m<5;
422 m++,mb++) {
423 if(dv->sampling == e_dv_sample_411) {
424 if(mb->x >= 704) {
425 dv_mb411_right_YUY2(mb, pixels, pitches, dv->add_ntsc_setup); /* Right edge are 420! */
426 } else {
427 dv_mb411_YUY2(mb, pixels, pitches, dv->add_ntsc_setup);
428 } /* else */
429 } else {
430 DV_MB420_YUV(mb, pixels, pitches);
431 } /* else */
432 } /* for */
433 } /* dv_render_video_segment_yuv */
434
435 #endif /* ! ARCH_X86 */
436
437 static int32_t ranges[6][2];
438
dv_check_coeff_ranges(dv_macroblock_t * mb)439 void dv_check_coeff_ranges(dv_macroblock_t *mb) {
440 dv_block_t *bl;
441 int b, i;
442 for (b=0,bl = mb->b;
443 b<6;
444 b++,bl++) {
445 for(i=0;i<64;i++) {
446 ranges[b][0] = MIN(ranges[b][0],bl->coeffs[i]);
447 ranges[b][1] = MAX(ranges[b][1],bl->coeffs[i]);
448 }
449 }
450 }
451
452 void
dv_decode_full_frame(dv_decoder_t * dv,const uint8_t * buffer,dv_color_space_t color_space,uint8_t ** pixels,int * pitches)453 dv_decode_full_frame(dv_decoder_t *dv, const uint8_t *buffer,
454 dv_color_space_t color_space, uint8_t **pixels, int *pitches) {
455
456 bitstream_t bs = { 0 };
457 dv_videosegment_t vs = { 0, 0, &bs };
458 static pthread_mutex_t dv_mutex = PTHREAD_MUTEX_INITIALIZER;
459 dv_videosegment_t *seg = &vs;
460 dv_macroblock_t *mb;
461 int ds, v, m;
462 unsigned int offset = 0, dif = 0, audio=0;
463
464 pthread_mutex_lock(&dv_mutex);
465 seg->isPAL = (dv->system == e_dv_system_625_50);
466
467 /* each DV frame consists of a sequence of DIF segments */
468 for (ds=0; ds < dv->num_dif_seqs; ds++) {
469 /** Each DIF segment conists of 150 dif blocks, 135 of which are video blocks
470 A video segment consists of 5 video blocks, where each video
471 block contains one compressed macroblock. DV bit allocation
472 for the VLC stage can spill bits between blocks in the same
473 video segment. So parsing needs the whole segment to decode
474 the VLC data
475 */
476 dif += 6;
477 audio=0;
478 /* Loop through video segments */
479 for (v=0;v<27;v++) {
480 /* skip audio block - interleaved before every 3rd video segment */
481 if(!(v % 3)) {
482 /*dv_dump_aaux_as(buffer+(dif*80), ds, audio); */
483 dif++;
484 audio++;
485 } /* if */
486 /* stage 1: parse and VLC decode 5 macroblocks that make up a video segment */
487 offset = dif * 80;
488 _dv_bitstream_new_buffer(seg->bs, (uint8_t *)buffer + offset, 80*5);
489 dv_parse_video_segment(seg, dv->quality);
490 /* stage 2: dequant/unweight/iDCT blocks, and place the macroblocks */
491 dif+=5;
492 seg->i = ds;
493 seg->k = v;
494
495 switch(color_space) {
496 case e_dv_color_yuv:
497 for (m=0,mb = seg->mb;
498 m<5;
499 m++,mb++) {
500 dv_decode_macroblock(dv, mb, dv->quality);
501 dv_place_macroblock(dv, seg, mb, m);
502 dv_render_macroblock_yuv(dv, mb, pixels, pitches);
503 } /* for m */
504 break;
505 case e_dv_color_bgr0:
506 for (m=0,mb = seg->mb;
507 m<5;
508 m++,mb++) {
509 dv_decode_macroblock(dv, mb, dv->quality);
510 dv_place_macroblock(dv, seg, mb, m);
511 dv_render_macroblock_bgr0(dv, mb, pixels, pitches);
512 } /* for m */
513 break;
514 case e_dv_color_rgb:
515 for (m=0,mb = seg->mb;
516 m<5;
517 m++,mb++) {
518 dv_decode_macroblock(dv, mb, dv->quality);
519 dv_place_macroblock(dv, seg, mb, m);
520 #if RANGE_CHECKING
521 dv_check_coeff_ranges(mb);
522 #endif
523 dv_render_macroblock_rgb(dv, mb, pixels, pitches);
524 } /* for m */
525 break;
526 } /* switch */
527
528 } /* for v */
529
530 } /* ds */
531 pthread_mutex_unlock(&dv_mutex);
532
533 #if RANGE_CHECKING
534 for(i=0;i<6;i++) {
535 fprintf(stderr, "range[%d] min %d max %d\n", i, ranges[i][0], ranges[i][1]);
536 }
537 #endif
538 } /* dv_decode_full_frame */
539
540 /* ---------------------------------------------------------------------------
541 */
542 int
dv_frame_has_audio_errors(dv_decoder_t * dv)543 dv_frame_has_audio_errors (dv_decoder_t *dv)
544 {
545 return (dv -> audio -> block_failure);
546 } /* dv_has_audio_errors */
547
548 /* ---------------------------------------------------------------------------
549 */
550 int
dv_decode_full_audio(dv_decoder_t * dv,const uint8_t * buffer,int16_t ** outbufs)551 dv_decode_full_audio(dv_decoder_t *dv, const uint8_t *buffer, int16_t **outbufs)
552 {
553 int ds, dif, audio_dif, result;
554
555 dif=0;
556 if (!dv_parse_audio_header (dv, buffer))
557 {
558 goto no_audio;
559 }
560 dv -> audio -> block_failure = dv -> audio -> sample_failure = 0;
561 for (ds = 0; ds < dv -> num_dif_seqs; ds++) {
562 dif += 6;
563 for (audio_dif = 0; audio_dif < 9; audio_dif++) {
564 if ((result = dv_decode_audio_block (dv -> audio,
565 buffer + (dif * 80),
566 ds,
567 audio_dif,
568 outbufs)))
569 {
570 goto fail;
571 }
572 dif += 16;
573 } /* for */
574 } /* for */
575
576 if (dv -> audio -> sample_failure) {
577 if (dv -> audio -> error_log) {
578 fprintf (dv -> audio -> error_log,
579 "# audio block/sample failure for %d blocks, %d samples of %d\n",
580 dv -> audio -> block_failure,
581 dv -> audio -> sample_failure,
582 dv -> audio -> raw_samples_this_frame [0]); /* TODO: second channel */
583 }
584 dv_audio_correct_errors (dv -> audio, outbufs);
585 }
586
587 dv_audio_deemphasis (dv -> audio, outbufs);
588
589 dv_audio_mix4ch (dv -> audio, outbufs);
590
591 return(TRUE);
592
593 fail:
594 if (dv -> audio -> error_log) {
595 fprintf (dv -> audio -> error_log,
596 "# decode failure \n");
597 }
598 no_audio:
599 if (dv -> audio -> error_log) {
600 fprintf (dv -> audio -> error_log,
601 "# no audio\n");
602 }
603 return(FALSE);
604
605 } /* dv_decode_full_audio */
606
607 /* ---------------------------------------------------------------------------
608 */
609 void
dv_report_video_error(dv_decoder_t * dv,uint8_t * data)610 dv_report_video_error (dv_decoder_t *dv, uint8_t *data)
611 {
612 int i, error_code;
613
614 if (!dv -> video -> error_log)
615 return;
616 /* -------------------------------------------------------------------------
617 * got through all packets
618 */
619 for (i = 0; i < dv -> frame_size; i += 80) {
620 /* -----------------------------------------------------------------------
621 * check that's a video packet
622 */
623 if ((data [i] & 0xe0) == 0x80) {
624 error_code = data [i + 3] >> 4;
625 #if 0
626 if (error_code) {
627 char err_msg1 [40], err_msg2 [40];
628 dv_get_timestamp (dv, err_msg1);
629 dv_get_recording_datetime (dv, err_msg2);
630 fprintf (dv -> video -> error_log,
631 "%s %s %s %02x %02x %02x %02x\n",
632 /* (error_code < 8) ? "vel" : "veh", */
633 "ver",
634 err_msg1,
635 err_msg2,
636 data [i + 0],
637 data [i + 1],
638 data [i + 2],
639 data [i + 3]);
640 }
641 #endif
642 }
643 }
644 }
645
646 /* ---------------------------------------------------------------------------
647 */
648 int
dv_is_PAL(dv_decoder_t * dv)649 dv_is_PAL (dv_decoder_t *dv)
650 {
651 return dv -> system == e_dv_system_625_50;
652 }
653
654 /* ---------------------------------------------------------------------------
655 */
656 int
dv_set_quality(dv_decoder_t * dv,int q)657 dv_set_quality (dv_decoder_t *dv, int q)
658 {
659 int old_q = dv -> quality;
660
661 dv -> quality = q;
662 return old_q;
663 }
664
665 /* ---------------------------------------------------------------------------
666 * query functions based upon VAUX data
667 */
668
669 /* ---------------------------------------------------------------------------
670 */
671 int
dv_get_vaux_pack(dv_decoder_t * dv,uint8_t pack_id,uint8_t * data)672 dv_get_vaux_pack (dv_decoder_t *dv, uint8_t pack_id, uint8_t *data)
673 {
674 uint8_t id;
675 if ((id = dv -> vaux_pack [pack_id]) == 0xff)
676 return -1;
677 memcpy (data, dv -> vaux_data [id], 4);
678 return 0;
679 } /* dv_get_vaux_pack */
680
681 /* ---------------------------------------------------------------------------
682 */
683 int
dv_get_ssyb_pack(dv_decoder_t * dv,uint8_t pack_id,uint8_t * data)684 dv_get_ssyb_pack (dv_decoder_t *dv, uint8_t pack_id, uint8_t *data)
685 {
686 uint8_t id;
687 if ((id = dv -> ssyb_pack [pack_id]) == 0xff)
688 return -1;
689 memcpy (data, dv -> ssyb_data [id], 4);
690 return 0;
691 } /* dv_get_vaux_pack */
692
693 /* ---------------------------------------------------------------------------
694 */
695 int
dv_frame_is_color(dv_decoder_t * dv)696 dv_frame_is_color (dv_decoder_t *dv)
697 {
698 uint8_t id;
699
700 if ((id = dv -> vaux_pack [0x60]) != 0xff) {
701 if (dv -> vaux_data [id] [1] & 0x80) {
702 return 1;
703 }
704 return 0;
705 }
706 return -1;
707 }
708
709 /* ---------------------------------------------------------------------------
710 */
711 int
dv_system_50_fields(dv_decoder_t * dv)712 dv_system_50_fields (dv_decoder_t *dv)
713 {
714 uint8_t id;
715
716 if ((id = dv -> vaux_pack [0x60]) != 0xff) {
717 if (dv -> vaux_data [id] [2] & 0x20) {
718 return 1;
719 }
720 return 0;
721 }
722 return -1;
723 }
724
725 /* ---------------------------------------------------------------------------
726 */
727 int
dv_format_normal(dv_decoder_t * dv)728 dv_format_normal (dv_decoder_t *dv)
729 {
730 int result = dv_format_wide(dv);
731 return (result == -1) ? -1 : !result;
732 }
733
734 /* ---------------------------------------------------------------------------
735 */
736 int
dv_format_wide(dv_decoder_t * dv)737 dv_format_wide (dv_decoder_t *dv)
738 {
739 uint8_t id;
740
741 if ((id = dv -> vaux_pack [0x61]) != 0xff) {
742 if (dv->std == e_dv_std_smpte_314m)
743 return ((dv->vaux_data[id][1] & 0x7) == 0x2);
744 else
745 return (((dv->vaux_data[id][1] & 0x7) == 0x2) || ((dv->vaux_data[id][1] & 0x7) == 0x7)) ;
746 }
747 return -1;
748 }
749
750 /* ---------------------------------------------------------------------------
751 */
752 int
dv_format_letterbox(dv_decoder_t * dv)753 dv_format_letterbox (dv_decoder_t *dv)
754 {
755 uint8_t id;
756
757 if ((id = dv -> vaux_pack [0x61]) != 0xff) {
758 /* FIXME: what SMPTE 314M implementations support a letterbox format? */
759 if ((dv->vaux_data[id][1] & 0x07) == 0x3) {
760 return 1;
761 }
762 return 0;
763 }
764 return -1;
765 }
766
767 /* ---------------------------------------------------------------------------
768 */
769 int
dv_frame_changed(dv_decoder_t * dv)770 dv_frame_changed (dv_decoder_t *dv)
771 {
772 uint8_t id;
773
774 if ((id = dv -> vaux_pack [0x61]) != 0xff) {
775 if (dv -> vaux_data [id] [2] & 0x20) {
776 return 1;
777 }
778 return 0;
779 }
780 return -1;
781 }
782
783 /* ---------------------------------------------------------------------------
784 */
785 int
dv_is_progressive(dv_decoder_t * dv)786 dv_is_progressive (dv_decoder_t *dv)
787 {
788 uint8_t id;
789
790 if ((id = dv -> vaux_pack [0x61]) != 0xff) {
791 if (dv -> vaux_data [id] [2] & 0x08) {
792 return 0;
793 }
794 return 1;
795 }
796 return -1;
797 }
798
799 /* ---------------------------------------------------------------------------
800 * query functions based upon SSYB data
801 * decoding code is taken from kino
802 */
803
804 /* ---------------------------------------------------------------------------
805 */
806 int
dv_get_timestamp(dv_decoder_t * dv,char * tstptr)807 dv_get_timestamp (dv_decoder_t *dv, char *tstptr)
808 {
809 int id;
810
811 if ((id = dv -> ssyb_pack [0x13]) != 0xff) {
812 sprintf (tstptr,
813 "%02d:%02d:%02d.%02d",
814 ((dv -> ssyb_data [id] [3] >> 4) & 0x03) * 10 +
815 (dv -> ssyb_data [id] [3] & 0x0f),
816 ((dv -> ssyb_data [id] [2] >> 4) & 0x07) * 10 +
817 (dv -> ssyb_data [id] [2] & 0x0f),
818 ((dv -> ssyb_data [id] [1] >> 4) & 0x07) * 10 +
819 (dv -> ssyb_data [id] [1] & 0x0f),
820 ((dv -> ssyb_data [id] [0] >> 4) & 0x03) * 10 +
821 (dv -> ssyb_data [id] [0] & 0x0f));
822
823 return 1;
824 }
825 strcpy (tstptr, "00:00:00.00");
826 return 0;
827 }
828
829 /* ---------------------------------------------------------------------------
830 * timecode is an array of 4 ints
831 */
832 int
dv_get_timestamp_int(dv_decoder_t * dv,int * timestamp)833 dv_get_timestamp_int (dv_decoder_t *dv, int *timestamp)
834 {
835 int id;
836
837 if ((id = dv -> ssyb_pack [0x13]) != 0xff) {
838 timestamp[0] = ((dv -> ssyb_data [id] [3] >> 4) & 0x03) * 10 +
839 (dv -> ssyb_data [id] [3] & 0x0f);
840
841 timestamp[1] = ((dv -> ssyb_data [id] [2] >> 4) & 0x07) * 10 +
842 (dv -> ssyb_data [id] [2] & 0x0f);
843
844 timestamp[2] = ((dv -> ssyb_data [id] [1] >> 4) & 0x07) * 10 +
845 (dv -> ssyb_data [id] [1] & 0x0f);
846
847 timestamp[3] = ((dv -> ssyb_data [id] [0] >> 4) & 0x03) * 10 +
848 (dv -> ssyb_data [id] [0] & 0x0f);
849
850 return 1;
851 }
852 return 0;
853 }
854
855 /* ---------------------------------------------------------------------------
856 */
857 int
dv_get_recording_datetime(dv_decoder_t * dv,char * dtptr)858 dv_get_recording_datetime (dv_decoder_t *dv, char *dtptr)
859 {
860 int id1, id2, year;
861
862 if ((id1 = dv -> ssyb_pack [0x62]) != 0xff &&
863 (id2 = dv -> ssyb_pack [0x63]) != 0xff) {
864 year = dv -> ssyb_data [id1] [3];
865 year = (year & 0x0f) + 10 * ((year >> 4) & 0x0f);
866 year += (year < 25) ? 2000 : 1900;
867 sprintf (dtptr,
868 "%04d-%02d-%02d %02d:%02d:%02d",
869 year,
870 ((dv -> ssyb_data [id1] [2] >> 4) & 0x01) * 10 +
871 (dv -> ssyb_data [id1] [2] & 0x0f),
872 ((dv -> ssyb_data [id1] [1] >> 4) & 0x03) * 10 +
873 (dv -> ssyb_data [id1] [1] & 0x0f),
874 ((dv -> ssyb_data [id2] [3] >> 4) & 0x03) * 10 +
875 (dv -> ssyb_data [id2] [3] & 0x0f),
876 ((dv -> ssyb_data [id2] [2] >> 4) & 0x07) * 10 +
877 (dv -> ssyb_data [id2] [2] & 0x0f),
878 ((dv -> ssyb_data [id2] [1] >> 4) & 0x07) * 10 +
879 (dv -> ssyb_data [id2] [1] & 0x0f));
880 return 1;
881 }
882
883 /* it may also be found in vaux for some... */
884 if ((id1 = dv -> vaux_pack [0x62]) != 0xff &&
885 (id2 = dv -> vaux_pack [0x63]) != 0xff) {
886 year = dv -> vaux_data [id1] [3];
887 year = (year & 0x0f) + 10 * ((year >> 4) & 0x0f);
888 year += (year < 25) ? 2000 : 1900;
889 sprintf (dtptr,
890 "%04d-%02d-%02d %02d:%02d:%02d",
891 year,
892 ((dv -> vaux_data [id1] [2] >> 4) & 0x01) * 10 +
893 (dv -> vaux_data [id1] [2] & 0x0f),
894 ((dv -> vaux_data [id1] [1] >> 4) & 0x03) * 10 +
895 (dv -> vaux_data [id1] [1] & 0x0f),
896 ((dv -> vaux_data [id2] [3] >> 4) & 0x03) * 10 +
897 (dv -> vaux_data [id2] [3] & 0x0f),
898 ((dv -> vaux_data [id2] [2] >> 4) & 0x07) * 10 +
899 (dv -> vaux_data [id2] [2] & 0x0f),
900 ((dv -> vaux_data [id2] [1] >> 4) & 0x07) * 10 +
901 (dv -> vaux_data [id2] [1] & 0x0f));
902 return 1;
903 }
904 strcpy (dtptr, "0000-00-00 00:00:00");
905 return 0;
906 }
907
908 /* ---------------------------------------------------------------------------
909 */
910 int
dv_get_recording_datetime_tm(dv_decoder_t * dv,struct tm * rec_dt)911 dv_get_recording_datetime_tm (dv_decoder_t *dv, struct tm *rec_dt)
912 {
913 int id1, id2, year;
914
915 if ((id1 = dv -> ssyb_pack [0x62]) != 0xff &&
916 (id2 = dv -> ssyb_pack [0x63]) != 0xff) {
917 year = dv -> ssyb_data [id1] [3];
918 year = (year & 0x0f) + 10 * ((year >> 4) & 0x0f);
919 year += (year < 25) ? 2000 : 1900;
920 rec_dt -> tm_isdst = rec_dt -> tm_yday = rec_dt -> tm_wday = -1;
921 rec_dt -> tm_year = year - 1900;
922 rec_dt -> tm_mon = ((dv -> ssyb_data [id1] [2] >> 4) & 0x01) * 10 +
923 (dv -> ssyb_data [id1] [2] & 0x0f) - 1;
924 rec_dt -> tm_mday = ((dv -> ssyb_data [id1] [1] >> 4) & 0x03) * 10 +
925 (dv -> ssyb_data [id1] [1] & 0x0f);
926 rec_dt -> tm_hour = ((dv -> ssyb_data [id2] [3] >> 4) & 0x03) * 10 +
927 (dv -> ssyb_data [id2] [3] & 0x0f);
928 rec_dt -> tm_min = ((dv -> ssyb_data [id2] [2] >> 4) & 0x07) * 10 +
929 (dv -> ssyb_data [id2] [2] & 0x0f);
930 rec_dt -> tm_sec = ((dv -> ssyb_data [id2] [1] >> 4) & 0x07) * 10 +
931 (dv -> ssyb_data [id2] [1] & 0x0f);
932 /* -----------------------------------------------------------------------
933 * sanity check
934 */
935 if (mktime (rec_dt) == -1)
936 return 0;
937
938 return 1;
939 }
940
941 /* it may also be found in vaux for some... */
942 if ((id1 = dv -> vaux_pack [0x62]) != 0xff &&
943 (id2 = dv -> vaux_pack [0x63]) != 0xff) {
944 year = dv -> vaux_data [id1] [3];
945 year = (year & 0x0f) + 10 * ((year >> 4) & 0x0f);
946 year += (year < 25) ? 2000 : 1900;
947 rec_dt -> tm_isdst = rec_dt -> tm_yday = rec_dt -> tm_wday = -1;
948 rec_dt -> tm_year = year - 1900;
949 rec_dt -> tm_mon = ((dv -> vaux_data [id1] [2] >> 4) & 0x01) * 10 +
950 (dv -> vaux_data [id1] [2] & 0x0f) - 1;
951 rec_dt -> tm_mday = ((dv -> vaux_data [id1] [1] >> 4) & 0x03) * 10 +
952 (dv -> vaux_data [id1] [1] & 0x0f);
953 rec_dt -> tm_hour = ((dv -> vaux_data [id2] [3] >> 4) & 0x03) * 10 +
954 (dv -> vaux_data [id2] [3] & 0x0f);
955 rec_dt -> tm_min = ((dv -> vaux_data [id2] [2] >> 4) & 0x07) * 10 +
956 (dv -> vaux_data [id2] [2] & 0x0f);
957 rec_dt -> tm_sec = ((dv -> vaux_data [id2] [1] >> 4) & 0x07) * 10 +
958 (dv -> vaux_data [id2] [1] & 0x0f);
959 /* -----------------------------------------------------------------------
960 * sanity check
961 */
962 if (mktime (rec_dt) == -1)
963 return 0;
964
965 return 1;
966 }
967 return 0;
968 }
969
970 /* ---------------------------------------------------------------------------
971 */
972 FILE *
dv_set_error_log(dv_decoder_t * dv,FILE * log)973 dv_set_error_log (dv_decoder_t *dv, FILE *log)
974 {
975 FILE *old_log;
976
977 old_log = dv -> audio -> error_log;
978 dv -> audio -> error_log =
979 dv -> video -> error_log =
980 log;
981 return old_log;
982 }
983
984 /*@}*/
985