00001 #include "mpeg3private.h"
00002 #include "mpeg3protos.h"
00003
00004 #include <pthread.h>
00005 #include <stdlib.h>
00006
00007 #define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
00008
00009
00010 int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
00011 {
00012 pthread_mutexattr_t mutex_attr;
00013
00014 slice_buffer->data = malloc(1024);
00015 slice_buffer->buffer_size = 0;
00016 slice_buffer->buffer_allocation = 1024;
00017 slice_buffer->current_position = 0;
00018 slice_buffer->bits_size = 0;
00019 slice_buffer->bits = 0;
00020 slice_buffer->done = 0;
00021 pthread_mutexattr_init(&mutex_attr);
00022
00023 pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr);
00024 return 0;
00025 }
00026
00027 int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
00028 {
00029 free(slice_buffer->data);
00030 pthread_mutex_destroy(&(slice_buffer->completion_lock));
00031 return 0;
00032 }
00033
00034 int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
00035 {
00036 int i;
00037 unsigned char *new_buffer = malloc(slice_buffer->buffer_allocation * 2);
00038 for(i = 0; i < slice_buffer->buffer_size; i++)
00039 new_buffer[i] = slice_buffer->data[i];
00040 free(slice_buffer->data);
00041 slice_buffer->data = new_buffer;
00042 slice_buffer->buffer_allocation *= 2;
00043 return 0;
00044 }
00045
00046
00047
00048
00049
00050 static inline int mpeg3video_addblock(mpeg3_slice_t *slice,
00051 mpeg3video_t *video,
00052 int comp,
00053 int bx,
00054 int by,
00055 int dct_type,
00056 int addflag)
00057 {
00058 int cc, i, iincr;
00059 unsigned char *rfp;
00060 short *bp;
00061 int spar = slice->sparse[comp];
00062
00063 cc = (comp < 4) ? 0 : (comp & 1) + 1;
00064
00065 if(cc == 0)
00066 {
00067
00068 if(video->pict_struct == FRAME_PICTURE)
00069 {
00070 if(dct_type)
00071 {
00072
00073 rfp = video->newframe[0] +
00074 video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
00075 iincr = (video->coded_picture_width << 1);
00076 }
00077 else
00078 {
00079
00080 rfp = video->newframe[0] +
00081 video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
00082 iincr = video->coded_picture_width;
00083 }
00084 }
00085 else
00086 {
00087
00088 rfp = video->newframe[0] +
00089 (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
00090 iincr = (video->coded_picture_width << 1);
00091 }
00092 }
00093 else
00094 {
00095
00096
00097
00098 if(video->chroma_format != CHROMA444) bx >>= 1;
00099 if(video->chroma_format == CHROMA420) by >>= 1;
00100 if(video->pict_struct == FRAME_PICTURE)
00101 {
00102 if(dct_type && (video->chroma_format != CHROMA420))
00103 {
00104
00105 rfp = video->newframe[cc]
00106 + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8);
00107 iincr = (video->chrom_width << 1);
00108 }
00109 else
00110 {
00111
00112 rfp = video->newframe[cc]
00113 + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8);
00114 iincr = video->chrom_width;
00115 }
00116 }
00117 else
00118 {
00119
00120 rfp = video->newframe[cc]
00121 + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8);
00122 iincr = (video->chrom_width << 1);
00123 }
00124 }
00125
00126 bp = slice->block[comp];
00127
00128 if(addflag)
00129 {
00130 for(i = 0; i < 8; i++)
00131 {
00132 rfp[0] = CLIP(bp[0] + rfp[0]);
00133 rfp[1] = CLIP(bp[1] + rfp[1]);
00134 rfp[2] = CLIP(bp[2] + rfp[2]);
00135 rfp[3] = CLIP(bp[3] + rfp[3]);
00136 rfp[4] = CLIP(bp[4] + rfp[4]);
00137 rfp[5] = CLIP(bp[5] + rfp[5]);
00138 rfp[6] = CLIP(bp[6] + rfp[6]);
00139 rfp[7] = CLIP(bp[7] + rfp[7]);
00140 rfp += iincr;
00141 bp += 8;
00142 }
00143 }
00144 else
00145 {
00146 for(i = 0; i < 8; i++)
00147 {
00148 rfp[0] = CLIP(bp[0] + 128);
00149 rfp[1] = CLIP(bp[1] + 128);
00150 rfp[2] = CLIP(bp[2] + 128);
00151 rfp[3] = CLIP(bp[3] + 128);
00152 rfp[4] = CLIP(bp[4] + 128);
00153 rfp[5] = CLIP(bp[5] + 128);
00154 rfp[6] = CLIP(bp[6] + 128);
00155 rfp[7] = CLIP(bp[7] + 128);
00156 rfp+= iincr;
00157 bp += 8;
00158 }
00159 }
00160 return 0;
00161 }
00162
00163 int mpeg3_decode_slice(mpeg3_slice_t *slice)
00164 {
00165 mpeg3video_t *video = slice->video;
00166 int comp;
00167 int mb_type, cbp, motion_type = 0, dct_type;
00168 int macroblock_address, mba_inc, mba_max;
00169 int slice_vert_pos_ext;
00170 unsigned int code;
00171 int bx, by;
00172 int dc_dct_pred[3];
00173 int mv_count, mv_format, mvscale;
00174 int pmv[2][2][2], mv_field_sel[2][2];
00175 int dmv, dmvector[2];
00176 int qs;
00177 int stwtype, stwclass;
00178 int snr_cbp;
00179 int i;
00180 mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
00181
00182
00183 mba_max = video->mb_width * video->mb_height;
00184
00185
00186 if(video->pict_struct != FRAME_PICTURE)
00187 mba_max >>= 1;
00188
00189
00190 macroblock_address = 0;
00191
00192 mba_inc = 0;
00193 slice->fault = 0;
00194
00195 code = mpeg3slice_getbits(slice_buffer, 32);
00196
00197 slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);
00198
00199
00200 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
00201 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
00202 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
00203
00204 for(i = 0;
00205 slice_buffer->current_position < slice_buffer->buffer_size;
00206 i++)
00207 {
00208 if(mba_inc == 0)
00209 {
00210
00211 if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;
00212
00213 mba_inc = mpeg3video_get_macroblock_address(slice);
00214
00215 if(slice->fault) return 1;
00216
00217 if(i == 0)
00218 {
00219
00220 macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;
00221
00222 mba_inc = 1;
00223 }
00224 }
00225
00226 if(slice->fault) return 1;
00227
00228 if(macroblock_address >= mba_max)
00229 {
00230
00231
00232 return 1;
00233 }
00234
00235
00236 if(mba_inc == 1)
00237 {
00238 mpeg3video_macroblock_modes(slice,
00239 video,
00240 &mb_type,
00241 &stwtype,
00242 &stwclass,
00243 &motion_type,
00244 &mv_count,
00245 &mv_format,
00246 &dmv,
00247 &mvscale,
00248 &dct_type);
00249
00250 if(slice->fault) return 1;
00251
00252 if(mb_type & MB_QUANT)
00253 {
00254 qs = mpeg3slice_getbits(slice_buffer, 5);
00255
00256 if(video->mpeg2)
00257 slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1);
00258 else
00259 slice->quant_scale = qs;
00260
00261 if(video->scalable_mode == SC_DP)
00262
00263 slice->quant_scale = slice->quant_scale;
00264 }
00265
00266
00267
00268
00269
00270 if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv))
00271 {
00272 if(video->mpeg2)
00273 mpeg3video_motion_vectors(slice,
00274 video,
00275 pmv,
00276 dmvector,
00277 mv_field_sel,
00278 0,
00279 mv_count,
00280 mv_format,
00281 video->h_forw_r_size,
00282 video->v_forw_r_size,
00283 dmv,
00284 mvscale);
00285 else
00286 mpeg3video_motion_vector(slice,
00287 video,
00288 pmv[0][0],
00289 dmvector,
00290 video->forw_r_size,
00291 video->forw_r_size,
00292 0,
00293 0,
00294 video->full_forw);
00295 }
00296 if(slice->fault) return 1;
00297
00298
00299 if(mb_type & MB_BACKWARD)
00300 {
00301 if(video->mpeg2)
00302 mpeg3video_motion_vectors(slice,
00303 video,
00304 pmv,
00305 dmvector,
00306 mv_field_sel,
00307 1,
00308 mv_count,
00309 mv_format,
00310 video->h_back_r_size,
00311 video->v_back_r_size,
00312 0,
00313 mvscale);
00314 else
00315 mpeg3video_motion_vector(slice,
00316 video,
00317 pmv[0][1],
00318 dmvector,
00319 video->back_r_size,
00320 video->back_r_size,
00321 0,
00322 0,
00323 video->full_back);
00324 }
00325
00326 if(slice->fault) return 1;
00327
00328
00329 if((mb_type & MB_INTRA) && video->conceal_mv)
00330 mpeg3slice_flushbit(slice_buffer);
00331
00332
00333 if(mb_type & MB_PATTERN)
00334 {
00335 cbp = mpeg3video_get_cbp(slice);
00336 if(video->chroma_format == CHROMA422)
00337 {
00338
00339 cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer);
00340 }
00341 else
00342 if(video->chroma_format == CHROMA444)
00343 {
00344
00345 cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6);
00346 }
00347 }
00348 else
00349 cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
00350
00351 if(slice->fault) return 1;
00352
00353 mpeg3video_clearblock(slice, 0, video->blk_cnt);
00354 for(comp = 0; comp < video->blk_cnt; comp++)
00355 {
00356 if(cbp & (1 << (video->blk_cnt - comp - 1)))
00357 {
00358 if(mb_type & MB_INTRA)
00359 {
00360 if(video->mpeg2)
00361 mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred);
00362 else
00363 mpeg3video_getintrablock(slice, video, comp, dc_dct_pred);
00364 }
00365 else
00366 {
00367 if(video->mpeg2)
00368 mpeg3video_getmpg2interblock(slice, video, comp);
00369 else
00370 mpeg3video_getinterblock(slice, video, comp);
00371 }
00372 if(slice->fault) return 1;
00373 }
00374 }
00375
00376
00377 if(!(mb_type & MB_INTRA))
00378 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
00379
00380
00381 if((mb_type & MB_INTRA) && !video->conceal_mv)
00382 {
00383
00384 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
00385 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
00386 }
00387
00388 if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA)))
00389 {
00390
00391 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
00392
00393
00394 if(video->pict_struct == FRAME_PICTURE)
00395 motion_type = MC_FRAME;
00396 else
00397 {
00398 motion_type = MC_FIELD;
00399
00400 mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD);
00401 }
00402 }
00403
00404 if(stwclass == 4)
00405 {
00406
00407 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
00408 pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
00409 }
00410 }
00411 else
00412 {
00413
00414 mpeg3video_clearblock(slice, 0, video->blk_cnt);
00415
00416
00417 dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
00418
00419
00420 if(video->pict_type == P_TYPE)
00421 pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
00422
00423
00424 if(video->pict_struct == FRAME_PICTURE)
00425 motion_type = MC_FRAME;
00426 else
00427 {
00428 motion_type = MC_FIELD;
00429
00430 mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD);
00431 }
00432
00433
00434
00435 stwtype = (video->pict_type == I_TYPE) ? 8 : 0;
00436
00437
00438 mb_type &= ~MB_INTRA;
00439
00440
00441 cbp = 0;
00442 }
00443
00444 snr_cbp = 0;
00445
00446
00447 bx = 16 * (macroblock_address % video->mb_width);
00448 by = 16 * (macroblock_address / video->mb_width);
00449
00450
00451 if(!(mb_type & MB_INTRA))
00452 mpeg3video_reconstruct(video,
00453 bx,
00454 by,
00455 mb_type,
00456 motion_type,
00457 pmv,
00458 mv_field_sel,
00459 dmvector,
00460 stwtype);
00461
00462
00463 for(comp = 0; comp < video->blk_cnt; comp++)
00464 {
00465 if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp)))
00466 {
00467 mpeg3video_idct_conversion(slice->block[comp]);
00468
00469 mpeg3video_addblock(slice,
00470 video,
00471 comp,
00472 bx,
00473 by,
00474 dct_type,
00475 (mb_type & MB_INTRA) == 0);
00476 }
00477 }
00478
00479
00480 macroblock_address++;
00481 mba_inc--;
00482 }
00483
00484 return 0;
00485 }
00486
00487 void mpeg3_slice_loop(mpeg3_slice_t *slice)
00488 {
00489 mpeg3video_t *video = slice->video;
00490 int result = 1;
00491
00492 while(!slice->done)
00493 {
00494 pthread_mutex_lock(&(slice->input_lock));
00495
00496 if(!slice->done)
00497 {
00498
00499 result = 1;
00500 pthread_mutex_lock(&(video->slice_lock));
00501 if(slice->buffer_step > 0)
00502 {
00503 while(slice->current_buffer <= slice->last_buffer)
00504 {
00505 if(!video->slice_buffers[slice->current_buffer].done &&
00506 slice->current_buffer <= slice->last_buffer)
00507 {
00508 result = 0;
00509 break;
00510 }
00511 slice->current_buffer += slice->buffer_step;
00512 }
00513 }
00514 else
00515 {
00516 while(slice->current_buffer >= slice->last_buffer)
00517 {
00518 if(!video->slice_buffers[slice->current_buffer].done &&
00519 slice->current_buffer >= slice->last_buffer)
00520 {
00521 result = 0;
00522 break;
00523 }
00524 slice->current_buffer += slice->buffer_step;
00525 }
00526 }
00527
00528
00529 if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers)
00530 {
00531 slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]);
00532 slice->slice_buffer->done = 1;
00533 pthread_mutex_unlock(&(video->slice_lock));
00534 pthread_mutex_unlock(&(slice->input_lock));
00535 mpeg3_decode_slice(slice);
00536 pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
00537 }
00538 else
00539
00540 {
00541 pthread_mutex_unlock(&(slice->completion_lock));
00542 pthread_mutex_unlock(&(video->slice_lock));
00543 }
00544 }
00545
00546 pthread_mutex_unlock(&(slice->output_lock));
00547 }
00548 }
00549
00550 int mpeg3_new_slice_decoder(void *video, mpeg3_slice_t *slice)
00551 {
00552 pthread_attr_t attr;
00553 pthread_mutexattr_t mutex_attr;
00554
00555 slice->video = video;
00556 slice->done = 0;
00557 pthread_mutexattr_init(&mutex_attr);
00558
00559 pthread_mutex_init(&(slice->input_lock), &mutex_attr);
00560 pthread_mutex_lock(&(slice->input_lock));
00561 pthread_mutex_init(&(slice->output_lock), &mutex_attr);
00562 pthread_mutex_lock(&(slice->output_lock));
00563 pthread_mutex_init(&(slice->completion_lock), &mutex_attr);
00564 pthread_mutex_lock(&(slice->completion_lock));
00565
00566 pthread_attr_init(&attr);
00567 pthread_create(&(slice->tid), &attr, (void*)mpeg3_slice_loop, slice);
00568
00569 return 0;
00570 }
00571
00572 int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice)
00573 {
00574 slice->done = 1;
00575 pthread_mutex_unlock(&(slice->input_lock));
00576 pthread_join(slice->tid, 0);
00577 pthread_mutex_destroy(&(slice->input_lock));
00578 pthread_mutex_destroy(&(slice->output_lock));
00579 return 0;
00580 }