h264转成 JPEG 海思
该代码只是编解码部分的代码。前台代码 需要 绑定 VDEC->VPSS->VENC参考 sample_comm.h接口 及 sample_comm_vdec.c正常的流程就是 sendstream (h264) 到VDEC 解码后给VPSS然后VPSS将数据 给 VENC 进行编码, 最后从 VENC的通道 取的数据流就是对应的编码成JEPG的数据了,保存即可。HISI_VENC_Sa
·
该代码只是编解码部分的代码。
前台代码 需要 绑定 VDEC->VPSS->VENC 参考 sample_comm.h接口 及 sample_comm_vdec.c
正常的流程就是 sendstream (h264) 到VDEC 解码后给VPSS然后VPSS将数据 给 VENC 进行编码, 最后从 VENC的通道 取的数据流就是对应的编码成JEPG的数据了,保存即可。
HISI_VENC_SaveSnap(.....)
{
for (i = 0; i < pstStream->u32PackCount; i++)
{
pstData = &pstStream->pstPack[i];
if (push_data->pic_len + pstData->u32Len - pstData->u32Offset < sizeof(push_data->pic_buf)) {
memcpy(push_data->pic_buf + push_data->pic_len, pstData->pu8Addr + pstData->u32Offset, pstData->u32Len - pstData->u32Offset);
push_data->pic_len += pstData->u32Len - pstData->u32Offset;
}
}
}
HI_VOID * HISI_VDEC_SendStreamThread(HI_VOID *pArgs)
{
char *stream_id = (char*)pArgs;
stream_task_t *task_item = NULL;
GList *list_item = NULL;
HI_S32 s32ChnId = 0;
HI_S32 s32MilliSec = 10;
HI_S32 s32IntervalTime = 500000;
HI_S32 retryMaxCount = 5;
HI_S32 retryCount = 0;
HI_BOOL bEndOfStream = HI_FALSE;
HI_U8 *pu8Buf = NULL;
HI_S32 s32ReadLen = 0;
VDEC_STREAM_S stStream;
HI_S32 s32Ret = HI_SUCCESS;
logger("[INFO] hisi vdec send stream thread running");
while (g_run_flag)
{
g_rw_lock_reader_lock(&stream_task_list_rwlock);
list_item = (GList*)g_datalist_get_data(&stream_task_hashlist, stream_id);
if (list_item == NULL) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
break;
}
task_item = (stream_task_t *)list_item->data;
if (task_item->convert_channel < 0) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
break;
}
if (task_item->status.status != STREAM_CONNECT) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME * 1000);
continue;
}
//非持续拉流,无需转换图片
if (task_item->status.total_success > 0 && !task_item->info.continued) {
task_item->status.status = STREAM_STOP;
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME * 1000);
continue;
}
if (retryCount >= retryMaxCount) {
//解码异常,关闭流
task_item->status.status = STREAM_CLOSE;
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME * 1000);
continue;
}
s32ChnId = (HI_S32)task_item->convert_channel;
g_mutex_lock(&task_item->frame_queue_mutex);
if (g_queue_is_empty(task_item->frame_queue)) { //队列空则等待
g_mutex_unlock(&task_item->frame_queue_mutex);
usleep(WAIT_TIME * 1000);
continue;
}
//从队列取帧数据
frame_data_t *frame = (frame_data_t*)g_queue_pop_head(task_item->frame_queue);
g_mutex_unlock(&task_item->frame_queue_mutex);
if (NULL == frame) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
continue;
}
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
retryCount = 0;
pu8Buf = (HI_U8 *)frame->buf;
s32ReadLen = (HI_S32)frame->len;
memset(&stStream, 0, sizeof(VDEC_STREAM_S));
if (conf_info->test)
logger("[DEBUG] vdec get frame, stream_id: %s, channel: %d, len: %d", stream_id, s32ChnId, s32ReadLen);
//解码264视频
stStream.u64PTS = 0;
stStream.pu8Addr = pu8Buf;
stStream.u32Len = s32ReadLen;
stStream.bEndOfFrame = HI_TRUE;
stStream.bEndOfStream = bEndOfStream;
stStream.bDisplay = 1; //必须设置为1,否则不能生成图片
SendAgain:
s32Ret = HI_MPI_VDEC_SendStream(s32ChnId, &stStream, s32MilliSec);
if (HI_SUCCESS != s32Ret)
{
HISI_PRT("[ERROR] VDEC SendStream failed, chn %d, ret: %x\n", s32ChnId, s32Ret);
usleep(s32IntervalTime);
if (retryCount < retryMaxCount)
{
retryCount++;
goto SendAgain;
}
}
free(frame);
usleep(WAIT_TIME / 2 * 1000);
}
logger("[INFO] hisi vdec send stream thread exit, id: %s \n", stream_id);
g_free(stream_id);
return (HI_VOID *)HI_SUCCESS;
}
HI_VOID* HISI_VENC_SnapPictureThread(HI_VOID* pArgs)
{
char *stream_id = (char*)pArgs;
GList *list_item = NULL;
stream_task_t *task_item = NULL;
VENC_CHN VencChn = 0;
HI_U32 SnapCnt = 1; //一次生成1个图片
HI_S32 s32VencFd = 0;
VENC_CHN_STATUS_S stStat;
VENC_STREAM_S stStream;
HI_S32 s32Ret = HI_SUCCESS;
HI_U32 i = 0;
logger("[INFO] hisi venc snap picture thread running");
while (g_run_flag)
{
g_rw_lock_reader_lock(&stream_task_list_rwlock);
list_item = (GList*)g_datalist_get_data(&stream_task_hashlist, stream_id);
if (list_item == NULL) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
break;
}
task_item = (stream_task_t *)list_item->data;
if (task_item->convert_channel < 0) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
break;
}
if (task_item->status.status != STREAM_CONNECT) {
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME * 1000);
continue;
}
VencChn = (VENC_CHN)task_item->convert_channel;
//非持续拉流,无需转换图片
if (task_item->status.total_success > 0 && !task_item->info.continued) {
task_item->status.status = STREAM_STOP;
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
//停止接收数据
HI_MPI_VENC_StopRecvFrame(VencChn);
usleep(WAIT_TIME * 1000);
continue;
}
if (conf_info->test)
logger("[DEBUG] venc snap picture, stream_id: %s, channel: %d", stream_id, VencChn);
//开始获取编码数据
s32VencFd = HI_MPI_VENC_GetFd(VencChn);
if (s32VencFd < 0)
{
HISI_PRT("HI_MPI_VENC_GetFd faild with%#x!\n", s32VencFd);
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME * 1000);
continue;
}
for (i = 0; i < SnapCnt; i++)
{
memset(&stStat, 0, sizeof(stStat));
s32Ret = HI_MPI_VENC_QueryStatus(VencChn, &stStat);
if (s32Ret != HI_SUCCESS)
{
HISI_PRT("HI_MPI_VENC_QueryStatus failed with %#x!\n", s32Ret);
usleep(WAIT_TIME * 1000);
continue;
}
if (0 == stStat.u32CurPacks)
{
HISI_PRT("[WARN] venc snap current frame is NULL! stream_id: %s, channel: %d, fd: %d", stream_id, VencChn, s32VencFd);
usleep(WAIT_TIME*3 * 1000);
continue;
}
memset(&stStream, 0, sizeof(stStream));
stStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
if (NULL == stStream.pstPack)
{
HISI_PRT("malloc memory failed!\n");
usleep(WAIT_TIME * 1000);
continue;
}
stStream.u32PackCount = stStat.u32CurPacks;
s32Ret = HI_MPI_VENC_GetStream(VencChn, &stStream, -1);
if (HI_SUCCESS != s32Ret)
{
HISI_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
usleep(WAIT_TIME * 1000);
continue;
}
//根据间隔,生成图片
long long cur_time = get_mtime();
if (cur_time - task_item->status.last_run >= (long long)task_item->info.frequency) {
task_item->status.last_run = cur_time;
task_item->status.last_success = time(NULL);
task_item->status.total_success++;
s32Ret = HISI_VENC_SaveSnap(task_item, &stStream);
if (HI_SUCCESS != s32Ret)
{
HISI_PRT("HISI_VENC_SaveSnap failed with %#x!\n", s32Ret);
}
}
s32Ret = HI_MPI_VENC_ReleaseStream(VencChn, &stStream);
if (s32Ret)
{
HISI_PRT("HI_MPI_VENC_ReleaseStream failed with %#x!\n", s32Ret);
free(stStream.pstPack);
stStream.pstPack = NULL;
usleep(WAIT_TIME * 1000);
continue;
}
free(stStream.pstPack);
stStream.pstPack = NULL;
}
g_rw_lock_reader_unlock(&stream_task_list_rwlock);
usleep(WAIT_TIME / 2 * 1000);
}
logger("[INFO] hisi venc snap picture thread exit, id: %s \n", stream_id);
g_free(stream_id);
return (HI_VOID *)HI_SUCCESS;
}
更多推荐
已为社区贡献1条内容
所有评论(0)