ref: a31395562e9757b7d7fa12bb87b6cc6a3d495a93
parent: 55b3ec0bab55921f5c35ddec92de4742aa0ee346
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Oct 26 19:24:18 EDT 2021
add 9-specific decoder logic
--- a/codec/plan9.c
+++ b/codec/plan9.c
@@ -1,4 +1,220 @@
#include "decoder.h"
+#include "decoder9.h"
+
+static void
+reorder(H264Aux *a)
+{
+ int i, firstvalid;
+
+ if(a->iNumOfPicts > 0){
+ if(a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb && a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin){
+ a->iLastGOPRemainPicts = a->iNumOfPicts;
+
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++)
+ a->pics[i].bLastGOP = a->pics[i].iPOC > IMinInt32;
+ }else{
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(a->pics[i].iPOC == a->ctx.pSliceHeader->iPicOrderCntLsb){
+ a->iLastGOPRemainPicts = a->iNumOfPicts;
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++)
+ a->pics[i].bLastGOP = a->pics[i].iPOC > IMinInt32;
+ break;
+ }
+ }
+ }
+ }
+
+ for(i = 0; i < nelem(a->pics); i++){
+ if(a->pics[i].iPOC == IMinInt32){
+ memmove(&a->pics[i].sBufferInfo, &a->info, sizeof(a->info));
+ a->pics[i].iPOC = a->ctx.pSliceHeader->iPicOrderCntLsb;
+ a->pics[i].iPicBuffIdx = a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
+ a->pics[i].uiDecodingTimeStamp = a->ctx.uiDecodingTimeStamp;
+ a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->iRefCount++;
+ a->pics[i].bLastGOP = false;
+ a->info.iBufferStatus = 0;
+ a->iNumOfPicts++;
+ if(a->iLargestBufferedPicIndex < i)
+ a->iLargestBufferedPicIndex = i;
+ break;
+ }
+ }
+
+ PPicBuff picbuf = a->ctx.pPicBuff;
+ if(a->iLastGOPRemainPicts > 0){
+ a->iMinPOC = IMinInt32;
+ firstvalid = -1;
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(a->iMinPOC == IMinInt32 && a->pics[i].iPOC > IMinInt32 && a->pics[i].bLastGOP){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ firstvalid = i;
+ break;
+ }
+ }
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(i == firstvalid)
+ continue;
+ if(a->pics[i].iPOC > IMinInt32 && a->pics[i].iPOC < a->iMinPOC && a->pics[i].bLastGOP){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ }
+ }
+ a->iLastWrittenPOC = a->iMinPOC;
+ memmove(&a->info, &a->pics[a->iPictInfoIndex].sBufferInfo, sizeof(a->info));
+ a->data[0] = a->info.pDst[0];
+ a->data[1] = a->info.pDst[1];
+ a->data[2] = a->info.pDst[2];
+ a->pics[a->iPictInfoIndex].iPOC = IMinInt32;
+ picbuf->ppPic[a->pics[a->iPictInfoIndex].iPicBuffIdx]->iRefCount--;
+ a->pics[a->iPictInfoIndex].bLastGOP = false;
+ a->iMinPOC = IMinInt32;
+ a->iNumOfPicts--;
+ a->iLastGOPRemainPicts--;
+ if(a->iLastGOPRemainPicts == 0)
+ a->iLastWrittenPOC = IMinInt32;
+ return;
+ }
+
+ if(a->iNumOfPicts > 0){
+ a->iMinPOC = IMinInt32;
+ firstvalid = -1;
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(a->iMinPOC == IMinInt32 && a->pics[i].iPOC > IMinInt32){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ firstvalid = i;
+ break;
+ }
+ }
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(i == firstvalid)
+ continue;
+ if(a->pics[i].iPOC > IMinInt32 && a->pics[i].iPOC < a->iMinPOC){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ }
+ }
+ }
+
+ if(a->iMinPOC > IMinInt32 && ((a->iLastWrittenPOC > IMinInt32 && a->iMinPOC - a->iLastWrittenPOC <= 1) || a->iMinPOC < a->ctx.pSliceHeader->iPicOrderCntLsb)){
+ a->iLastWrittenPOC = a->iMinPOC;
+ memmove(&a->info, &a->pics[a->iPictInfoIndex].sBufferInfo, sizeof(a->info));
+ a->data[0] = a->info.pDst[0];
+ a->data[1] = a->info.pDst[1];
+ a->data[2] = a->info.pDst[2];
+ a->pics[a->iPictInfoIndex].iPOC = IMinInt32;
+ picbuf->ppPic[a->pics[a->iPictInfoIndex].iPicBuffIdx]->iRefCount--;
+ a->pics[a->iPictInfoIndex].bLastGOP = false;
+ a->iMinPOC = IMinInt32;
+ a->iNumOfPicts--;
+ }
+}
+
+void
+h264flush(H264Aux *a)
+{
+ int i, firstvalid;
+
+ a->iMinPOC = IMinInt32;
+ firstvalid = -1;
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(a->iMinPOC == IMinInt32 && a->pics[i].iPOC > IMinInt32){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ firstvalid = i;
+ break;
+ }
+ }
+
+ for(i = 0; i <= a->iLargestBufferedPicIndex; i++){
+ if(i == firstvalid)
+ continue;
+ if(a->pics[i].iPOC > IMinInt32 && a->pics[i].iPOC < a->iMinPOC){
+ a->iMinPOC = a->pics[i].iPOC;
+ a->iPictInfoIndex = i;
+ }
+ }
+
+ if(a->iMinPOC > IMinInt32){
+ a->iLastWrittenPOC = a->iMinPOC;
+ memmove(&a->info, &a->pics[a->iPictInfoIndex].sBufferInfo, sizeof(a->info));
+ a->data[0] = a->info.pDst[0];
+ a->data[1] = a->info.pDst[1];
+ a->data[2] = a->info.pDst[2];
+ a->pics[a->iPictInfoIndex].iPOC = IMinInt32;
+ a->ctx.pPicBuff->ppPic[a->pics[a->iPictInfoIndex].iPicBuffIdx]->iRefCount--;
+ a->pics[a->iPictInfoIndex].bLastGOP = false;
+ a->iMinPOC = IMinInt32;
+ a->iNumOfPicts--;
+ }
+}
+
+int
+h264decode(H264Aux *a, u8int *buf, int sz, uvlong *timestamp)
+{
+ int res;
+
+ if(buf == nil || sz < 1){
+ a->ctx.bEndOfStreamFlag = true;
+ a->ctx.bInstantDecFlag = true;
+ }else{
+ a->ctx.bEndOfStreamFlag = false;
+ }
+ memset(a->data, 0, sizeof(a->data));
+ memset(&a->info, 0, sizeof(a->info));
+ a->info.uiInBsTimeStamp = *timestamp;
+ a->ctx.uiTimeStamp = *timestamp;
+ a->ctx.iErrorCode = dsErrorFree;
+ a->ctx.iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL;
+ a->ctx.bReferenceLostAtT0Flag = false;
+ a->ctx.bCurAuContainLtrMarkSeFlag = false;
+ a->ctx.iFrameNumOfAuMarkedLtr = 0;
+ a->ctx.iFrameNum = -1;
+ a->ctx.iFeedbackTidInAu = -1;
+ a->ctx.iFeedbackNalRefIdc = -1;
+ res = WelsDecodeBs(&a->ctx, buf, sz, a->data, &a->info, nil);
+ a->ctx.bInstantDecFlag = false;
+ if(res != 0){
+ if(res & dsOutOfMemory)
+ return 0;
+ werrstr("%s: %.*H", h264err2s(a->ctx.iErrorCode), sz <= 32 ? sz : 32, buf);
+ return -1;
+ }
+
+ if(a->info.iBufferStatus != 0 && a->ctx.pPps->bEntropyCodingModeFlag && a->ctx.pSps->uiProfileIdc != 66 && a->ctx.pSps->uiProfileIdc != 83){
+ /* non-baseline needs reordering */
+ reorder(a);
+ *timestamp = a->info.uiOutYuvTimeStamp;
+ }
+
+ return 0;
+}
+
+char *
+h264err2s(int err)
+{
+ static char t[256];
+ char *s, *e;
+
+ t[0] = t[1] = 0;
+ s = t;
+ e = t+sizeof(t);
+ if(err & dsFramePending) s = seprint(s, e, "|FramePending");
+ if(err & dsRefLost) s = seprint(s, e, "|RefLost");
+ if(err & dsBitstreamError) s = seprint(s, e, "|BitstreamError");
+ if(err & dsDepLayerLost) s = seprint(s, e, "|DepLayerLost");
+ if(err & dsNoParamSets) s = seprint(s, e, "|NoParamSets");
+ if(err & dsDataErrorConcealed) s = seprint(s, e, "|DataErrorConcealed");
+ if(err & dsRefListNullPtrs) s = seprint(s, e, "|RefListNullPtrs");
+ if(err & dsInvalidArgument) s = seprint(s, e, "|InvalidArgument");
+ if(err & dsInitialOptExpected) s = seprint(s, e, "|InitialOptExpected");
+ if(err & dsOutOfMemory) s = seprint(s, e, "|OutOfMemory");
+ if(err & dsDstBufNeedExpan) s = seprint(s, e, "|DstBufNeedExpan");
+ USED(s);
+
+ return t+1;
+}
uint32_t
WelsCPUFeatureDetect(int32_t *pNumberOfLogicProcessors)