blob: ee8b2a5e7b58ef11f4412f5993e33ee2081e3463
1 | /* |
2 | * This file is part of FFmpeg. |
3 | * |
4 | * FFmpeg is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2.1 of the License, or (at your option) any later version. |
8 | * |
9 | * FFmpeg is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with FFmpeg; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include "error_resilience.h" |
20 | #include "mpegvideo.h" |
21 | #include "mpeg_er.h" |
22 | |
23 | static void set_erpic(ERPicture *dst, Picture *src) |
24 | { |
25 | int i; |
26 | |
27 | memset(dst, 0, sizeof(*dst)); |
28 | if (!src) { |
29 | dst->f = NULL; |
30 | dst->tf = NULL; |
31 | return; |
32 | } |
33 | |
34 | dst->f = src->f; |
35 | dst->tf = &src->tf; |
36 | |
37 | for (i = 0; i < 2; i++) { |
38 | dst->motion_val[i] = src->motion_val[i]; |
39 | dst->ref_index[i] = src->ref_index[i]; |
40 | } |
41 | |
42 | dst->mb_type = src->mb_type; |
43 | dst->field_picture = src->field_picture; |
44 | } |
45 | |
46 | void ff_mpeg_er_frame_start(MpegEncContext *s) |
47 | { |
48 | ERContext *er = &s->er; |
49 | |
50 | set_erpic(&er->cur_pic, s->current_picture_ptr); |
51 | set_erpic(&er->next_pic, s->next_picture_ptr); |
52 | set_erpic(&er->last_pic, s->last_picture_ptr); |
53 | |
54 | er->pp_time = s->pp_time; |
55 | er->pb_time = s->pb_time; |
56 | er->quarter_sample = s->quarter_sample; |
57 | er->partitioned_frame = s->partitioned_frame; |
58 | |
59 | ff_er_frame_start(er); |
60 | } |
61 | |
62 | static void mpeg_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type, |
63 | int (*mv)[2][4][2], int mb_x, int mb_y, |
64 | int mb_intra, int mb_skipped) |
65 | { |
66 | MpegEncContext *s = opaque; |
67 | |
68 | s->mv_dir = mv_dir; |
69 | s->mv_type = mv_type; |
70 | s->mb_intra = mb_intra; |
71 | s->mb_skipped = mb_skipped; |
72 | s->mb_x = mb_x; |
73 | s->mb_y = mb_y; |
74 | memcpy(s->mv, mv, sizeof(*mv)); |
75 | |
76 | ff_init_block_index(s); |
77 | ff_update_block_index(s); |
78 | |
79 | s->bdsp.clear_blocks(s->block[0]); |
80 | |
81 | s->dest[0] = s->current_picture.f->data[0] + |
82 | s->mb_y * 16 * s->linesize + |
83 | s->mb_x * 16; |
84 | s->dest[1] = s->current_picture.f->data[1] + |
85 | s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize + |
86 | s->mb_x * (16 >> s->chroma_x_shift); |
87 | s->dest[2] = s->current_picture.f->data[2] + |
88 | s->mb_y * (16 >> s->chroma_y_shift) * s->uvlinesize + |
89 | s->mb_x * (16 >> s->chroma_x_shift); |
90 | |
91 | if (ref) |
92 | av_log(s->avctx, AV_LOG_DEBUG, |
93 | "Interlaced error concealment is not fully implemented\n"); |
94 | ff_mpv_decode_mb(s, s->block); |
95 | } |
96 | |
97 | int ff_mpeg_er_init(MpegEncContext *s) |
98 | { |
99 | ERContext *er = &s->er; |
100 | int mb_array_size = s->mb_height * s->mb_stride; |
101 | int i; |
102 | |
103 | er->avctx = s->avctx; |
104 | |
105 | er->mb_index2xy = s->mb_index2xy; |
106 | er->mb_num = s->mb_num; |
107 | er->mb_width = s->mb_width; |
108 | er->mb_height = s->mb_height; |
109 | er->mb_stride = s->mb_stride; |
110 | er->b8_stride = s->b8_stride; |
111 | |
112 | er->er_temp_buffer = av_malloc(s->mb_height * s->mb_stride * (4*sizeof(int) + 1)); |
113 | er->error_status_table = av_mallocz(mb_array_size); |
114 | if (!er->er_temp_buffer || !er->error_status_table) |
115 | goto fail; |
116 | |
117 | er->mbskip_table = s->mbskip_table; |
118 | er->mbintra_table = s->mbintra_table; |
119 | |
120 | for (i = 0; i < FF_ARRAY_ELEMS(s->dc_val); i++) |
121 | er->dc_val[i] = s->dc_val[i]; |
122 | |
123 | er->decode_mb = mpeg_er_decode_mb; |
124 | er->opaque = s; |
125 | |
126 | return 0; |
127 | fail: |
128 | av_freep(&er->er_temp_buffer); |
129 | av_freep(&er->error_status_table); |
130 | return AVERROR(ENOMEM); |
131 | } |
132 |