github.com/cnotch/ipchub@v1.1.0/av/format/flv/h264_packetizer.go (about)

     1  // Copyright (c) 2019,CAOHONGJU All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package flv
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/cnotch/ipchub/av/codec"
    11  	"github.com/cnotch/ipchub/av/codec/h264"
    12  )
    13  
    14  type h264Packetizer struct {
    15  	meta      *codec.VideoMeta
    16  	tagWriter TagWriter
    17  }
    18  
    19  func NewH264Packetizer(meta *codec.VideoMeta, tagWriter TagWriter) Packetizer {
    20  	h264p := &h264Packetizer{
    21  		meta:      meta,
    22  		tagWriter: tagWriter,
    23  	}
    24  	return h264p
    25  }
    26  
    27  func (h264p *h264Packetizer) PacketizeSequenceHeader() error {
    28  	record := NewAVCDecoderConfigurationRecord(h264p.meta.Sps, h264p.meta.Pps)
    29  	body, _ := record.Marshal()
    30  
    31  	videoData := &VideoData{
    32  		FrameType:       FrameTypeKeyFrame,
    33  		CodecID:         CodecIDAVC,
    34  		H2645PacketType: H2645PacketTypeSequenceHeader,
    35  		CompositionTime: 0,
    36  		Body:            body,
    37  	}
    38  	data, _ := videoData.Marshal()
    39  
    40  	tag := &Tag{
    41  		TagType:   TagTypeVideo,
    42  		DataSize:  uint32(len(data)),
    43  		Timestamp: 0,
    44  		StreamID:  0,
    45  		Data:      data,
    46  	}
    47  
    48  	return h264p.tagWriter.WriteFlvTag(tag)
    49  }
    50  
    51  func (h264p *h264Packetizer) Packetize(frame *codec.Frame) error {
    52  
    53  	dts := frame.Dts / int64(time.Millisecond)
    54  	pts := frame.Pts / int64(time.Millisecond)
    55  
    56  	videoData := &VideoData{
    57  		FrameType:       FrameTypeInterFrame,
    58  		CodecID:         CodecIDAVC,
    59  		H2645PacketType: H2645PacketTypeNALU,
    60  		CompositionTime: uint32(pts - dts),
    61  		Body:            frame.Payload,
    62  	}
    63  
    64  	if frame.Payload[0]&0x1F == h264.NalIdrSlice {
    65  		videoData.FrameType = FrameTypeKeyFrame
    66  	}
    67  	data, _ := videoData.Marshal()
    68  
    69  	tag := &Tag{
    70  		TagType:   TagTypeVideo,
    71  		DataSize:  uint32(len(data)),
    72  		Timestamp: uint32(dts),
    73  		StreamID:  0,
    74  		Data:      data,
    75  	}
    76  
    77  	return h264p.tagWriter.WriteFlvTag(tag)
    78  }