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;
}