shithub: treason

Download patch

ref: 063050e9aa438f4e88db813d1377b569a442de19
parent: f1e89731d431981623bc9f9481ec81fd02f0fe25
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Sat Dec 12 20:19:33 EST 2020

h264: reodering is hard. also make sure not to crash on unordered IVF

--- a/decoder_h264.c
+++ b/decoder_h264.c
@@ -30,19 +30,19 @@
 };
 
 static void
-logfun(void *pCtx, const int32_t iLevel, const char *kpFmt, va_list argv)
+logfun(void *ctx, const int32_t level, const char *fmt, va_list argv)
 {
-	USED(pCtx, iLevel);
-/*
-	fprint(2, "h264: ");
-	vfprint(2, kpFmt, argv);
-	fprint(2, "\n");
-*/
-	USED(kpFmt, argv);
+	USED(ctx);
+
+	if(debug >= level){
+		fprint(2, "h264: ");
+		vfprint(2, fmt, argv);
+		fprint(2, "\n");
+	}
 }
 
-static void
-reorder(Aux *a)
+static uvlong
+reorder(Aux *a, uvlong ts)
 {
 	int i, firstvalid;
 
@@ -49,18 +49,14 @@
 	if(a->npics && a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb && a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->bNewSeqBegin){
 		a->lastgopremain = a->npics;
 
-		for(i = 0; i <= a->lbufpicind; i++){
-			if(a->pics[i].iPOC > IMinInt32)
-				a->pics[i].bLastGOP = true;
-		}
+		for(i = 0; i <= a->lbufpicind; i++)
+			a->pics[i].bLastGOP = a->pics[i].iPOC > IMinInt32;
 	}else if(a->npics > 0){
 		for(i = 0; i <= a->lbufpicind; i++){
 			if(a->pics[i].iPOC == a->ctx.pSliceHeader->iPicOrderCntLsb){
 				a->lastgopremain = a->npics;
-				for(i = 0; i <= a->lbufpicind; i++){
-					if (a->pics[i].iPOC > IMinInt32)
-						a->pics[i].bLastGOP = true;
-				}
+				for(i = 0; i <= a->lbufpicind; i++)
+					a->pics[i].bLastGOP = a->pics[i].iPOC > IMinInt32;
 				break;
 			}
 		}
@@ -68,10 +64,11 @@
 
 	for(i = 0; i < nelem(a->pics); i++){
 		if(a->pics[i].iPOC == IMinInt32){
-			memmove(&a->pics[i].sBufferInfo, &a->info, sizeof (SBufferInfo));
+			memmove(&a->pics[i].sBufferInfo, &a->info, sizeof(a->info));
+			a->pics[i].uiDecodingTimeStamp = ts;
 			a->pics[i].iPOC = a->ctx.pSliceHeader->iPicOrderCntLsb;
-			a->pics[i].uiDecodingTimeStamp = a->ctx.uiDecodingTimeStamp;
 			a->pics[i].iPicBuffIdx = a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->iPicBuffIdx;
+			a->pics[i].uiDecodingTimeStamp = ts;
 			a->ctx.pLastDecPicInfo->pPreviousDecodedPictureInDpb->iRefCount++;
 			a->pics[i].bLastGOP = false;
 			a->lastbuffered = i;
@@ -83,7 +80,7 @@
 		}
 	}
 
-	PPicBuff pPicBuff = a->ctx.pPicBuff;
+	PPicBuff picbuf = a->ctx.pPicBuff;
 	if(a->lastgopremain > 0){
 		a->minpoc = IMinInt32;
 		firstvalid = -1;
@@ -104,13 +101,13 @@
 			}
 		}
 		a->lastwritten = a->minpoc;
-		memmove(&a->info, &a->pics[a->picind].sBufferInfo, sizeof (SBufferInfo));
+		memmove(&a->info, &a->pics[a->picind].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->picind].iPOC = IMinInt32;
-		PPicture pPic = pPicBuff->ppPic[a->pics[a->picind].iPicBuffIdx];
-		pPic->iRefCount--;
+		ts = a->pics[a->picind].uiDecodingTimeStamp;
+		picbuf->ppPic[a->pics[a->picind].iPicBuffIdx]->iRefCount--;
 		a->pics[a->picind].bLastGOP = false;
 		a->minpoc = IMinInt32;
 		a->npics--;
@@ -117,7 +114,7 @@
 		a->lastgopremain--;
 		if(a->lastgopremain == 0)
 			a->lastwritten = IMinInt32;
-		return;
+		return ts;
 	}
 
 	if(a->npics > 0){
@@ -140,19 +137,21 @@
 			}
 		}
 	}
-	if(a->minpoc > IMinInt32 && (a->lastwritten > IMinInt32 && a->minpoc - a->lastwritten <= 1) || a->minpoc < a->ctx.pSliceHeader->iPicOrderCntLsb){
+	if(a->minpoc > IMinInt32 && (a->lastwritten > IMinInt32 && a->minpoc - a->lastwritten <= 1) || a->minpoc < a->ctx.pSliceHeader->iPicOrderCntLsb){//a->pics[a->lastbuffered].iPOC){
 		a->lastwritten = a->minpoc;
 		memmove(&a->info, &a->pics[a->picind].sBufferInfo, sizeof (SBufferInfo));
 		a->data[0] = a->info.pDst[0];
 		a->data[1] = a->info.pDst[1];
 		a->data[2] = a->info.pDst[2];
+		ts = a->pics[a->picind].uiDecodingTimeStamp;
 		a->pics[a->picind].iPOC = IMinInt32;
-		PPicture pPic = pPicBuff->ppPic[a->pics[a->picind].iPicBuffIdx];
-		pPic->iRefCount--;
+		picbuf->ppPic[a->pics[a->picind].iPicBuffIdx]->iRefCount--;
 		a->pics[a->picind].bLastGOP = false;
 		a->minpoc = IMinInt32;
 		a->npics--;
 	}
+
+	return ts;
 }
 
 static void
@@ -179,11 +178,14 @@
 
 		if(a->ctx.pSps->uiProfileIdc != 66 && a->ctx.pSps->uiProfileIdc != 83){
 			/* non-baseline needs reordering */
-			reorder(a);
+			memset(a->data, 0, sizeof(a->data));
+			sf.timestamp = reorder(a, sf.timestamp);
 			if(a->data[0] == nil)
 				continue;
 		}
 
+		if(sf.timestamp < lasttimestamp) /* in case frames AREN'T reordered (mcfs HAS to do that) */
+			continue;
 		w = a->info.UsrData.sSystemBuffer.iWidth;
 		h = a->info.UsrData.sSystemBuffer.iHeight;
 		if((f = malloc(sizeof(*f) + w*h*3)) == nil)