Skip to content

Commit

Permalink
Merge pull request #32 from edgeware/clearer-doc
Browse files Browse the repository at this point in the history
Improved documentation
  • Loading branch information
tobbee authored Nov 17, 2020
2 parents 3ce9f47 + 45fbead commit 9528d72
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 32 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/edgeware/mp4ff)](https://goreportcard.com/report/github.com/edgeware/mp4ff)
[![license](https://img.shields.io/github/license/edgeware/mp4ff.svg)](https://github.com/edgeware/mp4ff/blob/master/LICENSE.md)

MP4/ISOBMFF media file parser and writer. Focused on fragmented files as used for streaming in DASH, MSS and HLS fMP4.
Package mp4ff implements MP4 media file parser and writer for AVC video, AAC audio and stpp/wvtt subtitles.
Focused on fragmented files as used for streaming in DASH, MSS and HLS fMP4.

## Library

The library has functions for parsing (called Decode) and writing (Encode).
The library has functions for parsing (called Decode) and writing (Encode) in the package `mp4ff/mp4`.
It also contains codec specific parsing of of AVC/H.264 including complete parsing of
SPS and PPS in the package `mp4ff.avc`.

Traditional multiplexed non-fragmented mp4 files can be parsed and decoded, see `examples/segment`.
Traditional multiplexed non-fragmented mp4 files can also be parsed and decoded, see `examples/segment`.

The focus is, however, on non-multiplexed single-track fragmented mp4 files as used in DASH, HLS, and CMAF.

Expand Down Expand Up @@ -114,7 +117,7 @@ it can be calculated. It is set to `MoofBox.Size()+8`.

Some simple command line tools are available in `cmd`.

1. `mp4ff-pslister` extracts and displays pps and sps for AVC in an mp4 file
1. `mp4ff-pslister` extracts and displays pps and sps for AVC in an mp4 file.

## Example code

Expand All @@ -133,7 +136,7 @@ The APIs should be fairly stable, but minor non-backwards-compatible tweaks may

MIT, see [LICENSE.md](LICENSE.md).

Some code in pkg/mp4, es from or is based on https://github.com/jfbus/mp4 which has
Some code in pkg/mp4, comes from or is based on https://github.com/jfbus/mp4 which has
`Copyright (c) 2015 Jean-François Bustarret`.

Some code in pkg/bits comes from or is based on https://github.com/tcnksm/go-casper/tree/master/internal/bits
Expand Down
4 changes: 4 additions & 0 deletions avc/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
Package avc implements parsing of AVC(H.264) nal headers, slice headers and complete SPS and PPS.
*/
package avc
4 changes: 0 additions & 4 deletions bits/README.md

This file was deleted.

8 changes: 5 additions & 3 deletions bits/bits.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"io"
)

// Writer writes bits into underlying io.Writer. Stops at first error
// Writer writes bits into underlying io.Writer. Stops writing at first error.
// Errors that have occured can later be checked with Error().
type Writer struct {
n int // current number of bits
v uint // current accumulated value
err error // Has a write caused an error
err error // The first error caused by any write operation

wr io.Writer
}
Expand Down Expand Up @@ -130,11 +131,12 @@ func (r *Reader) MustRead(n int) uint {
return v
}

// MustReadFlag - read 1 bit into flag
// MustReadFlag - read 1 bit into flag and panic if not possible
func (r *Reader) MustReadFlag() bool {
return r.MustRead(1) == 1
}

// mask - n-bit binary mask
func mask(n int) uint {
return (1 << uint(n)) - 1
}
4 changes: 2 additions & 2 deletions bits/doc.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
Package bits implements bit reading and writing.
Package bits implements bit reading and writing including EBSP.
Beyond plain bit reading and writing, it includes reading of ebsp (Encapsulated Byte Sequence Packets)
Golomb codes as usid in the AVC/H.264 video coding standard.
Golomb codes as used in the AVC/H.264 and HEVC video coding standards.
*/
package bits
21 changes: 13 additions & 8 deletions bits/ebsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import (
"io"
)

const (
startCodeEmulationPreventionByte = 0x03
)

var ErrNotReedSeeker = errors.New("Reader does not support Seek")

// NewEBSPReader - return a new Reader.
Expand Down Expand Up @@ -39,7 +43,7 @@ func (r *EBSPReader) MustRead(n int) uint {
panic("Reading error")
}
r.pos++
if r.zeroCount == 2 {
if r.zeroCount == 2 && b == startCodeEmulationPreventionByte {
err = binary.Read(r.rd, binary.BigEndian, &b)
if err != nil {
panic("Reading error")
Expand Down Expand Up @@ -70,7 +74,7 @@ func (r *EBSPReader) MustReadFlag() bool {
return r.MustRead(1) == 1
}

// MustReadExpGolomb - Read one unsigned exponential golomb code
// MustReadExpGolomb - Read one unsigned exponential golomb code. Panic if not possible
func (r *EBSPReader) MustReadExpGolomb() uint {
leadingZeroBits := 0

Expand All @@ -88,7 +92,7 @@ func (r *EBSPReader) MustReadExpGolomb() uint {
return res + endBits
}

// MustReadSignedGolomb - Read one signed exponential golomb code
// MustReadSignedGolomb - Read one signed exponential golomb code. Panic if not possible
func (r *EBSPReader) MustReadSignedGolomb() int {
unsignedGolomb := r.MustReadExpGolomb()
if unsignedGolomb%2 == 1 {
Expand All @@ -108,13 +112,13 @@ func (r *EBSPReader) NrBitsReadInCurrentByte() int {
return 8 - r.n
}

// EBSP2rbsp - convert from EBSP to RBSP by removing escape 0x03 after two 0x00
// EBSP2rbsp - convert from EBSP to RBSP by removing start code emulation prevention bytes
func EBSP2rbsp(ebsp []byte) []byte {
zeroCount := 0
output := make([]byte, 0, len(ebsp))
for i := 0; i < len(ebsp); i++ {
b := ebsp[i]
if zeroCount == 2 && b == 3 {
if zeroCount == 2 && b == startCodeEmulationPreventionByte {
zeroCount = 0
} else {
if b != 0 {
Expand All @@ -140,7 +144,7 @@ func (r *EBSPReader) Read(n int) (uint, error) {
return 0, err
}
r.pos++
if r.zeroCount == 2 && b <= 3 {
if r.zeroCount == 2 && b == startCodeEmulationPreventionByte {
err = binary.Read(r.rd, binary.BigEndian, &b)
if err != nil {
return 0, err
Expand Down Expand Up @@ -220,7 +224,7 @@ func (r *EBSPReader) IsSeeker() bool {
}

// MoreRbspData - false if next bit is 1 and last 1 in fullSlice
// Underlying reader must support ReadSeeker interface
// Underlying reader must support ReadSeeker interface to reset after check
func (r *EBSPReader) MoreRbspData() (bool, error) {
if !r.IsSeeker() {
return false, ErrNotReedSeeker
Expand All @@ -239,7 +243,7 @@ func (r *EBSPReader) MoreRbspData() (bool, error) {
}
return true, nil
}
// Must check if all remaining bits are zero
// If all remainging bits are zero, there is no more rbsp data
more := false
for {
b, err := r.Read(1)
Expand All @@ -261,6 +265,7 @@ func (r *EBSPReader) MoreRbspData() (bool, error) {
return more, nil
}

// reset EBSPReader based on copy of previous state
func (r *EBSPReader) reset(prevState EBSPReader) error {
rdSeek, ok := r.rd.(io.ReadSeeker)

Expand Down
1 change: 1 addition & 0 deletions bits/esbp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func TestGolomb(t *testing.T) {
})
}

// TestEbspParser including startCodeEmulationPrevention removal
func TestEbspParser(t *testing.T) {

cases := []struct{ name, start, want string }{
Expand Down
2 changes: 1 addition & 1 deletion cmd/mp4ff-pslister/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func main() {
avcC := stsd.AvcX.AvcC
trackID := trak.Tkhd.TrackID
if *verbose {
fmt.Printf("Videavo track ID=%d\n", trackID)
fmt.Printf("Video track ID=%d\n", trackID)
}
var spsInfo *avc.SPS
var err error
Expand Down
3 changes: 2 additions & 1 deletion doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Package mp4ff implements MP4 media file parser and writer.
Package mp4ff implements MP4 media file parser and writer for AVC video, AAC audio and stpp/wvtt subtitles.
Focused on fragmented files as used for streaming in DASH, MSS and HLS fMP4.
MP4 library
Expand Down
6 changes: 3 additions & 3 deletions examples/resegmenter/main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// mp4ff-resegmenter resegments mp4 files into concatenated segments with new duration.
// resegmenter resegments mp4 files into concatenated segments with new duration.
//
// The mp4 files must look like a CMAF track with init segment and media segments.
// The input file must be a CMAF track with init segment and media segments.
//
// Usage:
//
// mp4ff-resegmenter -f <input.mp4> -o <output.mp4> -b <chunk_dur>
// resegmenter -f <input.mp4> -o <output.mp4> -b <chunk_dur>
// -b int
// Required: chunk duration (ticks)
// -f string
Expand Down
6 changes: 3 additions & 3 deletions examples/segmenter/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// segmenter segments a progressive mp4 file into audio and video segments
//
// There should be at most one audio and one video track in the file.
// There should be at most one audio and one video track in the input.
// The output files will be named as
// init segments: <output>_a.mp4 and <output>_v.mp4
// media segments: <output>_a_<n>.m4s and <output>_v_<n>.m4s where n >= 1
// init segments: <output>_a.mp4 and <output>_v.mp4
// media segments: <output>_a_<n>.m4s and <output>_v_<n>.m4s where n >= 1
//
// Usage:
//
Expand Down
10 changes: 8 additions & 2 deletions examples/tree/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// mp4ff-tree print a tree of the box structure of a file.
// tree prints a tree of the box structure of a file using the Dump method of boxes.
//
// Usage:
//
Expand Down Expand Up @@ -30,5 +30,11 @@ func main() {
}
defer ifd.Close()
parsedMp4, err := mp4.DecodeFile(ifd)
parsedMp4.Dump(os.Stdout, " ")
if err != nil {
log.Fatal(err)
}
err = parsedMp4.Dump(os.Stdout, " ")
if err != nil {
log.Fatal(err)
}
}

0 comments on commit 9528d72

Please sign in to comment.