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