当前位置:网站首页 > Haskell函数式编程 > 正文

鸿蒙软件后缀格式(鸿蒙系统软件的后缀)



 鸿蒙NEXT开发实战往期必看文章:

一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!

“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)

HarmonyOS NEXT应用开发案例实践总结合(持续更新......)

HarmonyOS NEXT应用开发性能优化实践总结(持续更新......)


调用者可以调用本模块的Native API接口,完成视频编码,即将未压缩的视频数据压缩成视频码流。

当前支持的编码能力如下:

容器规格视频编码类型mp4HEVC(H.265)、 AVC(H.264)

目前仅支持硬件编码,基于MimeType创建编码器时,支持配置为H264 (OH_AVCODEC_MIMETYPE_VIDEO_AVC) 和 H265 (OH_AVCODEC_MIMETYPE_VIDEO_HEVC)。

每一种编码的能力范围,可以通过能力查询获取。

视频编码支持以下能力:

支持的能力使用简述分层编码
设置LTR帧、参考帧具体可参考:时域可分层视频编码
  1. Buffer模式不支持10bit的图像数据。
  2. 由于硬件编码器资源有限,每个编码器在使用完毕后都必须调用OH_VideoEncoder_Destroy接口来销毁实例并释放资源。
  3. 一旦调用Flush,Reset,Stop接口,会触发系统回收OH_AVBuffer,调用者不应对之前回调函数获取到的OH_AVBuffer继续进行操作。
  4. Buffer模式和Surface模式使用方式一致的接口,所以只提供了Surface模式的示例。
  5. 在Buffer模式下,调用者通过输入回调函数OH_AVCodecOnNeedInputBuffer获取到OH_AVBuffer的指针对象后,必须通过调用OH_VideoEncoder_PushInputBuffer接口 来通知系统该对象已被使用完毕。这样系统才能够将该对象里面的数据进行编码。如果调用者在调用OH_AVBuffer_GetNativeBuffer接口时获取到OH_NativeBuffer指针对象,并且该对象的生命周期超过了当前的OH_AVBuffer指针对象,那么需要进行一次数据的拷贝操作。在这种情况下,调用者需要自行管理新生成的OH_NativeBuffer对象的生命周期,确保其正确使用和释放。
  1. 两者的数据来源不同。
  2. 两者的适用场景不同:
  • surface输入是指用OHNativeWindow来传递输入数据,可以与其他模块对接,例如相机模块。
  • buffer输入是指有一块预先分配好的内存区域,调用者需要将原始数据拷贝进这块内存区域中。更适用于从文件中读取视频数据等场景。
  1. 在接口调用的过程中,两种方式的接口调用方式基本一致,但存在以下差异点:
  • Buffer模式下,调用者通过OH_VideoEncoder_PushInputBuffer接口输入数据;Surface模式下,调用者应在编码器就绪前调用OH_VideoEncoder_GetSurface接口,获取OHNativeWindow用于传递视频数据。
  • Buffer模式下,调用者通过OH_AVBuffer中的attr传入结束flag,编码器读取到尾帧后,停止编码;Surface模式下,需要调用OH_VideoEncoder_NotifyEndOfStream接口通知编码器输入流结束。

两种模式的开发步骤详细说明请参考:Surface模式和Buffer模式。

如下为状态机调用关系图:

  1. 有两种方式可以使编码器进入Initialized状态:
    • 初始创建编码器实例时,编码器处于Initialized状态。
    • 任何状态下调用OH_VideoEncoder_Reset接口,编码器将会移回Initialized状态。
  2. Initialized状态下,调用OH_VideoEncoder_Configure接口配置编码器,配置成功后编码器进入Configured状态。
  3. Configured状态下调用OH_VideoEncoder_Prepare()进入Prepared状态。
  4. Prepared状态调用OH_VideoEncoder_Start接口使编码器进入Executing状态:
    • 处于Executing状态时,调用OH_VideoEncoder_Stop接口可以使编码器返回到Prepared状态。
  5. 在极少数情况下,编码器可能会遇到错误并进入Error状态。编码器的错误传递,可以通过队列操作返回无效值或者抛出异常:
    • Error状态下可以调用OH_VideoEncoder_Reset接口将编码器移到Initialized状态;或者调用OH_VideoEncoder_Destroy接口移动到最后的Released状态。
  6. Executing 状态具有三个子状态:Flushed、Running和End-of-Stream:
    • 在调用了OH_VideoEncoder_Start接口之后,编码器立即进入Running子状态。
    • 对于处于Executing状态的编码器,可以调用OH_VideoEncoder_Flush接口返回到Flushed子状态。
    • 当待处理数据全部传递给编码器后,可以在input buffers队列中为最后一个入队的input buffer中添加AVCODEC_BUFFER_FLAGS_EOS标记,遇到这个标记时,编码器会转换为End-of-Stream子状态。在此状态下,编码器不再接受新的输入,但是仍然会继续生成输出,直到输出到达尾帧。
  7. 使用完编码器后,必须调用OH_VideoEncoder_Destroy接口销毁编码器实例。使编码器进入Released状态。

详细的API说明请参考API文档。 如下为视频编码调用关系图:

  • 虚线表示可选。
  • 实线表示必选。

在 CMake 脚本中链接动态库

 

说明:

上述’sample’字样仅为示例,此处由调用者根据实际工程目录自定义。

Surface模式

参考以下示例代码,调用者可以完成Surface模式下视频编码的全流程。此处以surface数据输入,编码成H.264格式为例。 本模块目前仅支持异步模式的数据轮转。

  1. 添加头文件。
     
  2. 全局变量。
     
  3. 创建编码器实例对象。

    调用者可以通过名称或媒体类型创建编码器。示例中的变量说明如下:

    • videoEnc:视频编码器实例的指针;
    • capability:编解码器能力查询实例的指针;
    • OH_AVCODEC_MIMETYPE_VIDEO_AVC:AVC格式视频编解码器。

    创建方式示例如下:

     
     
  4. 调用OH_VideoEncoder_RegisterCallback()设置回调函数。

    注册回调函数指针集合OH_AVCodecCallback,包括:

    • OH_AVCodecOnError 编码器运行错误,返回的错误码详情请参见OH_AVCodecOnError;
    • OH_AVCodecOnStreamChanged 码流信息变化,如格式变化等;
    • OH_AVCodecOnNeedInputBuffer 输入回调无作用,调用者通过获取的surface输入数据;
    • OH_AVCodecOnNewOutputBuffer 运行过程中产生了新的输出数据,即编码完成。

    示例如下所示:

     
     
     
     
     
      

    说明: 在回调函数中,对数据队列进行操作时,需要注意多线程同步的问题。

  5. (可选)调用OH_VideoEncoder_RegisterParameterCallback()在Configur接口之前注册随帧通路回调。

    详情请参考时域可分层视频编码。

     
  6. 调用OH_VideoEncoder_Configure()配置编码器。

    详细可配置选项的说明请参考视频专有键值对。

    参数校验规则请参考OH_VideoEncoder_Configure()参考文档。

    参数取值范围可以通过能力查询接口获取,具体示例请参考获取支持的编解码能力文档。

    目前支持的所有格式都必须配置以下选项:视频帧宽度、视频帧高度、视频像素格式。示例中的变量如下:

    • DEFAULT_WIDTH:320像素宽度;
    • DEFAULT_HEIGHT:240像素高度;
    • DEFAULT_PIXELFORMAT: 像素格式,因为示例使用YUV的文件保存的像素格式是NV12,所以设置为 AV_PIXEL_FORMAT_NV12。
     
      

    注意: 配置非必须参数错误时,会返回AV_ERR_INVAILD_VAL错误码。但OH_VideoEncoder_Configure()不会失败,而是使用默认值继续执行。

  7. 获取Surface。

    获取编码器Surface模式的OHNativeWindow输入,获取surface需要在准备编码器之前完成。

     

    OHNativeWindow*变量类型的使用方法请参考图形子系统 OHNativeWindow

  8. 调用OH_VideoEncoder_Prepare()编码器就绪。

    该接口将在编码器运行前进行一些数据的准备工作。

     
  9. 调用OH_VideoEncoder_Start()启动编码器。
     
  10. (可选)OH_VideoEncoder_SetParameter()在运行过程中动态配置编码器参数。 详细可配置选项的说明请参考视频专有键值对。
     
  11. 写入编码图像。 在之前的第7步中,开发者已经对OH_VideoEncoder_GetSurface接口返回的OHNativeWindow*类型变量进行配置。因为编码所需的数据,由配置的Surface进行持续地输入,所以开发者无需对OnNeedInputBuffer回调函数进行处理,也无需使用OH_VideoEncoder_PushInputBuffer接口输入数据。
  12. (可选)调用OH_VideoEncoder_PushInputParameter()通知编码器随帧参数配置输入完成。 在之前的第5步中,调用者已经注册随帧通路回调

    以下示例中:

    • index:回调函数OnNeedInputParameter传入的参数,与buffer唯一对应的标识。
     
  13. 调用OH_VideoEncoder_NotifyEndOfStream()通知编码器结束。
     
  14. 调用OH_VideoEncoder_FreeOutputBuffer()释放编码帧。

    以下示例中:

    • index:回调函数OnNewOutputBuffer传入的参数,与buffer唯一对应的标识。
    • buffer: 回调函数OnNewOutputBuffer传入的参数,Surface模式调用者无法通过OH_AVBuffer_GetAddr接口获取图像虚拟地址。
     
  15. (可选)调用OH_VideoEncoder_Flush()刷新编码器。

    调用OH_VideoEncoder_Flush接口后,编码器仍处于运行态,但会清除编码器中缓存的输入和输出数据及参数集如H264格式的PPS/SPS。

    此时需要调用OH_VideoEncoder_Start接口重新开始编码。

     
  16. (可选)调用OH_VideoEncoder_Reset()重置编码器。

    调用OH_VideoEncoder_Reset接口后,编码器将回到初始化的状态,需要调用OH_VideoEncoder_Configure接口和OH_VideoEncoder_Prepare接口重新配置。

     
  17. (可选)调用OH_VideoEncoder_Stop()停止编码器。

    调用OH_VideoEncoder_Stop接口后,编码器保留了编码实例,释放输入输出buffer。调用者可以直接调用OH_VideoEncoder_Start接口继续编码,

    输入的第一个buffer需要携带参数集,从IDR帧开始送入。

     
  18. 调用OH_VideoEncoder_Destroy()销毁编码器实例,释放资源。

    说明:

    不能在回调函数中调用; 执行该步骤之后,需要调用者将videoEnc指向NULL,防止野指针导致程序错误。

     

Buffer模式

参考以下示例代码,调用者可以完成Buffer模式下视频编码的全流程。此处以YUV文件输入,编码成H.264格式为例。 本模块目前仅支持异步模式的数据轮转。

  1. 添加头文件。
     
  2. 创建编码器实例对象。

    与Surface模式相同,此处不再赘述。

     
     
  3. 调用OH_VideoEncoder_RegisterCallback()设置回调函数。

    注册回调函数指针集合OH_AVCodecCallback,包括:

    • OH_AVCodecOnError 编码器运行错误,返回的错误码详情请参见OH_AVCodecOnError;
    • OH_AVCodecOnStreamChanged 码流信息变化,如格式变化等;
    • OH_AVCodecOnNeedInputBuffer 运行过程中需要新的输入数据,即编码器已准备好,可以输入YUV/RGB数据;
    • OH_AVCodecOnNewOutputBuffer 运行过程中产生了新的输出数据,即编码完成。

    调用者可以通过处理该回调报告的信息,确保编码器正常运转。

     
     
     
     
     
     
      

    说明:

    在回调函数中,对数据队列进行操作时,需要注意多线程同步的问题。

  4. 调用OH_VideoEncoder_Configure()配置编码器。

    与Surface模式相同,此处不再赘述。

     
  5. 调用OH_VideoEncoder_Prepare()编码器就绪。

    该接口将在编码器运行前进行一些数据的准备工作。

     
  6. 调用OH_VideoEncoder_Start()启动编码器,进入运行态。

    启动编码器后,回调函数将开始响应事件。所以,需要先配置输入文件、输出文件。

     
  7. (可选)在运行过程中动态配置编码器参数。
     
  8. 调用OH_VideoEncoder_PushInputBuffer()写入编码图像。

    送入输入队列进行编码,以下示例中:

    • buffer:回调函数OnNeedInputBuffer传入的参数,可以通过OH_AVBuffer_GetAddr接口得到共享内存地址的指针;
    • index:回调函数OnNeedInputBuffer传入的参数,与buffer唯一对应的标识;
    • flags:缓冲区标记的类别,请参考OH_AVCodecBufferFlags
    • stride: 获取到的buffer数据的跨距。
     

    对跨距进行偏移,以NV12图像为例,示例如下:

    以NV12图像为例,width、height、wStride、hStride图像排布参考下图:

    • OH_MD_KEY_VIDEO_PIC_WIDTH表示width;
    • OH_MD_KEY_VIDEO_PIC_HEIGHT表示height;
    • OH_MD_KEY_VIDEO_STRIDE表示wStride;
    • OH_MD_KEY_VIDEO_SLICE_HEIGHT表示hStride。

    添加头文件。

     

    使用示例:

     

    硬件编码在处理buffer数据时(推送数据前),需要调用者拷贝宽高对齐后的图像数据到输入回调的AVbuffer中。 一般需要获取数据的宽高、跨距、像素格式来保证编码输入数据被正确的处理。

    具体实现请参考:Buffer模式的步骤3-调用OH_VideoEncoder_RegisterCallback接口设置回调函数来获取数据的宽高、跨距、像素格式。

  9. 通知编码器结束。

    以下示例中:

    • index:回调函数OnNeedInputBuffer传入的参数,与buffer唯一对应的标识。
    • buffer:回调函数OnNeedInputBuffer传入的参数,可以通过OH_AVBuffer_GetAddr接口得到共享内存地址的指针;

    与“8. 写入编码图像”一样,使用同一个接口OH_VideoEncoder_PushInputBuffer,通知编码器输入结束,需要将flag标识成AVCODEC_BUFFER_FLAGS_EOS。

     
  10. 调用OH_VideoEncoder_FreeOutputBuffer()释放编码帧。 与Surface模式相同,此处不再赘述。
     

后续流程(包括刷新编码器、重置编码器、停止编码器、销毁编码器)与Surface模式一致,请参考Surface模式的步骤15-18。

 

到此这篇鸿蒙软件后缀格式(鸿蒙系统软件的后缀)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • mysql窗口函数执行顺序(mysql窗口函数从哪个版本开始有)2025-01-01 11:54:09
  • ifstream get函数(if(getchar()=='\\n'))2025-01-01 11:54:09
  • ip报文格式分析题(ipv4报文格式解析)2025-01-01 11:54:09
  • 安装信息是什么文件(安装信息是什么格式的)2025-01-01 11:54:09
  • 计算机零基础编程入门的书(计算机编程零基础教程)2025-01-01 11:54:09
  • 报文格式(报文格式错误怎么解决)2025-01-01 11:54:09
  • 生成范围内的随机数(生成范围内随机数的函数)2025-01-01 11:54:09
  • 读取pcap文件(pcap文件格式)2025-01-01 11:54:09
  • vbf文件格式(vb的格式)2025-01-01 11:54:09
  • 编程入门教学零基础(编程零基础入门视频)2025-01-01 11:54:09
  • 全屏图片