func (m *Muxer) writeAudioFrame(frame *C.AVFrame) bool { for C.av_audio_fifo_size(m.fifo) < 1024 { // generate & store in fifo C.fill_audio_frame(frame, m.audioStream.stream.codec) frame_size := frame.nb_samples if C.av_audio_fifo_realloc(m.fifo, C.av_audio_fifo_size(m.fifo)+frame_size) < 0 { return false } if C.av_audio_fifo_write(m.fifo, (*unsafe.Pointer)(unsafe.Pointer(&frame.data[0])), frame_size) < frame_size { return false } } got_packet := C.int(0) for C.av_audio_fifo_size(m.fifo) >= 1024 { // read & encode & write frame_size := C.min(C.av_audio_fifo_size(m.fifo), m.audioStream.stream.codec.frame_size) output_frame := C.alloc_audio_frame(m.audioStream.stream.codec) if C.av_audio_fifo_read(m.fifo, (*unsafe.Pointer)(unsafe.Pointer(&output_frame.data[0])), frame_size) < frame_size { C.av_frame_free(&output_frame) return false } pkt := C.AVPacket{} C.av_init_packet(&pkt) output_frame.pts = C.int64_t(m.audioStream.ts) m.audioStream.ts += int(m.audioStream.stream.codec.frame_size) if C.avcodec_encode_audio2(m.audioStream.stream.codec, &pkt, frame, &got_packet) < 0 { C.av_free_packet(&pkt) return false } if got_packet == 0 { continue } C.av_packet_rescale_ts(&pkt, m.audioStream.stream.codec.time_base, m.audioStream.stream.time_base) pkt.stream_index = m.audioStream.stream.index if C.av_interleaved_write_frame(m.context, &pkt) < 0 { return false } } return true }
func (m *Muxer) writeVideoFrame(frame *C.AVFrame) bool { if m.capture.Read(frame) != nil { return false } if m.display != nil { m.display.Render(frame) } pkt := C.AVPacket{} C.av_init_packet(&pkt) frame.pts = C.int64_t(m.videoStream.ts) m.videoStream.ts++ got_packet := C.int(0) if C.avcodec_encode_video2(m.videoStream.stream.codec, &pkt, frame, &got_packet) < 0 { C.av_free_packet(&pkt) return false } if got_packet == 0 { return false } C.av_packet_rescale_ts(&pkt, m.videoStream.stream.codec.time_base, m.videoStream.stream.time_base) pkt.stream_index = m.videoStream.stream.index return C.av_interleaved_write_frame(m.context, &pkt) == 0 }
//Convert valid timing fields (timestamps / durations) in a packet from one timebase to another. func (p *Packet) AvPacketRescaleTs(r, r2 Rational) { C.av_packet_rescale_ts((*C.struct_AVPacket)(p), (C.struct_AVRational)(r), (C.struct_AVRational)(r2)) }
//Convert valid timing fields (timestamps / durations) in a packet from one timebase to another. //void av_packet_rescale_ts (AVPacket *pkt, AVRational tb_src, AVRational tb_dst) func Av_packet_rescale_ts(p *AVPacket, r, r2 AVRational) { C.av_packet_rescale_ts((*C.struct_AVPacket)(p), (C.struct_AVRational)(r), (C.struct_AVRational)(r2)) }