1 /* putpic.c, block and motion vector encoding routines */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
34 /* output motion vectors (6.2.5.2, 6.3.16.2)
36 * this routine also updates the predictions for motion vectors (PMV)
39 static void putmvs(slice_engine_t
*engine
,
50 hor_f_code
= picture
->back_hor_f_code
;
51 vert_f_code
= picture
->back_vert_f_code
;
55 hor_f_code
= picture
->forw_hor_f_code
;
56 vert_f_code
= picture
->forw_vert_f_code
;
60 if(picture
->pict_struct
== FRAME_PICTURE
)
62 if(mb
->motion_type
== MC_FRAME
)
64 /* frame prediction */
65 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
66 putmv(engine
, mb
->MV
[0][back
][1] - PMV
[0][back
][1], vert_f_code
);
67 PMV
[0][back
][0] = PMV
[1][back
][0] = mb
->MV
[0][back
][0];
68 PMV
[0][back
][1] = PMV
[1][back
][1] = mb
->MV
[0][back
][1];
71 if (mb
->motion_type
== MC_FIELD
)
73 /* field prediction */
74 slice_putbits(engine
, mb
->mv_field_sel
[0][back
], 1);
75 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
76 putmv(engine
, (mb
->MV
[0][back
][1] >> 1) - (PMV
[0][back
][1] >> 1), vert_f_code
);
77 slice_putbits(engine
, mb
->mv_field_sel
[1][back
], 1);
78 putmv(engine
, mb
->MV
[1][back
][0] - PMV
[1][back
][0], hor_f_code
);
79 putmv(engine
, (mb
->MV
[1][back
][1] >> 1) - (PMV
[1][back
][1] >> 1), vert_f_code
);
80 PMV
[0][back
][0] = mb
->MV
[0][back
][0];
81 PMV
[0][back
][1] = mb
->MV
[0][back
][1];
82 PMV
[1][back
][0] = mb
->MV
[1][back
][0];
83 PMV
[1][back
][1] = mb
->MV
[1][back
][1];
87 /* dual prime prediction */
88 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
89 putdmv(engine
, mb
->dmvector
[0]);
90 putmv(engine
, (mb
->MV
[0][back
][1] >> 1) - (PMV
[0][back
][1] >> 1), vert_f_code
);
91 putdmv(engine
, mb
->dmvector
[1]);
92 PMV
[0][back
][0] = PMV
[1][back
][0] = mb
->MV
[0][back
][0];
93 PMV
[0][back
][1] = PMV
[1][back
][1] = mb
->MV
[0][back
][1];
99 if(mb
->motion_type
== MC_FIELD
)
101 /* field prediction */
102 slice_putbits(engine
, mb
->mv_field_sel
[0][back
], 1);
103 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
104 putmv(engine
, mb
->MV
[0][back
][1] - PMV
[0][back
][1], vert_f_code
);
105 PMV
[0][back
][0] = PMV
[1][back
][0] = mb
->MV
[0][back
][0];
106 PMV
[0][back
][1] = PMV
[1][back
][1] = mb
->MV
[0][back
][1];
109 if(mb
->motion_type
== MC_16X8
)
111 /* 16x8 prediction */
112 slice_putbits(engine
, mb
->mv_field_sel
[0][back
], 1);
113 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
114 putmv(engine
, mb
->MV
[0][back
][1] - PMV
[0][back
][1], vert_f_code
);
115 slice_putbits(engine
, mb
->mv_field_sel
[1][back
], 1);
116 putmv(engine
, mb
->MV
[1][back
][0] - PMV
[1][back
][0], hor_f_code
);
117 putmv(engine
, mb
->MV
[1][back
][1] - PMV
[1][back
][1], vert_f_code
);
118 PMV
[0][back
][0] = mb
->MV
[0][back
][0];
119 PMV
[0][back
][1] = mb
->MV
[0][back
][1];
120 PMV
[1][back
][0] = mb
->MV
[1][back
][0];
121 PMV
[1][back
][1] = mb
->MV
[1][back
][1];
125 /* dual prime prediction */
126 putmv(engine
, mb
->MV
[0][back
][0] - PMV
[0][back
][0], hor_f_code
);
127 putdmv(engine
, mb
->dmvector
[0]);
128 putmv(engine
, mb
->MV
[0][back
][1] - PMV
[0][back
][1], vert_f_code
);
129 putdmv(engine
, mb
->dmvector
[1]);
130 PMV
[0][back
][0] = PMV
[1][back
][0] = mb
->MV
[0][back
][0];
131 PMV
[0][back
][1] = PMV
[1][back
][1] = mb
->MV
[0][back
][1];
137 void* slice_engine_loop(slice_engine_t
*engine
)
141 pthread_mutex_lock(&(engine
->input_lock
));
145 pict_data_s
*picture
= engine
->picture
;
146 int i
, j
, k
, comp
, cc
;
150 short (*quant_blocks
)[64] = picture
->qblocks
;
152 k
= engine
->start_row
* mb_width
;
153 for(j
= engine
->start_row
; j
< engine
->end_row
; j
++)
155 /* macroblock row loop */
156 //printf("putpic 1\n");
157 //slice_testbits(engine);
158 for(i
= 0; i
< mb_width
; i
++)
160 mbinfo_s
*cur_mb
= &picture
->mbinfo
[k
];
161 int cur_mb_blocks
= k
* block_count
;
162 //pthread_mutex_lock(&test_lock);
163 /* macroblock loop */
166 slice_alignbits(engine
);
167 /* slice header (6.2.4) */
168 if(mpeg1
|| vertical_size
<= 2800)
169 slice_putbits(engine
, SLICE_MIN_START
+ j
, 32); /* slice_start_code */
172 slice_putbits(engine
, SLICE_MIN_START
+ (j
& 127), 32); /* slice_start_code */
173 slice_putbits(engine
, j
>> 7, 3); /* slice_vertical_position_extension */
175 /* quantiser_scale_code */
176 //printf("putpic 1\n");slice_testbits(engine);
177 slice_putbits(engine
,
178 picture
->q_scale_type
? map_non_linear_mquant
[engine
->prev_mquant
] : engine
->prev_mquant
>> 1,
181 slice_putbits(engine
, 0, 1); /* extra_bit_slice */
183 //printf("putpic 1 %d %d %d\n",engine->prev_mquant, map_non_linear_mquant[engine->prev_mquant], engine->prev_mquant >> 1);
184 //slice_testbits(engine);
185 /* reset predictors */
187 for(cc
= 0; cc
< 3; cc
++)
188 engine
->dc_dct_pred
[cc
] = 0;
190 PMV
[0][0][0] = PMV
[0][0][1] = PMV
[1][0][0] = PMV
[1][0][1] = 0;
191 PMV
[0][1][0] = PMV
[0][1][1] = PMV
[1][1][0] = PMV
[1][1][1] = 0;
193 MBAinc
= i
+ 1; /* first MBAinc denotes absolute position */
196 mb_type
= cur_mb
->mb_type
;
198 /* determine mquant (rate control) */
199 cur_mb
->mquant
= ratectl_calc_mquant(engine
->ratectl
, picture
, k
);
201 /* quantize macroblock */
202 //printf("putpic 1\n");
203 //printf("putpic 1\n");
204 //slice_testbits(engine);
205 if(mb_type
& MB_INTRA
)
207 //printf("putpic 2 %d\n", cur_mb->mquant);
208 quant_intra( picture
,
209 picture
->blocks
[cur_mb_blocks
],
210 quant_blocks
[cur_mb_blocks
],
214 //printf("putpic 3\n");
215 cur_mb
->cbp
= cbp
= (1<<block_count
) - 1;
219 //printf("putpic 4 %p %d\n", picture->blocks[cur_mb_blocks], cur_mb_blocks);
220 cbp
= (*pquant_non_intra
)(picture
,
221 picture
->blocks
[cur_mb_blocks
],
222 quant_blocks
[cur_mb_blocks
],
225 //printf("putpic 5\n");
228 mb_type
|= MB_PATTERN
;
230 //printf("putpic 6\n");
231 //printf("putpic 2\n");
232 //slice_testbits(engine);
234 /* output mquant if it has changed */
235 if(cbp
&& engine
->prev_mquant
!= cur_mb
->mquant
)
238 /* check if macroblock can be skipped */
239 if(i
!= 0 && i
!= mb_width
- 1 && !cbp
)
241 /* no DCT coefficients and neither first nor last macroblock of slice */
243 if(picture
->pict_type
== P_TYPE
&&
244 !(mb_type
& MB_FORWARD
))
246 /* P picture, no motion vectors -> skip */
248 /* reset predictors */
250 for(cc
= 0; cc
< 3; cc
++)
251 engine
->dc_dct_pred
[cc
] = 0;
253 PMV
[0][0][0] = PMV
[0][0][1] = PMV
[1][0][0] = PMV
[1][0][1] = 0;
254 PMV
[0][1][0] = PMV
[0][1][1] = PMV
[1][1][0] = PMV
[1][1][1] = 0;
256 cur_mb
->mb_type
= mb_type
;
263 if(picture
->pict_type
== B_TYPE
&&
264 picture
->pict_struct
== FRAME_PICTURE
&&
265 cur_mb
->motion_type
== MC_FRAME
&&
266 ((picture
->mbinfo
[k
- 1].mb_type
^ mb_type
) & (MB_FORWARD
| MB_BACKWARD
)) == 0 &&
267 (!(mb_type
& MB_FORWARD
) ||
268 (PMV
[0][0][0] == cur_mb
->MV
[0][0][0] &&
269 PMV
[0][0][1] == cur_mb
->MV
[0][0][1])) &&
270 (!(mb_type
& MB_BACKWARD
) ||
271 (PMV
[0][1][0] == cur_mb
->MV
[0][1][0] &&
272 PMV
[0][1][1] == cur_mb
->MV
[0][1][1])))
274 /* conditions for skipping in B frame pictures:
275 * - must be frame predicted
276 * - must be the same prediction type (forward/backward/interp.)
277 * as previous macroblock
278 * - relevant vectors (forward/backward/both) have to be the same
279 * as in previous macroblock
282 cur_mb
->mb_type
= mb_type
;
289 if (picture
->pict_type
== B_TYPE
&&
290 picture
->pict_struct
!= FRAME_PICTURE
&&
291 cur_mb
->motion_type
== MC_FIELD
&&
292 ((picture
->mbinfo
[k
- 1].mb_type
^ mb_type
) & (MB_FORWARD
| MB_BACKWARD
))==0 &&
293 (!(mb_type
& MB_FORWARD
) ||
294 (PMV
[0][0][0] == cur_mb
->MV
[0][0][0] &&
295 PMV
[0][0][1] == cur_mb
->MV
[0][0][1] &&
296 cur_mb
->mv_field_sel
[0][0] == (picture
->pict_struct
== BOTTOM_FIELD
))) &&
297 (!(mb_type
& MB_BACKWARD
) ||
298 (PMV
[0][1][0] == cur_mb
->MV
[0][1][0] &&
299 PMV
[0][1][1] == cur_mb
->MV
[0][1][1] &&
300 cur_mb
->mv_field_sel
[0][1] == (picture
->pict_struct
== BOTTOM_FIELD
))))
302 /* conditions for skipping in B field pictures:
303 * - must be field predicted
304 * - must be the same prediction type (forward/backward/interp.)
305 * as previous macroblock
306 * - relevant vectors (forward/backward/both) have to be the same
307 * as in previous macroblock
308 * - relevant motion_vertical_field_selects have to be of same
309 * parity as current field
312 cur_mb
->mb_type
= mb_type
;
319 //printf("putpic 3\n");
320 //slice_testbits(engine);
322 /* macroblock cannot be skipped */
325 /* there's no VLC for 'No MC, Not Coded':
326 * we have to transmit (0,0) motion vectors
328 if(picture
->pict_type
== P_TYPE
&&
330 !(mb_type
& MB_FORWARD
))
331 mb_type
|= MB_FORWARD
;
333 /* macroblock_address_increment */
334 putaddrinc(engine
, MBAinc
);
336 putmbtype(engine
, picture
->pict_type
, mb_type
); /* macroblock type */
337 //printf("putpic 3\n");
338 //slice_testbits(engine);
340 if(mb_type
& (MB_FORWARD
| MB_BACKWARD
) &&
341 !picture
->frame_pred_dct
)
342 slice_putbits(engine
, cur_mb
->motion_type
, 2);
344 //printf("putpic %x %d %d %d\n", mb_type, picture->pict_struct, cbp, picture->frame_pred_dct);
345 if(picture
->pict_struct
== FRAME_PICTURE
&&
347 !picture
->frame_pred_dct
)
348 slice_putbits(engine
, cur_mb
->dct_type
, 1);
350 if(mb_type
& MB_QUANT
)
352 slice_putbits(engine
,
353 picture
->q_scale_type
? map_non_linear_mquant
[cur_mb
->mquant
] : cur_mb
->mquant
>> 1,
355 engine
->prev_mquant
= cur_mb
->mquant
;
358 if(mb_type
& MB_FORWARD
)
360 /* forward motion vectors, update predictors */
361 putmvs(engine
, picture
, cur_mb
, PMV
, 0);
364 if(mb_type
& MB_BACKWARD
)
366 /* backward motion vectors, update predictors */
367 putmvs(engine
, picture
, cur_mb
, PMV
, 1);
370 if(mb_type
& MB_PATTERN
)
372 putcbp(engine
, (cbp
>> (block_count
- 6)) & 63);
373 if(chroma_format
!= CHROMA420
)
374 slice_putbits(engine
, cbp
, block_count
- 6);
377 //printf("putpic 4\n");
378 //slice_testbits(engine);
380 for(comp
= 0; comp
< block_count
; comp
++)
383 if(cbp
& (1 << (block_count
- 1 - comp
)))
385 if(mb_type
& MB_INTRA
)
387 cc
= (comp
< 4) ? 0 : (comp
& 1) + 1;
388 putintrablk(engine
, picture
, quant_blocks
[cur_mb_blocks
+ comp
], cc
);
392 putnonintrablk(engine
, picture
, quant_blocks
[cur_mb_blocks
+ comp
]);
395 //printf("putpic 5\n");
396 //slice_testbits(engine);
399 /* reset predictors */
400 if(!(mb_type
& MB_INTRA
))
401 for(cc
= 0; cc
< 3; cc
++)
402 engine
->dc_dct_pred
[cc
] = 0;
404 if(mb_type
& MB_INTRA
||
405 (picture
->pict_type
== P_TYPE
&& !(mb_type
& MB_FORWARD
)))
407 PMV
[0][0][0] = PMV
[0][0][1] = PMV
[1][0][0] = PMV
[1][0][1] = 0;
408 PMV
[0][1][0] = PMV
[0][1][1] = PMV
[1][1][0] = PMV
[1][1][1] = 0;
411 cur_mb
->mb_type
= mb_type
;
413 //pthread_mutex_unlock(&test_lock);
417 pthread_mutex_unlock(&(engine
->output_lock
));
422 /* quantization / variable length encoding of a complete picture */
423 void putpict(pict_data_s
*picture
)
427 for(i
= 0; i
< processors
; i
++)
429 ratectl_init_pict(ratectl
[i
], picture
); /* set up rate control */
432 /* picture header and picture coding extension */
434 if(!mpeg1
) putpictcodext(picture
);
435 /* Flush buffer before switching to slice mode */
439 for(i
= 0; i
< processors
; i
++)
441 slice_engines
[i
].prev_mquant
= ratectl_start_mb(ratectl
[i
], picture
);
442 slice_engines
[i
].picture
= picture
;
443 slice_engines
[i
].ratectl
= ratectl
[i
];
444 slice_initbits(&slice_engines
[i
]);
446 pthread_mutex_unlock(&(slice_engines
[i
].input_lock
));
449 /* Wait for completion and write slices */
450 for(i
= 0; i
< processors
; i
++)
452 pthread_mutex_lock(&(slice_engines
[i
].output_lock
));
453 slice_finishslice(&slice_engines
[i
]);
456 for(i
= 0; i
< processors
; i
++)
457 ratectl_update_pict(ratectl
[i
], picture
);
460 void start_slice_engines()
463 int rows_per_processor
= (int)((float)mb_height2
/ processors
+ 0.5);
466 pthread_mutexattr_t mutex_attr
;
468 pthread_mutexattr_init(&mutex_attr
);
469 pthread_attr_init(&attr
);
470 // pthread_mutex_init(&test_lock, &mutex_attr);
472 slice_engines
= calloc(1, sizeof(slice_engine_t
) * processors
);
473 for(i
= 0; i
< processors
; i
++)
475 slice_engines
[i
].start_row
= current_row
;
476 current_row
+= rows_per_processor
;
477 if(current_row
> mb_height2
) current_row
= mb_height2
;
478 slice_engines
[i
].end_row
= current_row
;
480 pthread_mutex_init(&(slice_engines
[i
].input_lock
), &mutex_attr
);
481 pthread_mutex_lock(&(slice_engines
[i
].input_lock
));
482 pthread_mutex_init(&(slice_engines
[i
].output_lock
), &mutex_attr
);
483 pthread_mutex_lock(&(slice_engines
[i
].output_lock
));
484 slice_engines
[i
].done
= 0;
485 pthread_create(&(slice_engines
[i
].tid
),
487 (void*)slice_engine_loop
,
492 void stop_slice_engines()
495 for(i
= 0; i
< processors
; i
++)
497 slice_engines
[i
].done
= 1;
498 pthread_mutex_unlock(&(slice_engines
[i
].input_lock
));
499 pthread_join(slice_engines
[i
].tid
, 0);
500 pthread_mutex_destroy(&(slice_engines
[i
].input_lock
));
501 pthread_mutex_destroy(&(slice_engines
[i
].output_lock
));
502 if(slice_engines
[i
].slice_buffer
) free(slice_engines
[i
].slice_buffer
);
505 // pthread_mutex_destroy(&test_lock);