shithub: treason

Download patch

ref: c6f38fccec03ed1c226e423bdbe2efd6fa02d224
parent: d696956ababd5fdec5bcb51373896468c310161d
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Oct 26 19:24:37 EDT 2021

h264: move decoder-specific logic where it belongs (more)

--- a/decoder_h264.c
+++ b/decoder_h264.c
@@ -1,5 +1,6 @@
 #include <decoder/core/inc/decoder.h>
 #include <decoder/core/inc/manage_dec_ref.h>
+#include <decoder/core/inc/decoder9.h>
 #include <thread.h>
 #include "frame.h"
 #include "stream.h"
@@ -8,21 +9,6 @@
 
 #pragma lib "../openh264/codec/libopenh264.$M.a"
 
-typedef struct Aux Aux;
-
-struct Aux {
-	SPictReoderingStatus;
-	SPictInfo pics[16];
-
-	SWelsDecoderContext ctx;
-	SLogContext logctx;
-	SBufferInfo info;
-	SWelsLastDecPicInfo pic;
-	SVlcTable vlctbl;
-	SDecoderStatistics stat;
-	uint8_t *data[3];
-};
-
 static void
 logfun(void *ctx, const int32_t level, const char *fmt, va_list argv)
 {
@@ -35,224 +21,9 @@
 	}
 }
 
-static void
-reorder(Aux *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--;
-	}
-}
-
-static char *
-err2s(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;
-}
-
-static void
-flush(Aux *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--;
-	}
-}
-
 static int
-one(Aux *a, Streamframe *sf)
+sendframe(H264Aux *a, uvlong dt, Channel *c)
 {
-	int res;
-
-	if(sf->buf == nil || sf->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 = sf->timestamp;
-	a->ctx.uiTimeStamp = sf->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, sf->buf, sf->sz, a->data, &a->info, nil);
-	a->ctx.bInstantDecFlag = false;
-	if(res != 0){
-		if(res & dsOutOfMemory)
-			return 0;
-		werrstr("%s: %.*H", err2s(a->ctx.iErrorCode), MIN(32, sf->sz), sf->buf);
-		return -1;
-	}
-
-	if(a->info.iBufferStatus != 0 && a->ctx.pSps->uiProfileIdc != 66 && a->ctx.pSps->uiProfileIdc != 83){
-		/* non-baseline needs reordering */
-		reorder(a);
-		sf->timestamp = a->info.uiOutYuvTimeStamp;
-	}
-
-	return 0;
-}
-
-static int
-sendframe(Aux *a, uvlong dt, Channel *c)
-{
 	int w, h, *stride;
 	Frame *f;
 
@@ -285,7 +56,7 @@
 	Decoder *d;
 	Channel *c;
 	int res, n;
-	Aux *a;
+	H264Aux *a;
 
 	threadsetname("decoder/h264");
 	d = x;
@@ -307,7 +78,7 @@
 				 * obviously, there might be multiple NALs in a single stream frame
 				 */
 				while(a->iNumOfPicts > 0){
-					flush(a);
+					h264flush(a);
 					ts = a->info.uiOutYuvTimeStamp;
 					if(ts < lasttimestamp){
 						/* FIXME this happens in some videos... */
@@ -326,11 +97,11 @@
 		}
 
 		start = nanosec();
-		if((res = one(a, &sf)) != 0)
+		if((res = h264decode(a, sf.buf, sf.sz, &sf.timestamp)) != 0)
 			break;
 		sf.buf = nil;
 		sf.sz = 0;
-		if((res = one(a, &sf)) != 0)
+		if((res = h264decode(a, sf.buf, sf.sz, &sf.timestamp)) != 0)
 			break;
 		d->decodetime = nanosec() - start;
 
@@ -362,7 +133,7 @@
 static int
 h264open(Decoder *d)
 {
-	Aux *a;
+	H264Aux *a;
 	int res;
 
 	a = calloc(1, sizeof(*a));
@@ -382,7 +153,7 @@
 	a->ctx.pParam->sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
 
 	if((res = WelsInitDecoder(&a->ctx, &a->logctx)) != 0){
-		werrstr("WelsInitDecoder: %s", err2s(res));
+		werrstr("WelsInitDecoder: %s", h264err2s(res));
 		free(a);
 		return -1;
 	}