iterator.c revision 5a50414796e9a458925c7a13a15055d02406bf43
15a50414796e9a458925c7a13a15055d02406bf43Vikas Arora// Copyright 2011 Google Inc. All Rights Reserved. 27c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 37c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// This code is licensed under the same terms as WebM: 47c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Software License Agreement: http://www.webmproject.org/license/software/ 57c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 67c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// ----------------------------------------------------------------------------- 77c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 87c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// VP8Iterator: block iterator 97c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 107c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Author: Skal (pascal.massimino@gmail.com) 117c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 127c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#include <string.h> 135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora#include "./vp8enci.h" 157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 177c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroraextern "C" { 187c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#endif 197c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 205a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 217c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// VP8Iterator 225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 237c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 247c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arorastatic void InitLeft(VP8EncIterator* const it) { 257c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const VP8Encoder* const enc = it->enc_; 267c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->y_left_[-1] = enc->u_left_[-1] = enc->v_left_[-1] = 275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora (it->y_ > 0) ? 129 : 127; 287c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(enc->y_left_, 129, 16); 297c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(enc->u_left_, 129, 8); 307c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(enc->v_left_, 129, 8); 317c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->left_nz_[8] = 0; 327c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 337c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 347c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arorastatic void InitTop(VP8EncIterator* const it) { 357c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const VP8Encoder* const enc = it->enc_; 365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const size_t top_size = enc->mb_w_ * 16; 377c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(enc->y_top_, 127, 2 * top_size); 387c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(enc->nz_, 0, enc->mb_w_ * sizeof(*enc->nz_)); 397c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 407c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 417c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorReset(VP8EncIterator* const it) { 427c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora VP8Encoder* const enc = it->enc_; 437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->x_ = 0; 447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->y_ = 0; 457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->y_offset_ = 0; 467c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->uv_offset_ = 0; 477c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_ = enc->mb_info_; 487c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->preds_ = enc->preds_; 497c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->nz_ = enc->nz_; 507c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->bw_ = &enc->parts_[0]; 517c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->done_ = enc->mb_w_* enc->mb_h_; 527c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora InitTop(it); 537c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora InitLeft(it); 547c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(it->bit_count_, 0, sizeof(it->bit_count_)); 557c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->do_trellis_ = 0; 567c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 577c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 587c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorInit(VP8Encoder* const enc, VP8EncIterator* const it) { 597c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->enc_ = enc; 607c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->y_stride_ = enc->pic_->y_stride; 617c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->uv_stride_ = enc->pic_->uv_stride; 627c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // TODO(later): for multithreading, these should be owned by 'it'. 637c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->yuv_in_ = enc->yuv_in_; 647c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->yuv_out_ = enc->yuv_out_; 657c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->yuv_out2_ = enc->yuv_out2_; 667c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->yuv_p_ = enc->yuv_p_; 677c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->lf_stats_ = enc->lf_stats_; 685a50414796e9a458925c7a13a15055d02406bf43Vikas Arora it->percent0_ = enc->percent_; 697c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora VP8IteratorReset(it); 707c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 725a50414796e9a458925c7a13a15055d02406bf43Vikas Aroraint VP8IteratorProgress(const VP8EncIterator* const it, int delta) { 735a50414796e9a458925c7a13a15055d02406bf43Vikas Arora VP8Encoder* const enc = it->enc_; 745a50414796e9a458925c7a13a15055d02406bf43Vikas Arora if (delta && enc->pic_->progress_hook) { 755a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int percent = (enc->mb_h_ <= 1) 765a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ? it->percent0_ 775a50414796e9a458925c7a13a15055d02406bf43Vikas Arora : it->percent0_ + delta * it->y_ / (enc->mb_h_ - 1); 785a50414796e9a458925c7a13a15055d02406bf43Vikas Arora return WebPReportProgress(enc->pic_, percent, &enc->percent_); 795a50414796e9a458925c7a13a15055d02406bf43Vikas Arora } 805a50414796e9a458925c7a13a15055d02406bf43Vikas Arora return 1; 815a50414796e9a458925c7a13a15055d02406bf43Vikas Arora} 825a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 835a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 847c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Import the source samples into the cache. Takes care of replicating 857c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// boundary pixels if necessary. 867c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 875a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void ImportBlock(const uint8_t* src, int src_stride, 885a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* dst, int w, int h, int size) { 895a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int i; 905a50414796e9a458925c7a13a15055d02406bf43Vikas Arora for (i = 0; i < h; ++i) { 915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora memcpy(dst, src, w); 925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora if (w < size) { 935a50414796e9a458925c7a13a15055d02406bf43Vikas Arora memset(dst + w, dst[w - 1], size - w); 945a50414796e9a458925c7a13a15055d02406bf43Vikas Arora } 955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora dst += BPS; 965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora src += src_stride; 975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora } 985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora for (i = h; i < size; ++i) { 995a50414796e9a458925c7a13a15055d02406bf43Vikas Arora memcpy(dst, dst - BPS, size); 1005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora dst += BPS; 1015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora } 1025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora} 1035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 1047c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorImport(const VP8EncIterator* const it) { 1057c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const VP8Encoder* const enc = it->enc_; 1067c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const int x = it->x_, y = it->y_; 1077c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const WebPPicture* const pic = enc->pic_; 1085a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const uint8_t* const ysrc = pic->y + (y * pic->y_stride + x) * 16; 1095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const uint8_t* const usrc = pic->u + (y * pic->uv_stride + x) * 8; 1105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const uint8_t* const vsrc = pic->v + (y * pic->uv_stride + x) * 8; 1115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const ydst = it->yuv_in_ + Y_OFF; 1125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const udst = it->yuv_in_ + U_OFF; 1135a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const vdst = it->yuv_in_ + V_OFF; 1147c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int w = (pic->width - x * 16); 1157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int h = (pic->height - y * 16); 1167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1177c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (w > 16) w = 16; 1187c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (h > 16) h = 16; 1195a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 1207c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Luma plane 1215a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ImportBlock(ysrc, pic->y_stride, ydst, w, h, 16); 1225a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 1235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora { // U/V planes 1245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int uv_w = (w + 1) >> 1; 1255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int uv_h = (h + 1) >> 1; 1265a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ImportBlock(usrc, pic->uv_stride, udst, uv_w, uv_h, 8); 1275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ImportBlock(vsrc, pic->uv_stride, vdst, uv_w, uv_h, 8); 1287c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 1297c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 1307c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 1327c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Copy back the compressed samples into user space if requested. 1337c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1345a50414796e9a458925c7a13a15055d02406bf43Vikas Arorastatic void ExportBlock(const uint8_t* src, uint8_t* dst, int dst_stride, 1355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int w, int h) { 1365a50414796e9a458925c7a13a15055d02406bf43Vikas Arora while (h-- > 0) { 1375a50414796e9a458925c7a13a15055d02406bf43Vikas Arora memcpy(dst, src, w); 1385a50414796e9a458925c7a13a15055d02406bf43Vikas Arora dst += dst_stride; 1395a50414796e9a458925c7a13a15055d02406bf43Vikas Arora src += BPS; 1405a50414796e9a458925c7a13a15055d02406bf43Vikas Arora } 1415a50414796e9a458925c7a13a15055d02406bf43Vikas Arora} 1425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 1437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorExport(const VP8EncIterator* const it) { 1447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const VP8Encoder* const enc = it->enc_; 1457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (enc->config_->show_compressed) { 1467c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const int x = it->x_, y = it->y_; 1477c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const ysrc = it->yuv_out_ + Y_OFF; 1487c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const usrc = it->yuv_out_ + U_OFF; 1497c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const vsrc = it->yuv_out_ + V_OFF; 1507c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const WebPPicture* const pic = enc->pic_; 1515a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const ydst = pic->y + (y * pic->y_stride + x) * 16; 1525a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const udst = pic->u + (y * pic->uv_stride + x) * 8; 1535a50414796e9a458925c7a13a15055d02406bf43Vikas Arora uint8_t* const vdst = pic->v + (y * pic->uv_stride + x) * 8; 1547c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int w = (pic->width - x * 16); 1557c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int h = (pic->height - y * 16); 1567c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1577c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (w > 16) w = 16; 1587c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (h > 16) h = 16; 1597c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1607c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Luma plane 1615a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ExportBlock(ysrc, ydst, pic->y_stride, w, h); 1625a50414796e9a458925c7a13a15055d02406bf43Vikas Arora 1635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora { // U/V planes 1645a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int uv_w = (w + 1) >> 1; 1655a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int uv_h = (h + 1) >> 1; 1665a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ExportBlock(usrc, udst, pic->uv_stride, uv_w, uv_h); 1675a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ExportBlock(vsrc, vdst, pic->uv_stride, uv_w, uv_h); 1687c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 1697c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 1707c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 1717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1725a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 1737c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Non-zero contexts setup/teardown 1747c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1757c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Nz bits: 1767c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 0 1 2 3 Y 1777c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 4 5 6 7 1787c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 8 9 10 11 1797c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 12 13 14 15 1807c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 16 17 U 1817c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 18 19 1827c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 20 21 V 1837c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 22 23 1847c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 24 DC-intra16 1857c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1867c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Convert packed context to byte array 1877c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#define BIT(nz, n) (!!((nz) & (1 << (n)))) 1887c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1897c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorNzToBytes(VP8EncIterator* const it) { 1907c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const int tnz = it->nz_[0], lnz = it->nz_[-1]; 1915a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int* const top_nz = it->top_nz_; 1925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int* const left_nz = it->left_nz_; 1937c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 1947c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Top-Y 1955a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[0] = BIT(tnz, 12); 1965a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[1] = BIT(tnz, 13); 1975a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[2] = BIT(tnz, 14); 1985a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[3] = BIT(tnz, 15); 1997c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Top-U 2005a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[4] = BIT(tnz, 18); 2015a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[5] = BIT(tnz, 19); 2027c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Top-V 2035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[6] = BIT(tnz, 22); 2045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[7] = BIT(tnz, 23); 2057c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // DC 2065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora top_nz[8] = BIT(tnz, 24); 2077c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2087c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // left-Y 2095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[0] = BIT(lnz, 3); 2105a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[1] = BIT(lnz, 7); 2115a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[2] = BIT(lnz, 11); 2125a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[3] = BIT(lnz, 15); 2137c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // left-U 2145a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[4] = BIT(lnz, 17); 2155a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[5] = BIT(lnz, 19); 2167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // left-V 2175a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[6] = BIT(lnz, 21); 2185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora left_nz[7] = BIT(lnz, 23); 2197c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // left-DC is special, iterated separately 2207c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2217c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2227c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorBytesToNz(VP8EncIterator* const it) { 2237c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora uint32_t nz = 0; 2245a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int* const top_nz = it->top_nz_; 2255a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const int* const left_nz = it->left_nz_; 2267c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // top 2275a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (top_nz[0] << 12) | (top_nz[1] << 13); 2285a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (top_nz[2] << 14) | (top_nz[3] << 15); 2295a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (top_nz[4] << 18) | (top_nz[5] << 19); 2305a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (top_nz[6] << 22) | (top_nz[7] << 23); 2315a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (top_nz[8] << 24); // we propagate the _top_ bit, esp. for intra4 2327c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // left 2335a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (left_nz[0] << 3) | (left_nz[1] << 7); 2345a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (left_nz[2] << 11); 2355a50414796e9a458925c7a13a15055d02406bf43Vikas Arora nz |= (left_nz[4] << 17) | (left_nz[6] << 21); 2367c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2377c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora *it->nz_ = nz; 2387c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2397c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2407c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#undef BIT 2417c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2425a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 2437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Advance to the next position, doing the bookeeping. 2447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroraint VP8IteratorNext(VP8EncIterator* const it, 2467c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const block_to_save) { 2477c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora VP8Encoder* const enc = it->enc_; 2487c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (block_to_save) { 2497c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const int x = it->x_, y = it->y_; 2507c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const ysrc = block_to_save + Y_OFF; 2517c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const usrc = block_to_save + U_OFF; 2527c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (x < enc->mb_w_ - 1) { // left 2537c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int i; 2547c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i < 16; ++i) { 2557c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->y_left_[i] = ysrc[15 + i * BPS]; 2567c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2577c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i < 8; ++i) { 2587c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->u_left_[i] = usrc[7 + i * BPS]; 2597c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->v_left_[i] = usrc[15 + i * BPS]; 2607c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2617c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // top-left (before 'top'!) 2627c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->y_left_[-1] = enc->y_top_[x * 16 + 15]; 2637c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->u_left_[-1] = enc->uv_top_[x * 16 + 0 + 7]; 2647c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora enc->v_left_[-1] = enc->uv_top_[x * 16 + 8 + 7]; 2657c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2667c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (y < enc->mb_h_ - 1) { // top 2677c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memcpy(enc->y_top_ + x * 16, ysrc + 15 * BPS, 16); 2687c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memcpy(enc->uv_top_ + x * 16, usrc + 7 * BPS, 8 + 8); 2697c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2707c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2727c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_++; 2737c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->preds_ += 4; 2747c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->nz_++; 2757c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->x_++; 2767c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (it->x_ == enc->mb_w_) { 2777c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->x_ = 0; 2787c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->y_++; 2797c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->bw_ = &enc->parts_[it->y_ & (enc->num_parts_ - 1)]; 2807c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->preds_ = enc->preds_ + it->y_ * 4 * enc->preds_w_; 2817c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->nz_ = enc->nz_; 2827c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora InitLeft(it); 2837c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2847c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return (0 < --it->done_); 2857c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2867c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2875a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 2887c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Helper function to set mode properties 2897c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 2907c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8SetIntra16Mode(const VP8EncIterator* const it, int mode) { 2917c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora uint8_t* preds = it->preds_; 2925a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int y; 2937c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (y = 0; y < 4; ++y) { 2947c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora memset(preds, mode, 4); 2957c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora preds += it->enc_->preds_w_; 2967c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 2977c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_->type_ = 1; 2987c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 2997c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3005a50414796e9a458925c7a13a15055d02406bf43Vikas Aroravoid VP8SetIntra4Mode(const VP8EncIterator* const it, const uint8_t* modes) { 3017c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora uint8_t* preds = it->preds_; 3025a50414796e9a458925c7a13a15055d02406bf43Vikas Arora int y; 3035a50414796e9a458925c7a13a15055d02406bf43Vikas Arora for (y = 4; y > 0; --y) { 3045a50414796e9a458925c7a13a15055d02406bf43Vikas Arora memcpy(preds, modes, 4 * sizeof(*modes)); 3057c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora preds += it->enc_->preds_w_; 3065a50414796e9a458925c7a13a15055d02406bf43Vikas Arora modes += 4; 3077c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3087c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_->type_ = 0; 3097c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 3107c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3117c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8SetIntraUVMode(const VP8EncIterator* const it, int mode) { 3127c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_->uv_mode_ = mode; 3137c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 3147c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8SetSkip(const VP8EncIterator* const it, int skip) { 3167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_->skip_ = skip; 3177c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 3187c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3197c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8SetSegment(const VP8EncIterator* const it, int segment) { 3207c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->mb_->segment_ = segment; 3217c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 3227c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3235a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 3247c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Intra4x4 sub-blocks iteration 3257c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 3267c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// We store and update the boundary samples into an array of 37 pixels. They 3277c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// are updated as we iterate and reconstructs each intra4x4 blocks in turn. 3287c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// The position of the samples has the following snake pattern: 3297c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 3307c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 16|17 18 19 20|21 22 23 24|25 26 27 28|29 30 31 32|33 34 35 36 <- Top-right 3317c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// --+-----------+-----------+-----------+-----------+ 3327c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 15| 19| 23| 27| 31| 3337c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 14| 18| 22| 26| 30| 3347c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 13| 17| 21| 25| 29| 3357c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 12|13 14 15 16|17 18 19 20|21 22 23 24|25 26 27 28| 3367c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// --+-----------+-----------+-----------+-----------+ 3377c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 11| 15| 19| 23| 27| 3387c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 10| 14| 18| 22| 26| 3397c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 9| 13| 17| 21| 25| 3407c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 8| 9 10 11 12|13 14 15 16|17 18 19 20|21 22 23 24| 3417c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// --+-----------+-----------+-----------+-----------+ 3427c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 7| 11| 15| 19| 23| 3437c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 6| 10| 14| 18| 22| 3447c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 5| 9| 13| 17| 21| 3457c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 4| 5 6 7 8| 9 10 11 12|13 14 15 16|17 18 19 20| 3467c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// --+-----------+-----------+-----------+-----------+ 3477c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 3| 7| 11| 15| 19| 3487c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 2| 6| 10| 14| 18| 3497c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 1| 5| 9| 13| 17| 3507c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// 0| 1 2 3 4| 5 6 7 8| 9 10 11 12|13 14 15 16| 3517c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// --+-----------+-----------+-----------+-----------+ 3527c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3537c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// Array to record the position of the top sample to pass to the prediction 3547c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora// functions in dsp.c. 3557c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arorastatic const uint8_t VP8TopLeftI4[16] = { 3567c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 17, 21, 25, 29, 3577c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 13, 17, 21, 25, 3587c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 9, 13, 17, 21, 3597c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 5, 9, 13, 17 3607c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora}; 3617c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3627c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroravoid VP8IteratorStartI4(VP8EncIterator* const it) { 3635a50414796e9a458925c7a13a15055d02406bf43Vikas Arora const VP8Encoder* const enc = it->enc_; 3647c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int i; 3657c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3667c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_ = 0; // first 4x4 sub-block 3677c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[0]; 3687c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3697c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Import the boundary samples 3707c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i < 17; ++i) { // left 3717c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_boundary_[i] = enc->y_left_[15 - i]; 3727c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3737c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i < 16; ++i) { // top 3747c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i]; 3757c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3767c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // top-right samples have a special case on the far right of the picture 3777c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (it->x_ < enc->mb_w_ - 1) { 3787c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 16; i < 16 + 4; ++i) { 3797c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_boundary_[17 + i] = enc->y_top_[it->x_ * 16 + i]; 3807c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3817c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } else { // else, replicate the last valid pixel four times 3827c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 16; i < 16 + 4; ++i) { 3837c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_boundary_[17 + i] = it->i4_boundary_[17 + 15]; 3847c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3857c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3867c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora VP8IteratorNzToBytes(it); // import the non-zero context 3877c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 3887c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3897c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Aroraint VP8IteratorRotateI4(VP8EncIterator* const it, 3907c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const yuv_out) { 3917c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora const uint8_t* const blk = yuv_out + VP8Scan[it->i4_]; 3927c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora uint8_t* const top = it->i4_top_; 3937c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora int i; 3947c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 3957c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // Update the cache with 7 fresh samples 3967c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i <= 3; ++i) { 3977c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora top[-4 + i] = blk[i + 3 * BPS]; // store future top samples 3987c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 3997c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if ((it->i4_ & 3) != 3) { // if not on the right sub-blocks #3, #7, #11, #15 4007c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i <= 2; ++i) { // store future left samples 4017c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora top[i] = blk[3 + (2 - i) * BPS]; 4027c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 4037c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } else { // else replicate top-right samples, as says the specs. 4047c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora for (i = 0; i <= 3; ++i) { 4057c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora top[i] = top[i + 4]; 4067c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 4077c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 4087c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora // move pointers to next sub-block 4095a50414796e9a458925c7a13a15055d02406bf43Vikas Arora ++it->i4_; 4107c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora if (it->i4_ == 16) { // we're done 4117c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 0; 4127c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora } 4137c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 4147c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora it->i4_top_ = it->i4_boundary_ + VP8TopLeftI4[it->i4_]; 4157c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora return 1; 4167c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} 4177c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 4185a50414796e9a458925c7a13a15055d02406bf43Vikas Arora//------------------------------------------------------------------------------ 4197c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora 4207c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#if defined(__cplusplus) || defined(c_plusplus) 4217c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora} // extern "C" 4227c970a0a679089e416c5887cf7fcece15a70bfa4Vikas Arora#endif 423