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 + -
显示快捷键?