weixin_40992846 2022-01-24 11:08 采纳率: 50%
浏览 12
已结题

linux 嵌入式ffmpeg音视频不同步,时间戳设置不合理,要怎么设置时间基呢?

嵌入式板子,从摄像头中拿h264 和aac,直接拿去封装成mp4文件,但音视频不同步,大概率是写入的时间戳有问题

附上使用ffmpeg写入音视频数据的实现

int WriteVideoAudio(uint8_t* data, int nLen,unsigned long int timestamp,const int keyframe)
{
    int ret;
    int64_t calc_duration;
    // Init packet
    AVPacket pkt;
    av_init_packet( &pkt );

    if(keyframe >= 0)//轮到视频写入
    {
        // 我的添加,为了计算pts
        AVCodecContext *c = m_pVideoSt->codec;

        int isI = keyframe;
        pkt.flags |=  isI ? AV_PKT_FLAG_KEY : 0;

        pkt.stream_index = m_pVideoSt->index;
        pkt.data = data;
        pkt.size = nLen;
        if ( waitkey ){
            if ( 0 == ( pkt.flags & AV_PKT_FLAG_KEY ) ){
                ret = -1;
                goto EXIT;
            }
            else
                waitkey = 0;
        }

        if(isI && !m_bHadFillGlobalHeader)
        {
            memcpy(m_pVideoSt->codec->extradata + m_pVideoSt->codec->extradata_size, pkt.data, 32);
            m_pVideoSt->codec->extradata_size += 32;
            m_bHadFillGlobalHeader = 1;
            pkt.data += 32;
        }
        pkt.pts = av_rescale_q((frameindex++), m_pVideoSt->codec->time_base,m_pVideoSt->time_base);//不同时间基的转换
        pkt.dts = pkt.pts;
        pkt.duration = av_rescale_q(pkt.duration,m_pVideoSt->time_base, m_pVideoSt->time_base);
        pkt.pos = -1;
        cur_pts_v=pkt.pts;

        pkt.pts = av_rescale_q(pkt.pts,m_pVideoSt->codec->time_base,m_pAudioSt->codec->time_base);//转成视频时间基
        pkt.dts=pkt.pts;
        pkt.duration=av_rescale_q(pkt.duration,m_pVideoSt->codec->time_base,m_pAudioSt->codec->time_base);

    }
    else{//轮到音频写入
        pkt.stream_index = m_pAudioSt->index;
        pkt.data = data;
        pkt.size = nLen;
        
        pkt.pts = av_rescale_q(Audioframeindex++, m_pAudioSt->codec->time_base,m_pAudioSt->time_base);//不同时间基的转换
        pkt.dts = pkt.pts;
        pkt.duration = av_rescale_q(pkt.duration,m_pAudioSt->time_base, m_pAudioSt->time_base);
        pkt.pos = -1;
        
        cur_pts_a=pkt.pts;
        cur_pts_a=pkt.pts;
    }
    ret = av_interleaved_write_frame( m_pOc, &pkt );
    if (ret < 0)
    {
        printf("cannot write frame");
        ret = -1;
    }
    av_free_packet(&pkt);
EXIT:
    return ret;
}

附上音视频时间戳比较的实现

int ffmpegMp4_compare_ts(){
    return av_compare_ts(cur_pts_v,m_pVideoSt->codec->time_base,cur_pts_a,m_pAudioSt->codec->time_base);
}

时间基的设置有点烦恼,该怎么设置?

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 2月1日
    • 修改了问题 1月24日
    • 创建了问题 1月24日

    悬赏问题

    • ¥15 征集Python提取PDF文字属性的代码
    • ¥15 如何联系真正的开发者而非公司
    • ¥15 有偿求苍穹外卖环境配置
    • ¥15 代码在keil5里变成了这样怎么办啊,文件图像也变了,
    • ¥20 Ue4.26打包win64bit报错,如何解决?(语言-c++)
    • ¥15 clousx6整点报时指令怎么写
    • ¥30 远程帮我安装软件及库文件
    • ¥15 关于#自动化#的问题:如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内
    • ¥20 深信服vpn-2050这台设备如何配置才能成功联网?
    • ¥15 Arduino的wifi连接,如何关闭低功耗模式?