func (dec *Decoder) Start(n int) error {
	if n < 1 {
		n = 1
	}
	if err := dec.readOSMHeader(); err != nil {
		return err
	}
	for i := 0; i < n; i++ {
		input := make(chan pair)
		output := make(chan pair)
		go func() {
			dd := new(dataDecoder)
			for p := range input {
				if p.e == nil {
					objects, err := dd.Decode(p.i.(*OSMPBF.Blob))
					output <- pair{objects, err}
				} else {
					output <- pair{nil, p.e}
				}
			}
			close(output)
		}()
		dec.inputs = append(dec.inputs, input)
		dec.outputs = append(dec.outputs, output)
	}
	go func() {
		var inputIndex int
		for {
			input := dec.inputs[inputIndex]
			inputIndex = (inputIndex + 1) % n
			blobHeader, blob, err := dec.readFileBlock()
			if err == nil && blobHeader.GetType() != "OSMData" {
				err = fmt.Errorf("unexpected fileblock of type %s", blobHeader.GetType())
			}
			if err == nil {
				input <- pair{blob, nil}
			} else {
				input <- pair{nil, err}
				for _, input := range dec.inputs {
					close(input)
				}
				return
			}
		}
	}()
	go func() {
		var outputIndex int
		for {
			output := dec.outputs[outputIndex]
			outputIndex = (outputIndex + 1) % n
			p := <-output
			if p.i != nil {
				for _, o := range p.i.([]interface{}) {
					dec.serializer <- pair{o, nil}
				}
			}
			if p.e != nil {
				dec.serializer <- pair{nil, p.e}
				close(dec.serializer)
				return
			}
		}
	}()
	return nil
}
Start decoding process using n goroutines.
package osmpbf  
import (
	"bytes"
	"compress/zlib"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"sync"
	"time"
	"github.com/qedus/osmpbf/OSMPBF"
	"google.golang.org/protobuf/proto"
)
const (
	maxBlobHeaderSize = 64 * 1024
	initialBlobBufSize = 1 * 1024 * 1024
	MaxBlobSize = 32 * 1024 * 1024
)
var (
	parseCapabilities = map[string]bool{
		"OsmSchema-V0.6": true,
		"DenseNodes":     true,
	}
)
type BoundingBox struct {
	Left   float64
	Right  float64
	Top    float64
	Bottom float64
}
type Header struct {
	BoundingBox                      *BoundingBox
	RequiredFeatures                 []string
	OptionalFeatures                 []string
	WritingProgram                   string
	Source                           string
	OsmosisReplicationTimestamp      time.Time
	OsmosisReplicationSequenceNumber int64
	OsmosisReplicationBaseUrl        string
}
type Info struct {
	Version   int32
	Uid       int32
	Timestamp time.Time
	Changeset int64
	User      string
	Visible   bool
}
type Node struct {
	ID   int64
	Lat  float64
	Lon  float64
	Tags map[string]string
	Info Info
}
type Way struct {
	ID      int64
	Tags    map[string]string
	NodeIDs []int64
	Info    Info
}
type Relation struct {
	ID      int64
	Tags    map[string]string
	Members []Member
	Info    Info
}
type MemberType int
const (
	NodeType MemberType = iota
	WayType
	RelationType
)
type Member struct {
	ID   int64
	Type MemberType
	Role string
}
type pair struct {
	i interface{}
	e error
}
type Decoder struct {
	r          io.Reader
	serializer chan pair
	buf *bytes.Buffer
	header *Header
	headerOnce sync.Once
	inputs  []chan<- pair
	outputs []<-chan pair
}
func NewDecoder(r io.Reader) *Decoder {
	d := &Decoder{
		r:          r,
		serializer: make(chan pair, 8000),  
	}
	d.SetBufferSize(initialBlobBufSize)
	return d
}
func (dec *Decoder) SetBufferSize(n int) {
	dec.buf = bytes.NewBuffer(make([]byte, 0, n))
}
func (dec *Decoder) Header() (*Header, error) {
	return dec.header, dec.readOSMHeader()
}