449 |
|
|
450 |
/* multithreaded stuff */ |
/* multithreaded stuff */ |
451 |
if (create->num_threads > 0) { |
if (create->num_threads > 0) { |
452 |
|
#ifndef HAVE_PTHREAD |
453 |
|
int t = MAX(1, create->num_threads); |
454 |
|
#else |
455 |
int t = MIN(create->num_threads, (int) (pEnc->mbParam.mb_height>>1)); /* at least two rows per thread */ |
int t = MIN(create->num_threads, (int) (pEnc->mbParam.mb_height>>1)); /* at least two rows per thread */ |
456 |
|
#endif |
457 |
int threads_per_slice = MAX(1, (t / pEnc->num_slices)); |
int threads_per_slice = MAX(1, (t / pEnc->num_slices)); |
458 |
int rows_per_thread = (pEnc->mbParam.mb_height + threads_per_slice - 1) / threads_per_slice; |
int rows_per_thread = (pEnc->mbParam.mb_height + threads_per_slice - 1) / threads_per_slice; |
459 |
|
|
1613 |
memcpy((void *)((ptr_t)bs->start + pos), |
memcpy((void *)((ptr_t)bs->start + pos), |
1614 |
(void *)((ptr_t)pEnc->smpData[k].bs->start), len); |
(void *)((ptr_t)pEnc->smpData[k].bs->start), len); |
1615 |
|
|
1616 |
current->length = pos += len; |
current->length += len; |
1617 |
|
pos += len; |
1618 |
|
|
1619 |
/* collect stats */ |
/* collect stats */ |
1620 |
current->sStat.iTextBits += pEnc->smpData[k].sStat->iTextBits; |
current->sStat.iTextBits += pEnc->smpData[k].sStat->iTextBits; |
1651 |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
1652 |
int slices_per_thread = (num_slices*1024 / num_threads); |
int slices_per_thread = (num_slices*1024 / num_threads); |
1653 |
int mb_height = pEnc->mbParam.mb_height; |
int mb_height = pEnc->mbParam.mb_height; |
1654 |
|
#ifdef HAVE_PTHREAD |
1655 |
void * status = NULL; |
void * status = NULL; |
1656 |
|
#endif |
1657 |
uint16_t k; |
uint16_t k; |
1658 |
|
|
1659 |
pEnc->mbParam.m_rounding_type = 1; |
pEnc->mbParam.m_rounding_type = 1; |
1694 |
pEnc->smpData[0].bs = bs; |
pEnc->smpData[0].bs = bs; |
1695 |
pEnc->smpData[0].sStat = &pEnc->current->sStat; |
pEnc->smpData[0].sStat = &pEnc->current->sStat; |
1696 |
|
|
1697 |
|
#ifdef HAVE_PTHREAD |
1698 |
/* create threads */ |
/* create threads */ |
1699 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
1700 |
pthread_create(&pEnc->smpData[k].handle, NULL, |
pthread_create(&pEnc->smpData[k].handle, NULL, |
1701 |
(void*)SliceCodeI, (void*)&pEnc->smpData[k]); |
(void*)SliceCodeI, (void*)&pEnc->smpData[k]); |
1702 |
} |
} |
1703 |
|
#endif |
1704 |
|
|
1705 |
SliceCodeI(&pEnc->smpData[0]); |
SliceCodeI(&pEnc->smpData[0]); |
1706 |
|
|
1707 |
|
#ifdef HAVE_PTHREAD |
1708 |
/* wait until all threads are finished */ |
/* wait until all threads are finished */ |
1709 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
1710 |
pthread_join(pEnc->smpData[k].handle, &status); |
pthread_join(pEnc->smpData[k].handle, &status); |
1711 |
} |
} |
1712 |
|
#endif |
1713 |
|
|
1714 |
pEnc->current->length = BitstreamLength(bs) - (bits/8); |
pEnc->current->length = BitstreamLength(bs) - (bits/8); |
1715 |
|
|
1918 |
|
|
1919 |
int k = 0, bound = 0, num_slices = pEnc->num_slices; |
int k = 0, bound = 0, num_slices = pEnc->num_slices; |
1920 |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
1921 |
|
#ifdef HAVE_PTHREAD |
1922 |
void * status = NULL; |
void * status = NULL; |
|
int slices_per_thread = (num_slices*1024 / num_threads); |
|
1923 |
int threads_per_slice = (pEnc->num_threads*1024 / num_threads); |
int threads_per_slice = (pEnc->num_threads*1024 / num_threads); |
1924 |
|
#endif |
1925 |
|
int slices_per_thread = (num_slices*1024 / num_threads); |
1926 |
|
|
1927 |
IMAGE *pRef = &reference->image; |
IMAGE *pRef = &reference->image; |
1928 |
|
|
1929 |
if (!reference->is_edged) { |
if (!reference->is_edged) { |
1930 |
start_timer(); |
start_timer(); |
1931 |
image_setedges(pRef, pParam->edged_width, pParam->edged_height, |
image_setedges(pRef, pParam->edged_width, pParam->edged_height, |
1932 |
pParam->width, pParam->height, 0); |
pParam->width, pParam->height, XVID_BS_VERSION); |
1933 |
stop_edges_timer(); |
stop_edges_timer(); |
1934 |
reference->is_edged = 1; |
reference->is_edged = 1; |
1935 |
} |
} |
2017 |
} |
} |
2018 |
} |
} |
2019 |
|
|
2020 |
|
#ifdef HAVE_PTHREAD |
2021 |
if (pEnc->num_threads > 0) { |
if (pEnc->num_threads > 0) { |
2022 |
|
|
2023 |
/* multithreaded motion estimation - dispatch threads */ |
/* multithreaded motion estimation - dispatch threads */ |
2072 |
current->fcode = pEnc->smpData[k].minfcode; |
current->fcode = pEnc->smpData[k].minfcode; |
2073 |
} |
} |
2074 |
|
|
2075 |
} else { |
} else |
2076 |
|
#endif |
2077 |
|
{ |
2078 |
|
|
2079 |
/* regular ME */ |
/* regular ME */ |
2080 |
|
|
2118 |
pEnc->smpData[0].bs = bs; |
pEnc->smpData[0].bs = bs; |
2119 |
pEnc->smpData[0].sStat = ¤t->sStat; |
pEnc->smpData[0].sStat = ¤t->sStat; |
2120 |
|
|
2121 |
|
#ifdef HAVE_PTHREAD |
2122 |
/* create threads */ |
/* create threads */ |
2123 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
2124 |
pthread_create(&pEnc->smpData[k].handle, NULL, |
pthread_create(&pEnc->smpData[k].handle, NULL, |
2125 |
(void*)SliceCodeP, (void*)&pEnc->smpData[k]); |
(void*)SliceCodeP, (void*)&pEnc->smpData[k]); |
2126 |
} |
} |
2127 |
|
#endif |
2128 |
|
|
2129 |
SliceCodeP(&pEnc->smpData[0]); |
SliceCodeP(&pEnc->smpData[0]); |
2130 |
|
|
2131 |
|
#ifdef HAVE_PTHREAD |
2132 |
/* wait until all threads are finished */ |
/* wait until all threads are finished */ |
2133 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
2134 |
pthread_join(pEnc->smpData[k].handle, &status); |
pthread_join(pEnc->smpData[k].handle, &status); |
2135 |
} |
} |
2136 |
|
#endif |
2137 |
|
|
2138 |
current->length = BitstreamLength(bs) - (bits/8); |
current->length = BitstreamLength(bs) - (bits/8); |
2139 |
|
|
2149 |
|
|
2150 |
if (current->sStat.kblks + current->sStat.mblks < |
if (current->sStat.kblks + current->sStat.mblks < |
2151 |
(pParam->frame_drop_ratio * mb_width * mb_height) / 100 && |
(pParam->frame_drop_ratio * mb_width * mb_height) / 100 && |
2152 |
( (pEnc->bframenum_head >= pEnc->bframenum_tail) || !(pEnc->mbParam.global_flags & XVID_GLOBAL_CLOSED_GOP)) ) |
( (pEnc->bframenum_head >= pEnc->bframenum_tail) || !(pEnc->mbParam.global_flags & XVID_GLOBAL_CLOSED_GOP)) && |
2153 |
|
(current->coding_type == P_VOP) ) |
2154 |
{ |
{ |
2155 |
current->sStat.kblks = current->sStat.mblks = current->sStat.iTextBits = 0; |
current->sStat.kblks = current->sStat.mblks = current->sStat.iTextBits = 0; |
2156 |
current->sStat.ublks = mb_width * mb_height; |
current->sStat.ublks = mb_width * mb_height; |
2296 |
int bits = BitstreamPos(bs); |
int bits = BitstreamPos(bs); |
2297 |
int k = 0, bound = 0, num_slices = pEnc->num_slices; |
int k = 0, bound = 0, num_slices = pEnc->num_slices; |
2298 |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
int num_threads = MAX(1, MIN(pEnc->num_threads, num_slices)); |
2299 |
|
#ifdef HAVE_PTHREAD |
2300 |
void * status = NULL; |
void * status = NULL; |
|
int slices_per_thread = (num_slices*1024 / num_threads); |
|
2301 |
int threads_per_slice = (pEnc->num_threads*1024 / num_threads); |
int threads_per_slice = (pEnc->num_threads*1024 / num_threads); |
2302 |
|
#endif |
2303 |
|
int slices_per_thread = (num_slices*1024 / num_threads); |
2304 |
|
|
2305 |
IMAGE *f_ref = &pEnc->reference->image; |
IMAGE *f_ref = &pEnc->reference->image; |
2306 |
IMAGE *b_ref = &pEnc->current->image; |
IMAGE *b_ref = &pEnc->current->image; |
2324 |
if (!pEnc->reference->is_edged) { |
if (!pEnc->reference->is_edged) { |
2325 |
image_setedges(f_ref, pEnc->mbParam.edged_width, |
image_setedges(f_ref, pEnc->mbParam.edged_width, |
2326 |
pEnc->mbParam.edged_height, pEnc->mbParam.width, |
pEnc->mbParam.edged_height, pEnc->mbParam.width, |
2327 |
pEnc->mbParam.height, 0); |
pEnc->mbParam.height, XVID_BS_VERSION); |
2328 |
pEnc->current->is_edged = 1; |
pEnc->reference->is_edged = 1; |
2329 |
} |
} |
2330 |
|
|
2331 |
if (pEnc->reference->is_interpolated != 0) { |
if (pEnc->reference->is_interpolated != 0) { |
2341 |
if (!pEnc->current->is_edged) { |
if (!pEnc->current->is_edged) { |
2342 |
image_setedges(b_ref, pEnc->mbParam.edged_width, |
image_setedges(b_ref, pEnc->mbParam.edged_width, |
2343 |
pEnc->mbParam.edged_height, pEnc->mbParam.width, |
pEnc->mbParam.edged_height, pEnc->mbParam.width, |
2344 |
pEnc->mbParam.height, 0); |
pEnc->mbParam.height, XVID_BS_VERSION); |
2345 |
pEnc->current->is_edged = 1; |
pEnc->current->is_edged = 1; |
2346 |
} |
} |
2347 |
|
|
2356 |
|
|
2357 |
frame->coding_type = B_VOP; |
frame->coding_type = B_VOP; |
2358 |
|
|
2359 |
if (pEnc->current->vop_flags & XVID_VOP_RD_PSNRHVSM) { |
if ((frame->vop_flags & XVID_VOP_RD_PSNRHVSM) && (frame->vop_flags & XVID_VOP_RD_BVOP)) { |
2360 |
image_block_variance(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->current->mbs, |
image_block_variance(&frame->image, pEnc->mbParam.edged_width, frame->mbs, |
2361 |
pEnc->mbParam.mb_width, pEnc->mbParam.mb_height); |
pEnc->mbParam.mb_width, pEnc->mbParam.mb_height); |
2362 |
} |
} |
2363 |
|
|
2367 |
|
|
2368 |
start_timer(); |
start_timer(); |
2369 |
|
|
2370 |
|
#ifdef HAVE_PTHREAD |
2371 |
if (pEnc->num_threads > 0) { |
if (pEnc->num_threads > 0) { |
2372 |
|
|
2373 |
/* multithreaded motion estimation - dispatch threads */ |
/* multithreaded motion estimation - dispatch threads */ |
2423 |
if (pEnc->smpData[k].minbcode > frame->bcode) |
if (pEnc->smpData[k].minbcode > frame->bcode) |
2424 |
frame->bcode = pEnc->smpData[k].minbcode; |
frame->bcode = pEnc->smpData[k].minbcode; |
2425 |
} |
} |
2426 |
} else { |
} else |
2427 |
|
#endif |
2428 |
|
{ |
2429 |
|
|
2430 |
MotionEstimationBVOP(&pEnc->mbParam, frame, |
MotionEstimationBVOP(&pEnc->mbParam, frame, |
2431 |
((int32_t)(pEnc->current->stamp - frame->stamp)), /* time_bp */ |
((int32_t)(pEnc->current->stamp - frame->stamp)), /* time_bp */ |
2475 |
} |
} |
2476 |
} |
} |
2477 |
|
|
2478 |
|
#ifdef HAVE_PTHREAD |
2479 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
2480 |
pthread_create(&pEnc->smpData[k].handle, NULL, |
pthread_create(&pEnc->smpData[k].handle, NULL, |
2481 |
(void*)SliceCodeB, (void*)&pEnc->smpData[k]); |
(void*)SliceCodeB, (void*)&pEnc->smpData[k]); |
2482 |
} |
} |
2483 |
|
#endif |
2484 |
|
|
2485 |
pEnc->smpData[0].bs = bs; |
pEnc->smpData[0].bs = bs; |
2486 |
pEnc->smpData[0].sStat = &frame->sStat; |
pEnc->smpData[0].sStat = &frame->sStat; |
2487 |
SliceCodeB(&pEnc->smpData[0]); |
SliceCodeB(&pEnc->smpData[0]); |
2488 |
|
|
2489 |
|
#ifdef HAVE_PTHREAD |
2490 |
for (k = 1; k < num_threads; k++) { |
for (k = 1; k < num_threads; k++) { |
2491 |
pthread_join(pEnc->smpData[k].handle, &status); |
pthread_join(pEnc->smpData[k].handle, &status); |
2492 |
} |
} |
2493 |
|
#endif |
2494 |
|
|
2495 |
frame->length = BitstreamLength(bs) - (bits/8); |
frame->length = BitstreamLength(bs) - (bits/8); |
2496 |
|
|