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)