RTK_mmp_enc.c
20.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "JZsdkLib.h"
#include "./RTK_mmp_enc.h"
#ifdef RTK_MPP_STATUS_ON
T_JZsdkReturnCode RTK_mmp_enc_Init(T_rtk_mmp_enc_info *enc_info)
{
int ret;
enc_info->ctx = NULL;
enc_info->mpi = NULL;
//编解码一体的情况下用不上这里了
switch (enc_info->Input_fmt & MPP_FRAME_FMT_MASK)
{
case MPP_FMT_YUV420SP:
case MPP_FMT_YUV420P: {
enc_info->Frame_data_size = MPP_ALIGN(enc_info->hor_stride, 64) * MPP_ALIGN(enc_info->ver_stride, 64) * 3 / 2;
} break;
case MPP_FMT_YUV422_YUYV :
case MPP_FMT_YUV422_YVYU :
case MPP_FMT_YUV422_UYVY :
case MPP_FMT_YUV422_VYUY :
case MPP_FMT_YUV422P :
case MPP_FMT_YUV422SP :
case MPP_FMT_RGB444 :
case MPP_FMT_BGR444 :
case MPP_FMT_RGB555 :
case MPP_FMT_BGR555 :
case MPP_FMT_RGB565 :
case MPP_FMT_BGR565 : {
enc_info->Frame_data_size = MPP_ALIGN(enc_info->hor_stride, 64) * MPP_ALIGN(enc_info->ver_stride, 64) * 2;
} break;
default: {
enc_info->Frame_data_size = MPP_ALIGN(enc_info->hor_stride, 64) * MPP_ALIGN(enc_info->ver_stride, 64) * 4;
} break;
}
//获取h264头长度
if (MPP_FRAME_FMT_IS_FBC(enc_info->Input_fmt))
{
enc_info->header_size = MPP_ALIGN(MPP_ALIGN(enc_info->width, 16) * MPP_ALIGN(enc_info->height, 16) / 16, SZ_4K);
}
else
{
enc_info->header_size = 0;
}
/***************************************************
*
* 注册输入输出数组的内存
*
* *****************************************************/
// 获取MPP缓冲区组,缓冲区类型为ION且可缓存
ret = mpp_buffer_group_get_internal(&enc_info->BufferGop, MPP_BUFFER_TYPE_ION);
if (ret) {
printf("获取MPP缓冲区组失败failed to get mpp buffer group ret %d\n", ret);
}
// 从缓冲区组中获取用于输入帧的缓冲区
ret = mpp_buffer_get(enc_info->BufferGop, &enc_info->FrameBuffer, enc_info->Frame_data_size + enc_info->header_size);
if (ret) {
printf("获取输入帧缓冲区失败failed to get buffer for input frame ret %d\n", ret);
}
// 从缓冲区组中获取用于输出包的缓冲区
ret = mpp_buffer_get(enc_info->BufferGop, &enc_info->PacketBuffer, enc_info->Frame_data_size);
if (ret) {
printf("获取输出包缓冲区失败failed to get buffer for output packet ret %d\n", ret);
}
// // 从缓冲区组中获取用于运动信息输出包的缓冲区
// ret = mpp_buffer_get(enc_info->BufferGop, &p->md_info, p->mdinfo_size);
// if (ret) {
// printf("获取运动信息输出包缓冲区失败failed to get buffer for motion info output packet ret %d\n", ret);
// }
//创建一个编码器
ret = mpp_create(&(enc_info->ctx), &enc_info->mpi);
if (ret != MPP_OK)
{
JZSDK_LOG_ERROR("mpp_create failed ret %d", ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
else
{
printf("编码器创建完毕\n");
}
//设置编码超时(堵塞)
MppPollType timeout = MPP_POLL_BLOCK;
ret = enc_info->mpi->control(enc_info->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
if (ret != MPP_OK)
{
JZSDK_LOG_ERROR("编码超时设置失败 %d", ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
else
{
printf("编码超时设置成功\n");
}
//初始化编码器
ret = mpp_init(enc_info->ctx, MPP_CTX_ENC, MPP_VIDEO_CodingAVC);
if (ret != MPP_OK)
{
JZSDK_LOG_ERROR("mpp_init failed ret %d", ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
else
{
printf("编码器初始化完毕\n");
}
//初始化编码器配置
ret = mpp_enc_cfg_init(&enc_info->cfg);
if (ret) {
JZSDK_LOG_ERROR("mpp_enc_cfg_init failed ret %d", ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
else
{
printf("编码器配置初始化完毕\n");
}
//获得基本编码器配置
ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_GET_CFG, enc_info->cfg);
if (ret) {
JZSDK_LOG_ERROR("get enc cfg failed ret %d", ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
/***********************************************************************************************************************
*
*
* 设置编码器参数
*
*
************************************************************************************************************************/
//设置位固定码率模式
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:mode", MPP_ENC_RC_MODE_CBR);
//设置码率 dji要小于8M 先填个4M 4000000
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:bps_target", 4000000);
//设置输入帧率不变
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:fps_in_flex", 0);
//设置输入帧率的分子
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:fps_in_num", enc_info->FrameNum);
//设置输入帧率的分母
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:fps_in_denorm", 1);
//设置输出帧率的分子
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:fps_out_num", enc_info->FrameNum);
//设置输出帧率的分母
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:fps_out_denorm", 1);
//设置i帧间隔,跟随帧率 1秒1 I帧
mpp_enc_cfg_set_s32(enc_info->cfg, "rc:gop", enc_info->IDR_gop);
//一帧图像最大重编码次数,次数越小,重编码次数越小,越清晰
//这里暂不开启
//mpp_enc_cfg_set_s32(enc_info->cfg, "rc:max_reenc_times", 1);
//设置输入图像的宽高
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:width", enc_info->width);
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:height", enc_info->height);
//垂直方向相邻两行之间的距离
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:hor_stride", enc_info->hor_stride);
//入图像分量之间的以行数间隔数
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:ver_stride", enc_info->ver_stride);
//MppFrameFormat 设置输入图像的像素格式
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:format", enc_info->Input_fmt);
//MppFrameColorSpace 设置输入图像的数据空间色彩范围, 不设置
//mpp_enc_cfg_set_s32(enc_info->cfg, "prep:color", MPP_FRAME_SPC_RGB);
//MppFrameColorRange 表示输入图像是 full range 还是 limit range 不设置
//mpp_enc_cfg_set_s32(enc_info->cfg, "prep:range", MPP_FRAME_RANGE_UNSPECIFIED);
//MppEncRotationCfg 选择旋转方向 不旋转!
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:rotation", MPP_ENC_ROT_0);
//是否镜像 0不镜像 水平镜像1 垂直镜像2
mpp_enc_cfg_set_s32(enc_info->cfg, "prep:mirroring", 0);
//MppCodingType 表示 MppEncCodecCfg 对应的协议类型,需要与 MppCtx初始化函数 mpp_init 的参数一致。
mpp_enc_cfg_set_s32(enc_info->cfg, "codec:type", MPP_VIDEO_CodingAVC); //h264类型
//h264流的码流格式类型 0 标识AnnexB 加入 00 00 00 01起始码 1 没有起始码
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:stream_type", 0);
//h264流的表示 SPS 中的 profile_idc 参数:
//66 – 表示 Baseline profile。
//77 – 表示 Main profile。
//100 – 表示 High profile。
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:profile", 66);
//sps档次 dji要求小于5.1 这里选4.1
//其中 10 表示 level 1.0:
// 10/11/12/13 – qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
// 20/21/22 – cif@30fps / half-D1@25fps / D1@12.5fps
// 30/31/32 – D1@25fps / 720p@30fps / 720p@60fps
// 40/41/42 – 1080p@30fps / 1080p@30fps / 1080p@60fps
// 50/51/52 – 4K@30fps / 4K@30fps / 4K@60fps
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:level", 41);
//表示编码器使用的熵编码格式: 0 CAVLC 1 CABAC cabac的精度更多,但是效率变低
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:cabac_en", 1);
//表示协议语法中的 cabac_init_idc,在 cabac_en 为 1 时有效,有效值为 0~2。
//DJI给的范围是1
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:cabac_idc", 1);
//表示协议语法中的 8x8 变换使能标志。
//0 – 为关闭,在 Baseline/Main profile 时固定关闭。
//1 – 为开启,在 High profile 时可选可启。
mpp_enc_cfg_set_s32(enc_info->cfg, "h264:trans8x8", 0);
//表示协议语法中 constrained_intra_pred_mode 模式使能标志。0 – 为关闭,1 – 为开启。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:const_intra", 0);
//表示协议语法中 scaling_list_matrix 模式 0 – 为 flat matrix,1 – 默认 matrix。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:scaling_list", 0);
//表示协议语法中 chroma_cb_qp_offset 值。有效范围为[-12, 12]。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:cb_qp_offset", 0);
//表示协议语法中 chroma_cr_qp_offset 值。有效范围为[-12, 12]。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:cr_qp_offset", 0);
//表示协议语法中 deblock_disable 标志,有效范围为[0, 2]。0 – deblocking 使能。1 – deblocking 关闭。2 – 在 slice 边界关闭 deblocking。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:dblk_disable", 0);
//表示协议语法中 deblock_offset_alpha 值。有效范围为[-6, 6]。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:dblk_alpha", 0);
//表示协议语法中 deblock_dblk_beta 值。有效范围为[-6, 6]。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:dblk_beta", 0)
//表示初始 QP 值,一般情况请勿配置。
//mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_init", 26);
// 表示最大 QP 值,一般情况请勿配置。
// mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_max", 51);
// 表示最小 QP 值,一般情况请勿配置。
// mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_min", 10);
// 表示最大 I 帧 QP 值,一般情况请勿配置。
// mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_max_i", 51);
// 表示最小 I 帧 QP 值,一般情况请勿配置。
// mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_min_i", 10);
// 表示相临两帧之间的帧级 QP 变化幅度。
// mpp_enc_cfg_set_s32(enc_info->cfg, "h264:qp_step", 10);
/***** h265 的自己翻阅文档********/
//表示 JPEG 编码器使用的量化参数等级,编码器一共内置了 11 级量化系数表格,从 0 到 10,图像质量从差到好。
//mpp_enc_cfg_set_s32(enc_info->cfg, "jpeg: quant", 10);
//MppEncSplitMode 切分模式
//1– BY_BYTE 切分 slice 根据 slice 大小。 2– BY_CTU 切分 slice 根据宏块或 CTU 个数
//mpp_enc_cfg_set_s32(enc_info->cfg, "split:mode", MPP_ENC_SPLIT_NONE);
//切分参数 Slice 切分参数:
//在 BY_BYTE 模式下,参数表示每个 slice 的最大大小。
//在 BY_CTU 模式下,参数表示每个 slice 包含的宏块或CTU 个数。
//mpp_enc_cfg_set_s32(enc_info->cfg, "split:arg", 1);
//将配置参数输入
ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_SET_CFG, enc_info->cfg);
if (ret)
{
printf("mpi control enc set cfg failed ret %d\n", ret);
return ret;
}
//设置帧信息 (可选项)
RK_U32 sei_mode;
mpp_env_get_u32("sei_mode", &sei_mode, MPP_ENC_SEI_MODE_ONE_FRAME);
enc_info->sei_mode = sei_mode;
ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_SET_SEI_CFG, &enc_info->sei_mode);
if (ret)
{
printf("mpi control enc set sei cfg failed ret %d\n", ret);
return ret;
}
//设置头信息 (可选项)
//如果是264 或者h265 给个信息头
if (enc_info->encType == MPP_VIDEO_CodingAVC || enc_info->encType == MPP_VIDEO_CodingHEVC)
{
enc_info->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_SET_HEADER_MODE, &enc_info->header_mode);
if (ret) {
printf("mpi control enc set header mode failed ret %d\n", ret);
return ret;
}
}
/* env测试内容 用于配置OSD(On-Screen Display)和ROI(Region of Interest)的功能。
OSD(On-Screen Display)是一种在计算机显示器上直接显示特定信息的功能。
它通常用于提供更直观和方便的用户体验,使用户能够通过屏幕上的菜单或操作界面来调整和管理显示器的参数设置。
OSD功能允许用户快速调整如屏幕颜色、亮度、对比度、锐度等参数,
也可以显示解析度、输入源、音量大小等信息。OSD界面使得用户无需使用单独的硬件设备或计算机软件就能直接进行配置,
特别适合在需要快速调整显示器参数的情况下使用。
ROI(Region of Interest)即感兴趣区域,主要应用在机器视觉、图像处理等领域。
在这个上下文中,ROI通常指的是从被处理的图像中以方框、圆、椭圆、不规则多边形等方式勾勒出的需要特别关注的区域。
在图像处理软件或机器视觉算法中,ROI的设置可以帮助算法更准确地识别和处理特定区域,从而提高处理的效率和准确性。
例如,在图像裁剪、目标跟踪、特征提取等任务中,ROI都扮演着重要的角色。
*/
// mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
// mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
// mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
// mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0);
// if (p->roi_enable) {
// mpp_enc_roi_init(&p->roi_ctx, p->width, p->height, p->type, 4);
// mpp_assert(p->roi_ctx);
// }
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
// /*************************
// *
// * h264的关键帧应该带上头信息,避免无法正常识别播放数据
// *
// * *******************/
// int RTK_mmp_enc_H264_HeadinfoInit(MPP_ENC_CONFIG *EncCfg)
// {
// int ret; //返回值
// //spi信息相关,要改成每一个关键帧都带上,避免无法解析
// //这里利用packter将sync头信息拿出来,并复制到h264_data中
// if (sps_head != NULL)
// {
// free(sps_head);
// sps_head = NULL;
// }
// MppPacket m_packet = NULL;
// // 检查编码类型是否为AVC(H.264)或HEVC(H.265)
// if (enc_info->type == MPP_VIDEO_CodingAVC || enc_info->type == MPP_VIDEO_CodingHEVC)
// {
// /*
// * 可以使用普通malloc分配的内存缓冲区作为输入,而不是pkt_buf。
// * 请参考vpu_api_legacy.cpp以了解普通缓冲区的情况。
// * 这里使用pkt_buf缓冲区只是为了简化演示。
// */
// // 使用pkt_buf缓冲区初始化packet
// mpp_packet_init_with_buffer(&m_packet, enc_info->Packet_data);
// /* NOTE: It is important to clear output packet length!! */
// /*
// * 注意:清除输出数据包长度非常重要!
// * 这样可以确保我们不会错误地读取旧的数据或未初始化的数据。
// */
// mpp_packet_set_length(m_packet, 0);
// // 调用mpi的control函数,获取编码的头部信息(如SPS和PPS),并将其存储在packet中
// ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_GET_HDR_SYNC, m_packet);
// if (ret) {
// printf("获取h264 enc头信息失败\n");
// return ret;
// }
// else
// {
// /* get and write sps/pps for H.264 */
// // 如果控制函数调用成功
// // 获取存储在packet中的数据指针和长度
// void *ptr = mpp_packet_get_pos(m_packet);
// sps_head_len = mpp_packet_get_length(m_packet);
// sps_head = (unsigned char *)malloc(sps_head_len * sizeof(unsigned char));
// //给数据写上信息头
// memcpy(sps_head, ptr, sps_head_len);
// }
// //重新将变量packet,设为NULL,用于清空Packet
// mpp_packet_deinit(&m_packet);
// }
// }
// yuv420sp转h264
// 但是输入和输出都是mmpframe的地址
// 注意,输出的画面帧要记得释放内存
T_JZsdkReturnCode RTK_mmp_enc_yuv_to_h264_byFrame(T_rtk_mmp_enc_info *enc_info, MppFrame input_data_frame, MppPacket *out_put_frame)
{
int ret; //返回值
//获取输入的数据
MppFrame frame = input_data_frame;
//printf("mmp开始编码\n");
/* 将帧编码并放入编码上下文 */
ret = enc_info->mpi->encode_put_frame(enc_info->ctx, frame);
if (ret) {
JZSDK_LOG_ERROR("mpp encode put frame failed");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
do {
//获取编码后的帧
ret = enc_info->mpi->encode_get_packet(enc_info->ctx, out_put_frame);
if (ret) {
JZSDK_LOG_ERROR("mpp encode get packet failed");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
if (*out_put_frame)
{
// write packet to file here
//ptr = mpp_packet_get_pos(packet);
//int packet_len = mpp_packet_get_length(enc_info->Packet_data);
//EncConfigInput->Packet_eos = mpp_packet_get_eos(packet);
//printf("获取到编码内容 len:%d\n",packet_len);
break; //跳出获取循环
}
} while (1);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
// yuv420个帧长度为 高*宽*3/2
T_JZsdkReturnCode RTK_mmp_enc_data_to_h264(T_rtk_mmp_enc_info *enc_info, char *in_data, int in_data_length, MppPacket *Packet)
{
int ret; //返回值
MppFrame frame = NULL;
MppMeta meta = NULL; //元数据指针
//初始化帧对象
ret = mpp_frame_init(&frame);
if (ret) {
JZSDK_LOG_ERROR("mpp_frame_init MMP frame 初始化错误");
return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER;
}
//设置帧对象的参数
// 设置处理帧的宽度、高度、水平跨度、垂直跨度和格式
mpp_frame_set_width(frame, enc_info->width);
mpp_frame_set_height(frame, enc_info->height);
mpp_frame_set_hor_stride(frame, enc_info->hor_stride);
mpp_frame_set_ver_stride(frame, enc_info->ver_stride);
mpp_frame_set_fmt(frame, enc_info->Input_fmt);
mpp_frame_set_eos(frame, enc_info->Frame_eos); // 设置帧的结束标志
//获取帧缓冲区的指针
void *buf = mpp_buffer_get_ptr(enc_info->FrameBuffer);
//将yuv数据写入缓冲区
memcpy(buf, in_data, in_data_length);
// 使用默认的帧缓冲区
mpp_frame_set_buffer(frame, enc_info->FrameBuffer);
// 获取帧的元数据对象
meta = mpp_frame_get_meta(frame);
// 初始化包对象,并使用指定的输出缓冲区
mpp_packet_init_with_buffer(Packet, enc_info->PacketBuffer);
// 注意:清除输出包的长度
// 设置包的长度为0
mpp_packet_set_length(*Packet, 0);
mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, *Packet); // 将包与元数据关联
/*
* 注意:在非阻塞模式下,帧可能会被重新发送。
* 默认的输入超时模式是阻塞模式。
*
* 用户应该释放输入帧,以满足资源创建者必须是资源销毁者的要求。
*/
/* 将frame数据放入编码器 */
ret = enc_info->mpi->encode_put_frame(enc_info->ctx, frame);
if (ret) {
JZSDK_LOG_ERROR("mpp encode put frame failed");
mpp_frame_deinit(&frame);
mpp_packet_deinit(Packet);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
/* 清理和释放帧资源 */
mpp_frame_deinit(&frame);
void *ptr = NULL; //获取packet数据用的指针
unsigned int packet_len; //获取到的packetlen长度
do {
//获取解码后的帧
ret = enc_info->mpi->encode_get_packet(enc_info->ctx, Packet);
if (ret) {
JZSDK_LOG_ERROR("mpp encode get packet failed");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
if (*Packet)
{
break; //跳出获取循环
}
} while (1);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/*************
*
*
* 设置下一帧为I帧
*
* *******************/
T_JZsdkReturnCode RTK_mmp_enc_SetNextFrame_IDR(T_rtk_mmp_enc_info *enc_info)
{
//将配置参数输入
int ret = enc_info->mpi->control(enc_info->ctx, MPP_ENC_SET_IDR_FRAME, enc_info->cfg);
if (ret)
{
printf("设置I帧失败%d\n", ret);
return ret;
}
}
#endif