feat(ffmpeg): speed optimization and export memory buffer
This commit is contained in:
parent
3a5e26f37c
commit
ce911eaf8a
6 changed files with 28 additions and 53 deletions
|
|
@ -214,36 +214,6 @@ AVFrame *convert_frame_to_rgb(AVFrame *frame, int alpha) {
|
|||
return output_frame;
|
||||
}
|
||||
|
||||
int encode_frame_to_image(AVFormatContext *fmt_ctx, AVFrame *frame, AVPacket *pkt) {
|
||||
AVCodec *enc = avcodec_find_encoder(AV_CODEC_ID_PNG);
|
||||
if (!enc) {
|
||||
return AVERROR_ENCODER_NOT_FOUND;
|
||||
}
|
||||
AVCodecContext *enc_ctx = avcodec_alloc_context3(enc);
|
||||
if (!enc_ctx) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
enc_ctx->width = frame->width;
|
||||
enc_ctx->height = frame->height;
|
||||
enc_ctx->pix_fmt = frame->format;
|
||||
enc_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
enc_ctx->time_base = (AVRational) {1, 1};
|
||||
enc_ctx->compression_level = INT_MAX;
|
||||
int err = open_codec(enc_ctx, enc);
|
||||
if (err < 0) {
|
||||
avcodec_free_context(&enc_ctx);
|
||||
return err;
|
||||
}
|
||||
err = avcodec_send_frame(enc_ctx, frame);
|
||||
if (err < 0) {
|
||||
avcodec_free_context(&enc_ctx);
|
||||
return err;
|
||||
}
|
||||
err = avcodec_receive_packet(enc_ctx, pkt);
|
||||
avcodec_free_context(&enc_ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
AVPacket create_packet() {
|
||||
AVPacket *pkt = av_packet_alloc();
|
||||
pkt->data = NULL;
|
||||
|
|
@ -462,8 +432,10 @@ static AVFrame *get_best_frame(ThumbContext *thumb_ctx) {
|
|||
n = i;
|
||||
}
|
||||
}
|
||||
thumb_ctx->alpha = alpha_check(thumb_ctx->frames[n].frame, thumb_ctx->desc->flags,
|
||||
thumb_ctx->frames[n].hist[thumb_ctx->hist_size - 1]);
|
||||
thumb_ctx->alpha = alpha_check(
|
||||
thumb_ctx->frames[n].frame,
|
||||
thumb_ctx->desc->flags,
|
||||
thumb_ctx->frames[n].hist[thumb_ctx->hist_size - 1]);
|
||||
return thumb_ctx->frames[n].frame;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,11 +80,8 @@ func LoadAVContext(ctx context.Context, reader io.Reader, size int64) (*AVContex
|
|||
return av, nil
|
||||
}
|
||||
|
||||
func (av *AVContext) ExportImage() ([]byte, error) {
|
||||
if !av.hasFrame {
|
||||
return nil, nil
|
||||
}
|
||||
return encodeFrameImage(av)
|
||||
func (av *AVContext) Export() (buf []byte, err error) {
|
||||
return exportBuffer(av)
|
||||
}
|
||||
|
||||
func (av *AVContext) Close() {
|
||||
|
|
@ -279,15 +276,16 @@ func convertFrameToRGB(av *AVContext) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func encodeFrameImage(av *AVContext) ([]byte, error) {
|
||||
pkt := C.create_packet()
|
||||
err := C.encode_frame_to_image(av.formatContext, av.frame, &pkt)
|
||||
if err < 0 {
|
||||
return nil, avError(err)
|
||||
func exportBuffer(av *AVContext) ([]byte, error) {
|
||||
if !av.hasFrame {
|
||||
return nil, ErrDecoderNotFound
|
||||
}
|
||||
p := C.GoBytes(unsafe.Pointer(pkt.data), pkt.size)
|
||||
if pkt.buf != nil {
|
||||
C.av_packet_unref(&pkt)
|
||||
size := av.height * av.width
|
||||
if av.hasAlpha {
|
||||
size *= 4
|
||||
} else {
|
||||
size *= 3
|
||||
}
|
||||
return p, nil
|
||||
buf := C.GoBytes(unsafe.Pointer(av.frame.data[0]), C.int(size))
|
||||
return buf, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ int create_codec_context(AVStream *video_stream, AVCodecContext **dec_ctx);
|
|||
|
||||
AVFrame *convert_frame_to_rgb(AVFrame *frame, int alpha);
|
||||
|
||||
int encode_frame_to_image(AVFormatContext *fmt_ctx, AVFrame *frame, AVPacket *pkt);
|
||||
|
||||
AVPacket create_packet();
|
||||
|
||||
int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue