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 {