Various spelling fixes.
[vlc.git] / modules / codec / xvmc / slice_xvmc_vld.c
1 /* $Id$
2  * Copyright (c) 2004 The Unichrome project. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2, or (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16  *
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <vlc/vlc.h>
25 #include <vlc_vout.h>
26 #include <vlc_codec.h>
27
28 #include "mpeg2.h"
29 #include "mpeg2_internal.h"
30 #include "xvmc_vld.h"
31
32 static uint8_t zig_zag_scan[64] ATTR_ALIGN(16) =
33 {
34     /* Zig-Zag scan pattern */
35      0, 1, 8,16, 9, 2, 3,10,
36     17,24,32,25,18,11, 4, 5,
37     12,19,26,33,40,48,41,34,
38     27,20,13, 6, 7,14,21,28,
39     35,42,49,56,57,50,43,36,
40     29,22,15,23,30,37,44,51,
41     58,59,52,45,38,31,39,46,
42     53,60,61,54,47,55,62,63
43 };
44
45 static uint8_t alternate_scan [64] ATTR_ALIGN(16) =
46 {
47     /* Alternate scan pattern */
48     0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
49     41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
50     51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
51     53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
52 };
53
54 void mpeg2_xxmc_choose_coding(decoder_t *p_dec,
55         mpeg2_decoder_t * const decoder, picture_t *picture,
56         double aspect_ratio, int flags)
57 {
58     if (picture)
59     {
60         //vlc_fourcc_t decoder_format = picture->format.i_chroma;
61         //if (decoder_format == VLC_FOURCC('X','x','M','C')) {
62         vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_data;
63
64         /*
65          * Make a request for acceleration type and mpeg coding from
66          * the output plugin.
67          */
68
69         xxmc->fallback_format = VLC_FOURCC('Y','V','1','2');
70         xxmc->acceleration = VLC_XVMC_ACCEL_VLD;//| VLC_XVMC_ACCEL_IDCT| VLC_XVMC_ACCEL_MOCOMP ;
71
72         //msg_Dbg(p_dec, "mpeg2_xxmc_choose_coding 2");
73         /*
74          * Standard MOCOMP / IDCT XvMC implementation for interlaced streams
75          * is buggy. The bug is inherited from the old XvMC driver. Don't use it until
76          * it has been fixed. (A volunteer ?)
77          */
78
79         //if ( decoder->picture_structure != 3 ) {
80         //xxmc->acceleration &= ~( VLC_XVMC_ACCEL_IDCT | VLC_XVMC_ACCEL_MOCOMP );
81         //}
82
83         xxmc->mpeg = (decoder->mpeg1) ? VLC_XVMC_MPEG_1:VLC_XVMC_MPEG_2;
84         xxmc->proc_xxmc_update_frame( picture,
85                                       decoder->width,
86                                       decoder->height,
87                                       aspect_ratio,
88                                       VLC_IMGFMT_XXMC, flags );
89         //}
90   }
91 }
92
93 void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture,
94                         int code, uint8_t *buffer, int size)
95 {
96     mpeg2_decoder_t * const decoder = &(mpeg2dec->decoder);
97     picture = (picture_t *)mpeg2dec->fbuf[0]->id;
98     vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_data;
99     vlc_vld_frame_t *vft = &xxmc->vld_frame;
100     unsigned mb_frame_height;
101     int i;
102     const uint8_t *scan_pattern;
103
104     if (1 == code)
105     {
106         //mpeg2_skip(mpeg2dec, 1);
107         //frame->bad_frame = 1;
108
109         /*
110          * Check that first field went through OK. Otherwise,
111          * indicate bad frame.
112          */ 
113         if (decoder->second_field)
114         {
115             mpeg2dec->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1;
116             xxmc->decoded = 0;
117         }
118         else
119         {
120             mpeg2dec->xvmc_last_slice_code = 0;
121         }
122
123         mb_frame_height =
124                 //(!(decoder->mpeg1) && (decoder->progressive_sequence)) ?
125                 //2*((decoder->height+31) >> 5) :
126                 (decoder->height+15) >> 4;
127         mpeg2dec->xxmc_mb_pic_height = (decoder->picture_structure == FRAME_PICTURE ) ?
128                                         mb_frame_height : mb_frame_height >> 1;
129
130         if (decoder->mpeg1)
131         {
132             vft->mv_ranges[0][0] = decoder->b_motion.f_code[0];
133             vft->mv_ranges[0][1] = decoder->b_motion.f_code[0];
134             vft->mv_ranges[1][0] = decoder->f_motion.f_code[0];
135             vft->mv_ranges[1][1] = decoder->f_motion.f_code[0];
136         }
137         else
138         {
139             vft->mv_ranges[0][0] = decoder->b_motion.f_code[0];
140             vft->mv_ranges[0][1] = decoder->b_motion.f_code[1];
141             vft->mv_ranges[1][0] = decoder->f_motion.f_code[0];
142             vft->mv_ranges[1][1] = decoder->f_motion.f_code[1];
143         }
144
145         vft->picture_structure = decoder->picture_structure;
146         vft->picture_coding_type = decoder->coding_type;
147         vft->mpeg_coding = (decoder->mpeg1) ? 0 : 1;
148         vft->progressive_sequence = decoder->progressive_sequence;
149         vft->scan = (decoder->scan == mpeg2_scan_alt);
150         vft->pred_dct_frame = decoder->frame_pred_frame_dct;
151         vft->concealment_motion_vectors =
152         decoder->concealment_motion_vectors;
153         vft->q_scale_type = decoder->q_scale_type;
154         vft->intra_vlc_format = decoder->intra_vlc_format;
155         vft->intra_dc_precision = 7 - decoder->intra_dc_precision;
156         vft->second_field = decoder->second_field;
157
158         /*
159          * Translation of libmpeg2's Q-matrix layout to VLD XvMC's.
160          * Errors here will give
161          * blocky artifacts and sometimes wrong colors.
162          */
163
164         scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan;
165         if( (vft->load_intra_quantizer_matrix = decoder->load_intra_quantizer_matrix) )
166         {
167             for (i=0; i<64; ++i)
168             {
169                 vft->intra_quantizer_matrix[scan_pattern[i]] =
170                 mpeg2dec->quantizer_matrix[0][decoder->scan[i]];
171             }
172         }
173
174         if( (vft->load_non_intra_quantizer_matrix = decoder->load_non_intra_quantizer_matrix) )
175         {
176             for (i=0; i<64; ++i)
177             {
178                 vft->non_intra_quantizer_matrix[scan_pattern[i]] =
179                                         mpeg2dec->quantizer_matrix[1][decoder->scan[i]];
180             }
181         }
182         decoder->load_intra_quantizer_matrix = 0;
183         decoder->load_non_intra_quantizer_matrix = 0;
184
185         vft->forward_reference_picture = (picture_t *)mpeg2dec->ptr_forward_ref_picture;
186         vft->backward_reference_picture = (picture_t *)mpeg2dec->ptr_backward_ref_picture;
187
188 #if 0
189     printf("\nSLICE DATA !!!! size=%d", size-4);
190     int i=0;
191     if ( vft->forward_reference_picture != NULL && ((vlc_xxmc_t *)
192          vft->forward_reference_picture->p_data)->slice_data_size > 10)
193     {
194         printf("\nFORWARD SLICE DATA !!!! size=%d\n", ((vlc_xxmc_t *)
195                vft->forward_reference_picture->p_data)->slice_data_size);
196         for (i=0;i<10;i++)
197         {
198             printf("%d ", *(((vlc_xxmc_t *) vft->forward_reference_picture->p_data)->slice_data+i));
199         }
200         printf("\nFORWARD SLICE DATA END!!!!\n");
201     }
202     if ( vft->backward_reference_picture != NULL && ((vlc_xxmc_t *)
203          vft->backward_reference_picture->p_data)->slice_data_size > 10)
204     {
205         printf("\nBACKWARD SLICE DATA !!!! size=%d\n", ((vlc_xxmc_t *)
206                vft->backward_reference_picture->p_data)->slice_data_size);
207         for (i=0;i<10;i++)
208         {
209             printf("%d ", *(((vlc_xxmc_t *) vft->backward_reference_picture->p_data)->slice_data+i));
210         }
211         printf("\nBACKWARD SLICE DATA END!!!!\n");
212     }
213 #endif
214
215         xxmc->proc_xxmc_begin( picture );
216         if (xxmc->result != 0)
217         {
218             /* "mpeg2_xxmc_slice begin failed" */
219             /* xmc->proc_xxmc_flushsync( picture ); */
220             xxmc->proc_xxmc_flush( picture );
221             mpeg2dec->xvmc_last_slice_code=-1;
222         }
223     }
224
225     if( ((code == mpeg2dec->xvmc_last_slice_code + 1 ||
226         code == mpeg2dec->xvmc_last_slice_code)) &&
227         (unsigned int)code <= mpeg2dec->xxmc_mb_pic_height )
228     {
229         /*
230          * Send this slice to the output plugin. May stall for a long
231          * time in proc_slice;
232          */
233         //mpeg2_skip(mpeg2dec, 1);
234
235         //frame->bad_frame = 1;
236         //size = mpeg2dec->chunk_ptr-mpeg2dec->chunk_start;
237         xxmc->slice_data_size = size;//mpeg2dec->buf_end - mpeg2dec->buf_start;
238         xxmc->slice_data = mpeg2dec->chunk_start;//buffer;
239         xxmc->slice_code = code;
240         xxmc->proc_xxmc_slice( picture );
241
242         if (xxmc->result != 0)
243         {
244             //xxmc->proc_xxmc_flushsync( picture );
245             xxmc->proc_xxmc_flush( picture );   
246             mpeg2dec->xvmc_last_slice_code=-1;
247             return;
248         }
249         if ( (unsigned int)code == mpeg2dec->xxmc_mb_pic_height)
250         {
251             /*
252              * We've encountered the last slice of this frame.
253              * Release the decoder for a new frame and, if all
254              * went well, tell libmpeg2 that we are ready.
255              */
256
257             mpeg2_xxmc_vld_frame_complete(mpeg2dec,picture,code);
258             return;
259         }
260         else if (code == mpeg2dec->xvmc_last_slice_code + 1)
261         {
262             //xxmc->proc_xxmc_flush( picture );
263
264             /*
265              * Keep track of slices.
266              */
267             mpeg2dec->xvmc_last_slice_code++;
268         }
269     }
270     else
271     {
272         /*
273          * An error has occurred.
274          */
275
276         //printf("VLD XvMC: Slice error: code=%d\tlast slice code=%d\tmb_pic_height=%d\n", code, mpeg2dec->xvmc_last_slice_code,mpeg2dec->xxmc_mb_pic_height);
277         mpeg2dec->xvmc_last_slice_code = -1;
278         xxmc->proc_xxmc_flush( picture );
279         return;
280     }
281 }
282
283 void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code) 
284 {
285     vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_data;
286     vlc_vld_frame_t *vft = &xxmc->vld_frame;
287
288     if (xxmc->decoded)
289         return;
290
291     if (mpeg2dec->xvmc_last_slice_code >= 1)
292     {
293         xxmc->proc_xxmc_flush( picture );
294         if (xxmc->result)
295         {
296             mpeg2dec->xvmc_last_slice_code=-1;
297             return;
298         }
299         xxmc->decoded = 1;
300         mpeg2dec->xvmc_last_slice_code++;
301         if (vft->picture_structure == 3 || vft->second_field)
302         {
303             if (xxmc->result == 0)
304                 mpeg2_skip(mpeg2dec, 0);
305             //frame->bad_frame = 0;
306         }
307     }
308 }
309