专栏底层软件J5平台decode解码无效(h265->yuv)

J5平台decode解码无效(h265->yuv)

已解决
yin_zuoshuai2024-05-31
175
4

用户您好,请详细描述您所遇到的问题,详细的描述有助于帮助我们快速定位,解决问题~Thanks♪(・ω・)ノ

1. 硬件获取渠道及型号: 中信科提供的J5

2. 系统镜像版本: Linux j5dvb 5.10.59-rt52 #4 SMP PREEMPT_RT Mon Mar 25 11:33:56 CST 2024 aarch64 GNU/Linux

3. 问题模块: h265编解码

4. 问题描述: J5平台编程解码h265数据->yuv数据,程序正常走完且无报错,生成的yuv文件大小是0

5. 示例代码: (见附件h265_decode.cpp,直接在文档《地平线平台底层软件接口手册》的3.3.2.3中的demo代码解决编译问题后如下:)

#include "hb_media_codec.h"

#include "hb_media_error.h"


#include

//#include

#include "vputypes.h"

#include

#include

#include


#define MAX_FILE_PATH 256

#define TAG "[Multi_Media]"


static Uint64 osal_gettime(void)

{

  struct timespec tp;

  clock_gettime(CLOCK_MONOTONIC, &tp);

  return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);

}


typedef struct MediaCodecTestContext {

  media_codec_context_t *context;

  char *inputFileName;

  char *outputFileName;

  int vlc_buf_size;

} MediaCodecTestContext;


typedef struct AsyncMediaCtx {

  media_codec_context_t *ctx;

  FILE *inFile;

  FILE *outFile;

  int lastStream;

  Uint64 startTime;

  int32_t duration;

} AsyncMediaCtx;


static void on_encoder_input_buffer_available(hb_ptr userdata, media_codec_buffer_t *inputBuffer) 

{

  AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;

  int noMoreInput = 0;

  hb_s32 ret = 0;

  Uint64 curTime = 0;

  if (!noMoreInput) {

    curTime = osal_gettime();

    if ((curTime - asyncCtx->startTime)/1000 < (uint32_t)asyncCtx->duration) {

      ret = fread(inputBuffer->vframe_buf.vir_ptr[0], 1, inputBuffer->vframe_buf.size, asyncCtx->inFile);

      if (ret

        if(fseek(asyncCtx->inFile, 0, SEEK_SET)) {

          printf("Failed to rewind input filen");

        } else {

          ret = fread(inputBuffer->vframe_buf.vir_ptr[0], 1, inputBuffer->vframe_buf.size, asyncCtx->inFile);

          if (ret

            printf("Failed to read input filen");

          }

        }

      }

    }

    if (!ret) {

      printf("%s There is no more input data!\n", TAG);

      inputBuffer->vframe_buf.frame_end = TRUE;

      noMoreInput = 1;

    } else {

      inputBuffer->vframe_buf.frame_end = TRUE;

      inputBuffer->vframe_buf.size = 0;

    }

  }

}


static void on_encoder_output_buffer_available(hb_ptr userdata, media_codec_buffer_t *outputBuffer, media_codec_output_buffer_info_t *extraInfo) 

{

  AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;

  //mc_h264_h265_output_stream_info_t info = extraInfo->video_stream_info;

  fwrite(outputBuffer->vstream_buf.vir_ptr, outputBuffer->vstream_buf.size, 1, asyncCtx->outFile);

  if (outputBuffer->vstream_buf.stream_end) {

    printf("There is no more output data!\n");

    asyncCtx->lastStream = 1;

  }

}


static void on_encoder_media_codec_message(hb_ptr userdata, hb_s32 error) 

{

  AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;

  if (error) {

    asyncCtx->lastStream = 1;

    printf("ERROR happened!\n");

  }

}

static void on_vlc_buffer_message(hb_ptr userdata, hb_s32 * vlc_buf)

{

  MediaCodecTestContext *ctx = (MediaCodecTestContext *)userdata;

  printf("%s %s VLC Buffer size = %d; Reset to %d.n", TAG, __FUNCTION__, *vlc_buf, ctx->vlc_buf_size);

  *vlc_buf = ctx->vlc_buf_size;

}


static void do_async_encoding(void *arg) 

{

  hb_s32 ret = 0;

  FILE *outFile;

  FILE *inFile;

  //int step = 0;

  AsyncMediaCtx asyncCtx;

  MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;

  media_codec_context_t *context = ctx->context;

  char *inputFileName = ctx->inputFileName;

  char *outputFileName = ctx->outputFileName;

  media_codec_state_t state = MEDIA_CODEC_STATE_NONE;

  inFile = fopen(inputFileName, "rb");

  if (!inFile) {

    goto ERR;

  }

  outFile = fopen(outputFileName, "wb");

  if (!outFile) {

    goto ERR;

  }

  memset(&asyncCtx, 0x00, sizeof(AsyncMediaCtx));

  asyncCtx.ctx = context;

  asyncCtx.inFile = inFile;

  asyncCtx.outFile = outFile;

  asyncCtx.lastStream = 0;

  asyncCtx.duration = 5;

  asyncCtx.startTime = osal_gettime();

  ret = hb_mm_mc_initialize(context);

  if (ret) {

    goto ERR;

  }

  media_codec_callback_t callback;

  callback.on_input_buffer_available = on_encoder_input_buffer_available;

  callback.on_output_buffer_available = on_encoder_output_buffer_available;

  callback.on_media_codec_message = on_encoder_media_codec_message;

  ret = hb_mm_mc_set_callback(context, &callback, &asyncCtx);

  if (ret) {

    goto ERR;

  }

  media_codec_callback_t callback2;

  callback2.on_vlc_buffer_message = on_vlc_buffer_message;

  if (ctx->vlc_buf_size > 0) {

    ret = hb_mm_mc_set_vlc_buffer_listener(context, &callback2, ctx);

    if (ret) {

      goto ERR;

    }

  }

  ret = hb_mm_mc_configure(context);

  if (ret) {

    goto ERR;

  }

  mc_av_codec_startup_params_t startup_params;

  startup_params.video_enc_startup_params.receive_frame_number = 0;

  ret = hb_mm_mc_start(context, &startup_params);

  if (ret) {

    goto ERR;

  }

  while(!asyncCtx.lastStream) {

    sleep(1);

  }

  hb_mm_mc_stop(context);

  hb_mm_mc_release(context);

  //context = NULL;

ERR:

  hb_mm_mc_get_state(context, &state);

  if (context && state != MEDIA_CODEC_STATE_UNINITIALIZED) {

    hb_mm_mc_stop(context);

    hb_mm_mc_release(context);

  }

  if (inFile)

    fclose(inFile);

  if (outFile)

    fclose(outFile);

}


int main(void)

{

  int ret = 0;

  char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";

  char inputFileName[MAX_FILE_PATH] = "./input_640x480_normal.h265";

  mc_video_codec_enc_params_t *params = NULL;

  media_codec_context_t context;

  memset(&context, 0x00, sizeof(media_codec_context_t));

  context.codec_id = MEDIA_CODEC_ID_H265;

  context.encoder = 1;

  params = &context.video_enc_params;

  params->width = 640;

  params->height = 480;

  params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;

  params->frame_buf_count = 5;

  params->external_frame_buf = 0;

  params->bitstream_buf_count = 5;

  params->rc_params.mode = MC_AV_RC_MODE_H265CBR;

  ret = hb_mm_mc_get_rate_control_config(&context, ¶ms->rc_params);

  if (ret) {

    return -1;

  }

  params->rc_params.h265_cbr_params.bit_rate = 5000;

  params->rc_params.h265_cbr_params.frame_rate = 30;

  params->rc_params.h265_cbr_params.intra_period = 30;

  params->gop_params.decoding_refresh_type = 2;

  params->gop_params.gop_preset_idx = 2;

  params->rot_degree = MC_CCW_0;

  params->mir_direction = MC_DIRECTION_NONE;

  params->frame_cropping_flag = FALSE;

  MediaCodecTestContext ctx;

  memset(&ctx, 0x00, sizeof(ctx));

  ctx.context = &context;

  ctx.inputFileName = inputFileName;

  ctx.outputFileName = outputFileName;

  do_async_encoding(&ctx);

  return 0;

}

6. log文件:logcat没有任何log

附件:
底层软件
征程5
评论4
0/1000
  • TROS.Assist
    Lv.3

    您好,此问题我们先内部看一下

    2024-05-31
    0
    0
  • TROS.Assist
    Lv.3

    您好,麻烦用源文件编码试试,是否会复现。

    2024-06-03
    0
    0
  • yin_zuoshuai
    Lv.1
    您好,请问用源文件编码是什么意思?另外我发现demo代码中使用的是“mc_video_codec_enc_params_t *params = NULL;”,从h265至yuv是不是应该用mc_video_codec_dec_params_t?
    2024-06-04
    0
    0
  • TROS.Assist
    Lv.3

    您可以尝试跑一下sample自带的demo,看是否正常。

    2024-06-04
    0
    0