Mercurial > libavcodec.hg
annotate vaapi_mpeg2.c @ 9896:bbefbca72722 libavcodec
Drop code that attempts to decode frames that are prefixed by junk.
Too often it ends up decoding random data into noise without detecting
it (for example after seeking of some MP3 data with oddly often occurring
startcode emulation).
Fixes issue1154.
| author | michael |
|---|---|
| date | Tue, 30 Jun 2009 03:57:27 +0000 |
| parents | f0732d44f655 |
| children | 140aa1e7328b |
| rev | line source |
|---|---|
| 9253 | 1 /* |
| 2 * MPEG-2 HW decode acceleration through VA API | |
| 3 * | |
| 4 * Copyright (C) 2008-2009 Splitted-Desktop Systems | |
| 5 * | |
| 6 * This file is part of FFmpeg. | |
| 7 * | |
| 8 * FFmpeg is free software; you can redistribute it and/or | |
| 9 * modify it under the terms of the GNU Lesser General Public | |
| 10 * License as published by the Free Software Foundation; either | |
| 11 * version 2.1 of the License, or (at your option) any later version. | |
| 12 * | |
| 13 * FFmpeg is distributed in the hope that it will be useful, | |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 * Lesser General Public License for more details. | |
| 17 * | |
| 18 * You should have received a copy of the GNU Lesser General Public | |
| 19 * License along with FFmpeg; if not, write to the Free Software | |
| 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 21 */ | |
| 22 | |
| 23 #include "vaapi_internal.h" | |
| 24 #include "dsputil.h" | |
| 25 | |
| 26 /** Reconstruct bitstream f_code */ | |
| 27 static inline int mpeg2_get_f_code(MpegEncContext *s) | |
| 28 { | |
| 29 return ((s->mpeg_f_code[0][0] << 12) | (s->mpeg_f_code[0][1] << 8) | | |
| 30 (s->mpeg_f_code[1][0] << 4) | s->mpeg_f_code[1][1]); | |
| 31 } | |
| 32 | |
| 33 /** Determine frame start: first field for field picture or frame picture */ | |
| 34 static inline int mpeg2_get_is_frame_start(MpegEncContext *s) | |
| 35 { | |
| 36 return s->first_field || s->picture_structure == PICT_FRAME; | |
| 37 } | |
| 38 | |
| 39 static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) | |
| 40 { | |
| 41 struct MpegEncContext * const s = avctx->priv_data; | |
| 42 struct vaapi_context * const vactx = avctx->hwaccel_context; | |
| 43 VAPictureParameterBufferMPEG2 *pic_param; | |
| 44 VAIQMatrixBufferMPEG2 *iq_matrix; | |
| 45 int i; | |
| 46 | |
| 47 dprintf(avctx, "vaapi_mpeg2_start_frame()\n"); | |
| 48 | |
| 49 vactx->slice_param_size = sizeof(VASliceParameterBufferMPEG2); | |
| 50 | |
| 51 /* Fill in VAPictureParameterBufferMPEG2 */ | |
|
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
52 pic_param = ff_vaapi_alloc_picture(vactx, sizeof(VAPictureParameterBufferMPEG2)); |
|
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
53 if (!pic_param) |
|
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
54 return -1; |
| 9253 | 55 pic_param->horizontal_size = s->width; |
| 56 pic_param->vertical_size = s->height; | |
| 57 pic_param->forward_reference_picture = 0xffffffff; | |
| 58 pic_param->backward_reference_picture = 0xffffffff; | |
| 59 pic_param->picture_coding_type = s->pict_type; | |
| 60 pic_param->f_code = mpeg2_get_f_code(s); | |
| 61 pic_param->picture_coding_extension.value = 0; /* reset all bits */ | |
| 62 pic_param->picture_coding_extension.bits.intra_dc_precision = s->intra_dc_precision; | |
| 63 pic_param->picture_coding_extension.bits.picture_structure = s->picture_structure; | |
| 64 pic_param->picture_coding_extension.bits.top_field_first = s->top_field_first; | |
| 65 pic_param->picture_coding_extension.bits.frame_pred_frame_dct = s->frame_pred_frame_dct; | |
| 66 pic_param->picture_coding_extension.bits.concealment_motion_vectors = s->concealment_motion_vectors; | |
| 67 pic_param->picture_coding_extension.bits.q_scale_type = s->q_scale_type; | |
| 68 pic_param->picture_coding_extension.bits.intra_vlc_format = s->intra_vlc_format; | |
| 69 pic_param->picture_coding_extension.bits.alternate_scan = s->alternate_scan; | |
| 70 pic_param->picture_coding_extension.bits.repeat_first_field = s->repeat_first_field; | |
| 71 pic_param->picture_coding_extension.bits.progressive_frame = s->progressive_frame; | |
| 72 pic_param->picture_coding_extension.bits.is_first_field = mpeg2_get_is_frame_start(s); | |
| 73 | |
| 74 switch (s->pict_type) { | |
| 75 case FF_B_TYPE: | |
| 76 pic_param->backward_reference_picture = ff_vaapi_get_surface(&s->next_picture); | |
| 77 // fall-through | |
| 78 case FF_P_TYPE: | |
| 79 pic_param->forward_reference_picture = ff_vaapi_get_surface(&s->last_picture); | |
| 80 break; | |
| 81 } | |
| 82 | |
| 83 /* Fill in VAIQMatrixBufferMPEG2 */ | |
|
9292
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
84 iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferMPEG2)); |
|
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
85 if (!iq_matrix) |
|
f0732d44f655
Improve VA API buffers allocation logic. This also reduces struct vaapi_context
gb
parents:
9253
diff
changeset
|
86 return -1; |
| 9253 | 87 iq_matrix->load_intra_quantiser_matrix = 1; |
| 88 iq_matrix->load_non_intra_quantiser_matrix = 1; | |
| 89 iq_matrix->load_chroma_intra_quantiser_matrix = 1; | |
| 90 iq_matrix->load_chroma_non_intra_quantiser_matrix = 1; | |
| 91 | |
| 92 for (i = 0; i < 64; i++) { | |
| 93 int n = s->dsp.idct_permutation[ff_zigzag_direct[i]]; | |
| 94 iq_matrix->intra_quantiser_matrix[i] = s->intra_matrix[n]; | |
| 95 iq_matrix->non_intra_quantiser_matrix[i] = s->inter_matrix[n]; | |
| 96 iq_matrix->chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[n]; | |
| 97 iq_matrix->chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[n]; | |
| 98 } | |
| 99 return 0; | |
| 100 } | |
| 101 | |
| 102 static int vaapi_mpeg2_end_frame(AVCodecContext *avctx) | |
| 103 { | |
| 104 return ff_vaapi_common_end_frame(avctx->priv_data); | |
| 105 } | |
| 106 | |
| 107 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) | |
| 108 { | |
| 109 MpegEncContext * const s = avctx->priv_data; | |
| 110 VASliceParameterBufferMPEG2 *slice_param; | |
| 111 GetBitContext gb; | |
| 112 uint32_t start_code, quantiser_scale_code, intra_slice_flag, macroblock_offset; | |
| 113 | |
| 114 dprintf(avctx, "vaapi_mpeg2_decode_slice(): buffer %p, size %d\n", buffer, size); | |
| 115 | |
| 116 /* Determine macroblock_offset */ | |
| 117 init_get_bits(&gb, buffer, 8 * size); | |
| 118 start_code = get_bits(&gb, 32); | |
| 119 assert((start_code & 0xffffff00) == 0x00000100); | |
| 120 quantiser_scale_code = get_bits(&gb, 5); | |
| 121 intra_slice_flag = get_bits1(&gb); | |
| 122 if (intra_slice_flag) { | |
| 123 skip_bits(&gb, 8); | |
| 124 while (get_bits1(&gb) != 0) | |
| 125 skip_bits(&gb, 8); | |
| 126 } | |
| 127 macroblock_offset = get_bits_count(&gb); | |
| 128 | |
| 129 /* Fill in VASliceParameterBufferMPEG2 */ | |
| 130 slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); | |
| 131 if (!slice_param) | |
| 132 return -1; | |
| 133 slice_param->macroblock_offset = macroblock_offset; | |
| 134 slice_param->slice_vertical_position = s->mb_y; | |
| 135 slice_param->quantiser_scale_code = quantiser_scale_code; | |
| 136 slice_param->intra_slice_flag = intra_slice_flag; | |
| 137 return 0; | |
| 138 } | |
| 139 | |
| 140 AVHWAccel mpeg2_vaapi_hwaccel = { | |
| 141 .name = "mpeg2_vaapi", | |
| 142 .type = CODEC_TYPE_VIDEO, | |
| 143 .id = CODEC_ID_MPEG2VIDEO, | |
| 144 .pix_fmt = PIX_FMT_VAAPI_VLD, | |
| 145 .capabilities = 0, | |
| 146 .start_frame = vaapi_mpeg2_start_frame, | |
| 147 .end_frame = vaapi_mpeg2_end_frame, | |
| 148 .decode_slice = vaapi_mpeg2_decode_slice, | |
| 149 .priv_data_size = 0, | |
| 150 }; |
