From d92e0bfb5e2e47131808a6e9d549ade1b26d1f34 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 11:28:43 +0930 Subject: [PATCH 1/9] codec/h264/h264dec/decode.go: wrote function picOrderCntType0 to handle derivation of TopFieldOrderCnt and BottomFieldOrderCnt when pic_order_cnt_type == 0 --- codec/h264/h264dec/decode.go | 35 +++++++++++++++++++++++++++++++++++ codec/h264/h264dec/slice.go | 11 ++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index 22cfc181..5a914263 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -23,3 +23,38 @@ LICENSE */ package h264dec + +// picOrderCntType0 is used to return topFieldOrderCnt and bottomFieldOrderCnt +// when pic_order_cnt_type i.e vid.PicOrderCntType == 0, using the process +// defined in section 8.2.1.1 of the specifications. +func picOrderCntType0(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { + prevPicOrderCntMsb, prevPicOrderCntLsb := 0, 0 + topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 + + // NB: We're currently only handling IDRs so panic. + if !vid.currPic.isIDR { + panic("not implemented") + } + + switch { + case (ctx.PicOrderCntLsb < prevPicOrderCntLsb) && ((prevPicOrderCntLsb - ctx.PicOrderCntLsb) >= (vid.maxPicOrderCntLsb / 2)): + vid.picOrderCntMsb = prevPicOrderCntMsb + vid.maxPicOrderCntLsb + case (ctx.PicOrderCntLsb > prevPicOrderCntLsb) && ((ctx.PicOrderCntLsb - prevPicOrderCntLsb) > (vid.maxPicOrderCntLsb / 2)): + vid.picOrderCntMsb = prevPicOrderCntMsb - vid.maxPicOrderCntLsb + default: + vid.picOrderCntMsb = prevPicOrderCntMsb + } + + if !vid.currPic.isBottomField { + topFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb + } + + if !vid.currPic.isTopField { + if !ctx.FieldPic { + bottomFieldOrderCnt = topFieldOrderCnt + ctx.DeltaPicOrderCntBottom + } else { + bottomFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb + } + } + return +} diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 4952cfd9..83e3b7bf 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -35,12 +35,21 @@ const ( chroma444 ) +type picture struct { + isIDR bool + isBottomField bool + isTopField bool +} + type VideoStream struct { *SPS *PPS Slices []*SliceContext - ChromaArrayType int + ChromaArrayType int + currPic picture + maxPicOrderCntLsb int + picOrderCntMsb int } type SliceContext struct { From 43118814fbc9b1c78d88be98ac21718bba76cad2 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 13:03:11 +0930 Subject: [PATCH 2/9] codec/h264/h264dec/decode.go: added picOrderCntType1 to derive topfieldOrderCnt and bottomFieldOrderCnt for when picOrderCntType == 1 --- codec/h264/h264dec/decode.go | 64 ++++++++++++++++++++++++++++++++---- codec/h264/h264dec/slice.go | 15 ++++++--- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index 5a914263..b3ec42dc 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -26,13 +26,14 @@ package h264dec // picOrderCntType0 is used to return topFieldOrderCnt and bottomFieldOrderCnt // when pic_order_cnt_type i.e vid.PicOrderCntType == 0, using the process -// defined in section 8.2.1.1 of the specifications. -func picOrderCntType0(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { +// defined in section 8.2.1.1 of the specifications. If topFieldOrderCnt or +// bottomFieldOrderCnt are -1 they are unset. +func picOrderCntType0(vid *VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { prevPicOrderCntMsb, prevPicOrderCntLsb := 0, 0 topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 // NB: We're currently only handling IDRs so panic. - if !vid.currPic.isIDR { + if !vid.idrPicFlag { panic("not implemented") } @@ -45,11 +46,9 @@ func picOrderCntType0(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bott vid.picOrderCntMsb = prevPicOrderCntMsb } - if !vid.currPic.isBottomField { + if !ctx.BottomField { topFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb - } - - if !vid.currPic.isTopField { + } else { if !ctx.FieldPic { bottomFieldOrderCnt = topFieldOrderCnt + ctx.DeltaPicOrderCntBottom } else { @@ -58,3 +57,54 @@ func picOrderCntType0(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bott } return } + +// picOrderCntType1 is used to return topFieldOrderCnt and bottomFieldOrderCnt +// when vic.PicOrderCntType == 1 according to logic defined in section 8.2.1.2 +// of the specifications. If topFieldOrderCnt or bottomFieldOrderCnt are -1, +// then they are considered unset. +func picOrderCntType1(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { + topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 + + // TODO: this will be prevFrameNum when we do frames other than IDR. + _ = vid.priorPic.FrameNum + + if vid.idrPicFlag { + vid.frameNumOffset = 0 + } else { + panic("not implemented") + } + + absFrameNum := 0 + if ctx.NumRefFramesInPicOrderCntCycle != 0 { + absFrameNum = vid.frameNumOffset + ctx.FrameNum + } + + if ctx.RefIdc == 0 && absFrameNum > 0 { + absFrameNum = absFrameNum - 1 + } + + var expectedPicOrderCnt int + if absFrameNum > 0 { + picOrderCntCycleCnt := (absFrameNum - 1) / int(ctx.NumRefFramesInPicOrderCntCycle) + frameNumInPicOrderCntCycle := (absFrameNum - 1) % int(ctx.NumRefFramesInPicOrderCntCycle) + expectedPicOrderCnt = picOrderCntCycleCnt * vid.expectedDeltaPerPicOrderCntCycle + for i := 0; i <= frameNumInPicOrderCntCycle; i++ { + expectedPicOrderCnt = expectedPicOrderCnt + ctx.OffsetForRefFrameList[i] + } + } + + if ctx.RefIdc == 0 { + expectedPicOrderCnt = expectedPicOrderCnt + int(ctx.OffsetForNonRefPic) + } + + switch { + case !ctx.FieldPic: + topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] + bottomFieldOrderCnt = topFieldOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[1] + case !ctx.BottomField: + topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] + default: + bottomFieldOrderCnt = expectedPicOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[0] + } + return +} diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 83e3b7bf..3a109a41 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -36,6 +36,7 @@ const ( ) type picture struct { + *SliceContext isIDR bool isBottomField bool isTopField bool @@ -46,13 +47,19 @@ type VideoStream struct { *PPS Slices []*SliceContext - ChromaArrayType int - currPic picture - maxPicOrderCntLsb int - picOrderCntMsb int + ChromaArrayType int + priorPic *picture + currPic *picture + maxPicOrderCntLsb int + picOrderCntMsb int + idrPicFlag bool + frameNumOffset int + expectedDeltaPerPicOrderCntCycle int } type SliceContext struct { + *SPS + *PPS *NALUnit *Slice } From c0be9b1910055cb98c12c08a7ad3747866866c62 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 13:26:46 +0930 Subject: [PATCH 3/9] codec/h264/h264dec/decode.go: added picOrderCntType2 to derive topfieldOrderCnt and bottomFieldOrderCnt for when picOrderCntType == 2 --- codec/h264/h264dec/decode.go | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index b3ec42dc..19ae3aa0 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -108,3 +108,41 @@ func picOrderCntType1(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bott } return } + +// picOrderCntType2 is used to return topFieldOrderCnt and bottomFieldOrderCnt +// when vic.PicOrderCntType == 1 according to logic defined in section 8.2.1.3 +// of the specifications. If topFieldOrderCnt or bottomFieldOrderCnt are -1, +// then they are considered unset. +func picOrderCntType2(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { + topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 + + // TODO: this will be prevFrameNum when we do frames other than IDR. + _ = vid.priorPic.FrameNum + + if vid.idrPicFlag { + vid.frameNumOffset = 0 + } else { + panic("not implemented") + } + + var tempPicOrderCnt int + switch { + case vid.idrPicFlag: + tempPicOrderCnt = 0 + case ctx.RefIdc == 0: + tempPicOrderCnt = 2*(vid.frameNumOffset+ctx.FrameNum) - 1 + default: + tempPicOrderCnt = 2 * (vid.frameNumOffset + ctx.FrameNum) + } + + switch { + case ctx.FieldPic: + topFieldOrderCnt = tempPicOrderCnt + bottomFieldOrderCnt = tempPicOrderCnt + case ctx.BottomField: + bottomFieldOrderCnt = tempPicOrderCnt + default: + topFieldOrderCnt = tempPicOrderCnt + } + return +} From 31179205b90414a91443d9b33a58b2f28fca13e3 Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 9 Sep 2019 16:18:33 +0930 Subject: [PATCH 4/9] codec/h264/264dec/decode.go: added decodePicOrderCnt to return topFieldOrderCnt and bottomFieldOrderCnt based on picOrderCntType Also added placeholder for a general 'decode' function. --- codec/h264/h264dec/decode.go | 62 ++++++++++++++++++++++++++++++++++-- codec/h264/h264dec/slice.go | 2 ++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index 19ae3aa0..abecbb7e 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -24,11 +24,67 @@ LICENSE package h264dec +import ( + "errors" + "fmt" +) + +// NB: this is a placeholder. +func decode(vid *VideoStream, ctx *SliceContext) error { + var err error + vid.topFieldOrderCnt, vid.bottomFieldOrderCnt, err = decodePicOrderCnt(vid, ctx) + if err != nil { + return fmt.Errorf("could not derive topFieldOrderCnt and bottomFieldOrderCnt, failed with error: %v", err) + } + + // According to 8.2.1 after decoding picture. + if ctx.elements[0].MemoryManagementControlOperation == 5 { + tempPicOrderCnt := picOrderCnt(ctx) + vid.topFieldOrderCnt = vid.topFieldOrderCnt - tempPicOrderCnt + vid.bottomFieldOrderCnt = vid.bottomFieldOrderCnt - tempPicOrderCnt + } + return nil +} + +// TODO: complete this. Unsure how to determine if pic is frame or a +// complementary field pair. +// picOrderCnt as defined by section 8.2.1. +func picOrderCnt(ctx *SliceContext) int { + panic("not implemented") +} + +// decodePicOrderCnt derives topFieldOrderCnt and bottomFieldOrderCnt based +// on the PicOrderCntType using the process defined in section 8.2.1 of the +// specifications. +func decodePicOrderCnt(vid *VideoStream, ctx *SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int, err error) { + // There are some steps listed in 8.2.1 regarding cases when not an IDR frame, + // but we're not yet dealing with that. + // TODO: write steps dealing with not IDR frame. + if !vid.idrPicFlag { + panic("not implemented") + } + + switch ctx.PicOrderCountType { + case 0: + topFieldOrderCnt, bottomFieldOrderCnt = decodePicOrderCntType0(vid, ctx) + case 1: + topFieldOrderCnt, bottomFieldOrderCnt = decodePicOrderCntType1(vid, ctx) + case 2: + topFieldOrderCnt, bottomFieldOrderCnt = decodePicOrderCntType2(vid, ctx) + default: + err = errors.New("invalid PicOrderCountType") + } + + // TODO: check DiffPicOrderCnt( picA, picB ) once picOrderCnt( picX ) is + // worked out. + return +} + // picOrderCntType0 is used to return topFieldOrderCnt and bottomFieldOrderCnt // when pic_order_cnt_type i.e vid.PicOrderCntType == 0, using the process // defined in section 8.2.1.1 of the specifications. If topFieldOrderCnt or // bottomFieldOrderCnt are -1 they are unset. -func picOrderCntType0(vid *VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { +func decodePicOrderCntType0(vid *VideoStream, ctx *SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { prevPicOrderCntMsb, prevPicOrderCntLsb := 0, 0 topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 @@ -62,7 +118,7 @@ func picOrderCntType0(vid *VideoStream, ctx SliceContext) (topFieldOrderCnt, bot // when vic.PicOrderCntType == 1 according to logic defined in section 8.2.1.2 // of the specifications. If topFieldOrderCnt or bottomFieldOrderCnt are -1, // then they are considered unset. -func picOrderCntType1(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { +func decodePicOrderCntType1(vid *VideoStream, ctx *SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 // TODO: this will be prevFrameNum when we do frames other than IDR. @@ -113,7 +169,7 @@ func picOrderCntType1(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bott // when vic.PicOrderCntType == 1 according to logic defined in section 8.2.1.3 // of the specifications. If topFieldOrderCnt or bottomFieldOrderCnt are -1, // then they are considered unset. -func picOrderCntType2(vid VideoStream, ctx SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { +func decodePicOrderCntType2(vid *VideoStream, ctx *SliceContext) (topFieldOrderCnt, bottomFieldOrderCnt int) { topFieldOrderCnt, bottomFieldOrderCnt = -1, -1 // TODO: this will be prevFrameNum when we do frames other than IDR. diff --git a/codec/h264/h264dec/slice.go b/codec/h264/h264dec/slice.go index 3a109a41..b34bef62 100644 --- a/codec/h264/h264dec/slice.go +++ b/codec/h264/h264dec/slice.go @@ -55,6 +55,8 @@ type VideoStream struct { idrPicFlag bool frameNumOffset int expectedDeltaPerPicOrderCntCycle int + topFieldOrderCnt int + bottomFieldOrderCnt int } type SliceContext struct { From 0df182018ae446b1245f7a65ad5d2dbf6a1d9b9e Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 10 Sep 2019 11:32:46 +0930 Subject: [PATCH 5/9] codec/h264/h264dec/decode.go: using else if structure instead of switch to derive value of vid.picOrderCntMsb --- codec/h264/h264dec/decode.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index abecbb7e..25c81c75 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -93,13 +93,11 @@ func decodePicOrderCntType0(vid *VideoStream, ctx *SliceContext) (topFieldOrderC panic("not implemented") } - switch { - case (ctx.PicOrderCntLsb < prevPicOrderCntLsb) && ((prevPicOrderCntLsb - ctx.PicOrderCntLsb) >= (vid.maxPicOrderCntLsb / 2)): + vid.picOrderCntMsb = prevPicOrderCntMsb + if ctx.PicOrderCntLsb < prevPicOrderCntLsb && (prevPicOrderCntLsb-ctx.PicOrderCntLsb) >= (vid.maxPicOrderCntLsb/2) { vid.picOrderCntMsb = prevPicOrderCntMsb + vid.maxPicOrderCntLsb - case (ctx.PicOrderCntLsb > prevPicOrderCntLsb) && ((ctx.PicOrderCntLsb - prevPicOrderCntLsb) > (vid.maxPicOrderCntLsb / 2)): + } else if ctx.PicOrderCntLsb > prevPicOrderCntLsb && (ctx.PicOrderCntLsb-prevPicOrderCntLsb) > (vid.maxPicOrderCntLsb/2) { vid.picOrderCntMsb = prevPicOrderCntMsb - vid.maxPicOrderCntLsb - default: - vid.picOrderCntMsb = prevPicOrderCntMsb } if !ctx.BottomField { From 40fa50d4f044e456221d6e6289fb20b830fa7b61 Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 10 Sep 2019 12:06:35 +0930 Subject: [PATCH 6/9] codec/h264/h264dec/decode.go: using if else structure for derivation of topFieldOrderCnt and bottomFieldOrderCnt in decodePicOrderCntType1 function --- codec/h264/h264dec/decode.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index 25c81c75..a777c73f 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -151,13 +151,12 @@ func decodePicOrderCntType1(vid *VideoStream, ctx *SliceContext) (topFieldOrderC expectedPicOrderCnt = expectedPicOrderCnt + int(ctx.OffsetForNonRefPic) } - switch { - case !ctx.FieldPic: + if !ctx.FieldPic { topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] bottomFieldOrderCnt = topFieldOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[1] - case !ctx.BottomField: + } else if !ctx.BottomField { topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] - default: + } else { bottomFieldOrderCnt = expectedPicOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[0] } return From 5939db6f1bbfe62f1973efe6738aaf310f2944de Mon Sep 17 00:00:00 2001 From: Saxon Date: Tue, 10 Sep 2019 12:12:08 +0930 Subject: [PATCH 7/9] codec/h264/h264dec/decode.go: using if else structures for topFieldOrderCnt/bottomFieldOrderCnt value derivations in decodePicOrderCntType2 --- codec/h264/h264dec/decode.go | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index a777c73f..bd686efc 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -178,24 +178,21 @@ func decodePicOrderCntType2(vid *VideoStream, ctx *SliceContext) (topFieldOrderC panic("not implemented") } - var tempPicOrderCnt int - switch { - case vid.idrPicFlag: + tempPicOrderCnt := 2 * (vid.frameNumOffset + ctx.FrameNum) + if vid.idrPicFlag { tempPicOrderCnt = 0 - case ctx.RefIdc == 0: + } else if ctx.RefIdc == 0 { tempPicOrderCnt = 2*(vid.frameNumOffset+ctx.FrameNum) - 1 - default: - tempPicOrderCnt = 2 * (vid.frameNumOffset + ctx.FrameNum) } - switch { - case ctx.FieldPic: + if !ctx.FieldPic { topFieldOrderCnt = tempPicOrderCnt bottomFieldOrderCnt = tempPicOrderCnt - case ctx.BottomField: + } else if ctx.BottomField { bottomFieldOrderCnt = tempPicOrderCnt - default: + } else { topFieldOrderCnt = tempPicOrderCnt } + return } From 117a75ae554e5ffcdb3f97c0d9c0d3584eb1008a Mon Sep 17 00:00:00 2001 From: Saxon Date: Mon, 16 Sep 2019 22:07:57 +0930 Subject: [PATCH 8/9] codec/h264/h264dec: simplified logic where there are things applicable to non-IDRs, which we don't handle yet. --- codec/h264/h264dec/decode.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index bd686efc..ac4ee928 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -122,12 +122,12 @@ func decodePicOrderCntType1(vid *VideoStream, ctx *SliceContext) (topFieldOrderC // TODO: this will be prevFrameNum when we do frames other than IDR. _ = vid.priorPic.FrameNum - if vid.idrPicFlag { - vid.frameNumOffset = 0 - } else { + if !vid.idrPicFlag { panic("not implemented") } + vid.frameNumOffset = 0 + absFrameNum := 0 if ctx.NumRefFramesInPicOrderCntCycle != 0 { absFrameNum = vid.frameNumOffset + ctx.FrameNum @@ -172,18 +172,13 @@ func decodePicOrderCntType2(vid *VideoStream, ctx *SliceContext) (topFieldOrderC // TODO: this will be prevFrameNum when we do frames other than IDR. _ = vid.priorPic.FrameNum - if vid.idrPicFlag { - vid.frameNumOffset = 0 - } else { + if !vid.idrPicFlag { panic("not implemented") } + vid.frameNumOffset = 0 - tempPicOrderCnt := 2 * (vid.frameNumOffset + ctx.FrameNum) - if vid.idrPicFlag { - tempPicOrderCnt = 0 - } else if ctx.RefIdc == 0 { - tempPicOrderCnt = 2*(vid.frameNumOffset+ctx.FrameNum) - 1 - } + // TODO: handle tempPicOrderCnt calculation for when not IDR. + var tempPicOrderCnt int if !ctx.FieldPic { topFieldOrderCnt = tempPicOrderCnt From 4c7f36ee364ff49af8188ed72adee20374889ef5 Mon Sep 17 00:00:00 2001 From: Saxon Date: Wed, 18 Sep 2019 19:41:32 +0930 Subject: [PATCH 9/9] codec/h264/h264dec/decode.go: slightly simplified if-else statements regarding BottomField and FieldPic --- codec/h264/h264dec/decode.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/codec/h264/h264dec/decode.go b/codec/h264/h264dec/decode.go index ac4ee928..d4d929e2 100644 --- a/codec/h264/h264dec/decode.go +++ b/codec/h264/h264dec/decode.go @@ -102,12 +102,10 @@ func decodePicOrderCntType0(vid *VideoStream, ctx *SliceContext) (topFieldOrderC if !ctx.BottomField { topFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb + } else if ctx.FieldPic { + bottomFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb } else { - if !ctx.FieldPic { - bottomFieldOrderCnt = topFieldOrderCnt + ctx.DeltaPicOrderCntBottom - } else { - bottomFieldOrderCnt = vid.picOrderCntMsb + ctx.PicOrderCntLsb - } + bottomFieldOrderCnt = topFieldOrderCnt + ctx.DeltaPicOrderCntBottom } return } @@ -154,10 +152,10 @@ func decodePicOrderCntType1(vid *VideoStream, ctx *SliceContext) (topFieldOrderC if !ctx.FieldPic { topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] bottomFieldOrderCnt = topFieldOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[1] - } else if !ctx.BottomField { - topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] - } else { + } else if ctx.BottomField { bottomFieldOrderCnt = expectedPicOrderCnt + int(ctx.OffsetForTopToBottomField) + ctx.DeltaPicOrderCnt[0] + } else { + topFieldOrderCnt = expectedPicOrderCnt + ctx.DeltaPicOrderCnt[0] } return }