日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

ffmpeg解析MP4封装的avc1编码问题「建议收藏」(Windows下安装使用ffmpeg)

發(fā)布時間:2023/12/24 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 ffmpeg解析MP4封装的avc1编码问题「建议收藏」(Windows下安装使用ffmpeg) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

0、問題

??遇到的問題:使用ffmpeg直接讀取avc1編碼的mp4視頻,將讀取到的幀寫下來(H264碼流),播放失敗。
??原因: ffmpeg解碼獲取的AVPacket只包含視頻壓縮數(shù)據(jù),并沒有包含相關(guān)的解碼信息(比如:h264的sps,pps頭信息),這些解碼信息包括編碼的profile,level,圖像的寬和高,deblock濾波器等。沒有這些編碼頭信息解碼器就不能進行解碼。

1、mp4封裝的avc1編碼

??mp4封裝的avc1編碼(不帶起始碼的H264編碼格式)視頻如果直接用av_read_frame接口讀取然后播放是不能播放成功的。因為讀取出來的數(shù)據(jù)不帶PPS/SPS、起始碼這三種信息。
必須添加上后才能播放。

sps,pps之后就是I幀的數(shù)據(jù)起始碼為00 00 00 01或00 00 01

上圖中黑框內(nèi)就是sps和psp數(shù)據(jù),藍色框為起始碼(00 00 00 01)及I幀標志碼(06 50)

2、SPS,PPS在ffmpeg

??H.264碼流的SPS和pps信息存儲在AVCidecContext結(jié)構(gòu)體的extradata中,添加這些信息需要使用ffmpeg中名稱為”h264_mp4toannexb”的bitstream filter處理。
查看ffmpeg工具支持的Bitstream Filter類型命令

ffmpeg -bsfs

3、新舊接口

《1》、舊接口

int ParseH264ExtraDataInMp4(int stream_id, AVPacket* packet) 
{
	uint8_t *dummy = NULL; int dummy_size;
	AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("h264_mp4toannexb");
	if (bsfc == NULL) 
	{
        envir() << "cannot open the h264_mp4toannexb\n";
        return -1;
	}

 	av_bitstream_filter_filter(bsfc, format_ctx_->streams[stream_id]->codec,
          NULL, &dummy, &dummy_size, NULL, 0, 0);

    av_bitstream_filter_close(bsfc);
}

舊接口使用時需要特別注意,否則很容易導致內(nèi)存泄漏。

《2》、新接口

int ParseH264ExtraDataInMp4(int stream_id, AVPacket* packet) 
{
const AVBitStreamFilter * absFilter = NULL;
    AVBSFContext *absCtx = NULL;
    AVCodecParameters *codecpar = NULL;

    absFilter = av_bsf_get_by_name("h264_mp4toannexb");

    //過濾器分配內(nèi)存   
    av_bsf_alloc(absFilter, &absCtx);

    //添加解碼器屬性   
    codecpar = format_ctx_->streams[stream_id]->codecpar;
    avcodec_parameters_copy(absCtx->par_in, codecpar);
    absCtx->time_base_in = format_ctx_->streams[stream_id]->time_base;

    //初始化過濾器上下文   
    av_bsf_init(absCtx);

    //AVPacket處理   
    if (av_bsf_send_packet(absCtx, packet) < 0)
    {
        printf("av_bsf_send_packet faile \n");
        av_bsf_free(&absCtx);
        absCtx = NULL;
        return -1;
    }


    if (av_bsf_receive_packet(absCtx, packet) == 0)
    {
        //printf("av_bsf_receive_packet faile \n");
        //av_bsf_free(&absCtx);
        //absCtx = NULL;
        return 0;

    }


    av_bsf_free(&absCtx);
    absCtx = NULL;
}

《3》、使用偽代碼

int main()
{
    //ffmpeg的open接口打開MP4封裝的avc1碼流視頻 , AVFormatContext *format_ctx_
    //讀取一幀av_read_frame,讀取到AVPacket packet中

    if(視頻幀)    //只處理視頻幀,音頻不處理  
    {
      int stream_id = packet->stream_index;
      AVCodecContext *codec = NULL;
      codec = format_ctx_->streams[stream_id]->codec;

        if (codec->codec_id == AV_CODEC_ID_H264) 
        {
            //pps and sps
            //const char start_code[4] = { 0, 0, 0, 1 };
            //memcpy(packet->data, start_code, 4);

            if ((codec->extradata[0] != 0) && 
                (ParseH264ExtraDataInMp4(stream_id, packet) == 0)) 
            {

                has_extra_data = True;

            }

#if 0
            {

                FILE* wfd = fopen("out.h264", "ab+");
                if (wfd)
                {

                    if (has_extra_data)
                    {

                        fwrite(codec->extradata, 1, codec->extradata_size, wfd);
                    }

                    fwrite(packet->data, 1, packet->size, wfd);
                    fflush(wfd);
                    fclose(wfd);
                    wfd = NULL;
                }
            }

#endif
        } 
    }
}

4、參考

《1》、https://www.jianshu.com/p/e5e021ccc980
《2》、https://blogs.gentoo.org/lu_zero/2016/03/21/bitstream-filtering/
《3》、http://www.xuhj.top/2018/06/26/ffmpeg-convert-to-ts-stream/
《4》、https://cloud.tencent.com/developer/article/1333501
《5》、sps/pps數(shù)據(jù)結(jié)構(gòu)
《6》、avc1余h264區(qū)別

總結(jié)

以上是生活随笔為你收集整理的ffmpeg解析MP4封装的avc1编码问题「建议收藏」(Windows下安装使用ffmpeg)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。