av_enc.c
来自「sample on embedded linux」· C语言 代码 · 共 312 行
C
312 行
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "hi_common_api.h"#include "video_comm.h"#include "audio_comm.h"/* Save audio and video stream togehter or alone *///#define SAVE_AVSTREAM_ALONE 1/* Set the video format */HI_U16 mode = D1;HI_U16 normal = PAL;VENC_FORMAT_E format = VENC_FORMAT_H264;/* Main function */HI_S32 main(int argc, char *args[]){ AVENC_STREAM_S struStream; VENC_INIT_S struVEncInit; AENC_STREAM_S *pAStream = NULL; VENC_STREAM_S *pVStream = NULL; AVENC_LIST_S *pNode = NULL; FILE *pFile = NULL; FILE *pAudioFile = NULL; AENC_CHN AencChn; VENC_CHN VencChn; AVENC_CHN AVEncChn; HI_S32 s32Ret; HI_U32 i, j, writelen; HI_S32 viChn; AUDIO_CODEC_FORMAT_E enFormat; VENC_CONFIG_H264_S venc_config; pFile = fopen("file_avenc.dat", "wb"); ASSERT_RETURN((NULL != pFile), HI_FAILURE); pAudioFile = fopen("file_audio.dat", "wb"); ASSERT_RETURN((NULL != pAudioFile), HI_FAILURE); /* Config the Video AD */ s32Ret = ADconfig(mode, normal); if (HI_SUCCESS != s32Ret) { printf ("ADconfig failed\n"); HI_VENC_Close(); return s32Ret; } /* Config the VI device. Should consistent with AD config. */ s32Ret = ViPubConfig(mode, normal, format); if (HI_SUCCESS != s32Ret) { printf ("vi public atr config failed\n"); HI_VENC_Close(); return s32Ret; } /* Config VI channel */ s32Ret = ViChnConfig(mode, normal, viChn); if (HI_SUCCESS != s32Ret) { printf ("vi chn atr config failed\n"); HI_VENC_Close(); return s32Ret; } /* 1. Open the audio encoder */ s32Ret = HI_AENC_Open(); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); /* 2. Create the audio encoder channel */ #if 0 /* HI_AENC_CreateCH function will use the default attribute to create ** this channel. But now, I am willing to to use HI_AENC_CreateCHEx. */ /* Set the sample rate of audio AD and SIO as 8K.*/ SetADSampleRate(SET_8K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_8); s32Ret = HI_AENC_CreateCH(0, AUDIO_CODEC_FORMAT_G726, HI_TRUE, &AencChn); #endif #if 1 { #if 0 /* If you want to create G711A/G711u/ADPCM/G726 encoder, ** the following code will be used */ AENC_VOICE_INIT_S initAttr; initAttr.bFlag = HI_TRUE; initAttr.enPackage = VOICE_PACAKGE_10MS; initAttr.u32BufDepth = 500; /* Set the sample rate of audio AD and SIO as 8K.*/ SetADSampleRate(SET_8K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_8); enFormat = AUDIO_CODEC_FORMAT_G711A; #endif #if 0 /* If you want to create AAC encoder,the following code will be used */ AENC_AAC_INIT_S initAttr; initAttr.bFlag = HI_TRUE; initAttr.u32BufDepth = 100; initAttr.aacCfg.enQuality = AAC_QUALITY_HIGH; initAttr.aacCfg.enSmpRate = AUDIO_SAMPLE_RATE_48; initAttr.aacCfg.s32BitRate = 128000; initAttr.aacCfg.s32BandWidth = AAC_MAX_BANDWIDTH; /* The follow three parament must be setted as this */ initAttr.aacCfg.enBitWidth = AUDIO_BIT_WIDTH_16; initAttr.aacCfg.s16ChannelsIn = AAC_CHANNEL_SUPPORT; initAttr.aacCfg.s16ChannelsOut = AAC_CHANNEL_SUPPORT; /* Set the sample rate of audio AD and SIO as 48K.*/ SetADSampleRate(SET_48K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_48); enFormat = AUDIO_CODEC_FORMAT_AAC; #endif #if 1 /* Now, I am willing to create the AMR encoder. */ AENC_AMR_INIT_S initAttr; initAttr.bFlag = HI_TRUE; initAttr.u32BufDepth = 200; initAttr.enAmrMode = AMR_MODE_MR122; initAttr.enFormat = AMR_PACKAGE_MMS; /* Set the sample rate of audio AD and SIO as 8K.*/ SetADSampleRate(SET_8K_SAMPLERATE); SetAiSampleRate(0, AUDIO_SAMPLE_RATE_8); enFormat = AUDIO_CODEC_FORMAT_AMR; #endif s32Ret = HI_AENC_CreateCHEx(0, enFormat, &initAttr, &AencChn); } #endif ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); /* 4. Create VENC channel */ HI_VENC_SetStreamMode(VENC_STREAM_FRAME); s32Ret = HI_VENC_CreateCH(viChn, &VencChn); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); /* 5. Create AVENC channel */ s32Ret = HI_AVENC_CreatCH(VencChn, AencChn, &AVEncChn); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); /* 6. Start AVENC channel */ s32Ret = HI_AVENC_StartCH(AVEncChn, AVENC_OPERATION_BOTH, 0); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); printf("Wait for a while please! Saveing file... \n"); /* Process the AV stream */ for(j=0; j<1000; j++) { printf("\b\b\b\b\b\b%06d", j); fflush(stdout); /* 7. Get the AV stream */ s32Ret = HI_AVENC_GetStream(AVEncChn, &struStream, HI_TRUE); if(HI_SUCCESS != s32Ret) { printf("Error Code 0x%08x\n", s32Ret); continue; } /* Save the audio stream first */ pNode = struStream.pAudioListHead; while(NULL != pNode) { pAStream = (AENC_STREAM_S *)(pNode->pData); #ifndef SAVE_AVSTREAM_ALONE /* Save the stream lenght at the first four bytes */ writelen = fwrite(&(pAStream->u32Len), sizeof(HI_U32), 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); /* Save the stream time stamp following */ writelen = fwrite(&(pAStream->u64TimeStamp), sizeof(HI_U64), 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); /* Save the stream data */ writelen = fwrite(pAStream->ps16Addr, pAStream->u32Len, 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); #else /* Save the naked audio stream */ writelen = fwrite(pAStream->ps16Addr, pAStream->u32Len, 1, pAudioFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); #endif /* There may be more than one audio stream frame. Search the list. */ pNode = pNode->pNext; } /* Save the video stream */ pNode = struStream.pVideoListHead; while(NULL != pNode) { pVStream = (VENC_STREAM_S *)(pNode->pData); #ifndef SAVE_AVSTREAM_ALONE /* Save the stream lenght */ writelen = fwrite(&(pVStream->u32DataLen), sizeof(HI_U32), 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); /* Save the time stamp of this video stream */ writelen = fwrite(&(pVStream->struDataInfo.u64PTS), sizeof(HI_U64), 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); #endif /* One video frame may comprise more than one slice. */ for ( i = 0 ; i < pVStream->u32DataNum ; i++ ) { writelen = fwrite(pVStream->struData[i].pAddr, pVStream->struData[i].u32Len, 1, pFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); } /* Although there only has one video frame, but it's a good habit ** to search the list whole. */ pNode = pNode->pNext; } /* 9. The AV stream is processed over, then release it. */ s32Ret = HI_AVENC_ReleaseStream(AVEncChn, &struStream); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); } /* 10. Stop video channel */ s32Ret = HI_AVENC_StopCH(AVEncChn, AVENC_OPERATION_VIDEO); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); printf("\nSave audio stream......\n"); /* Video channel has been stoped, process the audio only */ for(j=0; j<1000; j++) { printf("\b\b\b\b\b\b%06d", j); fflush(stdout); /* 11. Get the AV stream. Only audio stream is available */ s32Ret = HI_AVENC_GetStream(AVEncChn, &struStream, HI_TRUE); if(HI_SUCCESS != s32Ret) { continue; } /* 12. Save the audio stream */ pNode = struStream.pAudioListHead; while(NULL != pNode) { pAStream = (AENC_STREAM_S *)(pNode->pData); #ifndef SAVE_AVSTREAM_ALONE /* Save the stream lenght at the first four bytes */ writelen = fwrite(&(pAStream->u32Len), sizeof(HI_U32), 1, pAudioFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); /* Save the stream time stamp following */ writelen = fwrite(&(pAStream->u64TimeStamp), sizeof(HI_U64), 1, pAudioFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); #endif /* Save the stream data */ writelen = fwrite(pAStream->ps16Addr, pAStream->u32Len, 1, pAudioFile); ASSERT_RETURN((1 == writelen), HI_FAILURE); /* There may be more than one audio stream frame. Search the list. */ pNode = pNode->pNext; } /* 13. The AV stream is processed over, then release it */ s32Ret = HI_AVENC_ReleaseStream(AVEncChn, &struStream); ASSERT_RETURN((HI_SUCCESS == s32Ret), s32Ret); } /* 14: Stop the AV stream */ HI_AVENC_StopCH(AVEncChn, AVENC_OPERATION_BOTH); /* 15. Destroy the AV channel */ s32Ret = HI_AVENC_DestroyCH(AVEncChn, HI_FALSE); if(HI_ERR_AVENC_BUFFER_NOTFREE == s32Ret) { printf("Some AVENC buffer may be hold by user! Be sure to release all"\ "buffer! Otherwise some exception may arose!\n"); /* You can destroy the AV channel by force, if you are sure it's safe. */ HI_AVENC_DestroyCH(AVEncChn, HI_TRUE); } /* 16. Destroy the audio encoder channel */ HI_AENC_DestroyCH(AencChn, HI_FALSE); /* 17. Destroy the video encoder channel */ HI_VENC_DestroyCH(VencChn, HI_FALSE); /* 18. Close the audio encoder */ HI_AENC_Close(); /* 19. Close the video encoder */ HI_VENC_Close(); return HI_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?