From 9b84c3e58ed399b0e4edf09b71aa66a496161fec Mon Sep 17 00:00:00 2001 From: Malanchi Date: Mon, 6 Jan 2025 17:12:37 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/Makefile | 2 + mxVision/Ascendffmpeg/libavcodec/allcodecs.c | 1 + .../libavcodec/ascend_mjpeg_dec.c | 520 ++++++++++++++++++ .../libavcodec/ascend_mjpeg_dec.h | 70 +++ 4 files changed, 593 insertions(+) create mode 100644 mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c create mode 100644 mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h diff --git a/mxVision/Ascendffmpeg/libavcodec/Makefile b/mxVision/Ascendffmpeg/libavcodec/Makefile index fc092e39f..f5c3835fb 100644 --- a/mxVision/Ascendffmpeg/libavcodec/Makefile +++ b/mxVision/Ascendffmpeg/libavcodec/Makefile @@ -27,6 +27,7 @@ HEADERS = ac3_parser.h \ xvmc.h \ ascend_dec.h \ ascend_enc.h \ + ascend_mjpeg_dec.h \ OBJS = ac3_parser.o \ adts_parser.o \ @@ -374,6 +375,7 @@ OBJS-$(CONFIG_H264_DECODER) += h264dec.o h264_cabac.o h264_cavlc.o \ h264_slice.o h264data.o OBJS-$(CONFIG_H264_ASCEND_DECODER) += ascend_dec.o OBJS-$(CONFIG_H264_ASCEND_ENCODER) += ascend_enc.o +OBJS-$(CONFIG_MJPEG_ASCEND_DECODER) += ascend_mjpeg_dec.o OBJS-$(CONFIG_H264_AMF_ENCODER) += amfenc_h264.o OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o diff --git a/mxVision/Ascendffmpeg/libavcodec/allcodecs.c b/mxVision/Ascendffmpeg/libavcodec/allcodecs.c index b6885f8cd..2ae7a8e2d 100644 --- a/mxVision/Ascendffmpeg/libavcodec/allcodecs.c +++ b/mxVision/Ascendffmpeg/libavcodec/allcodecs.c @@ -791,6 +791,7 @@ extern AVCodec ff_h264_ascend_decoder; extern AVCodec ff_h265_ascend_decoder; extern AVCodec ff_h264_ascend_encoder; extern AVCodec ff_h265_ascend_encoder; +extern AVCodec ff_mjpeg_ascend_encoder; extern AVCodec ff_h264_amf_encoder; extern AVCodec ff_h264_cuvid_decoder; extern AVCodec ff_h264_mf_encoder; diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c new file mode 100644 index 000000000..d3036d447 --- /dev/null +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -0,0 +1,520 @@ +/* + * Copyright(c) 2024. Huawei Technologies Co.,Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except int compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "libavutil/imgutils.h" +#include "libavutil/avassert.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "blockdsp.h" +#include "copy_block.h" +#include "decode.h" +#include "hwconfig.h" +#include "idctdsp.h" +#include "internal.h" +#include "jpegtables.h" +#include "mjpeg.h" +#include "mjpegdec.h" +#include "jpeglsdec.h" +#include "profiles.h" +#include "put_bits.h" +#include "tiff.h" +#include "exif.h" +#include "bytestream.h" +#include "ascend_mjpeg_dec.h" + + +static const uint8_t jpeg_header2[] = { + 0xff, 0xd8, // SOI + 0xff, 0xe0, // APP0 + 0x00, 0x10, // APP0 header size + 0x4a, 0x46, 0x49, 0x46, 0x00, // ID string 'JFIF\0' + 0x01, 0x01, // version + 0x00, // bits per type + 0x00, 0x00, // X density + 0x00, 0x00, // Y density + 0x00, // X thumbnail size + 0x00, // Y thumbnail size +}; + +static const int dht_segment_size2 = 420; + +static const uint8_t dht_segment_head2[] = {0xFF, 0xC4, 0x01, 0xA2, 0x00}; +static const uint8_t dht_segment_frag2[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static uint8_t *append2(uint8_t *buf, const uint8_t *src, int size) +{ + memcpy(buf, src, size); + return buf + size; +} + +static uint8_t *append_dht_segment2(uint8_t *buf) +{ + buf = append2(buf, dht_segment_head2, sizeof(dht_segment_head2)); + buf = append2(buf, avpriv_mjpeg_bits_dc_luminance + 1, 16); + buf = append2(buf, dht_segment_frag2, sizeof(dht_segment_frag2)); + buf = append2(buf, avpriv_mjpeg_val_dc, 12); + *(buf++) = 0x10; + buf = append2(buf, avpriv_mjpeg_bits_ac_luminance + 1, 16); + buf = append2(buf, avpriv_mjpeg_val_ac_luminance, 162); + *(buf++) = 0x11; + buf = append2(buf, avpriv_mjpeg_bits_ac_chrominance + 1, 16); + buf = append2(buf, avpriv_mjpeg_val_ac_chrominance, 162); + return buf; +} + +#define REF_FRAME_NUM 8 +#define DISPLAY_FRAME_NUM 2 +#define FFALIGNMJPEG(x, a) (((x) + (a) - 1) &~ ((a) - 1)) +#define WIDTH_ALIGN 2 +#define HEIGHT_ALIGN 16 + +av_cold int ff_mjpeg_ascend_decode_init(AvCodecContext* avctx) +{ + AscendMjpegDecodeContext *s = avctx->priv_data; + int ret; + + enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_ASCEND, AV_PIX_FMT_NV12, AV_PIX_FMT_NONE }; + avctx->pix_fmt = ff_get_format(avctx, pix_fmts); + if (avctx->pix_fmt != AV_PIX_FMT_ASCEND) { + av_log(avctx, AV_LOG_ERROR, "Perhaps the command \"-hwaccel ascend\" is missing. Please check it.\n"); + return AVERROR(EINVAL); + } + + if (avctx->width < 128 || avctx->height < 128 || avctx->width > 4096 || avctx->height > 4096) { + av_log(avctx, AV_LOG_ERROR, "MJPEG decoder only support resolution: 128x128 ~ 4096x4096, now: %dx%d.\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + + char device_id[sizeof(int)]; + sprintf(device_id, "%d", s->device_id); + + AVASCENDDeviceContext* hw_device_ctx; + AVHWFramesContext* hw_frame_ctx; + if (avctx->hw_frame_ctx) { + av_buffer_unref(&s->hw_frame_ref); + s->hw_frame_ref = av_buffer_ref(avctx->hw_frame_ctx); + if (!s->hw_frame_ref) { + ret = AVERROR(EINVAL); + goto error; + } + + hw_frame_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; + if (!hw_frame_ctx->pool || (avctx->width != hw_frame_ctx->width)) { + if (hw_frame_ctx->pool) { + av_buffer_pool_uninit(&hw_frame_ctx->pool); + } + hw_frame_ctx->width = avctx->width; + hw_frame_ctx->height = avctx->height; + hw_frame_ctx->initial_pool_size = 2; + hw_frame_ctx->format = AV_PIX_FMT_ASCEND; + hw_frame_ctx->sw_format = AV_PIX_FMT_NV12; + + ret = av_hwframe_ctx_init(s->hw_frame_ref); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "HWFrame context init failed, ret is %d.\n", ret); + return AVERROR(ENAVAIL); + } + } + s->hw_device_ref = av_buffer_ref(hw_frame_ctx->device_ref); + if (!s->hw_device_ref) { + av_log(avctx, AV_LOG_ERROR, "Get hw_device_ref failed.\n"); + ret = AVERROR(EINVAL); + goto error; + } + } else { + if (avctx->hw_device_ctx) { + s->hw_device_ref = av_buffer_ref(avctx->hw_device_ctx); + if (!s->hw_device_ref) { + av_log(avctx, AV_LOG_ERROR, "ref hwdevice failed.\n"); + ret = AVERROR(EINVAL); + goto error; + } + } else { + ret = av_hwdevice_ctx_create(&s->hw_device_ref, AV_HWDEVICE_TYPE_ASCEND, device_id, NULL, 0); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "hwdevice context create failed. ret is %d.\n", ret); + goto error; + } + } + s->hw_frame_ref = av_hwframe_ctx_alloc(s->hw_device_ref); + if (!s->hw_frame_ref) { + av_log(avctx, AV_LOG_ERROR, "hwframe ctx alloc falied.\n"); + ret = AVERROR(EINVAL); + goto error; + } + hw_frame_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; + if (!hw_frame_ctx->pool) { + hw_frame_ctx->width = avctx_width; + hw_frame_ctx->height = avctx->height; + hw_frame_ctx->initial_pool_size = 2; + hw_frame_ctx->format = AV_PIX_FMT_ASCEND; + hw_frame_ctx->sw_format = AV_PIX_FMT_NV12; + ret = av_hwframe_ctx_init(s->hw_frame_ref); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "hwframe ctx init error, ret is %d.\n", ret); + ret = AVERROR(EINVAL); + goto error; + } + } + } + + hw_device_ctx = ((AVHWDeviceContext*)s->hw_device_ref->data)->hwctx; + s->hw_device_ctx = hw_device_ctx; + s->hw_frame_ctx = hw_frame_ctx; + s->ascend_ctx = s->hw_device_ctx->ascend_ctx; + + ret = aclrtSetCurrentContext(s->ascend_ctx->context); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "Set context failed at line(%d) in func(%s), ret is %d.\n", __LINE__, __func__, ret); + return ret; + } + + ret = hi_mpi_sys_init(); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi sys init failed, ret is %d.\n", ret); + return ret; + } + + hi_vdec_chn_attr chn_attr_; + chn_attr_.type = HI_PT_JPEG; + chn_attr_.mode = HI_VDEC_SEND_MODE_FRAME; + chn_attr_.pic_width = avctx->width; + chn_attr_.pic_height = avctx->height; + chn_attr_.stream_buf_size = chn_attr_.pic_width * chn_attr_.height * 3 / 2; + chn_attr_.frame_buf_cnt = REF_FRAME_NUM + DISPLAY_FRAME_NUM + 1; + + hi_pic_buf_attr buf_attr_; + buf_attr_.width = chn_attr_.pic_width; + buf_attr_.height = chn_attr_.pic_height; + buf_attr_.align = 0; + buf_attr_.bit_width = HI_DATA_BIT_WIDTH_8; + buf_attr_.pixel_format = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + buf_attr_.compress_mode = HI_COMPRESS_MODE_NONE; + + chn_attr_.frame_buf_size = hi_vdec_get_pic_buf_size(chn_attr_.type, &buf_attr_); + chn_attr_.video_attr.ref_frame_num = REF_FRAME_NUM; + chn_attr_.video_attr.temporal_mvp_en = HI_TRUE; + chn_attr_.video_attr.tmv_buf_size = hi_vdec_get_tmv_buf_size(chn_attr_.type, + chn_attr_.pic_width, + chn_attr_.pic_height); + uint32_t channel_id = s->channel_id; + ret = hi_mpi_vdec_create_chn(channel_id, &chn_attr_); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi create vdec channel failed, ret is %d.\n", ret); + return ret; + } + + hi_vdec_chn_param chn_param_; + ret = hi_mpi_vdec_get_chn_param(channel_id, &chn_param_); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi vdec get channel param failed, ret is %d.\n", ret); + return ret; + } + + chn_param_.video_param.dec_mode = HI_VIDEO_DEC_MODE_IPB; + chn_param_.video_param.compress_mode = HI_COMPRESS_MODE_HFBC; + chn_param_.video_param.video_format = HI_VIDEO_FORMAT_TILE_64x16; + chn_param_.display_frame_num = DISPLAY_FRAME_NUM; + chn_param_.video_param.out_order = HI_VIDEO_OUT_ORDER_DISPLAY; + + ret = hi_mpi_vdec_set_chn_param(channel_id, &chn_param_); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi vdec set channel param failed, ret is %d.\n", ret); + return ret; + } + + ret = hi_mpi_vdec_start_recv_stream(channel_id); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi vdec start receive stream failed, ret is %d.\n", ret); + return ret; + } + + s->pkt = av_packet_alloc(); + if (!s->pkt) + return AVERROR(ENOMEM); + s->avctx = avctx; + return 0; + error: + ff_mjpeg_ascend_decode_end(avctx); + return ret; +} + +int ff_mjpeg_ascend_receive_frame(AvCodecContext* avctx, AVFrame* frame) +{ + AscendMjpegDecodeContext *s = avctx->priv_data; + int ret = 0; + ret = mjpeg_get_packet(avctx); + if (ret < 0) { + return ret; + } + + /* GET JPEG */ + AVPacket *out = av_packet_alloc(); + uint8_t* output; + int input_skip, output_size; + AVPacket *in = s->pkt; + + if (in->size < 12) { + av_log(avctx, AV_LOG_ERROR, "Input is truncate.\n"); + return AVERROR_INVALIDDATA; + } + + if (AV_RB16(int->data) != 0xffd8) { + av_log(avctx, AV_LOG_ERROR, "Input is not MJPEG.\n"); + return AVERROR_INVALIDDATA; + } + + if (in->data[2] == 0xff && in->data[3] == APP0) { + input_skip = (in->data[4] << 8) + in->data[5] + 4; + } else { + input_skip = 2; + } + + if (in->size < input_skip) { + av_log(avctx, AV_LOG_ERROR, "Input is truncate.\n"); + return AVERROR_INVALIDDATA; + } + + output_size = in->size - input_skip + sizeof(jpeg_header2) + dht_segment_size2; + ret = av_new_packet(out, output_size); + if (ret < 0) + return AVERROR_INVALIDDATA; + output = out->data; + output = append2(output, jpeg_header2, sizeof(jpeg_header2)); + output = append_dht_segment2(output); + output = append2(output, in->data + input_skip, in->size - input_skip); + + /* JPEG to YUV420 By Ascend */ + ret = aclrtSetCurrentContext(s->ascend_ctx->context); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "Set context failed, ret is %d.\n", ret); + return ret; + } + + uint8_t* streamBuffer = NULL; + int device_id = 0; + ret = hi_mpi_dvpp_malloc(device_id, &streamBuffer, output_size); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi malloc packet failed, ret is %d.\n", ret); + return ret; + } + + ret = aclrtMemcpy(streamBuffer, output_size, output_size, out->data, output_size, ACL_MEMCPY_HOST_TO_DEVICE); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "Mem copy H2D failed. ret is %d.\n", ret); + return ret; + } + + hi_vdec_stream stream; + stream.pts = 0; + stream.addr = streamBuffer; + stream.len = output_size; + stream.end_of_frame = HI_TRUE; + stream.end_of_stream = HI_FALSE; + stream.need_display = HI_TRUE; + + hi_vdec_pic_info pic_info; + pic_info.width = s->avctx->width; + pic_info.height = s->avctx->height; + pic_info.width_stride = FFALIGNMJPEG(pic_info.width, WIDTH_ALIGN); + pic_info.height_stride = FFALIGNMJPEG(pic_info.height, HEIGHT_ALIGN); + pic_info.offset_top = 0; + pic_info.offset_bottom = 0; + pic_info.offset_left = 0; + pic_info.offset_right = 0; + + uint32_t size = pic_info.width_stride * pic_info.height_stride * 3 / 2; + pic_info.buffer_size = size; + pic_info.pixel_format = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; + + void* picBuffer = NULL; + ret = hi_mpi_dvpp_malloc(device_id, &picBuffer, size); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi malloc falied, ret is %d.\n", ret); + return ret; + } + + pic_info.vir_addr = (uint64_t)picBuffer; + + ret = hi_mpi_vdec_send_stream(s->channel_id, &stream, &pic_info, 1000); + if (ret != 0) { + hi_mpi_dvpp_free(picBuffer); + av_log(avctx, AV_LOG_ERROR, "Send stream failed, ret is %d.\n", ret); + return ret; + } + + hi_video_frame_info got_frame; + hi_vdec_stream got_stream; + hi_vdec_supplement_info stSupplement; + ret = hi_mpi_vdec_get_frame(s->channel_id, &got_frame, &stSupplement, &got_stream, 100); + if (ret != 0) { + hi_mpi_dvpp_free(picBuffer); + av_log(avctx, AV_LOG_ERROR, "Get frame failed, ret is %d.\n", ret); + return ret; + } + size_t decResult = got_frame.v_frame.frame_flag; + hi_mpi_dvpp_free(got_stream.addr); + if (decResult != 0 && got_frame.v_frame.virt_addr[0] != NULL) { + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); + return ret; + } + if (decResult != 0 || got_frame.v_frame.virt_addr[0] == NULL || got_stream.need_display = HI_FALSE) { + ret = hi_mpi_vdec_release_frame(s->channel_id, &got_frame); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi release frame failed, ret is %d.\n", ret); + return ret; + } + return -1; + } + ret = hi_mpi_vdec_release_frame(s->channel_id, &got_frame); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi release frame failed, ret is %d.\n", ret); + return ret; + } + + ret = av_hwframe_get_buffer(s->hw_frame_ref, frame, 0); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Frame get buffer failed, ret is %d.\n", ret); + return AVERROR(EINVAL); + } + ret = ff_deocde_frame_props(avctx, frame); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Fill frame properties failed. ret is %d.\n", ret); + return AVERROR(EINVAL); + } + + frame->pkt_pos = -1; + frame->pkt_duration = 0; + frame->pkt_size = pic_info.buffer_size; + frame->width = got_frame.v_frame.width_stride[0]; + frame->height = got_frame.v_frame.height_stride[0]; + frame->format = (int)AV_PIX_FMT_NV12; +// frame->pts = got_frame.v_frame.pts; +// frame->pkt_pts = frame->pts; +// frame->pkt_dts = out->dts; + + uint32_t offset = 0; + for (int i = 0; i < 2; i++) { + size_t dstBytes = got_frame.v_frame.width_stride[0] * got_frame.v_frame.height_stride[0] * (i ? 1.0 / 2 : 1); + ret = aclrtMemcpy(frame->data[i], dstBytes, got_frame.v_frame.virt_addr[0] + offset, dstBytes, + ACL_MEMCPY_DEVICE_TO_DEVICE); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "Mem copy D2D failed, ret is %d.\n", ret); + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); + return ret; + } + offset += dstBytes; + } + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); + error: + av_packet_free(&out); + return ret; +} + +av_cold int ff_mjpeg_ascend_decode_end(AvCodecContext* avctx) +{ + AscendMjpegDecodeContext *s = avctx->priv_data; + int ret; + ret = aclrtSetCurrentContext(s->ascend_ctx->context); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "Set context failed, ret is %d.\n", ret); + return ret; + } + + ret = hi_mpi_vdec_stop_recv_stream(s->channel_id); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi stop receive stream failed, ret is %d.\n", ret); + return ret; + } + + ret = hi_mpi_vdec_destroy_chn(s->channel_id); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi destroy channel failed, ret is %d.\n", ret); + return ret; + } + + ret = hi_mpi_sys_exit(); + if (ret != 0) { + av_log(avctx, AV_LOG_ERROR, "HiMpi sys exit failed, ret is %d.\n", ret); + return ret; + } + + av_packet_free(&s->pkt); + av_buffer_unref(&s->hw_device_ref); + return 0; +} + +static void ascend_decode_flush(AvCodecContext* avctx) +{ + ff_mjpeg_ascend_decode_end(avctx); + ff_mjpeg_ascend_decode_init(avctx); +} + +#define OFFSET(x) offsetof(AscendMjpegDecodeContext, x) +#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM +static_cast const AVOption options[] = { + { "device_id", "Use to choose the ascend chip.", OFFSET(device_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, VD }, + { "channel_id", "Set channelId of decoder.", OFFSET(channel_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 255, VD }, + { NULL } +}; + + +static const AVCodecHWConfigInternal* ascend_hw_configs[] = { + &(const AVCodecHWConfigInternal) { + .public = { + .pix_fmt = AV_PIX_FMT_ASCEND, + .methods = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX | AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX | + AV_CODEC_HW_CONFIG_METHOD_INTERNAL, + .device_type = AV_HWDEVICE_TYPE_ASCEND + }, + .hwaccel = NULL, + }, + NULL +}; + +#define ASCEND_DEC_CODEC(x, X) \ + static const AVClass x##_ascend_class = { \ + .class_name = #x "_ascend_dec", \ + .item_name = av_default_item_name, \ + .option = options, \ + .version = LIBAVUTIL_VERSION_INT, \ + }; \ + AVCodec ff_##x##_ascend_decoder = { \ + .name = #x "_ascend", \ + .long_name = NULL_IF_CONFIG_SMALL("Ascend HiMpi " #X " decoder"), \ + .type = AVMEDIA_TYPE_VIDEO, \ + .id = AV_CODEC_ID_MJPEG, \ + .priv_data_size = sizeof(AscendMjpegDecodeContext), \ + .priv_class = &x##_ascend_class, \ + .init = ff_mjpeg_ascend_decode_init, \ + .close = ff_mjpeg_ascend_decode_end, \ + .receive_frame = ff_mjpeg_ascend_receive_frame, \ + .flush = ascend_decode_flush, \ + .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \ + .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_ASCEND, \ + AV_PIX_FMT_NV12, \ + AV_PIX_FMT_NONE }, \ + .hw_config2 = ascend_hw_configs, \ + .wrapper_name = "ascendmjpegdec", \ + }; +#if CONFIG_MJPEG_ASCEND_DECODER +ASCEND_DEC_CODEC(mjpeg, MJPEG) +##endif \ No newline at end of file diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h new file mode 100644 index 000000000..f429b07e8 --- /dev/null +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h @@ -0,0 +1,70 @@ +/* + * MJPEG Ascend decoder + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003 Alex Beregszaszi + * Copyright (c) 2003-2004 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MJPEG Ascend decoder. + */ + +#ifndef ASCEND_AVCODEC_MJPEGDEC_H +#define ASCEND_AVCODEC_MJPEGDEC_H + +#include "libavutil/log.h" +#include "libavutil/mem_internal.h" +#include "libavutil/pixdesc.h" +#include "libavutil/stereo3d.h" + +#include "avcodec.h" +#include "blockdsp.h" +#include "get_bits.h" +#include "hpeldsp.h" +#include "idctdsp.h" +#include "libavutil/hwcontext.h" +#include "libavutil/hwcontext_ascend.h" +#include "acl/dvpp/hi_dvpp.h" + +typedef struct AscendMJpegDecodeContext { + AVClass *class; + AVCodecContext *avctx; + int buf_size; + + AVPacket *pkt; + enum AVPixelFormat hwaccel_sw_pix_fmt; + enum AVPixelFormat hwaccel_pix_fmt; + void* hwaccel_picture_private; + int device_id; + uint32_t channel_id; + uint32_t vdec_width; + uint32_t vdec_height; + AVBufferRef* hw_device_ref; + AVBufferRef* hw_frame_ref; + AVASCENDDeviceContext *hw_device_ctx; + AVHWFramesContext* hw_frames_ctx; + AscendContext* ascend_ctx; +} AscendMJpegDecodeContext; + +int ff_mjpeg_ascend_decode_init(AVCodecContext *avctx); +int ff_mjpeg_ascend_decode_end(AVCodecContext *avctx); +int ff_mjpeg_ascend_receive_frame(AVCodecContext *avctx, AVFrame *frame); + +#endif -- Gitee From 67880f76034672ef7cc90e6900cc07a4955ffad3 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:30:15 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/allcodecs.c | 2 +- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/allcodecs.c b/mxVision/Ascendffmpeg/libavcodec/allcodecs.c index 2ae7a8e2d..1e2e0f356 100644 --- a/mxVision/Ascendffmpeg/libavcodec/allcodecs.c +++ b/mxVision/Ascendffmpeg/libavcodec/allcodecs.c @@ -791,7 +791,7 @@ extern AVCodec ff_h264_ascend_decoder; extern AVCodec ff_h265_ascend_decoder; extern AVCodec ff_h264_ascend_encoder; extern AVCodec ff_h265_ascend_encoder; -extern AVCodec ff_mjpeg_ascend_encoder; +extern AVCodec ff_mjpeg_ascend_decoder; extern AVCodec ff_h264_amf_encoder; extern AVCodec ff_h264_cuvid_decoder; extern AVCodec ff_h264_mf_encoder; diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index d3036d447..20b2b078d 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -85,7 +85,7 @@ static uint8_t *append_dht_segment2(uint8_t *buf) #define WIDTH_ALIGN 2 #define HEIGHT_ALIGN 16 -av_cold int ff_mjpeg_ascend_decode_init(AvCodecContext* avctx) +av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) { AscendMjpegDecodeContext *s = avctx->priv_data; int ret; @@ -257,7 +257,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AvCodecContext* avctx) return ret; } -int ff_mjpeg_ascend_receive_frame(AvCodecContext* avctx, AVFrame* frame) +int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) { AscendMjpegDecodeContext *s = avctx->priv_data; int ret = 0; @@ -429,7 +429,7 @@ int ff_mjpeg_ascend_receive_frame(AvCodecContext* avctx, AVFrame* frame) return ret; } -av_cold int ff_mjpeg_ascend_decode_end(AvCodecContext* avctx) +av_cold int ff_mjpeg_ascend_decode_end(AVCodecContext* avctx) { AscendMjpegDecodeContext *s = avctx->priv_data; int ret; @@ -462,7 +462,7 @@ av_cold int ff_mjpeg_ascend_decode_end(AvCodecContext* avctx) return 0; } -static void ascend_decode_flush(AvCodecContext* avctx) +static void ascend_decode_flush(AVCodecContext* avctx) { ff_mjpeg_ascend_decode_end(avctx); ff_mjpeg_ascend_decode_init(avctx); @@ -470,7 +470,7 @@ static void ascend_decode_flush(AvCodecContext* avctx) #define OFFSET(x) offsetof(AscendMjpegDecodeContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM -static_cast const AVOption options[] = { +static const AVOption options[] = { { "device_id", "Use to choose the ascend chip.", OFFSET(device_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, VD }, { "channel_id", "Set channelId of decoder.", OFFSET(channel_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 255, VD }, { NULL } -- Gitee From f0dd3d2c5d4a2c69dd2df007d2f04ffce036707f Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:34:11 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 20b2b078d..714da5f05 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -87,7 +87,7 @@ static uint8_t *append_dht_segment2(uint8_t *buf) av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) { - AscendMjpegDecodeContext *s = avctx->priv_data; + AscendMJpegDecodeContext *s = avctx->priv_data; int ret; enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_ASCEND, AV_PIX_FMT_NV12, AV_PIX_FMT_NONE }; @@ -259,7 +259,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) { - AscendMjpegDecodeContext *s = avctx->priv_data; + AscendMJpegDecodeContext *s = avctx->priv_data; int ret = 0; ret = mjpeg_get_packet(avctx); if (ret < 0) { @@ -431,7 +431,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) av_cold int ff_mjpeg_ascend_decode_end(AVCodecContext* avctx) { - AscendMjpegDecodeContext *s = avctx->priv_data; + AscendMJpegDecodeContext *s = avctx->priv_data; int ret; ret = aclrtSetCurrentContext(s->ascend_ctx->context); if (ret != 0) { @@ -468,7 +468,7 @@ static void ascend_decode_flush(AVCodecContext* avctx) ff_mjpeg_ascend_decode_init(avctx); } -#define OFFSET(x) offsetof(AscendMjpegDecodeContext, x) +#define OFFSET(x) offsetof(AscendMJpegDecodeContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "device_id", "Use to choose the ascend chip.", OFFSET(device_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, VD }, @@ -502,7 +502,7 @@ static const AVCodecHWConfigInternal* ascend_hw_configs[] = { .long_name = NULL_IF_CONFIG_SMALL("Ascend HiMpi " #X " decoder"), \ .type = AVMEDIA_TYPE_VIDEO, \ .id = AV_CODEC_ID_MJPEG, \ - .priv_data_size = sizeof(AscendMjpegDecodeContext), \ + .priv_data_size = sizeof(AscendMJpegDecodeContext), \ .priv_class = &x##_ascend_class, \ .init = ff_mjpeg_ascend_decode_init, \ .close = ff_mjpeg_ascend_decode_end, \ @@ -512,7 +512,7 @@ static const AVCodecHWConfigInternal* ascend_hw_configs[] = { .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_ASCEND, \ AV_PIX_FMT_NV12, \ AV_PIX_FMT_NONE }, \ - .hw_config2 = ascend_hw_configs, \ + .hw_configs = ascend_hw_configs, \ .wrapper_name = "ascendmjpegdec", \ }; #if CONFIG_MJPEG_ASCEND_DECODER -- Gitee From 79b329c5497f9305c50a7d8ef339db94482656fd Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:34:39 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 714da5f05..8730646e2 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -517,4 +517,4 @@ static const AVCodecHWConfigInternal* ascend_hw_configs[] = { }; #if CONFIG_MJPEG_ASCEND_DECODER ASCEND_DEC_CODEC(mjpeg, MJPEG) -##endif \ No newline at end of file +#endif \ No newline at end of file -- Gitee From 6c6e2dac2a3f314ef74318c5054768040a8da2a1 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:41:16 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libavcodec/ascend_mjpeg_dec.c | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 8730646e2..77f40d699 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -25,8 +25,8 @@ #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" -#include "mjpeg.h" -#include "mjpegdec.h" +//#include "mjpeg.h" +//#include "mjpegdec.h" #include "jpeglsdec.h" #include "profiles.h" #include "put_bits.h" @@ -107,25 +107,25 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) sprintf(device_id, "%d", s->device_id); AVASCENDDeviceContext* hw_device_ctx; - AVHWFramesContext* hw_frame_ctx; - if (avctx->hw_frame_ctx) { + AVHWFramesContext* hw_frames_ctx; + if (avctx->hw_frames_ctx) { av_buffer_unref(&s->hw_frame_ref); - s->hw_frame_ref = av_buffer_ref(avctx->hw_frame_ctx); + s->hw_frame_ref = av_buffer_ref(avctx->hw_frames_ctx); if (!s->hw_frame_ref) { ret = AVERROR(EINVAL); goto error; } - hw_frame_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; - if (!hw_frame_ctx->pool || (avctx->width != hw_frame_ctx->width)) { - if (hw_frame_ctx->pool) { - av_buffer_pool_uninit(&hw_frame_ctx->pool); + hw_frames_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; + if (!hw_frames_ctx->pool || (avctx->width != hw_frames_ctx->width)) { + if (hw_frames_ctx->pool) { + av_buffer_pool_uninit(&hw_frames_ctx->pool); } - hw_frame_ctx->width = avctx->width; - hw_frame_ctx->height = avctx->height; - hw_frame_ctx->initial_pool_size = 2; - hw_frame_ctx->format = AV_PIX_FMT_ASCEND; - hw_frame_ctx->sw_format = AV_PIX_FMT_NV12; + hw_frames_ctx->width = avctx->width; + hw_frames_ctx->height = avctx->height; + hw_frames_ctx->initial_pool_size = 2; + hw_frames_ctx->format = AV_PIX_FMT_ASCEND; + hw_frames_ctx->sw_format = AV_PIX_FMT_NV12; ret = av_hwframe_ctx_init(s->hw_frame_ref); if (ret < 0) { @@ -133,7 +133,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) return AVERROR(ENAVAIL); } } - s->hw_device_ref = av_buffer_ref(hw_frame_ctx->device_ref); + s->hw_device_ref = av_buffer_ref(hw_frames_ctx->device_ref); if (!s->hw_device_ref) { av_log(avctx, AV_LOG_ERROR, "Get hw_device_ref failed.\n"); ret = AVERROR(EINVAL); @@ -160,13 +160,13 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) ret = AVERROR(EINVAL); goto error; } - hw_frame_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; - if (!hw_frame_ctx->pool) { - hw_frame_ctx->width = avctx_width; - hw_frame_ctx->height = avctx->height; - hw_frame_ctx->initial_pool_size = 2; - hw_frame_ctx->format = AV_PIX_FMT_ASCEND; - hw_frame_ctx->sw_format = AV_PIX_FMT_NV12; + hw_frames_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; + if (!hw_frames_ctx->pool) { + hw_frames_ctx->width = avctx->width; + hw_frames_ctx->height = avctx->height; + hw_frames_ctx->initial_pool_size = 2; + hw_frames_ctx->format = AV_PIX_FMT_ASCEND; + hw_frames_ctx->sw_format = AV_PIX_FMT_NV12; ret = av_hwframe_ctx_init(s->hw_frame_ref); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "hwframe ctx init error, ret is %d.\n", ret); @@ -178,7 +178,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) hw_device_ctx = ((AVHWDeviceContext*)s->hw_device_ref->data)->hwctx; s->hw_device_ctx = hw_device_ctx; - s->hw_frame_ctx = hw_frame_ctx; + s->hw_frames_ctx = hw_frames_ctx; s->ascend_ctx = s->hw_device_ctx->ascend_ctx; ret = aclrtSetCurrentContext(s->ascend_ctx->context); @@ -198,7 +198,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) chn_attr_.mode = HI_VDEC_SEND_MODE_FRAME; chn_attr_.pic_width = avctx->width; chn_attr_.pic_height = avctx->height; - chn_attr_.stream_buf_size = chn_attr_.pic_width * chn_attr_.height * 3 / 2; + chn_attr_.stream_buf_size = chn_attr_.pic_width * chn_attr_.pic_height * 3 / 2; chn_attr_.frame_buf_cnt = REF_FRAME_NUM + DISPLAY_FRAME_NUM + 1; hi_pic_buf_attr buf_attr_; -- Gitee From 4fb45f8896fb06457457905c6cf5d4d894a758d3 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:48:54 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 77f40d699..a1117905b 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -277,7 +277,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) return AVERROR_INVALIDDATA; } - if (AV_RB16(int->data) != 0xffd8) { + if (AV_RB16(int->data)) != 0xffd8) { av_log(avctx, AV_LOG_ERROR, "Input is not MJPEG.\n"); return AVERROR_INVALIDDATA; } @@ -317,7 +317,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) return ret; } - ret = aclrtMemcpy(streamBuffer, output_size, output_size, out->data, output_size, ACL_MEMCPY_HOST_TO_DEVICE); + ret = aclrtMemcpy(streamBuffer, output_size, out->data, output_size, ACL_MEMCPY_HOST_TO_DEVICE); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "Mem copy H2D failed. ret is %d.\n", ret); return ret; @@ -395,7 +395,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) av_log(avctx, AV_LOG_ERROR, "Frame get buffer failed, ret is %d.\n", ret); return AVERROR(EINVAL); } - ret = ff_deocde_frame_props(avctx, frame); + ret = ff_decode_frame_props(avctx, frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Fill frame properties failed. ret is %d.\n", ret); return AVERROR(EINVAL); -- Gitee From 5b4fe58731956c21fd5c02f35872d01588fa6718 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:52:10 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index a1117905b..a560edbfa 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -257,6 +257,18 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) return ret; } +static int mjpeg_get_packet(AVCodecContext* avctx) +{ + AscendMJpegDecodeContext* s = avctx->priv_data; + int ret; + av_packet_unref(s->pkt); + ret = ff_decode_get_packet(avctxm s->pkt); + if (ret < 0) + return ret; + s->buf_size = s->pkt->size; + return 0; +} + int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) { AscendMJpegDecodeContext *s = avctx->priv_data; -- Gitee From 45633769452780090316bde0cbe80a710076b07b Mon Sep 17 00:00:00 2001 From: Malanchi Date: Tue, 7 Jan 2025 10:55:41 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index a560edbfa..1770043b5 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -262,7 +262,7 @@ static int mjpeg_get_packet(AVCodecContext* avctx) AscendMJpegDecodeContext* s = avctx->priv_data; int ret; av_packet_unref(s->pkt); - ret = ff_decode_get_packet(avctxm s->pkt); + ret = ff_decode_get_packet(avctx, s->pkt); if (ret < 0) return ret; s->buf_size = s->pkt->size; @@ -289,7 +289,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) return AVERROR_INVALIDDATA; } - if (AV_RB16(int->data)) != 0xffd8) { + if (AV_RB16(in->data) != 0xffd8) { av_log(avctx, AV_LOG_ERROR, "Input is not MJPEG.\n"); return AVERROR_INVALIDDATA; } @@ -388,7 +388,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); return ret; } - if (decResult != 0 || got_frame.v_frame.virt_addr[0] == NULL || got_stream.need_display = HI_FALSE) { + if (decResult != 0 || got_frame.v_frame.virt_addr[0] == NULL || got_stream.need_display == HI_FALSE) { ret = hi_mpi_vdec_release_frame(s->channel_id, &got_frame); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "HiMpi release frame failed, ret is %d.\n", ret); -- Gitee From c219354110353b773e6eebac645c19d24363e553 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Thu, 9 Jan 2025 10:32:48 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libavcodec/ascend_mjpeg_dec.c | 107 ++++++++++-------- 1 file changed, 62 insertions(+), 45 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 1770043b5..7e6ba2b41 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -36,7 +36,7 @@ #include "ascend_mjpeg_dec.h" -static const uint8_t jpeg_header2[] = { +static const uint8_t jpeg_header_ascend[] = { 0xff, 0xd8, // SOI 0xff, 0xe0, // APP0 0x00, 0x10, // APP0 header size @@ -49,33 +49,33 @@ static const uint8_t jpeg_header2[] = { 0x00, // Y thumbnail size }; -static const int dht_segment_size2 = 420; +static const int dht_segment_size_ascend = 420; -static const uint8_t dht_segment_head2[] = {0xFF, 0xC4, 0x01, 0xA2, 0x00}; -static const uint8_t dht_segment_frag2[] = { +static const uint8_t dht_segment_head_ascend[] = {0xFF, 0xC4, 0x01, 0xA2, 0x00}; +static const uint8_t dht_segment_frag_ascend[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, }; -static uint8_t *append2(uint8_t *buf, const uint8_t *src, int size) +static uint8_t *append_ascend(uint8_t *buf, const uint8_t *src, int size) { memcpy(buf, src, size); return buf + size; } -static uint8_t *append_dht_segment2(uint8_t *buf) +static uint8_t *append_dht_segment_ascend(uint8_t *buf) { - buf = append2(buf, dht_segment_head2, sizeof(dht_segment_head2)); - buf = append2(buf, avpriv_mjpeg_bits_dc_luminance + 1, 16); - buf = append2(buf, dht_segment_frag2, sizeof(dht_segment_frag2)); - buf = append2(buf, avpriv_mjpeg_val_dc, 12); + buf = append_ascend(buf, dht_segment_head_ascend, sizeof(dht_segment_head_ascend)); + buf = append_ascend(buf, avpriv_mjpeg_bits_dc_luminance + 1, 16); + buf = append_ascend(buf, dht_segment_frag_ascend, sizeof(dht_segment_frag_ascend)); + buf = append_ascend(buf, avpriv_mjpeg_val_dc, 12); *(buf++) = 0x10; - buf = append2(buf, avpriv_mjpeg_bits_ac_luminance + 1, 16); - buf = append2(buf, avpriv_mjpeg_val_ac_luminance, 162); + buf = append_ascend(buf, avpriv_mjpeg_bits_ac_luminance + 1, 16); + buf = append_ascend(buf, avpriv_mjpeg_val_ac_luminance, 162); *(buf++) = 0x11; - buf = append2(buf, avpriv_mjpeg_bits_ac_chrominance + 1, 16); - buf = append2(buf, avpriv_mjpeg_val_ac_chrominance, 162); + buf = append_ascend(buf, avpriv_mjpeg_bits_ac_chrominance + 1, 16); + buf = append_ascend(buf, avpriv_mjpeg_val_ac_chrominance, 162); return buf; } @@ -113,7 +113,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) s->hw_frame_ref = av_buffer_ref(avctx->hw_frames_ctx); if (!s->hw_frame_ref) { ret = AVERROR(EINVAL); - goto error; + return ret; } hw_frames_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; @@ -137,7 +137,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) if (!s->hw_device_ref) { av_log(avctx, AV_LOG_ERROR, "Get hw_device_ref failed.\n"); ret = AVERROR(EINVAL); - goto error; + return ret; } } else { if (avctx->hw_device_ctx) { @@ -145,20 +145,20 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) if (!s->hw_device_ref) { av_log(avctx, AV_LOG_ERROR, "ref hwdevice failed.\n"); ret = AVERROR(EINVAL); - goto error; + return ret; } } else { ret = av_hwdevice_ctx_create(&s->hw_device_ref, AV_HWDEVICE_TYPE_ASCEND, device_id, NULL, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "hwdevice context create failed. ret is %d.\n", ret); - goto error; + return retr; } } s->hw_frame_ref = av_hwframe_ctx_alloc(s->hw_device_ref); if (!s->hw_frame_ref) { av_log(avctx, AV_LOG_ERROR, "hwframe ctx alloc falied.\n"); ret = AVERROR(EINVAL); - goto error; + return ret; } hw_frames_ctx = (AVHWFramesContext*)s->hw_frame_ref->data; if (!hw_frames_ctx->pool) { @@ -171,7 +171,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "hwframe ctx init error, ret is %d.\n", ret); ret = AVERROR(EINVAL); - goto error; + return ret; } } } @@ -218,6 +218,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) uint32_t channel_id = s->channel_id; ret = hi_mpi_vdec_create_chn(channel_id, &chn_attr_); if (ret != 0) { + hi_mpi_sys_exit(); av_log(avctx, AV_LOG_ERROR, "HiMpi create vdec channel failed, ret is %d.\n", ret); return ret; } @@ -225,6 +226,8 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) hi_vdec_chn_param chn_param_; ret = hi_mpi_vdec_get_chn_param(channel_id, &chn_param_); if (ret != 0) { + hi_mpi_vdec_destroy_chn(s->channel_id); + hi_mpi_sys_exit(); av_log(avctx, AV_LOG_ERROR, "HiMpi vdec get channel param failed, ret is %d.\n", ret); return ret; } @@ -237,24 +240,31 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) ret = hi_mpi_vdec_set_chn_param(channel_id, &chn_param_); if (ret != 0) { + hi_mpi_vdec_destroy_chn(s->channel_id); + hi_mpi_sys_exit(); av_log(avctx, AV_LOG_ERROR, "HiMpi vdec set channel param failed, ret is %d.\n", ret); return ret; } ret = hi_mpi_vdec_start_recv_stream(channel_id); if (ret != 0) { + hi_mpi_vdec_stop_recv_stream(s->channel_id); + hi_mpi_vdec_destroy_chn(s->channel_id); + hi_mpi_sys_exit(); av_log(avctx, AV_LOG_ERROR, "HiMpi vdec start receive stream failed, ret is %d.\n", ret); return ret; } s->pkt = av_packet_alloc(); - if (!s->pkt) + if (!s->pkt) { + hi_mpi_vdec_stop_recv_stream(s->channel_id); + hi_mpi_vdec_destroy_chn(s->channel_id); + hi_mpi_sys_exit(); + av_log(avctx, AV_LOG_ERROR, "Init packet failed, ret is %d.\n", ret); return AVERROR(ENOMEM); + } s->avctx = avctx; return 0; - error: - ff_mjpeg_ascend_decode_end(avctx); - return ret; } static int mjpeg_get_packet(AVCodecContext* avctx) @@ -305,20 +315,20 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) return AVERROR_INVALIDDATA; } - output_size = in->size - input_skip + sizeof(jpeg_header2) + dht_segment_size2; + output_size = in->size - input_skip + sizeof(jpeg_header_ascend) + dht_segment_size_ascend; ret = av_new_packet(out, output_size); if (ret < 0) return AVERROR_INVALIDDATA; output = out->data; - output = append2(output, jpeg_header2, sizeof(jpeg_header2)); - output = append_dht_segment2(output); - output = append2(output, in->data + input_skip, in->size - input_skip); + output = append_ascend(output, jpeg_header_ascend, sizeof(jpeg_header_ascend)); + output = append_dht_segment_ascend(output); + output = append_ascend(output, in->data + input_skip, in->size - input_skip); /* JPEG to YUV420 By Ascend */ ret = aclrtSetCurrentContext(s->ascend_ctx->context); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "Set context failed, ret is %d.\n", ret); - return ret; + goto error; } uint8_t* streamBuffer = NULL; @@ -326,13 +336,14 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) ret = hi_mpi_dvpp_malloc(device_id, &streamBuffer, output_size); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "HiMpi malloc packet failed, ret is %d.\n", ret); - return ret; + goto error; } ret = aclrtMemcpy(streamBuffer, output_size, out->data, output_size, ACL_MEMCPY_HOST_TO_DEVICE); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "Mem copy H2D failed. ret is %d.\n", ret); - return ret; + hi_mpi_dvpp_free(streamBuffer); + goto error; } hi_vdec_stream stream; @@ -361,7 +372,8 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) ret = hi_mpi_dvpp_malloc(device_id, &picBuffer, size); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "HiMpi malloc falied, ret is %d.\n", ret); - return ret; + hi_mpi_dvpp_free(streamBuffer); + goto error; } pic_info.vir_addr = (uint64_t)picBuffer; @@ -369,8 +381,9 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) ret = hi_mpi_vdec_send_stream(s->channel_id, &stream, &pic_info, 1000); if (ret != 0) { hi_mpi_dvpp_free(picBuffer); + hi_mpi_dvpp_free(streamBuffer); av_log(avctx, AV_LOG_ERROR, "Send stream failed, ret is %d.\n", ret); - return ret; + goto error; } hi_video_frame_info got_frame; @@ -379,38 +392,44 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) ret = hi_mpi_vdec_get_frame(s->channel_id, &got_frame, &stSupplement, &got_stream, 100); if (ret != 0) { hi_mpi_dvpp_free(picBuffer); + hi_mpi_dvpp_free(streamBuffer); av_log(avctx, AV_LOG_ERROR, "Get frame failed, ret is %d.\n", ret); - return ret; + goto error; } size_t decResult = got_frame.v_frame.frame_flag; - hi_mpi_dvpp_free(got_stream.addr); + hi_mpi_dvpp_free(got_stream.addr); // free decode input if (decResult != 0 && got_frame.v_frame.virt_addr[0] != NULL) { hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); - return ret; + goto error; } if (decResult != 0 || got_frame.v_frame.virt_addr[0] == NULL || got_stream.need_display == HI_FALSE) { + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); ret = hi_mpi_vdec_release_frame(s->channel_id, &got_frame); if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "HiMpi release frame failed, ret is %d.\n", ret); - return ret; + goto error; } - return -1; + ret = -1; + goto error; } ret = hi_mpi_vdec_release_frame(s->channel_id, &got_frame); if (ret != 0) { + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); av_log(avctx, AV_LOG_ERROR, "HiMpi release frame failed, ret is %d.\n", ret); - return ret; + goto error; } ret = av_hwframe_get_buffer(s->hw_frame_ref, frame, 0); if (ret < 0) { + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); av_log(avctx, AV_LOG_ERROR, "Frame get buffer failed, ret is %d.\n", ret); - return AVERROR(EINVAL); + goto error; } ret = ff_decode_frame_props(avctx, frame); if (ret < 0) { + hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); av_log(avctx, AV_LOG_ERROR, "Fill frame properties failed. ret is %d.\n", ret); - return AVERROR(EINVAL); + goto error; } frame->pkt_pos = -1; @@ -419,9 +438,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) frame->width = got_frame.v_frame.width_stride[0]; frame->height = got_frame.v_frame.height_stride[0]; frame->format = (int)AV_PIX_FMT_NV12; -// frame->pts = got_frame.v_frame.pts; -// frame->pkt_pts = frame->pts; -// frame->pkt_dts = out->dts; + frame->pkt_dts = s->pkt->dts; uint32_t offset = 0; for (int i = 0; i < 2; i++) { @@ -431,7 +448,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) if (ret != 0) { av_log(avctx, AV_LOG_ERROR, "Mem copy D2D failed, ret is %d.\n", ret); hi_mpi_dvpp_free(got_frame.v_frame.virt_addr[0]); - return ret; + goto error; } offset += dstBytes; } -- Gitee From 1da9570c9e9d4e901df723036bfa908f56151f95 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Thu, 9 Jan 2025 11:01:48 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index 7e6ba2b41..e77c53942 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -25,8 +25,6 @@ #include "idctdsp.h" #include "internal.h" #include "jpegtables.h" -//#include "mjpeg.h" -//#include "mjpegdec.h" #include "jpeglsdec.h" #include "profiles.h" #include "put_bits.h" @@ -151,7 +149,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) ret = av_hwdevice_ctx_create(&s->hw_device_ref, AV_HWDEVICE_TYPE_ASCEND, device_id, NULL, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "hwdevice context create failed. ret is %d.\n", ret); - return retr; + return ret; } } s->hw_frame_ref = av_hwframe_ctx_alloc(s->hw_device_ref); -- Gitee From 55ed4e94c443340575340b28dcf40cb0eabc608e Mon Sep 17 00:00:00 2001 From: Malanchi Date: Thu, 9 Jan 2025 11:04:54 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libavcodec/ascend_mjpeg_dec.h | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h index f429b07e8..fbd7ff72f 100644 --- a/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h +++ b/mxVision/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h @@ -1,24 +1,17 @@ /* - * MJPEG Ascend decoder - * Copyright (c) 2000, 2001 Fabrice Bellard - * Copyright (c) 2003 Alex Beregszaszi - * Copyright (c) 2003-2004 Michael Niedermayer + * Copyright(c) 2024. Huawei Technologies Co.,Ltd. All rights reserved. * - * This file is part of FFmpeg. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except int compliance with the License. + * You may obtain a copy of the License at * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * http://www.apache.org/licenses/LICENSE-2.0 * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /** -- Gitee From 70558798ab246ec9f13f8610c12c1ca5d87783a7 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Thu, 9 Jan 2025 11:39:52 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h index fbd7ff72f..087ca37cb 100644 --- a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h +++ b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.h @@ -1,5 +1,5 @@ /* - * Copyright(c) 2024. Huawei Technologies Co.,Ltd. All rights reserved. + * Copyright(c) 2025. Huawei Technologies Co.,Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except int compliance with the License. -- Gitee From 02118ddeda33dbde13c6093cb991ebbe5d0eccb5 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Mon, 13 Jan 2025 10:41:11 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libavcodec/ascend_mjpeg_dec.c | 94 ++++++++++++------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index e77c53942..a5833a8a0 100644 --- a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -35,25 +35,31 @@ static const uint8_t jpeg_header_ascend[] = { - 0xff, 0xd8, // SOI - 0xff, 0xe0, // APP0 - 0x00, 0x10, // APP0 header size - 0x4a, 0x46, 0x49, 0x46, 0x00, // ID string 'JFIF\0' - 0x01, 0x01, // version - 0x00, // bits per type - 0x00, 0x00, // X density - 0x00, 0x00, // Y density - 0x00, // X thumbnail size - 0x00, // Y thumbnail size + 0xff, 0xd8, // SOI + 0xff, 0xe0, // APP0 + 0x00, 0x10, // APP0 header size + 0x4a, 0x46, 0x49, 0x46, 0x00, // ID string 'JFIF\0' + 0x01, 0x01, // version + 0x00, // bits per type + 0x00, 0x00, // X density + 0x00, 0x00, // Y density + 0x00, // X thumbnail size + 0x00, // Y thumbnail size }; static const int dht_segment_size_ascend = 420; +static const int bits_dc_luminance = 16; +static const int val_dc = 12; +static const int bits_ac_luminance = 16; +static const int val_ac_luminance = 162; +static const int bits_ac_chrominance = 16; +static const int val_ac_chrominance = 162; static const uint8_t dht_segment_head_ascend[] = {0xFF, 0xC4, 0x01, 0xA2, 0x00}; static const uint8_t dht_segment_frag_ascend[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, }; static uint8_t *append_ascend(uint8_t *buf, const uint8_t *src, int size) @@ -65,15 +71,15 @@ static uint8_t *append_ascend(uint8_t *buf, const uint8_t *src, int size) static uint8_t *append_dht_segment_ascend(uint8_t *buf) { buf = append_ascend(buf, dht_segment_head_ascend, sizeof(dht_segment_head_ascend)); - buf = append_ascend(buf, avpriv_mjpeg_bits_dc_luminance + 1, 16); + buf = append_ascend(buf, avpriv_mjpeg_bits_dc_luminance + 1, bits_dc_luminance); buf = append_ascend(buf, dht_segment_frag_ascend, sizeof(dht_segment_frag_ascend)); - buf = append_ascend(buf, avpriv_mjpeg_val_dc, 12); + buf = append_ascend(buf, avpriv_mjpeg_val_dc, val_dc); *(buf++) = 0x10; - buf = append_ascend(buf, avpriv_mjpeg_bits_ac_luminance + 1, 16); - buf = append_ascend(buf, avpriv_mjpeg_val_ac_luminance, 162); + buf = append_ascend(buf, avpriv_mjpeg_bits_ac_luminance + 1, bits_ac_luminance); + buf = append_ascend(buf, avpriv_mjpeg_val_ac_luminance, val_ac_luminance); *(buf++) = 0x11; - buf = append_ascend(buf, avpriv_mjpeg_bits_ac_chrominance + 1, 16); - buf = append_ascend(buf, avpriv_mjpeg_val_ac_chrominance, 162); + buf = append_ascend(buf, avpriv_mjpeg_bits_ac_chrominance + 1, bits_ac_chrominance); + buf = append_ascend(buf, avpriv_mjpeg_val_ac_chrominance, val_ac_chrominance); return buf; } @@ -82,6 +88,20 @@ static uint8_t *append_dht_segment_ascend(uint8_t *buf) #define FFALIGNMJPEG(x, a) (((x) + (a) - 1) &~ ((a) - 1)) #define WIDTH_ALIGN 2 #define HEIGHT_ALIGN 16 +#define MAX_WIDTH 4096 +#define MAX_HEIGHT 4096 +#define MIN_WIDTH 128 +#define MIN_HEIGHT 128 +#define POOL_SIZE 2 +#define NUM_EIGHT 8 +#define NUM_FIVE 5 +#define NUM_FOUR 4 +#define NUM_THREE 3 +#define NUM_TWO 2 +#define MIN_PKT_SIZE 12 +#define SEND_STREAM_TIME_DELAY 1000 +#define GET_FRAME_TIME_DELAY 100 + av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) { @@ -95,7 +115,8 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) return AVERROR(EINVAL); } - if (avctx->width < 128 || avctx->height < 128 || avctx->width > 4096 || avctx->height > 4096) { + if (avctx->width < MIN_WIDTH || avctx->height < MIN_HEIGHT || + avctx->width > MAX_WIDTH || avctx->height > MAX_HEIGHT) { av_log(avctx, AV_LOG_ERROR, "MJPEG decoder only support resolution: 128x128 ~ 4096x4096, now: %dx%d.\n", avctx->width, avctx->height); return AVERROR(EINVAL); @@ -121,7 +142,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) } hw_frames_ctx->width = avctx->width; hw_frames_ctx->height = avctx->height; - hw_frames_ctx->initial_pool_size = 2; + hw_frames_ctx->initial_pool_size = POOL_SIZE; hw_frames_ctx->format = AV_PIX_FMT_ASCEND; hw_frames_ctx->sw_format = AV_PIX_FMT_NV12; @@ -162,7 +183,7 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) if (!hw_frames_ctx->pool) { hw_frames_ctx->width = avctx->width; hw_frames_ctx->height = avctx->height; - hw_frames_ctx->initial_pool_size = 2; + hw_frames_ctx->initial_pool_size = POOL_SIZE; hw_frames_ctx->format = AV_PIX_FMT_ASCEND; hw_frames_ctx->sw_format = AV_PIX_FMT_NV12; ret = av_hwframe_ctx_init(s->hw_frame_ref); @@ -181,7 +202,8 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) ret = aclrtSetCurrentContext(s->ascend_ctx->context); if (ret != 0) { - av_log(avctx, AV_LOG_ERROR, "Set context failed at line(%d) in func(%s), ret is %d.\n", __LINE__, __func__, ret); + av_log(avctx, AV_LOG_ERROR, "Set context failed at line(%d) in func(%s), + ret is %d.\n", __LINE__, __func__, ret); return ret; } @@ -196,7 +218,8 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) chn_attr_.mode = HI_VDEC_SEND_MODE_FRAME; chn_attr_.pic_width = avctx->width; chn_attr_.pic_height = avctx->height; - chn_attr_.stream_buf_size = chn_attr_.pic_width * chn_attr_.pic_height * 3 / 2; + chn_attr_.stream_buf_size = chn_attr_.pic_width * chn_attr_.pic_height * + NUM_THREE / NUM_TWO; chn_attr_.frame_buf_cnt = REF_FRAME_NUM + DISPLAY_FRAME_NUM + 1; hi_pic_buf_attr buf_attr_; @@ -271,8 +294,9 @@ static int mjpeg_get_packet(AVCodecContext* avctx) int ret; av_packet_unref(s->pkt); ret = ff_decode_get_packet(avctx, s->pkt); - if (ret < 0) + if (ret < 0) { return ret; + } s->buf_size = s->pkt->size; return 0; } @@ -292,7 +316,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) int input_skip, output_size; AVPacket *in = s->pkt; - if (in->size < 12) { + if (in->size < MIN_PKT_SIZE) { av_log(avctx, AV_LOG_ERROR, "Input is truncate.\n"); return AVERROR_INVALIDDATA; } @@ -302,10 +326,10 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) return AVERROR_INVALIDDATA; } - if (in->data[2] == 0xff && in->data[3] == APP0) { - input_skip = (in->data[4] << 8) + in->data[5] + 4; + if (in->data[NUM_TWO] == 0xff && in->data[NUM_THREE] == APP0) { + input_skip = (in->data[NUM_FOUR] << NUM_EIGHT) + in->data[NUM_FIVE] + NUM_FOUR; } else { - input_skip = 2; + input_skip = NUM_TWO; } if (in->size < input_skip) { @@ -362,7 +386,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) pic_info.offset_left = 0; pic_info.offset_right = 0; - uint32_t size = pic_info.width_stride * pic_info.height_stride * 3 / 2; + uint32_t size = pic_info.width_stride * pic_info.height_stride * NUM_THREE / NUM_TWO; pic_info.buffer_size = size; pic_info.pixel_format = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420; @@ -376,7 +400,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) pic_info.vir_addr = (uint64_t)picBuffer; - ret = hi_mpi_vdec_send_stream(s->channel_id, &stream, &pic_info, 1000); + ret = hi_mpi_vdec_send_stream(s->channel_id, &stream, &pic_info, SEND_STREAM_TIME_DELAY); if (ret != 0) { hi_mpi_dvpp_free(picBuffer); hi_mpi_dvpp_free(streamBuffer); @@ -387,7 +411,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) hi_video_frame_info got_frame; hi_vdec_stream got_stream; hi_vdec_supplement_info stSupplement; - ret = hi_mpi_vdec_get_frame(s->channel_id, &got_frame, &stSupplement, &got_stream, 100); + ret = hi_mpi_vdec_get_frame(s->channel_id, &got_frame, &stSupplement, &got_stream, GET_FRAME_TIME_DELAY); if (ret != 0) { hi_mpi_dvpp_free(picBuffer); hi_mpi_dvpp_free(streamBuffer); @@ -439,7 +463,7 @@ int ff_mjpeg_ascend_receive_frame(AVCodecContext* avctx, AVFrame* frame) frame->pkt_dts = s->pkt->dts; uint32_t offset = 0; - for (int i = 0; i < 2; i++) { + for (int i = 0; i < NUM_TWO; i++) { size_t dstBytes = got_frame.v_frame.width_stride[0] * got_frame.v_frame.height_stride[0] * (i ? 1.0 / 2 : 1); ret = aclrtMemcpy(frame->data[i], dstBytes, got_frame.v_frame.virt_addr[0] + offset, dstBytes, ACL_MEMCPY_DEVICE_TO_DEVICE); @@ -498,8 +522,8 @@ static void ascend_decode_flush(AVCodecContext* avctx) #define OFFSET(x) offsetof(AscendMJpegDecodeContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "device_id", "Use to choose the ascend chip.", OFFSET(device_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, VD }, - { "channel_id", "Set channelId of decoder.", OFFSET(channel_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 255, VD }, + { "device_id", "Use to choose the ascend chip.", OFFSET(device_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 8, VD }, + { "channel_id", "Set channelId of decoder.", OFFSET(channel_id), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 255, VD }, { NULL } }; -- Gitee From 9b02179df83c4d3c567fa823b0713d00380e8e41 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Mon, 13 Jan 2025 10:57:04 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VisionSDK/Ascendffmpeg/README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/VisionSDK/Ascendffmpeg/README.md b/VisionSDK/Ascendffmpeg/README.md index 5b97a713f..ef61ed6bb 100644 --- a/VisionSDK/Ascendffmpeg/README.md +++ b/VisionSDK/Ascendffmpeg/README.md @@ -8,12 +8,12 @@ mxVison ascend 硬件平台内置了视频相关的硬件加速解码器,为 支持的功能: -|功能|mpeg4|h264/h265|多路| -|:----:|:----:|:----:|:----:| -|硬件解码|√|√|√| -|硬件编码|√|√|√| -|硬件转码|√|√|√| -|硬件缩放|√|√|√| +|功能|mpeg4|h264/h265| mjpeg |多路 | +|:----:|:----:|:----:|:-----:|:-------:| +|硬件解码|√|√| √ | √ | +|硬件编码|√|√| | √ | +|硬件转码|√|√| √ | √ | +|硬件缩放|√|√| | √ | ### 1.2 支持的产品 @@ -86,7 +86,7 @@ export LD_LIBRARY_PATH=/PATH/TO/mindxsdk-referenceapps/VisionSDK/Ascendffmpeg/as * `-hwaccel` - 指定采用 ascend 来进行硬件加速, 用来做硬件相关初始化工作。 解码相关参数(注意:解码相关参数需要在 `-i` 参数前设置): -* `-c:v` - 指定解码器为 h264_ascend (解码 h265 格式可以使用 h265_ascend)。 +* `-c:v` - 指定解码器为 h264_ascend (解码 h265 格式可以使用 h265_ascend,解码 mjpeg 格式可以使用 mjpeg_ascend)。 * `-device_id` - 指定硬件设备 id 为 0。取值范围取决于芯片个数,默认为 0。 `npu-smi info` 命令可以查看芯片个数 * `-channel_id` - 指定解码通道 id ,默认为0,取值范围取决于芯片实际情况,超出时会报错(对于昇腾Atlas 300I pro、 Atlas 300V pro,该参数的取值范围:[0, 256),JPEGD功能和VDEC功能共用通道,且通道总数最多256。对于Atlas 500 A2推理产品,该参数的取值范围:[0, 128),JPEGD功能和VDEC功能共用通道,且通道总数最多128)。 若是指定的通道已被占用, 则自动寻找并申请新的通道。 * `-resize` - 指定缩放大小, 输入格式为: {width}x{height}。宽高:[128x128-4096x4096], 宽高相乘不能超过 4096*2304(此为h264的约束)。宽要与 16 对齐,高要与 2 对齐。 @@ -120,7 +120,10 @@ export LD_LIBRARY_PATH=/PATH/TO/mindxsdk-referenceapps/VisionSDK/Ascendffmpeg/as # 将输入文件 out.yuv 编码为H.264格式,输出文件为 out.264 ./ffmpeg -hwaccel ascend -s 1920x1080 -pix_fmt nv12 -i out.yuv -c:v h264_ascend out.264 ``` - +```bash +# 将输入文件 test.mjpeg 解码,通过 Ascend 硬件解码与编码,最终输出为 out.264 +./ffmpeg -hwaccel ascend -c:v mjpeg_ascend -device_id 0 -channel_id 0 -i test.mjpeg -c:v h264_ascend -device_id 0 -channel_id 0 out.264 +``` ## 4 常见问题 ### 4.1 文件编译不通过 -- Gitee From 794b7b490c2a84264da7b6c54079b40195cb667f Mon Sep 17 00:00:00 2001 From: Malanchi Date: Mon, 13 Jan 2025 10:57:52 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VisionSDK/Ascendffmpeg/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VisionSDK/Ascendffmpeg/README.md b/VisionSDK/Ascendffmpeg/README.md index ef61ed6bb..a310c3511 100644 --- a/VisionSDK/Ascendffmpeg/README.md +++ b/VisionSDK/Ascendffmpeg/README.md @@ -121,7 +121,7 @@ export LD_LIBRARY_PATH=/PATH/TO/mindxsdk-referenceapps/VisionSDK/Ascendffmpeg/as ./ffmpeg -hwaccel ascend -s 1920x1080 -pix_fmt nv12 -i out.yuv -c:v h264_ascend out.264 ``` ```bash -# 将输入文件 test.mjpeg 解码,通过 Ascend 硬件解码与编码,最终输出为 out.264 +# 将输入文件 test.mjpeg 通过 Ascend 硬件解码与编码,最终输出为 out.264 ./ffmpeg -hwaccel ascend -c:v mjpeg_ascend -device_id 0 -channel_id 0 -i test.mjpeg -c:v h264_ascend -device_id 0 -channel_id 0 out.264 ``` ## 4 常见问题 -- Gitee From cbc9af1b256130b6f0d99291e6027a4d51cc54c5 Mon Sep 17 00:00:00 2001 From: Malanchi Date: Mon, 13 Jan 2025 11:20:10 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=E6=96=B0=E5=A2=9Emjpeg=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c index a5833a8a0..cdf69df74 100644 --- a/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c +++ b/VisionSDK/Ascendffmpeg/libavcodec/ascend_mjpeg_dec.c @@ -202,8 +202,8 @@ av_cold int ff_mjpeg_ascend_decode_init(AVCodecContext* avctx) ret = aclrtSetCurrentContext(s->ascend_ctx->context); if (ret != 0) { - av_log(avctx, AV_LOG_ERROR, "Set context failed at line(%d) in func(%s), - ret is %d.\n", __LINE__, __func__, ret); + av_log(avctx, + AV_LOG_ERROR, "Set context failed at line(%d) in func(%s), ret is %d.\n", __LINE__, __func__, ret); return ret; } -- Gitee