2 * Copyright (c) 2004 The Unichrome project. All rights reserved.
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.
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.
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.
22 #include <vlc_codec.h>
25 #include "mpeg2_internal.h"
28 static uint8_t zig_zag_scan[64] ATTR_ALIGN(16) =
30 /* Zig-Zag scan pattern */
31 0, 1, 8,16, 9, 2, 3,10,
32 17,24,32,25,18,11, 4, 5,
33 12,19,26,33,40,48,41,34,
34 27,20,13, 6, 7,14,21,28,
35 35,42,49,56,57,50,43,36,
36 29,22,15,23,30,37,44,51,
37 58,59,52,45,38,31,39,46,
38 53,60,61,54,47,55,62,63
41 static uint8_t alternate_scan [64] ATTR_ALIGN(16) =
43 /* Alternate scan pattern */
44 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
45 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
46 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
47 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
53 void mpeg2_xxmc_choose_coding(decoder_t *p_dec, mpeg2_decoder_t * const decoder, picture_t *picture,
54 double aspect_ratio, int flags)
58 //vlc_fourcc_t decoder_format = picture->format.i_chroma;
59 //if (decoder_format == VLC_FOURCC('X','x','M','C')) {
60 vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_accel_data;
63 * Make a request for acceleration type and mpeg coding from
67 xxmc->fallback_format = VLC_FOURCC('Y','V','1','2');
68 xxmc->acceleration = VLC_XVMC_ACCEL_VLD;//| VLC_XVMC_ACCEL_IDCT| VLC_XVMC_ACCEL_MOCOMP ;
70 //msg_Dbg(p_dec, "mpeg2_xxmc_choose_coding 2");
72 * Standard MOCOMP / IDCT XvMC implementation for interlaced streams
73 * is buggy. The bug is inherited from the old XvMC driver. Don't use it until
74 * it has been fixed. (A volunteer ?)
77 //if ( decoder->picture_structure != 3 ) {
78 //xxmc->acceleration &= ~( VLC_XVMC_ACCEL_IDCT | VLC_XVMC_ACCEL_MOCOMP );
81 xxmc->mpeg = (decoder->mpeg1) ? VLC_XVMC_MPEG_1:VLC_XVMC_MPEG_2;
82 xxmc->proc_xxmc_update_frame( picture,
86 VLC_IMGFMT_XXMC, flags );
91 void mpeg2_xxmc_slice( mpeg2dec_t *mpeg2dec, picture_t *picture, int code,
92 uint8_t *buffer, int size)
94 mpeg2_decoder_t * const decoder = &(mpeg2dec->decoder);
95 picture = (picture_t *)mpeg2dec->fbuf[0]->id;
96 vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_accel_data;
97 vlc_vld_frame_t *vft = &xxmc->vld_frame;
98 unsigned mb_frame_height;
100 const uint8_t *scan_pattern;
104 //mpeg2_skip(mpeg2dec, 1);
105 //frame->bad_frame = 1;
108 * Check that first field went through OK. Otherwise,
109 * indicate bad frame.
111 if (decoder->second_field)
113 mpeg2dec->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1;
118 mpeg2dec->xvmc_last_slice_code = 0;
122 //(!(decoder->mpeg1) && (decoder->progressive_sequence)) ?
123 //2*((decoder->height+31) >> 5) :
124 (decoder->height+15) >> 4;
125 mpeg2dec->xxmc_mb_pic_height = (decoder->picture_structure == FRAME_PICTURE ) ?
126 mb_frame_height : mb_frame_height >> 1;
130 vft->mv_ranges[0][0] = decoder->b_motion.f_code[0];
131 vft->mv_ranges[0][1] = decoder->b_motion.f_code[0];
132 vft->mv_ranges[1][0] = decoder->f_motion.f_code[0];
133 vft->mv_ranges[1][1] = decoder->f_motion.f_code[0];
137 vft->mv_ranges[0][0] = decoder->b_motion.f_code[0];
138 vft->mv_ranges[0][1] = decoder->b_motion.f_code[1];
139 vft->mv_ranges[1][0] = decoder->f_motion.f_code[0];
140 vft->mv_ranges[1][1] = decoder->f_motion.f_code[1];
143 vft->picture_structure = decoder->picture_structure;
144 vft->picture_coding_type = decoder->coding_type;
145 vft->mpeg_coding = (decoder->mpeg1) ? 0 : 1;
146 vft->progressive_sequence = decoder->progressive_sequence;
147 vft->scan = (decoder->scan == mpeg2_scan_alt);
148 vft->pred_dct_frame = decoder->frame_pred_frame_dct;
149 vft->concealment_motion_vectors =
150 decoder->concealment_motion_vectors;
151 vft->q_scale_type = decoder->q_scale_type;
152 vft->intra_vlc_format = decoder->intra_vlc_format;
153 vft->intra_dc_precision = 7 - decoder->intra_dc_precision;
154 vft->second_field = decoder->second_field;
157 * Translation of libmpeg2's Q-matrix layout to VLD XvMC's.
158 * Errors here will give
159 * blocky artifacts and sometimes wrong colors.
162 scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan;
163 if( (vft->load_intra_quantizer_matrix = decoder->load_intra_quantizer_matrix) )
167 vft->intra_quantizer_matrix[scan_pattern[i]] =
168 mpeg2dec->quantizer_matrix[0][decoder->scan[i]];
172 if( (vft->load_non_intra_quantizer_matrix = decoder->load_non_intra_quantizer_matrix) )
176 vft->non_intra_quantizer_matrix[scan_pattern[i]] =
177 mpeg2dec->quantizer_matrix[1][decoder->scan[i]];
180 decoder->load_intra_quantizer_matrix = 0;
181 decoder->load_non_intra_quantizer_matrix = 0;
183 vft->forward_reference_picture = (picture_t *)mpeg2dec->ptr_forward_ref_picture;
184 vft->backward_reference_picture = (picture_t *)mpeg2dec->ptr_backward_ref_picture;
187 printf("\nSLICE DATA !!!! size=%d", size-4);
189 if ( vft->forward_reference_picture != NULL && ((vlc_xxmc_t *)
190 vft->forward_reference_picture->p_accel_data)->slice_data_size > 10)
192 printf("\nFORWARD SLICE DATA !!!! size=%d\n", ((vlc_xxmc_t *)
193 vft->forward_reference_picture->p_accel_data)->slice_data_size);
196 printf("%d ", *(((vlc_xxmc_t *) vft->forward_reference_picture->p_accel_data)->slice_data+i));
198 printf("\nFORWARD SLICE DATA END!!!!\n");
200 if ( vft->backward_reference_picture != NULL && ((vlc_xxmc_t *)
201 vft->backward_reference_picture->p_accel_data)->slice_data_size > 10)
203 printf("\nBACKWARD SLICE DATA !!!! size=%d\n", ((vlc_xxmc_t *)
204 vft->backward_reference_picture->p_accel_data)->slice_data_size);
207 printf("%d ", *(((vlc_xxmc_t *) vft->backward_reference_picture->p_accel_data)->slice_data+i));
209 printf("\nBACKWARD SLICE DATA END!!!!\n");
213 xxmc->proc_xxmc_begin( picture );
214 if (xxmc->result != 0)
216 /* "mpeg2_xxmc_slice begin failed" */
217 /* xmc->proc_xxmc_flushsync( picture ); */
218 xxmc->proc_xxmc_flush( picture );
219 mpeg2dec->xvmc_last_slice_code=-1;
223 if( ((code == mpeg2dec->xvmc_last_slice_code + 1 ||
224 code == mpeg2dec->xvmc_last_slice_code)) &&
225 code <= mpeg2dec->xxmc_mb_pic_height )
228 * Send this slice to the output plugin. May stall for a long
229 * time in proc_slice;
231 //mpeg2_skip(mpeg2dec, 1);
233 //frame->bad_frame = 1;
234 //size = mpeg2dec->chunk_ptr-mpeg2dec->chunk_start;
235 xxmc->slice_data_size = size;//mpeg2dec->buf_end - mpeg2dec->buf_start;
236 xxmc->slice_data = mpeg2dec->chunk_start;//buffer;
237 xxmc->slice_code = code;
238 xxmc->proc_xxmc_slice( picture );
240 if (xxmc->result != 0)
242 //xxmc->proc_xxmc_flushsync( picture );
243 xxmc->proc_xxmc_flush( picture );
244 mpeg2dec->xvmc_last_slice_code=-1;
247 if (code == mpeg2dec->xxmc_mb_pic_height)
250 * We've encountered the last slice of this frame.
251 * Release the decoder for a new frame and, if all
252 * went well, tell libmpeg2 that we are ready.
255 mpeg2_xxmc_vld_frame_complete(mpeg2dec,picture,code);
258 else if (code == mpeg2dec->xvmc_last_slice_code + 1)
260 //xxmc->proc_xxmc_flush( picture );
263 * Keep track of slices.
265 mpeg2dec->xvmc_last_slice_code++;
271 * An error has occured.
274 //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);
275 mpeg2dec->xvmc_last_slice_code = -1;
276 xxmc->proc_xxmc_flush( picture );
281 void mpeg2_xxmc_vld_frame_complete(mpeg2dec_t *mpeg2dec, picture_t *picture, int code)
283 vlc_xxmc_t *xxmc = (vlc_xxmc_t *) picture->p_accel_data;
284 vlc_vld_frame_t *vft = &xxmc->vld_frame;
289 if (mpeg2dec->xvmc_last_slice_code >= 1)
291 xxmc->proc_xxmc_flush( picture );
294 mpeg2dec->xvmc_last_slice_code=-1;
298 mpeg2dec->xvmc_last_slice_code++;
299 if (vft->picture_structure == 3 || vft->second_field)
301 if (xxmc->result == 0)
302 mpeg2_skip(mpeg2dec, 0);
303 //frame->bad_frame = 0;