Benz

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz  发布于  2016-11-09 20:43:35
采纳率 0%
29个问答
11713

3518E录制视频,音视频不同步

 
本帖最后由 Benz 于 2016-11-9 21:16 编辑

请教各位大神,为什么我用3518E录制mp4,音频会慢慢的快于视频啊?播放的开始时间和结束时间都是一致的,搞不明白啊?我是将venc和audio两个例子融合在一起,在一个线程里面调用音频和视频的getstrame的,分别保存了pcm和h264文件,两个同时播放,发现和转码后封mp4差不多,都是音频会慢慢的快于视频。拜托给位帮忙给点思路 !谢谢大家-----这是我的代码,音频用libfacc转码,最后用mp4v2封装mp4:
    while(pstAencCtl->bStart)
    {

        m++;
        FD_ZERO(&readVenc_fds);
        for (i = 0; i < s32ChnTotal; i++)
        {
            FD_SET(VencFd, &readVenc_fds);
        }

        TimeoutVal.tv_sec  = 2;
        TimeoutVal.tv_usec = 0;

        FD_ZERO(&readAenc_fds);
        FD_SET(AencFd,&readAenc_fds);


        s32Ret = select(maxfd + 1, &readVenc_fds, NULL, NULL, &TimeoutVal);

        if (s32Ret < 0)
        {
            SAMPLE_PRT("select failed!\n");
            break;
        }
        else if (s32Ret == 0)
        {
            SAMPLE_PRT("get venc stream time out, exit thread\n");
            continue;
        }
        else
        {

            for (i = 0; i < s32ChnTotal; i++)
            {
                if (FD_ISSET(VencFd, &readVenc_fds))
                {
                    /*******************************************************
                     step 2.1 : query how many packs in one-frame stream.
                    *******************************************************/
                    memset(&videostStream, 0, sizeof(videostStream));
                    s32Ret = HI_MPI_VENC_Query(i, &stStat);
                    if (HI_SUCCESS != s32Ret)
                    {
                        SAMPLE_PRT("HI_MPI_VENC_Query chn[%d] failed with %#x!\n", i, s32Ret);
                        break;
                    }

                    /*******************************************************
                     step 2.2 : malloc corresponding number of pack nodes.
                    *******************************************************/
                    videostStream.pstPack = (VENC_PACK_S*)malloc(sizeof(VENC_PACK_S) * stStat.u32CurPacks);
                    if (NULL == videostStream.pstPack)
                    {
                        SAMPLE_PRT("malloc stream pack failed!\n");
                        break;
                    }
                    
                    /*******************************************************
                     step 2.3 : call mpi to get one-frame stream
                    *******************************************************/
                    videostStream.u32PackCount = stStat.u32CurPacks;
                    s32Ret = HI_MPI_VENC_GetStream(i, &videostStream, HI_TRUE);
                    if (HI_SUCCESS != s32Ret)
                    {
                        free(videostStream.pstPack);
                        videostStream.pstPack = NULL;
                        SAMPLE_PRT("HI_MPI_VENC_GetStream failed with %#x!\n", \
                               s32Ret);
                        break;
                    }

                    if(m>25)   //从下一个I帧开始,写视频到mp4
                    {
                       s32Ret=SAMPLE_COMM_VENC_SaveH264(mp4file,&videostStream);
                    }

                    /*******************************************************
                     step 2.5 : release stream
                    *******************************************************/
                    s32Ret = HI_MPI_VENC_ReleaseStream(i, &videostStream);

                    if (HI_SUCCESS != s32Ret)
                    {
                        free(videostStream.pstPack);
                        videostStream.pstPack = NULL;
                        break;
                    }             
                }
            }
        }
        s32Ret = select(AencFd+1, &readAenc_fds, NULL, NULL, &TimeoutVal);

        if (s32Ret < 0)
        {
            break;
        }
        else if (0 == s32Ret)
        {
             printf("%s: get aenc stream select time out\n", __FUNCTION__);
             break;
        }

        if (FD_ISSET(AencFd, &readAenc_fds))
        {
            s32Ret = HI_MPI_AENC_GetStream(pstAencCtl->AeChn, &audiostStream, HI_TRUE);

            if (HI_SUCCESS != s32Ret )
            {
                printf("%s: HI_MPI_AENC_GetStream(%d), failed with %#x!\n", __FUNCTION__, pstAencCtl->AeChn, s32Ret);
                pstAencCtl->bStart = HI_FALSE;
                return NULL;
            }

fwrite(audiostStream.pStream,1,audiostStream.u32Len, pcm);


        if(m>15)    //libfaac编码前3帧会失败,跳过前面的25帧,获取下一个I帧再写mp4
        {
//AAC转码
            memcpy(&buf_tmp[pos],audiostStream.pStream,audiostStream.u32Len);
            pos+=640;
//            printf("pos is:%d\n",pos);
            if(pos < 2048)
            {
                goto got_the_stream;
            }
            memcpy(InputBuffer,buf_tmp,2048);
            memset(buf_tmp,0,2048);
            memcpy(buf_tmp,&buf_tmp[2048],pos-2048);
            pos=pos-2048;
            flag=faacEncEncode(hEncoder,                (int*)InputBuffer,inputSamples,OutputBuffer,maxOutputBytes);
            if(flag <= 0)
            {
                printf("start the Encoder failure\n");
            }
if(flag > 0)      //音频转ACC再写MP4
{

            bool ret=MP4SetTrackESConfiguration(mp4file,audio,spec_buf,spec_len);
            if(1!=ret)
            {
                printf("MP4SetTrackESConfiguration audio failed\n");       
            }
            int nret=MP4WriteSample(mp4file, audio, &OutputBuffer[0], flag,128*8000/1000, 0, 1);
            if(1!=nret)
            {
                printf("MP4WriteSample audio failed\n");       
            }

}
            memset(InputBuffer,0,2048);
            memset(OutputBuffer,0,768);
        }
got_the_stream:

                    /*******************************************************
                     step 2.6 : free pack nodes
                    *******************************************************/
                    free(videostStream.pstPack);
                    videostStream.pstPack = NULL;
                    // finally you must release the stream
                        HI_MPI_AENC_ReleaseStream(pstAencCtl->AeChn, &audiostStream);

        }

//    pasttime=nowtime;
    }
    faacEncClose(hEncoder);
    pstAencCtl->bStart = HI_FALSE;
    return NULL;
}
我来回答
回答34个
时间排序
认可量排序

WK12432

0个粉丝

0

问答

0

专栏

0

资料

WK12432 2016-11-09 21:08:16
认可0
我也是音视频不同步,继续关注,等待大神的出现

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-10 09:33:48
认可0
音视频同步本身就不好做, 用sample这么简单的流程来实现本身就不靠谱

通常情况下录不是问题,码流加上时间戳存文件即可, 但是文件结构就有讲究了

而播放就复杂了, 由于音频是有固定的采样率的,也就是说音频的时间是有很高的要求的,比如一帧和下一帧之间是不能有间隔的(注意这里不是指调用sendframe或sendstream的时间),所以从同步的要求来看, 一般是以音频为参考,音频正常播放, 然后去看时间,如果到了要播一个视频帧的时候播一个视频帧, 这样才能勉强实现所谓的音视频同步(不能算严格意义的同步)
这里音频帧的大小就需要选择了, 太小播放线程调用太频繁, 容易出现缓存中无数据,导致音频播放出问题 太大会导致视频播放控制不便

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-10 10:08:12
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41056&ptid=13313]zhuangweiye 发表于 2016-11-10 09:33[/url]
音视频同步本身就不好做, 用sample这么简单的流程来实现本身就不靠谱

通常情况下录不是问题,码流加上时 ...[/quote]

谢谢你的耐心解答,我是以音频为参考时间的,我在程序里面统计了写入的音频和视频的帧数,然后分别乘以他们的duration,它们的时间是一致的,但就是画面不同步     我直接在while里面写pcm和h264也是一样的音频会慢慢变快 ?这个应该不是pts和播放器的问题吧?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-10 10:46:54
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41061&ptid=13313]Benz 发表于 2016-11-10 10:08[/url]
谢谢你的耐心解答,我是以音频为参考时间的,我在程序里面统计了写入的音频和视频的帧数,然后分别乘以他 ...[/quote]

1. 海思的ADEC/VDEC都是有缓冲的
2. 关于视频的pts好像是由vo控制的(前提是pts > 0), 所以并不是写了相同的值就能同步

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-10 10:57:21
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41069&ptid=13313]zhuangweiye 发表于 2016-11-10 10:46[/url]
1. 海思的ADEC/VDEC都是有缓冲的
2. 关于视频的pts好像是由vo控制的(前提是pts > 0), 所以并不是写了相 ...[/quote]

我这里项目是做录制   并没有涉及到ADEC和VDEC啊  ,我从编码器里得到的码流的pts,一开始是一样的,然后音频会越来越大   我发现,每帧视频的pts差值是39.9ms,每帧音频的pts差值是40ms

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-10 11:01:29
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41071&ptid=13313]Benz 发表于 2016-11-10 10:57[/url]
我这里项目是做录制   并没有涉及到ADEC和VDEC啊  ,我从编码器里得到的码流的pts,一开始是一样的,然后 ...[/quote]

如果只是录, 那么就是码流并没有按播放器的要求填写pts了

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-10 11:07:37
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41073&ptid=13313]zhuangweiye 发表于 2016-11-10 11:01[/url]
如果只是录, 那么就是码流并没有按播放器的要求填写pts了[/quote]

但是   我没有转码和写mp4,就只是保存PCM和264两个播放器来同时播放,也会出现不同步是什么情况啊?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-10 11:11:13
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41075&ptid=13313]Benz 发表于 2016-11-10 11:07[/url]
但是   我没有转码和写mp4,就只是保存PCM和264两个播放器来同时播放,也会出现不同步是什么情况啊?[/quote]

慢多少有具体的比例吗?

另外确定一下视频的帧率是30fps还是25fps的, 看看是否和这个有关系

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-10 11:25:16
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41077&ptid=13313]zhuangweiye 发表于 2016-11-10 11:11[/url]
慢多少有具体的比例吗?

另外确定一下视频的帧率是30fps还是25fps的, 看看是否和这个有关系[/quote]

没有具体的比列,大概40分钟会有6s左右,帧率是25fps,我是在一个while里面存的pcm和264,一帧音频对应一帧视频写的,应该没问题吧,我试着把它们的缓冲区都加大了 ,也是这个效果,而且开始的时候视频还会快一点点

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-10 11:30:06
认可0
本帖最后由 zhuangweiye 于 2016-11-10 11:31 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=41079&ptid=13313]Benz 发表于 2016-11-10 11:25[/url]
没有具体的比列,大概40分钟会有6s左右,帧率是25fps,我是在一个while里面存的pcm和264,一帧音频对应一 ...[/quote]

40min慢6s, 6/2400 = 1/400, 这个是累积误差吧, 楼主上面视频是39.9ms, 不就是1/400的比例吗?

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-10 11:37:06
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41080&ptid=13313]zhuangweiye 发表于 2016-11-10 11:30[/url]
40min慢6s, 6/2400 = 1/400, 这个是累积误差吧, 楼主上面视频是39.9ms, 不就是1/400的比例吗?[/quote]

不好意思,问题有点多,先谢谢了
1.pcm和264文件也会按照pts来显示吗?
2我写mp4的时候,已将视频的39.9改成了40,也还是一样的
3.我 可以修改它的pts吗?或者说我自己改成当前系统时间来赋给pts
4.为什么一开始视频会快一点点呢?

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-11 16:04:07
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41080&ptid=13313]zhuangweiye 发表于 2016-11-10 11:30[/url]
40min慢6s, 6/2400 = 1/400, 这个是累积误差吧, 楼主上面视频是39.9ms, 不就是1/400的比例吗?[/quote]

大神,我今天测试了,把h264和pcm的pts都设置成了0.也是可以正常播放的啊!也是音频会快于视频,大概问题会在哪里啊?

zhuangweiye

8个粉丝

0

问答

0

专栏

0

资料

zhuangweiye 2016-11-11 16:52:22
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41173&ptid=13313]Benz 发表于 2016-11-11 16:04[/url]
大神,我今天测试了,把h264和pcm的pts都设置成了0.也是可以正常播放的啊!也是音频会快于视频,大概问题 ...[/quote]

楼主确定写码流文件时有写pts吗 ? 文件结构里面有文件头吗? 如果没有pts写在哪里呢 ? 播放器使用的什么样的文件格式?

我这里看过去全是问题, 猜不出来楼主所说的 "把h264和pcm的pts都设置成了0.也是可以正常播放的啊!" 里面把pts设成0是在哪里设的? 是播放程序里面?是文件里面?还是...? 楼主使用的播放器是自己写的还是别人的? 播放的时序控制是什么机制?所谓的音视频同时播放又是个什么概念?

太多问题了

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-11-11 17:43:59
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=41177&ptid=13313]zhuangweiye 发表于 2016-11-11 16:52[/url]
楼主确定写码流文件时有写pts吗 ? 文件结构里面有文件头吗? 如果没有pts写在哪里呢 ? 播放器使用的什么样 ...[/quote]

哦哦,谢谢提醒    我只是改变了海思码流结构体里面的pts,但实际写入的只是裸码流;我指的同时播放是将pcm和h264的裸码流文件,在两个播放器里面同时播放,音频会慢慢的变快!这个应该是跟播放器默认的解码有关的吧?没同步正常吗?

win992590594

0个粉丝

6

问答

0

专栏

0

资料

win992590594 2016-12-01 11:32:12
认可0
楼主解决了吗??给下思路,遇到同样问题

win992590594

0个粉丝

6

问答

0

专栏

0

资料

win992590594 2016-12-02 16:56:49
认可0
本帖最后由 win992590594 于 2016-12-2 16:57 编辑

楼主,我出现了有音频,却没有视频的情况,请问你是否出现过,是不是也是同步问题??

Benz

0个粉丝

29

问答

0

专栏

0

资料

Benz 2016-12-03 14:05:40
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42308&ptid=13313]win992590594 发表于 2016-12-2 16:56[/url]
楼主,我出现了有音频,却没有视频的情况,请问你是否出现过,是不是也是同步问题??[/quote]

音频播放是否正常?  视频的头四个字节你换成每帧数据的长度了吗?

henman

0个粉丝

7

问答

0

专栏

0

资料

henman 2016-12-03 16:09:45
认可0
首先声明我没仔细看,mp4等文件封装我也没做过,但我觉得这个问题跟海思本身是没关系的,有关系的是这个码流的处理思路。
海思音视频帧的时间戳,就是那个u64的pts,是很精准的,所有跳过该值的思路都是不对的。
你说分别保存了pcm和h264文件,那这个就是裸流了,时间戳都不见了吧?
正确的思路是,根据时间戳,排列出顺序的音视频混合裸流,然后根据每帧之间的时间戳差值作为延时标准。
PS:绝对不能根据码率和采样率估算时间戳。

cy_ygs

0个粉丝

0

问答

0

专栏

0

资料

cy_ygs 2016-12-05 13:06:32
认可0
了解下,顶顶顶

win992590594

0个粉丝

6

问答

0

专栏

0

资料

win992590594 2016-12-07 17:13:48
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42343&ptid=13313]Benz 发表于 2016-12-3 14:05[/url]
音频播放是否正常?  视频的头四个字节你换成每帧数据的长度了吗?[/quote]

音频貌似正常,视频头四个字节也换成每帧数据的长度,就是显示不出来,我是用FAAC+MP4V2库封装成MP4文件的,打开MP4文件就是有音频没视频显示,黑屏,另外我分开存视频H264文件和音.aac文件都可以播放,说明我PCM转AAC是可以的??不知为什么封装成MP4文件后,打开音频有声音,但播放器黑屏
加载中···
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区