| rev |
line source |
|
nengel@2
|
1 /*
|
|
nengel@2
|
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
|
nengel@2
|
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
|
nengel@2
|
4 *
|
|
nengel@2
|
5 * This file is part of FFmpeg.
|
|
nengel@2
|
6 *
|
|
nengel@2
|
7 * FFmpeg is free software; you can redistribute it and/or
|
|
nengel@2
|
8 * modify it under the terms of the GNU Lesser General Public
|
|
nengel@2
|
9 * License as published by the Free Software Foundation; either
|
|
nengel@2
|
10 * version 2.1 of the License, or (at your option) any later version.
|
|
nengel@2
|
11 *
|
|
nengel@2
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
|
nengel@2
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
nengel@2
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
nengel@2
|
15 * Lesser General Public License for more details.
|
|
nengel@2
|
16 *
|
|
nengel@2
|
17 * You should have received a copy of the GNU Lesser General Public
|
|
nengel@2
|
18 * License along with FFmpeg; if not, write to the Free Software
|
|
nengel@2
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
nengel@2
|
20 */
|
|
nengel@2
|
21 #include "h264_types.h"
|
|
nengel@2
|
22 #include "h264_parser.h"
|
|
nengel@2
|
23 #include "h264_nal.h"
|
|
nengel@2
|
24 #include "h264_entropy.h"
|
|
nengel@2
|
25 #include "h264_rec.h"
|
|
nengel@2
|
26 #include "h264_pred_mode.h"
|
|
nengel@2
|
27 #include "h264_misc.h"
|
|
nengel@2
|
28 // #undef NDEBUG
|
|
nengel@2
|
29 #include <assert.h>
|
|
nengel@2
|
30
|
|
nengel@2
|
31 #pragma omp task inout(*pc, *nc) output(*sbe)
|
|
nengel@2
|
32 static void parse_task(H264Context *h, ParserContext *pc, NalContext *nc, SliceBufferEntry *sbe){
|
|
nengel@2
|
33 H264Slice *s;
|
|
nengel@2
|
34
|
|
nengel@2
|
35 if (!sbe->initialized){
|
|
nengel@2
|
36 init_sb_entry(h, sbe);
|
|
nengel@2
|
37 sbe->lines_total=h->mb_height;
|
|
nengel@2
|
38 }
|
|
nengel@2
|
39
|
|
nengel@2
|
40 av_read_frame_internal(pc, &sbe->gb);
|
|
nengel@2
|
41 s = &sbe->slice;
|
|
nengel@2
|
42
|
|
nengel@2
|
43 decode_nal_units(nc, s, &sbe->gb);
|
|
nengel@2
|
44 }
|
|
nengel@2
|
45
|
|
nengel@2
|
46 #pragma omp task inout(*ec) inout(*sbe)
|
|
nengel@2
|
47 static void decode_slice_entropy_task(H264Context *h, EntropyContext *ec, SliceBufferEntry *sbe){
|
|
nengel@2
|
48 int i,j;
|
|
nengel@2
|
49 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
50 GetBitContext *gb = &sbe->gb;
|
|
nengel@2
|
51 H264Mb *mbs = sbe->mbs;
|
|
nengel@2
|
52 // GetBitContext *gb = s->gb;
|
|
nengel@2
|
53 CABACContext *c = &ec->c;
|
|
nengel@2
|
54
|
|
nengel@2
|
55 if( !s->pps.cabac ){
|
|
nengel@2
|
56 av_log(AV_LOG_ERROR, "Only cabac encoded streams are supported\n");
|
|
nengel@2
|
57 return ;
|
|
nengel@2
|
58 }
|
|
nengel@2
|
59
|
|
nengel@2
|
60 init_dequant_tables(s, ec);
|
|
nengel@2
|
61 ec->curr_qscale = s->qscale;
|
|
nengel@2
|
62 ec->last_qscale_diff = 0;
|
|
nengel@2
|
63 ec->chroma_qp[0] = get_chroma_qp((H264Slice *) s, 0, s->qscale);
|
|
nengel@2
|
64 ec->chroma_qp[1] = get_chroma_qp((H264Slice *) s, 1, s->qscale);
|
|
nengel@2
|
65
|
|
nengel@2
|
66 /* realign */
|
|
nengel@2
|
67 align_get_bits( gb );
|
|
nengel@2
|
68 /* init cabac */
|
|
nengel@2
|
69 ff_init_cabac_decoder( c, gb->buffer + get_bits_count(gb)/8, (get_bits_left(gb) + 7)/8);
|
|
nengel@2
|
70
|
|
nengel@2
|
71 ff_h264_init_cabac_states(ec, s, c);
|
|
nengel@2
|
72
|
|
nengel@2
|
73 for(j=0; j<ec->mb_height; j++){
|
|
nengel@2
|
74 init_entropy_buf(ec, s, j);
|
|
nengel@2
|
75 for(i=0; i<ec->mb_width; i++){
|
|
nengel@2
|
76 int eos,ret;
|
|
nengel@2
|
77 H264Mb *m = &mbs[i + j*ec->mb_width];
|
|
nengel@2
|
78 m->mb_x=i;
|
|
nengel@2
|
79 m->mb_y=j;
|
|
nengel@2
|
80 ec->m = m;
|
|
nengel@2
|
81
|
|
nengel@2
|
82 ret = ff_h264_decode_mb_cabac(ec, s, c);
|
|
nengel@2
|
83 eos = get_cabac_terminate( c);
|
|
nengel@2
|
84 (void) eos;
|
|
nengel@2
|
85 if( ret < 0 || c->bytestream > c->bytestream_end + 2) {
|
|
nengel@2
|
86 av_log(AV_LOG_ERROR, "error while decoding MB %d %d, bytestream (%td)\n", m->mb_x, m->mb_y, c->bytestream_end - c->bytestream);
|
|
nengel@2
|
87 return ;
|
|
nengel@2
|
88 }
|
|
nengel@2
|
89 }
|
|
nengel@2
|
90 }
|
|
nengel@2
|
91 }
|
|
nengel@2
|
92
|
|
nengel@2
|
93 static void decode_super_mb_block(MBRecContext *d, H264Slice *s, SuperMBContext *smbc, H264Mb *mbs, int smb_x, int smb_y){
|
|
nengel@2
|
94 MBRecState mrs;
|
|
nengel@2
|
95 // memset(&mrs, 0, sizeof(MBRecState));
|
|
nengel@2
|
96
|
|
nengel@2
|
97 for (int k=0, i= smb_y; i< smb_y + smbc->smb_height; i++, k++){
|
|
nengel@2
|
98 init_mbrec_context(d, &mrs, s, i);
|
|
nengel@2
|
99 for (int j= smb_x -k ; j< smb_x - k + smbc->smb_width; j++){
|
|
nengel@2
|
100 if (i< d->mb_height && j >= 0 && j < d->mb_width){
|
|
nengel@2
|
101 h264_decode_mb_internal (d, &mrs, s, &mbs[i*d->mb_width+j]);
|
|
nengel@2
|
102 }
|
|
nengel@2
|
103 }
|
|
nengel@2
|
104 }
|
|
nengel@2
|
105 }
|
|
nengel@2
|
106
|
|
nengel@2
|
107 #pragma omp task input(*d, *sbe, *ml, *mur) inout(*m)
|
|
nengel@2
|
108 static void decode_super_mb_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *ml,
|
|
nengel@2
|
109 SuperMBTask *mur, SuperMBTask *m){
|
|
nengel@2
|
110 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
111 H264Mb *mbs = sbe->mbs;
|
|
nengel@2
|
112 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
|
|
nengel@2
|
113 }
|
|
nengel@2
|
114
|
|
nengel@2
|
115 #pragma omp task input(*d, *sbe) inout(*sm)
|
|
nengel@2
|
116 static void draw_edges_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *sm, int line){
|
|
nengel@2
|
117 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
118 for (int i=line*smbc->smb_height; i< (line+1)*smbc->smb_height && i< d->mb_height; i++)
|
|
nengel@2
|
119 draw_edges(d, s, i);
|
|
nengel@2
|
120 }
|
|
nengel@2
|
121
|
|
nengel@2
|
122 static void decode_mb_in_slice(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){
|
|
nengel@2
|
123 int i,j;
|
|
nengel@2
|
124
|
|
nengel@2
|
125 SuperMBContext *smbc = acquire_smbc(h);
|
|
nengel@2
|
126 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
|
|
nengel@2
|
127 SuperMBTask *smbs = smbc->smbs[0];
|
|
nengel@2
|
128
|
|
nengel@2
|
129 SuperMBTask *sm=NULL, *sml, *smur;
|
|
nengel@2
|
130 for(j=0; j< smb_height; j++){
|
|
nengel@2
|
131 for(i=0; i< smb_width; i++){
|
|
nengel@2
|
132 sm = smbs + j*smb_width + i;
|
|
nengel@2
|
133 sml = sm - ((i > 0) ? 1: 0);
|
|
nengel@2
|
134 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
|
|
nengel@2
|
135 decode_super_mb_task(d, sbe, smbc, sml, smur, sm);
|
|
nengel@2
|
136 }
|
|
nengel@2
|
137 draw_edges_task(d, sbe, smbc, sm, j);
|
|
nengel@2
|
138 }
|
|
nengel@2
|
139 #pragma omp taskwait on(*sm)
|
|
nengel@2
|
140
|
|
nengel@2
|
141 release_smbc(h, smbc);
|
|
nengel@2
|
142 }
|
|
nengel@2
|
143
|
|
nengel@2
|
144 #pragma omp task inout(*d) inout(*sbe)
|
|
nengel@2
|
145 static void decode_slice_mb_task(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe){
|
|
nengel@2
|
146 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
147
|
|
nengel@2
|
148 for (int i=0; i<2; i++){
|
|
nengel@2
|
149 for(int j=0; j< s->ref_count[i]; j++){
|
|
nengel@2
|
150 if (s->ref_list_cpn[i][j] ==-1)
|
|
nengel@2
|
151 continue;
|
|
nengel@2
|
152 int k;
|
|
nengel@2
|
153 for (k=0; k< h->max_dpb_cnt; k++){
|
|
nengel@2
|
154 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
|
|
nengel@2
|
155 s->dp_ref_list[i][j] = &h->dpb[k];
|
|
nengel@2
|
156 break;
|
|
nengel@2
|
157 }
|
|
nengel@2
|
158 }
|
|
nengel@2
|
159 }
|
|
nengel@2
|
160 }
|
|
nengel@2
|
161
|
|
nengel@2
|
162 #pragma omp critical (dpb)
|
|
nengel@2
|
163 get_dpb_entry(h, s);
|
|
nengel@2
|
164
|
|
nengel@2
|
165 if (!h->no_mbd){
|
|
nengel@2
|
166 decode_mb_in_slice (h, d, sbe);
|
|
nengel@2
|
167 }
|
|
nengel@2
|
168
|
|
nengel@2
|
169 for (int i=0; i<s->release_cnt; i++){
|
|
nengel@2
|
170 for(int j=0; j<h->max_dpb_cnt; j++){
|
|
nengel@2
|
171 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
|
|
nengel@2
|
172 #pragma omp critical (dpb)
|
|
nengel@2
|
173 release_dpb_entry(h, &h->dpb[j], 2);
|
|
nengel@2
|
174 break;
|
|
nengel@2
|
175 }
|
|
nengel@2
|
176 }
|
|
nengel@2
|
177 }
|
|
nengel@2
|
178 s->release_cnt=0;
|
|
nengel@2
|
179 }
|
|
nengel@2
|
180
|
|
nengel@2
|
181 // for static 3d wave
|
|
nengel@2
|
182 /*-------------------------------------------------------------------------------*/
|
|
nengel@2
|
183 #pragma omp task input(*d, *sbe, *ml, *mur, *mprev) inout(*m)
|
|
nengel@2
|
184 static void decode_3dwave_super_mb_task(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc, SuperMBTask *ml,
|
|
nengel@2
|
185 SuperMBTask *mur, SuperMBTask *mprev, SuperMBTask *m){
|
|
nengel@2
|
186 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
187 H264Mb *mbs = sbe->mbs;
|
|
nengel@2
|
188
|
|
nengel@2
|
189 decode_super_mb_block(d, s, smbc, mbs, m->smb_x, m->smb_y);
|
|
nengel@2
|
190 }
|
|
nengel@2
|
191
|
|
nengel@2
|
192 // int init_ref_count=0;
|
|
nengel@2
|
193 #pragma omp task inout(*d, *sbe, *init)
|
|
nengel@2
|
194 static void init_ref_list_and_get_dpb_task(H264Context *h, MBRecContext *d, SliceBufferEntry *sbe, int *init){
|
|
nengel@2
|
195 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
196 for (int i=0; i<2; i++){
|
|
nengel@2
|
197 for(int j=0; j< s->ref_count[i]; j++){
|
|
nengel@2
|
198 if (s->ref_list_cpn[i][j] ==-1)
|
|
nengel@2
|
199 continue;
|
|
nengel@2
|
200 int k;
|
|
nengel@2
|
201 for (k=0; k<h->max_dpb_cnt; k++){
|
|
nengel@2
|
202 if(h->dpb[k].reference >= 2 && h->dpb[k].cpn == s->ref_list_cpn[i][j]){
|
|
nengel@2
|
203 s->dp_ref_list[i][j] = &h->dpb[k];
|
|
nengel@2
|
204 break;
|
|
nengel@2
|
205 }
|
|
nengel@2
|
206 }
|
|
nengel@2
|
207 }
|
|
nengel@2
|
208 }
|
|
nengel@2
|
209
|
|
nengel@2
|
210 #pragma omp critical (dpb)
|
|
nengel@2
|
211 get_dpb_entry(h, s);
|
|
nengel@2
|
212
|
|
nengel@2
|
213 }
|
|
nengel@2
|
214
|
|
nengel@2
|
215 static SuperMBTask* add_decode_slice_3dwave_tasks(MBRecContext *d, SliceBufferEntry *sbe, SuperMBContext *smbc){
|
|
nengel@2
|
216 int i,j;
|
|
nengel@2
|
217
|
|
nengel@2
|
218 int smb_3d_height =smbc->nsmb_3dheight;
|
|
nengel@2
|
219 int smb_height =smbc->nsmb_height, smb_width= smbc->nsmb_width;
|
|
nengel@2
|
220 int smb_diff_prev = smb_height - smb_3d_height;
|
|
nengel@2
|
221 SuperMBTask *sm=NULL, *sml, *smur, *smprev;
|
|
nengel@2
|
222
|
|
nengel@2
|
223 SuperMBTask *smbs = smbc->smbs[smbc->index++]; smbc->index%=2;
|
|
nengel@2
|
224 SuperMBTask *smbs_prev = smbc->smbs[smbc->index]; // index rotates -> next == prev
|
|
nengel@2
|
225
|
|
nengel@2
|
226 for(j=0; j<smb_3d_height ; j++){
|
|
nengel@2
|
227 for(i=0; i< smb_width; i++){
|
|
nengel@2
|
228 sm = smbs + j*smb_width + i;
|
|
nengel@2
|
229 sml = sm - ((i > 0) ? 1: 0);
|
|
nengel@2
|
230 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
|
|
nengel@2
|
231 smprev = smbs_prev + (j + smb_diff_prev+1)*smb_width -1;
|
|
nengel@2
|
232 decode_3dwave_super_mb_task(d, sbe, smbc, sml, smur, smprev, sm);
|
|
nengel@2
|
233 }
|
|
nengel@2
|
234 draw_edges_task(d, sbe, smbc, sm, j);
|
|
nengel@2
|
235 }
|
|
nengel@2
|
236
|
|
nengel@2
|
237 for(; j< smb_height; j++){
|
|
nengel@2
|
238 for(i=0; i< smb_width; i++){
|
|
nengel@2
|
239 sm = smbs + j*smb_width + i;
|
|
nengel@2
|
240 sml = sm - ((i > 0) ? 1: 0);
|
|
nengel@2
|
241 smur = sm + (((i < smb_width-1) && (j >0)) ? -smb_width+1: 0);
|
|
nengel@2
|
242 decode_super_mb_task(d, sbe, smbc, sml, smur, sm);
|
|
nengel@2
|
243 }
|
|
nengel@2
|
244 draw_edges_task(d, sbe, smbc, sm, j);
|
|
nengel@2
|
245 }
|
|
nengel@2
|
246 return sm;
|
|
nengel@2
|
247 }
|
|
nengel@2
|
248
|
|
nengel@2
|
249 #pragma omp task inout(*d, *sbe, *release) input (*lastsmb)
|
|
nengel@2
|
250 static void release_ref_list_task(H264Context *h, SuperMBContext *smbc, MBRecContext *d, SliceBufferEntry *sbe, SuperMBTask *lastsmb, int *release){
|
|
nengel@2
|
251 H264Slice *s = &sbe->slice;
|
|
nengel@2
|
252 for (int i=0; i<s->release_cnt; i++){
|
|
nengel@2
|
253 for(int j=0; j<h->max_dpb_cnt; j++){
|
|
nengel@2
|
254 if(h->dpb[j].cpn== s->release_ref_cpn[i]){
|
|
nengel@2
|
255 #pragma omp critical (dpb)
|
|
nengel@2
|
256 release_dpb_entry(h, &h->dpb[j], 2);
|
|
nengel@2
|
257 break;
|
|
nengel@2
|
258 }
|
|
nengel@2
|
259 }
|
|
nengel@2
|
260 }
|
|
nengel@2
|
261 s->release_cnt=0;
|
|
nengel@2
|
262
|
|
nengel@2
|
263 release_smbc(h, smbc);
|
|
nengel@2
|
264
|
|
nengel@2
|
265 }
|
|
nengel@2
|
266
|
|
nengel@2
|
267 // static void decode_mb_static_3dwave(H264Context *h, int mb_height, int mb_width, MBRecContext *d, H264Slice *s, H264Mb *mbs, SuperMBTask *smbs, SuperMBTask *smbs_prev){
|
|
nengel@2
|
268 //
|
|
nengel@2
|
269 // }
|
|
nengel@2
|
270 /*-------------------------------------------------------------------------------*/
|
|
nengel@2
|
271 //end for static 3d wave
|
|
nengel@2
|
272
|
|
nengel@2
|
273 #pragma omp task inout (*oc) input(*sbe)
|
|
nengel@2
|
274 static void output_task(H264Context *h, OutputContext *oc, SliceBufferEntry *sbe){
|
|
nengel@2
|
275 DecodedPicture* out =output_frame(h, oc, sbe->slice.curr_pic, h->ofile, h->frame_width, h->frame_height);
|
|
nengel@2
|
276 if (out){
|
|
nengel@2
|
277 #pragma omp critical (dpb)
|
|
nengel@2
|
278 release_dpb_entry(h, out, 1);
|
|
nengel@2
|
279 }
|
|
nengel@2
|
280 print_report(oc->frame_number, oc->video_size, 0, h->verbose);
|
|
nengel@2
|
281 }
|
|
nengel@2
|
282
|
|
nengel@2
|
283 /*
|
|
nengel@2
|
284 * The following code is the main loop of the file converter
|
|
nengel@2
|
285 */
|
|
nengel@2
|
286 //Put VMS entry point here
|
|
nengel@2
|
287 int h264_decode_ompss( H264Context *h) {
|
|
nengel@2
|
288 const int bufs = h->pipe_bufs;
|
|
nengel@2
|
289
|
|
nengel@2
|
290 ParserContext *pc;
|
|
nengel@2
|
291 NalContext *nc;
|
|
nengel@2
|
292 EntropyContext *ec[bufs];
|
|
nengel@2
|
293 MBRecContext *rc[2];
|
|
nengel@2
|
294 OutputContext *oc;
|
|
nengel@2
|
295 SliceBufferEntry *sbe;
|
|
nengel@2
|
296 SuperMBContext *smbc;
|
|
nengel@2
|
297
|
|
nengel@2
|
298 DecodedPicture *out;
|
|
nengel@2
|
299 int frames=0;
|
|
nengel@2
|
300
|
|
nengel@2
|
301 #if HAVE_LIBSDL2
|
|
nengel@2
|
302 pthread_t sdl_thr;
|
|
nengel@2
|
303 if (h->display){
|
|
nengel@2
|
304 pthread_create(&sdl_thr, NULL, sdl_thread, h);
|
|
nengel@2
|
305 }
|
|
nengel@2
|
306 #endif
|
|
nengel@2
|
307 sbe= av_mallocz(sizeof(SliceBufferEntry) * bufs);
|
|
nengel@2
|
308
|
|
nengel@2
|
309
|
|
nengel@2
|
310 pc = get_parse_context(h->ifile);
|
|
nengel@2
|
311 nc = get_nal_context(h->width, h->height);
|
|
nengel@2
|
312
|
|
nengel@2
|
313 for(int i=0; i<bufs; i++){
|
|
nengel@2
|
314 ec[i] = get_entropy_context( h );
|
|
nengel@2
|
315 }
|
|
nengel@2
|
316
|
|
nengel@2
|
317 for(int i=0; i<2; i++){
|
|
nengel@2
|
318 rc[i] = get_mbrec_context(h);
|
|
nengel@2
|
319 }
|
|
nengel@2
|
320
|
|
nengel@2
|
321 oc = get_output_context( h );
|
|
nengel@2
|
322
|
|
nengel@2
|
323 av_start_timer();
|
|
nengel@2
|
324 int k=0; int init, release;
|
|
nengel@2
|
325 if (h->static_3d && bufs < h->num_frames ){
|
|
nengel@2
|
326 int num_pre_ed =0;
|
|
nengel@2
|
327 for (num_pre_ed=0; num_pre_ed< bufs -1 && !pc->final_frame; num_pre_ed++){
|
|
nengel@2
|
328 parse_task( h, pc, nc, &sbe[k%bufs] );
|
|
nengel@2
|
329 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]);
|
|
nengel@2
|
330 #pragma omp taskwait on(*pc)
|
|
nengel@2
|
331 k++;
|
|
nengel@2
|
332 }
|
|
nengel@2
|
333
|
|
nengel@2
|
334 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
|
|
nengel@2
|
335 parse_task( h, pc, nc, &sbe[k%bufs] );
|
|
nengel@2
|
336 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]);
|
|
nengel@2
|
337
|
|
nengel@2
|
338 k++;
|
|
nengel@2
|
339
|
|
nengel@2
|
340 init_ref_list_and_get_dpb_task(h, rc[k%2], &sbe[k%bufs], &init);
|
|
nengel@2
|
341 smbc = acquire_smbc(h);
|
|
nengel@2
|
342 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc);
|
|
nengel@2
|
343 release_ref_list_task(h, smbc, rc[k%2], &sbe[k%bufs], lastsmb, &release);
|
|
nengel@2
|
344
|
|
nengel@2
|
345 output_task (h, oc, &sbe[k%bufs]);
|
|
nengel@2
|
346 #pragma omp taskwait on(*pc)
|
|
nengel@2
|
347 }
|
|
nengel@2
|
348
|
|
nengel@2
|
349 for (int i=0; i< num_pre_ed; i++){
|
|
nengel@2
|
350 k++;
|
|
nengel@2
|
351 init_ref_list_and_get_dpb_task(h, rc[k%2], &sbe[k%bufs], &init);
|
|
nengel@2
|
352 smbc = acquire_smbc(h);
|
|
nengel@2
|
353 SuperMBTask *lastsmb= add_decode_slice_3dwave_tasks(rc[k%2], &sbe[k%bufs], smbc);
|
|
nengel@2
|
354 release_ref_list_task(h, smbc, rc[k%2], &sbe[k%bufs], lastsmb, &release);
|
|
nengel@2
|
355
|
|
nengel@2
|
356 output_task (h, oc, &sbe[k%bufs]);
|
|
nengel@2
|
357 }
|
|
nengel@2
|
358
|
|
nengel@2
|
359 } else {
|
|
nengel@2
|
360 while(!pc->final_frame && frames++ < h->num_frames && !h->quit){
|
|
nengel@2
|
361 parse_task( h, pc, nc, &sbe[k%bufs] );
|
|
nengel@2
|
362
|
|
nengel@2
|
363 decode_slice_entropy_task(h, ec[k%bufs], &sbe[k%bufs]);
|
|
nengel@2
|
364
|
|
nengel@2
|
365 decode_slice_mb_task(h, rc[0], &sbe[k%bufs]);
|
|
nengel@2
|
366
|
|
nengel@2
|
367 output_task (h, oc, &sbe[k%bufs]);
|
|
nengel@2
|
368 #pragma omp taskwait on(*pc)
|
|
nengel@2
|
369 k++;
|
|
nengel@2
|
370 }
|
|
nengel@2
|
371 }
|
|
nengel@2
|
372 #pragma omp taskwait
|
|
nengel@2
|
373
|
|
nengel@2
|
374 while ((out=output_frame(h, oc, NULL, h->ofile, h->frame_width, h->frame_height))) ;
|
|
nengel@2
|
375
|
|
nengel@2
|
376 print_report(oc->frame_number, oc->video_size, 1, h->verbose);
|
|
nengel@2
|
377 h->num_frames = oc->frame_number;
|
|
nengel@2
|
378 /* finished ! */
|
|
nengel@2
|
379
|
|
nengel@2
|
380 free_parse_context(pc);
|
|
nengel@2
|
381 free_nal_context (nc);
|
|
nengel@2
|
382 free_output_context(oc);
|
|
nengel@2
|
383 for (int i=0; i<bufs; i++){
|
|
nengel@2
|
384 free_sb_entry(&sbe[i]);
|
|
nengel@2
|
385 free_entropy_context(ec[i]);
|
|
nengel@2
|
386 }
|
|
nengel@2
|
387 av_free(sbe);
|
|
nengel@2
|
388
|
|
nengel@2
|
389 for (int i=0; i<2; i++){
|
|
nengel@2
|
390 free_mbrec_context(rc[i]);
|
|
nengel@2
|
391 }
|
|
nengel@2
|
392
|
|
nengel@2
|
393 #if HAVE_LIBSDL2
|
|
nengel@2
|
394 if (h->display){
|
|
nengel@2
|
395 signal_sdl_exit(h);
|
|
nengel@2
|
396 pthread_join(sdl_thr, NULL);
|
|
nengel@2
|
397 }
|
|
nengel@2
|
398 #endif
|
|
nengel@2
|
399
|
|
nengel@2
|
400 return 0;
|
|
nengel@2
|
401 }
|