本帖最后由 MaybeNot 于 2024-10-21 18:44 编辑 使用ffmedia对本地mp4视频文件进行mpp解码+rga颜色空间转换和缩放,将获取到的rgb数据通过opencv显示,发现在正常执行一段时间后(从几分钟到半小时不等),概率出现画面异常,如下图所示,且画面出现异常时没有报错信息。
代码大致如下:之所以不用drm显示而是用opencv是为了测试得到的数据画面是否正常,若用drm display的话无法设置384x2960(是16对齐)的宽高。不知道对于宽高差距较大是否有问题,需不需要调节setBufferCount的大小呢? void callback_external(void* _ctx, shared_ptr<MediaBuffer> buffer) { External_ctx* ctx = static_cast<External_ctx*>(_ctx); shared_ptr<ModuleRga> module = ctx->module; if (buffer == NULL || buffer->getMediaBufferType() != BUFFER_TYPE_VIDEO) return; shared_ptr<VideoBuffer> buf = static_pointer_cast<VideoBuffer>(buffer); void *data = buf->getActiveData(); uint32_t size = buf->getActiveSize(); pthread_mutex_lock(&rgb_data_ctx.mutex); while (rgb_data_ctx.count == VBUFFER_SIZE) { pthread_cond_wait(&rgb_data_ctx.not_full, &rgb_data_ctx.mutex); } memcpy(rgb_data_ctx.rgb_buf[(rgb_data_ctx.in % VBUFFER_SIZE)].rgb_frame, (uchar *)data, size); rgb_data_ctx.in = (rgb_data_ctx.in + 1) % VBUFFER_SIZE; rgb_data_ctx.count++; pthread_cond_signal(&rgb_data_ctx.not_empty); pthread_mutex_unlock(&rgb_data_ctx.mutex); } void process_rgb_frame(void *_ctx) { while (true){ pthread_mutex_lock(&rgb_data_ctx.mutex); if (rgb_data_ctx.count == 0 && rgb_data_ctx.done == 1){ pthread_mutex_unlock(&rgb_data_ctx.mutex); log_info("done, break"); break; } while(rgb_data_ctx.count == 0 && rgb_data_ctx.done == 0){ pthread_cond_wait(&rgb_data_ctx.not_empty, &rgb_data_ctx.mutex); } void *data = rgb_data_ctx.rgb_buf[rgb_data_ctx.out].rgb_frame; if(rgb_data_ctx.count > 0) rgb_data_ctx.count--; rgb_data_ctx.out = (rgb_data_ctx.out+1) % VBUFFER_SIZE; cv::Mat mat(cv::Size(384, 2960), CV_8UC3, data); cv::imshow("display window", mat); cv::waitKey(1); pthread_cond_signal(&rgb_data_ctx.not_full); pthread_mutex_unlock(&rgb_data_ctx.mutex); } for(int i=0; i<VBUFFER_SIZE; i++){ free(rgb_data_ctx.rgb_buf[i].rgb_frame); rgb_data_ctx.rgb_buf[i].rgb_frame = NULL; rgb_data_ctx.rgb_buf[i].rgb_ts = 0; } return; } int start_instance(External_ctx* ctx) { int ret; DemoConfig* inst_conf = &(ctx->config); file_reader->setProductor(NULL); file_reader->setBufferCount(20); ret = file_reader->init(); shared_ptr<ModuleMppDec> dec = make_shared<ModuleMppDec>(inst_conf->input_image_para); dec->setProductor(file_reader); dec->setBufferCount(10); ret = dec->init(); if (ret < 0) { ff_error("Dec init failed\n"); // goto FAILED; } shared_ptr<ModuleRga> rga = make_shared<ModuleRga>(inst_conf->output_image_para, inst_conf->rotate); rga->setProductor(dec); rga->setBufferCount(2); ret = rga->init(); if (ret < 0) { ff_error("rga init failed\n"); // goto FAILED; } ctx->module = rga; ctx->rga_buffer = rga->newModuleMediaBuffer(); // 默认为cacheable的buffer rga->setOutputDataCallback(ctx, callback_external); std::thread frame_processor(process_rgb_frame, ctx); frame_processor.detach(); clock_gettime(CLOCK_MONOTONIC, &ctx->start); file_reader->start(); file_reader->dumpPipe(); while (true) { int played_cnt = 0; if(STATUS_EOS == file_reader->getModuleStatus()){ // 获取当前组件工作状态 log_info("STATUS_EOS, end of stream. cnt = %d", played_cnt++); goto STOP; } usleep(5000); } } |
-
646 Bytes, 下载次数: 0, 下载积分: 灯泡 -1 , 经验 -1