1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840 |
- #include <stdlib.h>
- #include <string.h>
- #include "encint.h"
- #include "dequant.h"
- static const int OC_VP31_RANGE_SIZES[1]={63};
- static const th_quant_base OC_VP31_BASES_INTRA_Y[2]={
- {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 58, 68,109,103, 77,
- 24, 35, 55, 64, 81,104,113, 92,
- 49, 64, 78, 87,103,121,120,101,
- 72, 92, 95, 98,112,100,103, 99
- },
- {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 58, 68,109,103, 77,
- 24, 35, 55, 64, 81,104,113, 92,
- 49, 64, 78, 87,103,121,120,101,
- 72, 92, 95, 98,112,100,103, 99
- }
- };
- static const th_quant_base OC_VP31_BASES_INTRA_C[2]={
- {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- },
- {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- }
- };
- static const th_quant_base OC_VP31_BASES_INTER[2]={
- {
- 16, 16, 16, 20, 24, 28, 32, 40,
- 16, 16, 20, 24, 28, 32, 40, 48,
- 16, 20, 24, 28, 32, 40, 48, 64,
- 20, 24, 28, 32, 40, 48, 64, 64,
- 24, 28, 32, 40, 48, 64, 64, 64,
- 28, 32, 40, 48, 64, 64, 64, 96,
- 32, 40, 48, 64, 64, 64, 96,128,
- 40, 48, 64, 64, 64, 96,128,128
- },
- {
- 16, 16, 16, 20, 24, 28, 32, 40,
- 16, 16, 20, 24, 28, 32, 40, 48,
- 16, 20, 24, 28, 32, 40, 48, 64,
- 20, 24, 28, 32, 40, 48, 64, 64,
- 24, 28, 32, 40, 48, 64, 64, 64,
- 28, 32, 40, 48, 64, 64, 64, 96,
- 32, 40, 48, 64, 64, 64, 96,128,
- 40, 48, 64, 64, 64, 96,128,128
- }
- };
- const th_quant_info TH_VP31_QUANT_INFO={
- {
- 220,200,190,180,170,170,160,160,
- 150,150,140,140,130,130,120,120,
- 110,110,100,100, 90, 90, 90, 80,
- 80, 80, 70, 70, 70, 60, 60, 60,
- 60, 50, 50, 50, 50, 40, 40, 40,
- 40, 40, 30, 30, 30, 30, 30, 30,
- 30, 20, 20, 20, 20, 20, 20, 20,
- 20, 10, 10, 10, 10, 10, 10, 10
- },
- {
- 500,450,400,370,340,310,285,265,
- 245,225,210,195,185,180,170,160,
- 150,145,135,130,125,115,110,107,
- 100, 96, 93, 89, 85, 82, 75, 74,
- 70, 68, 64, 60, 57, 56, 52, 50,
- 49, 45, 44, 43, 40, 38, 37, 35,
- 33, 32, 30, 29, 28, 25, 24, 22,
- 21, 19, 18, 17, 15, 13, 12, 10
- },
- {
- 30,25,20,20,15,15,14,14,
- 13,13,12,12,11,11,10,10,
- 9, 9, 8, 8, 7, 7, 7, 7,
- 6, 6, 6, 6, 5, 5, 5, 5,
- 4, 4, 4, 4, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- {
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_Y},
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C},
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTRA_C}
- },
- {
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER},
- {1,OC_VP31_RANGE_SIZES,OC_VP31_BASES_INTER}
- }
- }
- };
- static const int OC_DEF_QRANGE_SIZES[3]={32,16,15};
- static const th_quant_base OC_DEF_BASES_INTRA_Y[4]={
- {
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- },
- {
- 15, 12, 12, 15, 18, 20, 20, 21,
- 13, 13, 14, 17, 18, 21, 21, 20,
- 14, 14, 15, 18, 20, 21, 21, 21,
- 14, 16, 17, 19, 20, 21, 21, 21,
- 16, 17, 20, 21, 21, 21, 21, 21,
- 18, 19, 20, 21, 21, 21, 21, 21,
- 20, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21
- },
- {
- 16, 12, 11, 16, 20, 25, 27, 28,
- 13, 13, 14, 18, 21, 28, 28, 27,
- 14, 13, 16, 20, 25, 28, 28, 28,
- 14, 16, 19, 22, 27, 29, 29, 28,
- 17, 19, 25, 28, 28, 30, 30, 29,
- 20, 24, 27, 28, 29, 30, 30, 29,
- 27, 28, 29, 29, 30, 30, 30, 30,
- 29, 29, 29, 29, 30, 30, 30, 29
- },
- {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 58, 68,109,103, 77,
- 24, 35, 55, 64, 81,104,113, 92,
- 49, 64, 78, 87,103,121,120,101,
- 72, 92, 95, 98,112,100,103, 99
- }
- };
- static const th_quant_base OC_DEF_BASES_INTRA_C[4]={
- {
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19
- },
- {
- 18, 18, 21, 25, 26, 26, 26, 26,
- 18, 20, 22, 26, 26, 26, 26, 26,
- 21, 22, 25, 26, 26, 26, 26, 26,
- 25, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26,
- 26, 26, 26, 26, 26, 26, 26, 26
- },
- {
- 17, 18, 22, 31, 36, 36, 36, 36,
- 18, 20, 24, 34, 36, 36, 36, 36,
- 22, 24, 33, 36, 36, 36, 36, 36,
- 31, 34, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 36, 36, 36, 36
- },
- {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
- }
- };
- static const th_quant_base OC_DEF_BASES_INTER[4]={
- {
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21
- },
- {
- 18, 18, 18, 21, 23, 24, 25, 27,
- 18, 18, 21, 23, 24, 25, 27, 28,
- 18, 21, 23, 24, 25, 27, 28, 29,
- 21, 23, 24, 25, 27, 28, 29, 29,
- 23, 24, 25, 27, 28, 29, 29, 29,
- 24, 25, 27, 28, 29, 29, 29, 30,
- 25, 27, 28, 29, 29, 29, 30, 30,
- 27, 28, 29, 29, 29, 30, 30, 30
- },
- {
- 17, 17, 17, 20, 23, 26, 28, 32,
- 17, 17, 20, 23, 26, 28, 32, 34,
- 17, 20, 23, 26, 28, 32, 34, 37,
- 20, 23, 26, 28, 32, 34, 37, 37,
- 23, 26, 28, 32, 34, 37, 37, 37,
- 26, 28, 32, 34, 37, 37, 37, 41,
- 28, 32, 34, 37, 37, 37, 41, 42,
- 32, 34, 37, 37, 37, 41, 42, 42
- },
- {
- 16, 16, 16, 20, 24, 28, 32, 40,
- 16, 16, 20, 24, 28, 32, 40, 48,
- 16, 20, 24, 28, 32, 40, 48, 64,
- 20, 24, 28, 32, 40, 48, 64, 64,
- 24, 28, 32, 40, 48, 64, 64, 64,
- 28, 32, 40, 48, 64, 64, 64, 96,
- 32, 40, 48, 64, 64, 64, 96,128,
- 40, 48, 64, 64, 64, 96,128,128
- }
- };
- const th_quant_info TH_DEF_QUANT_INFO={
- {
- 365,348,333,316,300,287,277,265,
- 252,240,229,219,206,197,189,180,
- 171,168,160,153,146,139,132,127,
- 121,115,110,107,101, 97, 94, 89,
- 85, 83, 78, 73, 72, 67, 66, 62,
- 60, 59, 56, 53, 52, 48, 47, 43,
- 42, 40, 36, 35, 34, 33, 31, 30,
- 28, 25, 24, 22, 20, 17, 14, 10
- },
- {
- 365,348,333,316,300,287,277,265,
- 252,240,229,219,206,197,189,180,
- 171,168,160,153,146,139,132,127,
- 121,115,110,107,101, 97, 94, 89,
- 85, 83, 78, 73, 72, 67, 66, 62,
- 60, 59, 56, 53, 52, 48, 47, 43,
- 42, 40, 36, 35, 34, 33, 31, 30,
- 28, 25, 24, 22, 20, 17, 14, 10
- },
- {
- 15,12, 9, 8, 6, 6, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 4, 4, 4, 4, 4, 4, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- {
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_Y},
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_C},
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTRA_C}
- },
- {
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER},
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER},
- {3,OC_DEF_QRANGE_SIZES,OC_DEF_BASES_INTER}
- }
- }
- };
- const unsigned char OC_MODE_BITS[2][OC_NMODES]={
-
- {1,2,3,4,5,6,7,7},
-
- {3,3,3,3,3,3,3,3}
- };
- static const unsigned char OC_MODE_CODES[2][OC_NMODES]={
-
- {0x00,0x02,0x06,0x0E,0x1E,0x3E,0x7E,0x7F},
-
- {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07}
- };
- const unsigned char OC_MV_BITS[2][64]={
-
- {
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
- 8,7,7,7,7,7,7,7,7,6,6,6,6,4,4,3,
- 3,
- 3,4,4,6,6,6,6,7,7,7,7,7,7,7,7,8,
- 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
- },
-
- {
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6
- }
- };
- static const unsigned char OC_MV_CODES[2][64]={
-
- {
- 0xFF,0xFD,0xFB,0xF9,0xF7,0xF5,0xF3,
- 0xF1,0xEF,0xED,0xEB,0xE9,0xE7,0xE5,0xE3,
- 0xE1,0x6F,0x6D,0x6B,0x69,0x67,0x65,0x63,
- 0x61,0x2F,0x2D,0x2B,0x29,0x09,0x07,0x02,
- 0x00,
- 0x01,0x06,0x08,0x28,0x2A,0x2C,0x2E,0x60,
- 0x62,0x64,0x66,0x68,0x6A,0x6C,0x6E,0xE0,
- 0xE2,0xE4,0xE6,0xE8,0xEA,0xEC,0xEE,0xF0,
- 0xF2,0xF4,0xF6,0xF8,0xFA,0xFC,0xFE
- },
-
- {
- 0x3F,0x3D,0x3B,0x39,0x37,0x35,0x33,
- 0x31,0x2F,0x2D,0x2B,0x29,0x27,0x25,0x23,
- 0x21,0x1F,0x1D,0x1B,0x19,0x17,0x15,0x13,
- 0x11,0x0F,0x0D,0x0B,0x09,0x07,0x05,0x03,
- 0x00,
- 0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,0x10,
- 0x12,0x14,0x16,0x18,0x1A,0x1C,0x1E,0x20,
- 0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E,0x30,
- 0x32,0x34,0x36,0x38,0x3A,0x3C,0x3E
- }
- };
- const ogg_uint16_t OC_SB_RUN_VAL_MIN[8]={1,2,4,6,10,18,34,4130};
- static const unsigned OC_SB_RUN_CODE_PREFIX[7]={
- 0,4,0xC,0x38,0xF0,0x3E0,0x3F000
- };
- const unsigned char OC_SB_RUN_CODE_NBITS[7]={1,3,4,6,8,10,18};
- static void oc_sb_run_pack(oggpack_buffer *_opb,ptrdiff_t _run_count,
- int _flag,int _done){
- int i;
- if(_run_count>=4129){
- do{
- oggpackB_write(_opb,0x3FFFF,18);
- _run_count-=4129;
- if(_run_count>0)oggpackB_write(_opb,_flag,1);
- else if(!_done)oggpackB_write(_opb,!_flag,1);
- }
- while(_run_count>=4129);
- if(_run_count<=0)return;
- }
- for(i=0;_run_count>=OC_SB_RUN_VAL_MIN[i+1];i++);
- oggpackB_write(_opb,OC_SB_RUN_CODE_PREFIX[i]+_run_count-OC_SB_RUN_VAL_MIN[i],
- OC_SB_RUN_CODE_NBITS[i]);
- }
- const unsigned char OC_BLOCK_RUN_CODE_NBITS[30]={
- 2,2,3,3,4,4,6,6,6,6,7,7,7,7,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9
- };
- static const ogg_uint16_t OC_BLOCK_RUN_CODE_PATTERN[30]={
- 0x000,0x001,0x004,0x005,0x00C,0x00D,0x038,
- 0x039,0x03A,0x03B,0x078,0x079,0x07A,0x07B,0x1F0,
- 0x1F1,0x1F2,0x1F3,0x1F4,0x1F5,0x1F6,0x1F7,0x1F8,
- 0x1F9,0x1FA,0x1FB,0x1FC,0x1FD,0x1FE,0x1FF
- };
- static void oc_block_run_pack(oggpack_buffer *_opb,int _run_count){
- oggpackB_write(_opb,OC_BLOCK_RUN_CODE_PATTERN[_run_count-1],
- OC_BLOCK_RUN_CODE_NBITS[_run_count-1]);
- }
- static void oc_enc_frame_header_pack(oc_enc_ctx *_enc){
-
- oggpackB_write(&_enc->opb,0,1);
-
- oggpackB_write(&_enc->opb,_enc->state.frame_type,1);
-
- oggpackB_write(&_enc->opb,_enc->state.qis[0],6);
- if(_enc->state.nqis>1){
- oggpackB_write(&_enc->opb,1,1);
- oggpackB_write(&_enc->opb,_enc->state.qis[1],6);
- if(_enc->state.nqis>2){
- oggpackB_write(&_enc->opb,1,1);
- oggpackB_write(&_enc->opb,_enc->state.qis[2],6);
- }
- else oggpackB_write(&_enc->opb,0,1);
- }
- else oggpackB_write(&_enc->opb,0,1);
- if(_enc->state.frame_type==OC_INTRA_FRAME){
-
- oggpackB_write(&_enc->opb,0,3);
- }
- }
- static unsigned oc_enc_partial_sb_flags_pack(oc_enc_ctx *_enc){
- const oc_sb_flags *sb_flags;
- unsigned nsbs;
- unsigned sbi;
- unsigned npartial;
- int flag;
- sb_flags=_enc->state.sb_flags;
- nsbs=_enc->state.nsbs;
- flag=sb_flags[0].coded_partially;
- oggpackB_write(&_enc->opb,flag,1);
- sbi=npartial=0;
- do{
- unsigned run_count;
- for(run_count=0;sbi<nsbs;sbi++){
- if(sb_flags[sbi].coded_partially!=flag)break;
- run_count++;
- npartial+=flag;
- }
- oc_sb_run_pack(&_enc->opb,run_count,flag,sbi>=nsbs);
- flag=!flag;
- }
- while(sbi<nsbs);
- return npartial;
- }
- static void oc_enc_coded_sb_flags_pack(oc_enc_ctx *_enc){
- const oc_sb_flags *sb_flags;
- unsigned nsbs;
- unsigned sbi;
- int flag;
- sb_flags=_enc->state.sb_flags;
- nsbs=_enc->state.nsbs;
-
- for(sbi=0;sb_flags[sbi].coded_partially;sbi++);
- flag=sb_flags[sbi].coded_fully;
- oggpackB_write(&_enc->opb,flag,1);
- do{
- unsigned run_count;
- for(run_count=0;sbi<nsbs;sbi++){
- if(sb_flags[sbi].coded_partially)continue;
- if(sb_flags[sbi].coded_fully!=flag)break;
- run_count++;
- }
- oc_sb_run_pack(&_enc->opb,run_count,flag,sbi>=nsbs);
- flag=!flag;
- }
- while(sbi<nsbs);
- }
- static void oc_enc_coded_flags_pack(oc_enc_ctx *_enc){
- const oc_sb_map *sb_maps;
- const oc_sb_flags *sb_flags;
- unsigned nsbs;
- const oc_fragment *frags;
- unsigned npartial;
- int run_count;
- int flag;
- int pli;
- unsigned sbi;
- npartial=oc_enc_partial_sb_flags_pack(_enc);
- if(npartial<_enc->state.nsbs)oc_enc_coded_sb_flags_pack(_enc);
- sb_maps=(const oc_sb_map *)_enc->state.sb_maps;
- sb_flags=_enc->state.sb_flags;
- nsbs=_enc->state.nsbs;
- frags=_enc->state.frags;
- for(sbi=0;sbi<nsbs&&!sb_flags[sbi].coded_partially;sbi++);
-
- if(sbi<nsbs){
- flag=frags[sb_maps[sbi][0][0]].coded;
- oggpackB_write(&_enc->opb,flag,1);
- run_count=0;
- nsbs=sbi=0;
- for(pli=0;pli<3;pli++){
- nsbs+=_enc->state.fplanes[pli].nsbs;
- for(;sbi<nsbs;sbi++){
- int quadi;
- int bi;
- ptrdiff_t fragi;
- if(sb_flags[sbi].coded_partially){
- for(quadi=0;quadi<4;quadi++){
- for(bi=0;bi<4;bi++){
- fragi=sb_maps[sbi][quadi][bi];
- if(fragi>=0){
- if(frags[fragi].coded!=flag){
- oc_block_run_pack(&_enc->opb,run_count);
- flag=!flag;
- run_count=1;
- }
- else run_count++;
- }
- }
- }
- }
- }
- }
-
- if(run_count>0)oc_block_run_pack(&_enc->opb,run_count);
- }
- }
- static void oc_enc_mb_modes_pack(oc_enc_ctx *_enc){
- const unsigned char *mode_codes;
- const unsigned char *mode_bits;
- const unsigned char *mode_ranks;
- unsigned *coded_mbis;
- size_t ncoded_mbis;
- const signed char *mb_modes;
- unsigned mbii;
- int scheme;
- int mb_mode;
- scheme=_enc->chooser.scheme_list[0];
-
- oggpackB_write(&_enc->opb,scheme,3);
-
- if(scheme==0){
- for(mb_mode=0;mb_mode<OC_NMODES;mb_mode++){
- oggpackB_write(&_enc->opb,_enc->chooser.scheme0_ranks[mb_mode],3);
- }
- }
- mode_ranks=_enc->chooser.mode_ranks[scheme];
- mode_bits=OC_MODE_BITS[scheme+1>>3];
- mode_codes=OC_MODE_CODES[scheme+1>>3];
- coded_mbis=_enc->coded_mbis;
- ncoded_mbis=_enc->ncoded_mbis;
- mb_modes=_enc->state.mb_modes;
- for(mbii=0;mbii<ncoded_mbis;mbii++){
- int rank;
- rank=mode_ranks[mb_modes[coded_mbis[mbii]]];
- oggpackB_write(&_enc->opb,mode_codes[rank],mode_bits[rank]);
- }
- }
- static void oc_enc_mv_pack(oc_enc_ctx *_enc,int _mv_scheme,oc_mv _mv){
- int dx;
- int dy;
- dx=OC_MV_X(_mv);
- dy=OC_MV_Y(_mv);
- oggpackB_write(&_enc->opb,
- OC_MV_CODES[_mv_scheme][dx+31],OC_MV_BITS[_mv_scheme][dx+31]);
- oggpackB_write(&_enc->opb,
- OC_MV_CODES[_mv_scheme][dy+31],OC_MV_BITS[_mv_scheme][dy+31]);
- }
- static void oc_enc_mvs_pack(oc_enc_ctx *_enc){
- const unsigned *coded_mbis;
- size_t ncoded_mbis;
- const oc_mb_map *mb_maps;
- const signed char *mb_modes;
- const oc_fragment *frags;
- const oc_mv *frag_mvs;
- unsigned mbii;
- int mv_scheme;
-
- mv_scheme=_enc->mv_bits[1]<_enc->mv_bits[0];
- oggpackB_write(&_enc->opb,mv_scheme,1);
-
- coded_mbis=_enc->coded_mbis;
- ncoded_mbis=_enc->ncoded_mbis;
- mb_modes=_enc->state.mb_modes;
- mb_maps=(const oc_mb_map *)_enc->state.mb_maps;
- frags=_enc->state.frags;
- frag_mvs=_enc->state.frag_mvs;
- for(mbii=0;mbii<ncoded_mbis;mbii++){
- ptrdiff_t fragi;
- unsigned mbi;
- int bi;
- mbi=coded_mbis[mbii];
- switch(mb_modes[mbi]){
- case OC_MODE_INTER_MV:
- case OC_MODE_GOLDEN_MV:{
- for(bi=0;;bi++){
- fragi=mb_maps[mbi][0][bi];
- if(frags[fragi].coded){
- oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]);
-
- break;
- }
- }
- }break;
- case OC_MODE_INTER_MV_FOUR:{
- for(bi=0;bi<4;bi++){
- fragi=mb_maps[mbi][0][bi];
- if(frags[fragi].coded){
- oc_enc_mv_pack(_enc,mv_scheme,frag_mvs[fragi]);
-
- }
- }
- }break;
- }
- }
- }
- static void oc_enc_block_qis_pack(oc_enc_ctx *_enc){
- const oc_fragment *frags;
- ptrdiff_t *coded_fragis;
- ptrdiff_t ncoded_fragis;
- ptrdiff_t fragii;
- ptrdiff_t run_count;
- ptrdiff_t nqi0;
- int flag;
- if(_enc->state.nqis<=1)return;
- ncoded_fragis=_enc->state.ntotal_coded_fragis;
- if(ncoded_fragis<=0)return;
- coded_fragis=_enc->state.coded_fragis;
- frags=_enc->state.frags;
- flag=!!frags[coded_fragis[0]].qii;
- oggpackB_write(&_enc->opb,flag,1);
- nqi0=0;
- for(fragii=0;fragii<ncoded_fragis;){
- for(run_count=0;fragii<ncoded_fragis;fragii++){
- if(!!frags[coded_fragis[fragii]].qii!=flag)break;
- run_count++;
- nqi0+=!flag;
- }
- oc_sb_run_pack(&_enc->opb,run_count,flag,fragii>=ncoded_fragis);
- flag=!flag;
- }
- if(_enc->state.nqis<3||nqi0>=ncoded_fragis)return;
- for(fragii=0;!frags[coded_fragis[fragii]].qii;fragii++);
- flag=frags[coded_fragis[fragii]].qii-1;
- oggpackB_write(&_enc->opb,flag,1);
- while(fragii<ncoded_fragis){
- for(run_count=0;fragii<ncoded_fragis;fragii++){
- int qii;
- qii=frags[coded_fragis[fragii]].qii;
- if(!qii)continue;
- if(qii-1!=flag)break;
- run_count++;
- }
- oc_sb_run_pack(&_enc->opb,run_count,flag,fragii>=ncoded_fragis);
- flag=!flag;
- }
- }
- static void oc_enc_count_tokens(oc_enc_ctx *_enc,int _zzi_start,int _zzi_end,
- ptrdiff_t _token_counts_y[32],ptrdiff_t _token_counts_c[32]){
- const unsigned char *dct_tokens;
- ptrdiff_t ndct_tokens;
- int pli;
- int zzi;
- ptrdiff_t ti;
- memset(_token_counts_y,0,32*sizeof(*_token_counts_y));
- memset(_token_counts_c,0,32*sizeof(*_token_counts_c));
- for(zzi=_zzi_start;zzi<_zzi_end;zzi++){
- dct_tokens=_enc->dct_tokens[0][zzi];
- ndct_tokens=_enc->ndct_tokens[0][zzi];
- for(ti=_enc->dct_token_offs[0][zzi];ti<ndct_tokens;ti++){
- _token_counts_y[dct_tokens[ti]]++;
- }
- }
- for(pli=1;pli<3;pli++){
- for(zzi=_zzi_start;zzi<_zzi_end;zzi++){
- dct_tokens=_enc->dct_tokens[pli][zzi];
- ndct_tokens=_enc->ndct_tokens[pli][zzi];
- for(ti=_enc->dct_token_offs[pli][zzi];ti<ndct_tokens;ti++){
- _token_counts_c[dct_tokens[ti]]++;
- }
- }
- }
- }
- static void oc_enc_count_bits(oc_enc_ctx *_enc,int _hgi,
- const ptrdiff_t _token_counts[32],size_t _bit_counts[16]){
- int huffi;
- int huff_offs;
- int token;
- huff_offs=_hgi<<4;
- for(huffi=0;huffi<16;huffi++){
- for(token=0;token<32;token++){
- _bit_counts[huffi]+=
- _token_counts[token]*_enc->huff_codes[huffi+huff_offs][token].nbits;
- }
- }
- }
- static int oc_select_huff_idx(size_t _bit_counts[16]){
- int best_huffi;
- int huffi;
- best_huffi=0;
- for(huffi=1;huffi<16;huffi++)if(_bit_counts[huffi]<_bit_counts[best_huffi]){
- best_huffi=huffi;
- }
- return best_huffi;
- }
- static void oc_enc_huff_group_pack(oc_enc_ctx *_enc,
- int _zzi_start,int _zzi_end,const int _huff_idxs[2]){
- int zzi;
- for(zzi=_zzi_start;zzi<_zzi_end;zzi++){
- int pli;
- for(pli=0;pli<3;pli++){
- const unsigned char *dct_tokens;
- const ogg_uint16_t *extra_bits;
- ptrdiff_t ndct_tokens;
- const th_huff_code *huff_codes;
- ptrdiff_t ti;
- dct_tokens=_enc->dct_tokens[pli][zzi];
- extra_bits=_enc->extra_bits[pli][zzi];
- ndct_tokens=_enc->ndct_tokens[pli][zzi];
- huff_codes=_enc->huff_codes[_huff_idxs[pli+1>>1]];
- for(ti=_enc->dct_token_offs[pli][zzi];ti<ndct_tokens;ti++){
- int token;
- int neb;
- token=dct_tokens[ti];
- oggpackB_write(&_enc->opb,huff_codes[token].pattern,
- huff_codes[token].nbits);
- neb=OC_DCT_TOKEN_EXTRA_BITS[token];
- if(neb)oggpackB_write(&_enc->opb,extra_bits[ti],neb);
- }
- }
- }
- }
- static void oc_enc_residual_tokens_pack(oc_enc_ctx *_enc){
- static const unsigned char OC_HUFF_GROUP_MIN[6]={0,1,6,15,28,64};
- static const unsigned char *OC_HUFF_GROUP_MAX=OC_HUFF_GROUP_MIN+1;
- ptrdiff_t token_counts_y[32];
- ptrdiff_t token_counts_c[32];
- size_t bits_y[16];
- size_t bits_c[16];
- int huff_idxs[2];
- int frame_type;
- int hgi;
- frame_type=_enc->state.frame_type;
-
- oc_enc_count_tokens(_enc,0,1,token_counts_y,token_counts_c);
- memset(bits_y,0,sizeof(bits_y));
- memset(bits_c,0,sizeof(bits_c));
- oc_enc_count_bits(_enc,0,token_counts_y,bits_y);
- oc_enc_count_bits(_enc,0,token_counts_c,bits_c);
- huff_idxs[0]=oc_select_huff_idx(bits_y);
- huff_idxs[1]=oc_select_huff_idx(bits_c);
-
- oggpackB_write(&_enc->opb,huff_idxs[0],4);
- oggpackB_write(&_enc->opb,huff_idxs[1],4);
- _enc->huff_idxs[frame_type][0][0]=(unsigned char)huff_idxs[0];
- _enc->huff_idxs[frame_type][0][1]=(unsigned char)huff_idxs[1];
- oc_enc_huff_group_pack(_enc,0,1,huff_idxs);
-
- memset(bits_y,0,sizeof(bits_y));
- memset(bits_c,0,sizeof(bits_c));
- for(hgi=1;hgi<5;hgi++){
- oc_enc_count_tokens(_enc,OC_HUFF_GROUP_MIN[hgi],OC_HUFF_GROUP_MAX[hgi],
- token_counts_y,token_counts_c);
- oc_enc_count_bits(_enc,hgi,token_counts_y,bits_y);
- oc_enc_count_bits(_enc,hgi,token_counts_c,bits_c);
- }
- huff_idxs[0]=oc_select_huff_idx(bits_y);
- huff_idxs[1]=oc_select_huff_idx(bits_c);
-
- oggpackB_write(&_enc->opb,huff_idxs[0],4);
- oggpackB_write(&_enc->opb,huff_idxs[1],4);
- _enc->huff_idxs[frame_type][1][0]=(unsigned char)huff_idxs[0];
- _enc->huff_idxs[frame_type][1][1]=(unsigned char)huff_idxs[1];
- for(hgi=1;hgi<5;hgi++){
- huff_idxs[0]+=16;
- huff_idxs[1]+=16;
- oc_enc_huff_group_pack(_enc,
- OC_HUFF_GROUP_MIN[hgi],OC_HUFF_GROUP_MAX[hgi],huff_idxs);
- }
- }
- static void oc_enc_drop_frame_pack(oc_enc_ctx *_enc){
- unsigned nsbs;
-
- oggpackB_write(&_enc->opb,0,1);
-
- oggpackB_write(&_enc->opb,OC_INTER_FRAME,1);
-
- oggpackB_write(&_enc->opb,_enc->state.qis[0],6);
- oggpackB_write(&_enc->opb,0,1);
-
- nsbs=_enc->state.nsbs;
-
- oggpackB_write(&_enc->opb,0,1);
- oc_sb_run_pack(&_enc->opb,nsbs,0,1);
-
- oggpackB_write(&_enc->opb,0,1);
- oc_sb_run_pack(&_enc->opb,nsbs,0,1);
-
- oggpackB_write(&_enc->opb,7,3);
-
- oggpackB_write(&_enc->opb,1,1);
-
- oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][0][0],4);
- oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][0][1],4);
-
- oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][1][0],4);
- oggpackB_write(&_enc->opb,_enc->huff_idxs[OC_INTER_FRAME][1][1],4);
- }
- static void oc_enc_frame_pack(oc_enc_ctx *_enc){
-
- oc_restore_fpu(&_enc->state);
- oggpackB_reset(&_enc->opb);
-
- if(_enc->state.ntotal_coded_fragis>0){
- oc_enc_frame_header_pack(_enc);
- if(_enc->state.frame_type==OC_INTER_FRAME){
-
- oc_enc_coded_flags_pack(_enc);
- oc_enc_mb_modes_pack(_enc);
- oc_enc_mvs_pack(_enc);
- }
- oc_enc_block_qis_pack(_enc);
- oc_enc_tokenize_finish(_enc);
- oc_enc_residual_tokens_pack(_enc);
- }
-
- else if(_enc->vp3_compatible)oc_enc_drop_frame_pack(_enc);
-
- _enc->packet_state=OC_PACKET_READY;
- #if defined(OC_COLLECT_METRICS)
- oc_enc_mode_metrics_collect(_enc);
- #endif
- }
- void oc_enc_accel_init_c(oc_enc_ctx *_enc){
-
- # if defined(OC_ENC_USE_VTABLE)
- _enc->opt_vtable.frag_sub=oc_enc_frag_sub_c;
- _enc->opt_vtable.frag_sub_128=oc_enc_frag_sub_128_c;
- _enc->opt_vtable.frag_sad=oc_enc_frag_sad_c;
- _enc->opt_vtable.frag_sad_thresh=oc_enc_frag_sad_thresh_c;
- _enc->opt_vtable.frag_sad2_thresh=oc_enc_frag_sad2_thresh_c;
- _enc->opt_vtable.frag_intra_sad=oc_enc_frag_intra_sad_c;
- _enc->opt_vtable.frag_satd=oc_enc_frag_satd_c;
- _enc->opt_vtable.frag_satd2=oc_enc_frag_satd2_c;
- _enc->opt_vtable.frag_intra_satd=oc_enc_frag_intra_satd_c;
- _enc->opt_vtable.frag_ssd=oc_enc_frag_ssd_c;
- _enc->opt_vtable.frag_border_ssd=oc_enc_frag_border_ssd_c;
- _enc->opt_vtable.frag_copy2=oc_enc_frag_copy2_c;
- _enc->opt_vtable.enquant_table_init=oc_enc_enquant_table_init_c;
- _enc->opt_vtable.enquant_table_fixup=oc_enc_enquant_table_fixup_c;
- _enc->opt_vtable.quantize=oc_enc_quantize_c;
- _enc->opt_vtable.frag_recon_intra=oc_frag_recon_intra_c;
- _enc->opt_vtable.frag_recon_inter=oc_frag_recon_inter_c;
- _enc->opt_vtable.fdct8x8=oc_enc_fdct8x8_c;
- # endif
- _enc->opt_data.enquant_table_size=64*sizeof(oc_iquant);
- _enc->opt_data.enquant_table_alignment=16;
- }
- static void oc_enc_mb_info_init(oc_enc_ctx *_enc){
- oc_mb_enc_info *embs;
- const signed char *mb_modes;
- unsigned nhsbs;
- unsigned nvsbs;
- unsigned nhmbs;
- unsigned nvmbs;
- unsigned sby;
- mb_modes=_enc->state.mb_modes;
- embs=_enc->mb_info;
- nhsbs=_enc->state.fplanes[0].nhsbs;
- nvsbs=_enc->state.fplanes[0].nvsbs;
- nhmbs=_enc->state.nhmbs;
- nvmbs=_enc->state.nvmbs;
- for(sby=0;sby<nvsbs;sby++){
- unsigned sbx;
- for(sbx=0;sbx<nhsbs;sbx++){
- int quadi;
- for(quadi=0;quadi<4;quadi++){
-
-
- static const unsigned char NCNEIGHBORS[4]={4,3,2,4};
-
- static const signed char CDX[4][4]={
- {-1,0,1,-1},
- {-1,0,-1,},
- {-1,-1},
- {-1,0,0,1}
- };
-
- static const signed char CDY[4][4]={
- {0,-1,-1,-1},
- {0,-1,-1},
- {0,-1},
- {0,-1,1,-1}
- };
-
- static const signed char PDX[4]={-1,0,1,0};
-
- static const signed char PDY[4]={0,-1,0,1};
- unsigned mbi;
- int mbx;
- int mby;
- unsigned nmbi;
- int nmbx;
- int nmby;
- int ni;
- mbi=(sby*nhsbs+sbx<<2)+quadi;
- if(mb_modes[mbi]==OC_MODE_INVALID)continue;
- mbx=2*sbx+(quadi>>1);
- mby=2*sby+(quadi+1>>1&1);
-
- for(ni=0;ni<NCNEIGHBORS[quadi];ni++){
- nmbx=mbx+CDX[quadi][ni];
- nmby=mby+CDY[quadi][ni];
- if(nmbx<0||nmbx>=nhmbs||nmby<0||nmby>=nvmbs)continue;
- nmbi=(nmby&~1)*nhmbs+((nmbx&~1)<<1)+OC_MB_MAP[nmby&1][nmbx&1];
- if(mb_modes[nmbi]==OC_MODE_INVALID)continue;
- embs[mbi].cneighbors[embs[mbi].ncneighbors++]=nmbi;
- }
-
- for(ni=0;ni<4;ni++){
- nmbx=mbx+PDX[ni];
- nmby=mby+PDY[ni];
- if(nmbx<0||nmbx>=nhmbs||nmby<0||nmby>=nvmbs)continue;
- nmbi=(nmby&~1)*nhmbs+((nmbx&~1)<<1)+OC_MB_MAP[nmby&1][nmbx&1];
- if(mb_modes[nmbi]==OC_MODE_INVALID)continue;
- embs[mbi].pneighbors[embs[mbi].npneighbors++]=nmbi;
- }
- }
- }
- }
- }
- static int oc_enc_set_huffman_codes(oc_enc_ctx *_enc,
- const th_huff_code _codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS]){
- int ret;
- if(_enc==NULL)return TH_EFAULT;
- if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL;
- if(_codes==NULL)_codes=TH_VP31_HUFF_CODES;
-
- oggpackB_reset(&_enc->opb);
- ret=oc_huff_codes_pack(&_enc->opb,_codes);
- if(ret<0)return ret;
- memcpy(_enc->huff_codes,_codes,sizeof(_enc->huff_codes));
- return 0;
- }
- static void oc_enc_enquant_tables_init(oc_enc_ctx *_enc,
- const th_quant_info *_qinfo){
- unsigned char *etd;
- size_t ets;
- int align;
- int qii;
- int qi;
- int pli;
- int qti;
- for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){
- _enc->state.dequant_tables[qi][pli][qti]=
- _enc->state.dequant_table_data[qi][pli][qti];
- }
-
- oc_dequant_tables_init(_enc->state.dequant_tables,NULL,_qinfo);
-
- for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){
- _enc->dequant_dc[qi][pli][qti]=_enc->state.dequant_tables[qi][pli][qti][0];
- }
-
- etd=_enc->enquant_table_data;
- ets=_enc->opt_data.enquant_table_size;
- align=-(etd-(unsigned char *)0)&_enc->opt_data.enquant_table_alignment-1;
- etd+=align;
-
- for(qi=0;qi<64;qi++)for(pli=0;pli<3;pli++)for(qti=0;qti<2;qti++){
- _enc->enquant_tables[qi][pli][qti]=etd;
- oc_enc_enquant_table_init(_enc,etd,
- _enc->state.dequant_tables[qi][pli][qti]);
- etd+=ets;
- }
-
- for(pli=0;pli<3;pli++)for(qii=0;qii<3;qii++)for(qti=0;qti<2;qti++){
- _enc->enquant[pli][qii][qti]=etd;
- etd+=ets;
- }
- }
- static void oc_enc_quant_params_updated(oc_enc_ctx *_enc,
- const th_quant_info *_qinfo){
- oc_enc_enquant_tables_init(_enc,_qinfo);
- memcpy(_enc->state.loop_filter_limits,_qinfo->loop_filter_limits,
- sizeof(_enc->state.loop_filter_limits));
- oc_enquant_qavg_init(_enc->log_qavg,_enc->log_plq,_enc->chroma_rd_scale,
- _enc->state.dequant_tables,_enc->state.info.pixel_fmt);
- }
- static int oc_enc_set_quant_params(oc_enc_ctx *_enc,
- const th_quant_info *_qinfo){
- th_quant_info old_qinfo;
- int ret;
- if(_enc==NULL)return TH_EFAULT;
- if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL;
- if(_qinfo==NULL)_qinfo=&TH_DEF_QUANT_INFO;
- memcpy(&old_qinfo,&_enc->qinfo,sizeof(old_qinfo));
- ret=oc_quant_params_clone(&_enc->qinfo,_qinfo);
- if(ret<0){
- oc_quant_params_clear(&_enc->qinfo);
- memcpy(&_enc->qinfo,&old_qinfo,sizeof(old_qinfo));
- return ret;
- }
- else oc_quant_params_clear(&old_qinfo);
- oc_enc_quant_params_updated(_enc,_qinfo);
- return 0;
- }
- static void oc_enc_clear(oc_enc_ctx *_enc);
- static int oc_enc_init(oc_enc_ctx *_enc,const th_info *_info){
- th_info info;
- size_t mcu_nmbs;
- ptrdiff_t mcu_ncfrags;
- ptrdiff_t mcu_nfrags;
- int hdec;
- int vdec;
- int ret;
- int pli;
-
- memcpy(&info,_info,sizeof(info));
- info.version_major=TH_VERSION_MAJOR;
- info.version_minor=TH_VERSION_MINOR;
- info.version_subminor=TH_VERSION_SUB;
- if(info.quality>63)info.quality=63;
- if(info.quality<0)info.quality=32;
- if(info.target_bitrate<0)info.target_bitrate=0;
-
- ret=oc_state_init(&_enc->state,&info,6);
- if(ret<0)return ret;
- oc_enc_accel_init(_enc);
- _enc->mb_info=_ogg_calloc(_enc->state.nmbs,sizeof(*_enc->mb_info));
- _enc->frag_dc=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_dc));
- _enc->coded_mbis=
- (unsigned *)_ogg_malloc(_enc->state.nmbs*sizeof(*_enc->coded_mbis));
- hdec=!(_enc->state.info.pixel_fmt&1);
- vdec=!(_enc->state.info.pixel_fmt&2);
-
- _enc->mcu_nvsbs=1<<vdec;
- mcu_nmbs=_enc->mcu_nvsbs*_enc->state.fplanes[0].nhsbs*(size_t)4;
- mcu_ncfrags=mcu_nmbs<<3-(hdec+vdec);
- mcu_nfrags=4*mcu_nmbs+mcu_ncfrags;
- _enc->mcu_skip_ssd=(unsigned *)_ogg_malloc(
- mcu_nfrags*sizeof(*_enc->mcu_skip_ssd));
- _enc->mcu_rd_scale=(ogg_uint16_t *)_ogg_malloc(
- (mcu_ncfrags>>1)*sizeof(*_enc->mcu_rd_scale));
- _enc->mcu_rd_iscale=(ogg_uint16_t *)_ogg_malloc(
- (mcu_ncfrags>>1)*sizeof(*_enc->mcu_rd_iscale));
- for(pli=0;pli<3;pli++){
- _enc->dct_tokens[pli]=(unsigned char **)oc_malloc_2d(64,
- _enc->state.fplanes[pli].nfrags,sizeof(**_enc->dct_tokens));
- _enc->extra_bits[pli]=(ogg_uint16_t **)oc_malloc_2d(64,
- _enc->state.fplanes[pli].nfrags,sizeof(**_enc->extra_bits));
- }
- #if defined(OC_COLLECT_METRICS)
- _enc->frag_sad=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_sad));
- _enc->frag_satd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_satd));
- _enc->frag_ssd=_ogg_calloc(_enc->state.nfrags,sizeof(*_enc->frag_ssd));
- #endif
- _enc->enquant_table_data=(unsigned char *)_ogg_malloc(
- (64+3)*3*2*_enc->opt_data.enquant_table_size
- +_enc->opt_data.enquant_table_alignment-1);
- _enc->keyframe_frequency_force=1<<_enc->state.info.keyframe_granule_shift;
- _enc->state.qis[0]=_enc->state.info.quality;
- _enc->state.nqis=1;
- _enc->activity_avg=90<<12;
- _enc->luma_avg=128<<8;
- oc_rc_state_init(&_enc->rc,_enc);
- oggpackB_writeinit(&_enc->opb);
- memcpy(_enc->huff_codes,TH_VP31_HUFF_CODES,sizeof(_enc->huff_codes));
- memset(_enc->qinfo.qi_ranges,0,sizeof(_enc->qinfo.qi_ranges));
-
- _enc->packet_state=OC_PACKET_INFO_HDR;
- _enc->dup_count=0;
- _enc->nqueued_dups=0;
- _enc->prev_dup_count=0;
-
- _enc->sp_level=OC_SP_LEVEL_EARLY_SKIP;
-
- _enc->vp3_compatible=0;
-
- _enc->coded_inter_frame=0;
- if(_enc->mb_info==NULL||_enc->frag_dc==NULL||_enc->coded_mbis==NULL
- ||_enc->mcu_skip_ssd==NULL||_enc->dct_tokens[0]==NULL
- ||_enc->dct_tokens[1]==NULL||_enc->dct_tokens[2]==NULL
- ||_enc->extra_bits[0]==NULL||_enc->extra_bits[1]==NULL
- ||_enc->extra_bits[2]==NULL
- #if defined(OC_COLLECT_METRICS)
- ||_enc->frag_sad==NULL||_enc->frag_satd==NULL||_enc->frag_ssd==NULL
- #endif
- ||oc_enc_set_quant_params(_enc,NULL)<0){
- oc_enc_clear(_enc);
- return TH_EFAULT;
- }
- oc_mode_scheme_chooser_init(&_enc->chooser);
- oc_enc_mb_info_init(_enc);
- memset(_enc->huff_idxs,0,sizeof(_enc->huff_idxs));
- return 0;
- }
- static void oc_enc_clear(oc_enc_ctx *_enc){
- int pli;
- oc_rc_state_clear(&_enc->rc);
- oggpackB_writeclear(&_enc->opb);
- oc_quant_params_clear(&_enc->qinfo);
- _ogg_free(_enc->enquant_table_data);
- #if defined(OC_COLLECT_METRICS)
-
- oc_mode_metrics_dump();
- _ogg_free(_enc->frag_ssd);
- _ogg_free(_enc->frag_satd);
- _ogg_free(_enc->frag_sad);
- #endif
- for(pli=3;pli-->0;){
- oc_free_2d(_enc->extra_bits[pli]);
- oc_free_2d(_enc->dct_tokens[pli]);
- }
- _ogg_free(_enc->mcu_rd_iscale);
- _ogg_free(_enc->mcu_rd_scale);
- _ogg_free(_enc->mcu_skip_ssd);
- _ogg_free(_enc->coded_mbis);
- _ogg_free(_enc->frag_dc);
- _ogg_free(_enc->mb_info);
- oc_state_clear(&_enc->state);
- }
- static void oc_enc_drop_frame(th_enc_ctx *_enc){
-
- _enc->state.ref_frame_idx[OC_FRAME_SELF]=
- _enc->state.ref_frame_idx[OC_FRAME_PREV];
- _enc->state.ref_frame_data[OC_FRAME_SELF]=
- _enc->state.ref_frame_data[OC_FRAME_PREV];
-
- _enc->prevframe_dropped=1;
-
- oggpackB_reset(&_enc->opb);
-
- if(_enc->vp3_compatible)oc_enc_drop_frame_pack(_enc);
- }
- static void oc_enc_compress_keyframe(oc_enc_ctx *_enc,int _recode){
- if(_enc->state.info.target_bitrate>0){
- _enc->state.qis[0]=oc_enc_select_qi(_enc,OC_INTRA_FRAME,
- _enc->state.curframe_num>0);
- _enc->state.nqis=1;
- }
- oc_enc_calc_lambda(_enc,OC_INTRA_FRAME);
- oc_enc_analyze_intra(_enc,_recode);
- oc_enc_frame_pack(_enc);
-
- if(!_recode&&_enc->state.curframe_num==0){
- if(_enc->state.info.target_bitrate>0){
- oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3,
- OC_INTRA_FRAME,_enc->state.qis[0],1,0);
- }
- oc_enc_compress_keyframe(_enc,1);
- }
- }
- static void oc_enc_compress_frame(oc_enc_ctx *_enc,int _recode){
- if(_enc->state.info.target_bitrate>0){
- _enc->state.qis[0]=oc_enc_select_qi(_enc,OC_INTER_FRAME,1);
- _enc->state.nqis=1;
- }
- oc_enc_calc_lambda(_enc,OC_INTER_FRAME);
- if(oc_enc_analyze_inter(_enc,_enc->rc.twopass!=2,_recode)){
-
- oc_enc_compress_keyframe(_enc,1);
- }
- else{
- oc_enc_frame_pack(_enc);
- if(!_enc->coded_inter_frame){
-
- _enc->coded_inter_frame=1;
- if(_enc->state.info.target_bitrate>0){
-
- oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3,
- OC_INTER_FRAME,_enc->state.qis[0],1,0);
- }
- oc_enc_compress_frame(_enc,1);
- }
- }
- }
- static void oc_enc_set_granpos(oc_enc_ctx *_enc){
- unsigned dup_offs;
-
- dup_offs=_enc->prev_dup_count-_enc->nqueued_dups;
-
- if(_enc->state.frame_type==OC_INTRA_FRAME){
- _enc->state.granpos=(_enc->state.curframe_num+_enc->state.granpos_bias<<
- _enc->state.info.keyframe_granule_shift)+dup_offs;
- }
-
- else{
- _enc->state.granpos=
- (_enc->state.keyframe_num+_enc->state.granpos_bias<<
- _enc->state.info.keyframe_granule_shift)
- +_enc->state.curframe_num-_enc->state.keyframe_num+dup_offs;
- }
- }
- th_enc_ctx *th_encode_alloc(const th_info *_info){
- oc_enc_ctx *enc;
- if(_info==NULL)return NULL;
- enc=oc_aligned_malloc(sizeof(*enc),16);
- if(enc==NULL||oc_enc_init(enc,_info)<0){
- oc_aligned_free(enc);
- return NULL;
- }
- return enc;
- }
- void th_encode_free(th_enc_ctx *_enc){
- if(_enc!=NULL){
- oc_enc_clear(_enc);
- oc_aligned_free(_enc);
- }
- }
- int th_encode_ctl(th_enc_ctx *_enc,int _req,void *_buf,size_t _buf_sz){
- switch(_req){
- case TH_ENCCTL_SET_HUFFMAN_CODES:{
- if(_buf==NULL&&_buf_sz!=0||
- _buf!=NULL&&_buf_sz!=sizeof(th_huff_table)*TH_NHUFFMAN_TABLES){
- return TH_EINVAL;
- }
- return oc_enc_set_huffman_codes(_enc,(const th_huff_table *)_buf);
- }break;
- case TH_ENCCTL_SET_QUANT_PARAMS:{
- if(_buf==NULL&&_buf_sz!=0||
- _buf!=NULL&&_buf_sz!=sizeof(th_quant_info)){
- return TH_EINVAL;
- }
- return oc_enc_set_quant_params(_enc,(th_quant_info *)_buf);
- }break;
- case TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE:{
- ogg_uint32_t keyframe_frequency_force;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(keyframe_frequency_force))return TH_EINVAL;
- keyframe_frequency_force=*(ogg_uint32_t *)_buf;
- if(keyframe_frequency_force<=0)keyframe_frequency_force=1;
- if(_enc->packet_state==OC_PACKET_INFO_HDR){
-
- _enc->state.info.keyframe_granule_shift=OC_CLAMPI(
- _enc->state.info.keyframe_granule_shift,
- OC_ILOG_32(keyframe_frequency_force-1),31);
- }
- _enc->keyframe_frequency_force=OC_MINI(keyframe_frequency_force,
- (ogg_uint32_t)1U<<_enc->state.info.keyframe_granule_shift);
- *(ogg_uint32_t *)_buf=_enc->keyframe_frequency_force;
- return 0;
- }break;
- case TH_ENCCTL_SET_VP3_COMPATIBLE:{
- int vp3_compatible;
- int ret;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(vp3_compatible))return TH_EINVAL;
-
- ret=oc_enc_set_quant_params(_enc,&TH_VP31_QUANT_INFO);
-
- if(ret==TH_EFAULT)return ret;
- vp3_compatible=*(int *)_buf;
- _enc->vp3_compatible=vp3_compatible;
- if(oc_enc_set_huffman_codes(_enc,TH_VP31_HUFF_CODES)<0)vp3_compatible=0;
- if(ret<0)vp3_compatible=0;
- if(_enc->state.info.pixel_fmt!=TH_PF_420||
- _enc->state.info.pic_width<_enc->state.info.frame_width||
- _enc->state.info.pic_height<_enc->state.info.frame_height||
-
- _enc->state.nsbs>4095){
- vp3_compatible=0;
- }
- *(int *)_buf=vp3_compatible;
- return 0;
- }break;
- case TH_ENCCTL_GET_SPLEVEL_MAX:{
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(int))return TH_EINVAL;
- *(int *)_buf=OC_SP_LEVEL_MAX;
- return 0;
- }break;
- case TH_ENCCTL_SET_SPLEVEL:{
- int speed;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(speed))return TH_EINVAL;
- speed=*(int *)_buf;
- if(speed<0||speed>OC_SP_LEVEL_MAX)return TH_EINVAL;
- _enc->sp_level=speed;
- return 0;
- }break;
- case TH_ENCCTL_GET_SPLEVEL:{
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(int))return TH_EINVAL;
- *(int *)_buf=_enc->sp_level;
- return 0;
- }
- case TH_ENCCTL_SET_DUP_COUNT:{
- int dup_count;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(dup_count))return TH_EINVAL;
- dup_count=*(int *)_buf;
- if(dup_count>=_enc->keyframe_frequency_force)return TH_EINVAL;
- _enc->dup_count=OC_MAXI(dup_count,0);
- return 0;
- }break;
- case TH_ENCCTL_SET_QUALITY:{
- int qi;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_enc->state.info.target_bitrate>0)return TH_EINVAL;
- qi=*(int *)_buf;
- if(qi<0||qi>63)return TH_EINVAL;
- _enc->state.info.quality=qi;
- _enc->state.qis[0]=(unsigned char)qi;
- _enc->state.nqis=1;
- return 0;
- }break;
- case TH_ENCCTL_SET_BITRATE:{
- long bitrate;
- int reset;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- bitrate=*(long *)_buf;
- if(bitrate<=0)return TH_EINVAL;
- reset=_enc->state.info.target_bitrate<=0;
- _enc->state.info.target_bitrate=bitrate>INT_MAX?INT_MAX:bitrate;
- if(reset)oc_rc_state_init(&_enc->rc,_enc);
- else oc_enc_rc_resize(_enc);
- return 0;
- }break;
- case TH_ENCCTL_SET_RATE_FLAGS:{
- int set;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(set))return TH_EINVAL;
- if(_enc->state.info.target_bitrate<=0)return TH_EINVAL;
- set=*(int *)_buf;
- _enc->rc.drop_frames=set&TH_RATECTL_DROP_FRAMES;
- _enc->rc.cap_overflow=set&TH_RATECTL_CAP_OVERFLOW;
- _enc->rc.cap_underflow=set&TH_RATECTL_CAP_UNDERFLOW;
- return 0;
- }break;
- case TH_ENCCTL_SET_RATE_BUFFER:{
- int set;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_buf_sz!=sizeof(set))return TH_EINVAL;
- if(_enc->state.info.target_bitrate<=0)return TH_EINVAL;
- set=*(int *)_buf;
- _enc->rc.buf_delay=set;
- oc_enc_rc_resize(_enc);
- *(int *)_buf=_enc->rc.buf_delay;
- return 0;
- }break;
- case TH_ENCCTL_2PASS_OUT:{
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_enc->state.info.target_bitrate<=0||
- _enc->state.curframe_num>=0&&_enc->rc.twopass!=1||
- _buf_sz!=sizeof(unsigned char *)){
- return TH_EINVAL;
- }
- return oc_enc_rc_2pass_out(_enc,(unsigned char **)_buf);
- }break;
- case TH_ENCCTL_2PASS_IN:{
- if(_enc==NULL)return TH_EFAULT;
- if(_enc->state.info.target_bitrate<=0||
- _enc->state.curframe_num>=0&&_enc->rc.twopass!=2){
- return TH_EINVAL;
- }
- return oc_enc_rc_2pass_in(_enc,_buf,_buf_sz);
- }break;
- case TH_ENCCTL_SET_COMPAT_CONFIG:{
- unsigned char buf[7];
- oc_pack_buf opb;
- th_quant_info qinfo;
- th_huff_code huff_codes[TH_NHUFFMAN_TABLES][TH_NDCT_TOKENS];
- int ret;
- int i;
- if(_enc==NULL||_buf==NULL)return TH_EFAULT;
- if(_enc->packet_state>OC_PACKET_SETUP_HDR)return TH_EINVAL;
- oc_pack_readinit(&opb,_buf,_buf_sz);
-
- for(i=0;i<7;i++)buf[i]=(unsigned char)oc_pack_read(&opb,8);
- if(!(buf[0]&0x80)||memcmp(buf+1,"theora",6)!=0)return TH_ENOTFORMAT;
- if(buf[0]!=0x82)return TH_EBADHEADER;
-
- ret=oc_quant_params_unpack(&opb,&qinfo);
- if(ret<0){
- oc_quant_params_clear(&qinfo);
- return ret;
- }
- ret=oc_huff_codes_unpack(&opb,huff_codes);
- if(ret<0){
- oc_quant_params_clear(&qinfo);
- return ret;
- }
-
- oc_quant_params_clear(&_enc->qinfo);
- memcpy(&_enc->qinfo,&qinfo,sizeof(qinfo));
- oc_enc_quant_params_updated(_enc,&qinfo);
- memcpy(_enc->huff_codes,huff_codes,sizeof(_enc->huff_codes));
- return 0;
- }
- #if defined(OC_COLLECT_METRICS)
- case TH_ENCCTL_SET_METRICS_FILE:{
- OC_MODE_METRICS_FILENAME=(const char *)_buf;
- return 0;
- }
- #endif
- default:return TH_EIMPL;
- }
- }
- int th_encode_flushheader(th_enc_ctx *_enc,th_comment *_tc,ogg_packet *_op){
- if(_enc==NULL)return TH_EFAULT;
- return oc_state_flushheader(&_enc->state,&_enc->packet_state,&_enc->opb,
- &_enc->qinfo,(const th_huff_table *)_enc->huff_codes,th_version_string(),
- _tc,_op);
- }
- static void oc_img_plane_copy_pad(th_img_plane *_dst,th_img_plane *_src,
- ogg_int32_t _pic_x,ogg_int32_t _pic_y,
- ogg_int32_t _pic_width,ogg_int32_t _pic_height){
- unsigned char *dst;
- int dstride;
- ogg_uint32_t frame_width;
- ogg_uint32_t frame_height;
- ogg_uint32_t y;
- frame_width=_dst->width;
- frame_height=_dst->height;
-
- if(_pic_width==0||_pic_height==0){
- dst=_dst->data;
- dstride=_dst->stride;
- for(y=0;y<frame_height;y++){
- memset(dst,0,frame_width*sizeof(*dst));
- dst+=dstride;
- }
- }
-
- else{
- unsigned char *dst_data;
- unsigned char *src_data;
- unsigned char *src;
- int sstride;
- ogg_uint32_t x;
-
- dstride=_dst->stride;
- sstride=_src->stride;
- dst_data=_dst->data;
- src_data=_src->data;
- dst=dst_data+_pic_y*(ptrdiff_t)dstride+_pic_x;
- src=src_data+_pic_y*(ptrdiff_t)sstride+_pic_x;
- for(y=0;y<_pic_height;y++){
- memcpy(dst,src,_pic_width);
- dst+=dstride;
- src+=sstride;
- }
-
-
- for(x=_pic_x;x-->0;){
- dst=dst_data+_pic_y*(ptrdiff_t)dstride+x;
- for(y=0;y<_pic_height;y++){
- dst[0]=(dst[1]<<1)+(dst-(dstride&-(y>0)))[1]
- +(dst+(dstride&-(y+1<_pic_height)))[1]+2>>2;
- dst+=dstride;
- }
- }
-
- for(x=_pic_x+_pic_width;x<frame_width;x++){
- dst=dst_data+_pic_y*(ptrdiff_t)dstride+x-1;
- for(y=0;y<_pic_height;y++){
- dst[1]=(dst[0]<<1)+(dst-(dstride&-(y>0)))[0]
- +(dst+(dstride&-(y+1<_pic_height)))[0]+2>>2;
- dst+=dstride;
- }
- }
-
- dst=dst_data+_pic_y*(ptrdiff_t)dstride;
- for(y=_pic_y;y-->0;){
- for(x=0;x<frame_width;x++){
- (dst-dstride)[x]=(dst[x]<<1)+dst[x-(x>0)]
- +dst[x+(x+1<frame_width)]+2>>2;
- }
- dst-=dstride;
- }
-
- dst=dst_data+(_pic_y+_pic_height)*(ptrdiff_t)dstride;
- for(y=_pic_y+_pic_height;y<frame_height;y++){
- for(x=0;x<frame_width;x++){
- dst[x]=((dst-dstride)[x]<<1)+(dst-dstride)[x-(x>0)]
- +(dst-dstride)[x+(x+1<frame_width)]+2>>2;
- }
- dst+=dstride;
- }
- }
- }
- int th_encode_ycbcr_in(th_enc_ctx *_enc,th_ycbcr_buffer _img){
- th_ycbcr_buffer img;
- int frame_width;
- int frame_height;
- int pic_width;
- int pic_height;
- int pic_x;
- int pic_y;
- int cframe_width;
- int cframe_height;
- int cpic_width;
- int cpic_height;
- int cpic_x;
- int cpic_y;
- int hdec;
- int vdec;
- int pli;
- int refi;
- int drop;
-
- if(_enc==NULL||_img==NULL)return TH_EFAULT;
- if(_enc->packet_state==OC_PACKET_DONE)return TH_EINVAL;
- if(_enc->rc.twopass&&_enc->rc.twopass_buffer_bytes==0)return TH_EINVAL;
- hdec=!(_enc->state.info.pixel_fmt&1);
- vdec=!(_enc->state.info.pixel_fmt&2);
- frame_width=_enc->state.info.frame_width;
- frame_height=_enc->state.info.frame_height;
- pic_x=_enc->state.info.pic_x;
- pic_y=_enc->state.info.pic_y;
- pic_width=_enc->state.info.pic_width;
- pic_height=_enc->state.info.pic_height;
- cframe_width=frame_width>>hdec;
- cframe_height=frame_height>>vdec;
- cpic_x=pic_x>>hdec;
- cpic_y=pic_y>>vdec;
- cpic_width=(pic_x+pic_width+hdec>>hdec)-cpic_x;
- cpic_height=(pic_y+pic_height+vdec>>vdec)-cpic_y;
-
- oc_ycbcr_buffer_flip(img,_img);
- if(img[0].width!=frame_width||img[0].height!=frame_height||
- img[1].width!=cframe_width||img[2].width!=cframe_width||
- img[1].height!=cframe_height||img[2].height!=cframe_height){
-
- if(img[0].width!=pic_width||img[0].height!=pic_height||
- img[1].width!=cpic_width||img[2].width!=cpic_width||
- img[1].height!=cpic_height||img[2].height!=cpic_height){
-
- return TH_EINVAL;
- }
-
- img[0].data-=pic_y*(ptrdiff_t)img[0].stride+pic_x;
- img[1].data-=cpic_y*(ptrdiff_t)img[1].stride+cpic_x;
- img[2].data-=cpic_y*(ptrdiff_t)img[2].stride+cpic_x;
- }
-
- if(_enc->state.ref_frame_idx[OC_FRAME_SELF]>=0){
- _enc->state.ref_frame_idx[OC_FRAME_PREV]=
- _enc->state.ref_frame_idx[OC_FRAME_SELF];
- _enc->state.ref_frame_data[OC_FRAME_PREV]=
- _enc->state.ref_frame_data[OC_FRAME_SELF];
- if(_enc->state.frame_type==OC_INTRA_FRAME){
-
- _enc->state.keyframe_num=_enc->state.curframe_num;
- _enc->state.ref_frame_idx[OC_FRAME_GOLD]=
- _enc->state.ref_frame_idx[OC_FRAME_SELF];
- _enc->state.ref_frame_data[OC_FRAME_GOLD]=
- _enc->state.ref_frame_data[OC_FRAME_SELF];
- }
- }
- if(_enc->state.ref_frame_idx[OC_FRAME_IO]>=0&&_enc->prevframe_dropped==0){
- _enc->state.ref_frame_idx[OC_FRAME_PREV_ORIG]=
- _enc->state.ref_frame_idx[OC_FRAME_IO];
- _enc->state.ref_frame_data[OC_FRAME_PREV_ORIG]=
- _enc->state.ref_frame_data[OC_FRAME_IO];
- if(_enc->state.frame_type==OC_INTRA_FRAME){
-
- _enc->state.ref_frame_idx[OC_FRAME_GOLD_ORIG]=
- _enc->state.ref_frame_idx[OC_FRAME_IO];
- _enc->state.ref_frame_data[OC_FRAME_GOLD_ORIG]=
- _enc->state.ref_frame_data[OC_FRAME_IO];
- }
- }
-
- for(refi=3;refi==_enc->state.ref_frame_idx[OC_FRAME_GOLD_ORIG]||
- refi==_enc->state.ref_frame_idx[OC_FRAME_PREV_ORIG];refi++);
- _enc->state.ref_frame_idx[OC_FRAME_IO]=refi;
- _enc->state.ref_frame_data[OC_FRAME_IO]=
- _enc->state.ref_frame_bufs[refi][0].data;
-
- oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[refi]+0,img+0,
- pic_x,pic_y,pic_width,pic_height);
- oc_state_borders_fill_rows(&_enc->state,refi,0,0,frame_height);
- oc_state_borders_fill_caps(&_enc->state,refi,0);
- for(pli=1;pli<3;pli++){
- oc_img_plane_copy_pad(_enc->state.ref_frame_bufs[refi]+pli,img+pli,
- cpic_x,cpic_y,cpic_width,cpic_height);
- oc_state_borders_fill_rows(&_enc->state,refi,pli,0,cframe_height);
- oc_state_borders_fill_caps(&_enc->state,refi,pli);
- }
-
- for(refi=0;refi==_enc->state.ref_frame_idx[OC_FRAME_GOLD]||
- refi==_enc->state.ref_frame_idx[OC_FRAME_PREV];refi++);
- _enc->state.ref_frame_idx[OC_FRAME_SELF]=refi;
- _enc->state.ref_frame_data[OC_FRAME_SELF]=
- _enc->state.ref_frame_bufs[refi][0].data;
- _enc->state.curframe_num+=_enc->prev_dup_count+1;
-
-
- if(_enc->rc.twopass_force_kf||_enc->state.curframe_num==0||
- _enc->state.curframe_num-_enc->state.keyframe_num+_enc->dup_count>=
- _enc->keyframe_frequency_force){
- oc_enc_compress_keyframe(_enc,0);
- drop=0;
- }
- else{
- oc_enc_compress_frame(_enc,0);
- drop=1;
- }
- oc_restore_fpu(&_enc->state);
-
- if(_enc->state.info.target_bitrate>0){
- drop=oc_enc_update_rc_state(_enc,oggpackB_bytes(&_enc->opb)<<3,
- _enc->state.frame_type,_enc->state.qis[0],0,drop);
- }
- else drop=0;
-
- if(drop)oc_enc_drop_frame(_enc);
- else _enc->prevframe_dropped=0;
- _enc->packet_state=OC_PACKET_READY;
- _enc->prev_dup_count=_enc->nqueued_dups=_enc->dup_count;
- _enc->dup_count=0;
- #if defined(OC_DUMP_IMAGES)
- oc_enc_set_granpos(_enc);
- oc_state_dump_frame(&_enc->state,OC_FRAME_IO,"src");
- oc_state_dump_frame(&_enc->state,OC_FRAME_SELF,"rec");
- #endif
- return 0;
- }
- int th_encode_packetout(th_enc_ctx *_enc,int _last_p,ogg_packet *_op){
- unsigned char *packet;
- if(_enc==NULL||_op==NULL)return TH_EFAULT;
- if(_enc->packet_state==OC_PACKET_READY){
- _enc->packet_state=OC_PACKET_EMPTY;
- if(_enc->rc.twopass!=1){
- packet=oggpackB_get_buffer(&_enc->opb);
-
- if(packet==NULL)return TH_EFAULT;
- _op->packet=packet;
- _op->bytes=oggpackB_bytes(&_enc->opb);
- }
-
- else{
- _op->packet=NULL;
- _op->bytes=0;
- }
- }
- else if(_enc->packet_state==OC_PACKET_EMPTY){
- if(_enc->nqueued_dups>0){
- _enc->nqueued_dups--;
-
- if(_enc->vp3_compatible){
- oggpackB_reset(&_enc->opb);
- oc_enc_drop_frame_pack(_enc);
- packet=oggpackB_get_buffer(&_enc->opb);
-
- if(packet==NULL)return TH_EFAULT;
- _op->packet=packet;
- _op->bytes=oggpackB_bytes(&_enc->opb);
- }
-
- else{
- _op->packet=NULL;
- _op->bytes=0;
- }
- }
- else{
- if(_last_p)_enc->packet_state=OC_PACKET_DONE;
- return 0;
- }
- }
- else return 0;
- _last_p=_last_p&&_enc->nqueued_dups<=0;
- _op->b_o_s=0;
- _op->e_o_s=_last_p;
- oc_enc_set_granpos(_enc);
- _op->packetno=th_granule_frame(_enc,_enc->state.granpos)+3;
- _op->granulepos=_enc->state.granpos;
- if(_last_p)_enc->packet_state=OC_PACKET_DONE;
- return 1+_enc->nqueued_dups;
- }
|