mirror of
https://github.com/pion/mediadevices.git
synced 2025-09-27 04:46:10 +08:00
Fix reading multiple decoded frames
This commit is contained in:

committed by
Leo (Lei) Kang

parent
0710906fc7
commit
e9f3dc20b6
@@ -41,6 +41,11 @@ vpx_image_t* getFrame(vpx_codec_ctx_t* ctx, vpx_codec_iter_t* iter) {
|
|||||||
return vpx_codec_get_frame(ctx, iter);
|
return vpx_codec_get_frame(ctx, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Frees a decoded frane
|
||||||
|
void freeFrame(vpx_image_t* f) {
|
||||||
|
vpx_img_free(f);
|
||||||
|
}
|
||||||
|
|
||||||
// Frees a decoder context
|
// Frees a decoder context
|
||||||
void freeDecoderCtx(vpx_codec_ctx_t* ctx) {
|
void freeDecoderCtx(vpx_codec_ctx_t* ctx) {
|
||||||
vpx_codec_destroy(ctx);
|
vpx_codec_destroy(ctx);
|
||||||
@@ -65,6 +70,7 @@ type decoder struct {
|
|||||||
codec *C.vpx_codec_ctx_t
|
codec *C.vpx_codec_ctx_t
|
||||||
raw *C.vpx_image_t
|
raw *C.vpx_image_t
|
||||||
cfg *C.vpx_codec_dec_cfg_t
|
cfg *C.vpx_codec_dec_cfg_t
|
||||||
|
iter C.vpx_codec_iter_t
|
||||||
frameIndex int
|
frameIndex int
|
||||||
tStart time.Time
|
tStart time.Time
|
||||||
tLastFrame time.Time
|
tLastFrame time.Time
|
||||||
@@ -93,28 +99,30 @@ func NewDecoder(r io.Reader, p prop.Media) (codec.VideoDecoder, error) {
|
|||||||
return &decoder{
|
return &decoder{
|
||||||
codec: codec,
|
codec: codec,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
iter: nil, // initialize to NULL to start iteration
|
||||||
reader: r,
|
reader: r,
|
||||||
buf: make([]byte, 1024*1024),
|
buf: make([]byte, 1024*1024),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decoder) Read() (image.Image, func(), error) {
|
func (d *decoder) Read() (image.Image, func(), error) {
|
||||||
n, err := d.reader.Read(d.buf)
|
var input *C.vpx_image_t
|
||||||
if err != nil {
|
for {
|
||||||
return nil, nil, err
|
input = C.getFrame(d.codec, &d.iter)
|
||||||
}
|
if input != nil {
|
||||||
if n > 0 {
|
break
|
||||||
|
}
|
||||||
|
d.iter = nil
|
||||||
|
// Read if there are no remained frames in the decoder
|
||||||
|
n, err := d.reader.Read(d.buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
status := C.decodeFrame(d.codec, (*C.uint8_t)(&d.buf[0]), C.uint(n))
|
status := C.decodeFrame(d.codec, (*C.uint8_t)(&d.buf[0]), C.uint(n))
|
||||||
if status != C.VPX_CODEC_OK {
|
if status != C.VPX_CODEC_OK {
|
||||||
return nil, nil, fmt.Errorf("decode failed: %v", status)
|
return nil, nil, fmt.Errorf("decode failed: %v", status)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var iter C.vpx_codec_iter_t = nil // initialize to NULL to start iteration
|
|
||||||
input := C.getFrame(d.codec, &iter)
|
|
||||||
if input == nil {
|
|
||||||
return nil, nil, io.EOF
|
|
||||||
}
|
|
||||||
w := int(input.d_w)
|
w := int(input.d_w)
|
||||||
h := int(input.d_h)
|
h := int(input.d_h)
|
||||||
yStride := int(input.stride[0])
|
yStride := int(input.stride[0])
|
||||||
@@ -136,6 +144,7 @@ func (d *decoder) Read() (image.Image, func(), error) {
|
|||||||
copy(dst.Cb[r*dst.CStride:r*dst.CStride+w/2], uSrc[r*uStride:r*uStride+w/2])
|
copy(dst.Cb[r*dst.CStride:r*dst.CStride+w/2], uSrc[r*uStride:r*uStride+w/2])
|
||||||
copy(dst.Cr[r*dst.CStride:r*dst.CStride+w/2], vSrc[r*vStride:r*vStride+w/2])
|
copy(dst.Cr[r*dst.CStride:r*dst.CStride+w/2], vSrc[r*vStride:r*vStride+w/2])
|
||||||
}
|
}
|
||||||
|
C.freeFrame(input)
|
||||||
return dst, func() {}, nil
|
return dst, func() {}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user