1
0
mirror of https://github.com/Luzifer/cam2mjpeg.git synced 2024-09-16 13:58:25 +00:00

Replace mjpeg reader to fix broken frames

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2019-04-29 13:02:23 +02:00
parent ce8b98b9cb
commit e0d5f6a195
Signed by: luzifer
GPG Key ID: DC2729FDD34BE99E
2 changed files with 33 additions and 13 deletions

44
main.go
View File

@ -3,7 +3,6 @@ package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
"os/exec"
@ -96,27 +95,46 @@ func main() {
log.Debug("ffmpeg spawned")
buf := new(bytes.Buffer)
var (
br, bw int
buf = make([]byte, 10*1024*1024) // 10MB (jpg should be smaller)
)
for {
if _, err := io.CopyN(buf, out, 1024); err != nil {
log.WithError(err).Error("Failed to read ffmpeg output")
break
// If buffer was read, slide the remains to the beginning
if br > 0 {
copy(buf, buf[br:bw])
bw -= br
br = 0
}
eoj := bytes.Index(buf.Bytes(), endOfJPEG)
if eoj == -1 {
// Fill buffer
n, err := out.Read(buf[bw:])
if err != nil {
log.WithError(err).Fatal("Unable to read from output")
}
bw += n
if n == 0 {
// Nothing read, try again
continue
}
img := buf.Next(eoj + len(endOfJPEG))
// Extract as many images as possible before next read
for eoj := bytes.Index(buf[br:bw], endOfJPEG); eoj >= 0; eoj = bytes.Index(buf[br:bw], endOfJPEG) {
eoj += len(endOfJPEG)
img := make([]byte, eoj-br)
copy(img, buf[br:br+eoj])
if !bytes.HasPrefix(img, beginOfJPEG) || !bytes.HasSuffix(img, endOfJPEG) {
log.Warn("Found invalid JPEG, skipping")
continue
br += eoj
if !bytes.HasPrefix(img, beginOfJPEG) || !bytes.HasSuffix(img, endOfJPEG) {
log.Warn("Found invalid JPEG, skipping")
continue
}
go sendImage(img)
}
go sendImage(img)
}
}

View File

@ -5,6 +5,7 @@ import (
"mime/multipart"
"net/http"
"net/textproto"
"strconv"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
@ -38,6 +39,7 @@ func handleMJPEG(res http.ResponseWriter, r *http.Request, imgs chan []byte, uid
err := func() error {
partHeader := make(textproto.MIMEHeader)
partHeader.Add("Content-Type", "image/jpeg")
partHeader.Add("Content-Length", strconv.Itoa(len(img)))
partWriter, err := mimeWriter.CreatePart(partHeader)
if err != nil {