ffmpeg转码多路输出(二)

https://blog.csdn.net/zhuweigangzwg/article/details/72481966
ffmpeg转码多路输出(二)

本程序支持一路输入多路输出,可根据map配置自行添加,第1路为纯拷贝,其他2路经过编解码,格式转换缩放和重采样,纯拷贝方面不同格式适应方面还没做全,以后补充。本程序适合多分辨率切换等方面内容。注意重采样等方面的注释内容。

具体看代码:

#include "ffmpeg_transcode.h"
 
 
/*
int main()
{
    AVOutputFormat *ofmt = NULL;
    AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
    AVPacket pkt;
    int ret, i;
    av_register_all();
    if ((ret = avformat_open_input(&ifmt_ctx, INPUTURL, 0, 0)) < 0) {
        fprintf(stderr, "Could not open input file '%s'", INPUTURL);
    }
    if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
        fprintf(stderr, "Failed to retrieve input stream information");
    }
    av_dump_format(ifmt_ctx, 0, INPUTURL, 0);
    avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, OUTPUTURL);
    if (!ofmt_ctx) {
        fprintf(stderr, "Could not create output context\n");
        ret = AVERROR_UNKNOWN;
    }
    ofmt = ofmt_ctx->oformat;
    for (i = 0; i < ifmt_ctx->nb_streams; i++) {
        AVStream *in_stream = ifmt_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
        if (!out_stream) {
            fprintf(stderr, "Failed allocating output stream\n");
            ret = AVERROR_UNKNOWN;
        }
        ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
        if (ret < 0) {
            fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
        }
        out_stream->codec->codec_tag = 0;
        if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
    if (!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&ofmt_ctx->pb, OUTPUTURL, AVIO_FLAG_WRITE);
        if (ret < 0) {
            fprintf(stderr, "Could not open output file '%s'", OUTPUTURL);
        }
    }
    ret = avformat_write_header(ofmt_ctx, NULL);
    if (ret < 0) {
        fprintf(stderr, "Error occurred when opening output file\n");
    }
    av_dump_format(ofmt_ctx, 0, OUTPUTURL, 1);
    AVBitStreamFilterContext * m_vbsf_aac_adtstoasc;     //aac->adts to asc过滤器 
    m_vbsf_aac_adtstoasc =  av_bitstream_filter_init("aac_adtstoasc");
    while (1) 
    {
        AVStream *in_stream, *out_stream;
        ret = av_read_frame(ifmt_ctx, &pkt);
        if (ret < 0)
            break;
        in_stream  = ifmt_ctx->streams[pkt.stream_index];
        out_stream = ofmt_ctx->streams[pkt.stream_index];
        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AVRounding(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
        pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AVRounding(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
        pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
        pkt.pos = -1;
        if (in_stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            if (m_vbsf_aac_adtstoasc != NULL)  
            {  
                AVPacket filteredPacket = pkt;   
                int a = av_bitstream_filter_filter(m_vbsf_aac_adtstoasc,                                             
                    out_stream->codec, NULL,&filteredPacket.data, &filteredPacket.size,  
                    pkt.data, pkt.size, pkt.flags & AV_PKT_FLAG_KEY);   
                if (a >  0)               
                {                  
                    av_free_packet(&pkt);   
                    filteredPacket.destruct = av_destruct_packet;    
                    pkt = filteredPacket;               
                }     
                else if (a == 0)  
                {  
                    pkt = filteredPacket;     
                }  
                else if (a < 0)              
                {                  
                    fprintf(stderr, "%s failed for stream %d, codec %s",  
                        m_vbsf_aac_adtstoasc->filter->name,pkt.stream_index,out_stream->codec->codec ?  out_stream->codec->codec->name : "copy");  
                    av_free_packet(&pkt);     
                }  
            }  
        }
        ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
        if (ret < 0) 
        {
            break;
        }
        av_packet_unref(&pkt);
    }
    av_write_trailer(ofmt_ctx);
    avformat_close_input(&ifmt_ctx);
    if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
    {
        avio_closep(&ofmt_ctx->pb);
    }
    avformat_free_context(ofmt_ctx);
}
*/
 
 
 
 
 
 
 
int main(int argc ,char ** argv)
{
    int ret = 0;
 
    av_register_all();
    avformat_network_init();
 
    ffmpeg_init_demux(INPUTURL,&m_icodec);
 
    //out_stream1 用原始的
    Out_stream_info *out_stream_info1 = NULL;
    out_stream_info1 = new Out_stream_info();
    out_stream_info1->user_stream_id = 10;
    sprintf(out_stream_info1->m_outurlname,"%s",OUTPUTURL10);
    //out_stream2
    Out_stream_info *out_stream_info2 = NULL;
    out_stream_info2 = new Out_stream_info();
    out_stream_info2->user_stream_id = 11;
    sprintf(out_stream_info2->m_outurlname,"%s",OUTPUTURL11);
    out_stream_info2->m_dwWidth = 640;
    out_stream_info2->m_dwHeight = 480;
    out_stream_info2->m_dbFrameRate = 25;
    out_stream_info2->m_video_codecID = (int)AV_CODEC_ID_H264;
    out_stream_info2->m_video_pixelfromat = (int)AV_PIX_FMT_YUV420P;
    out_stream_info2->m_bit_rate = 800000;
    out_stream_info2->m_gop_size = 125;
    out_stream_info2->m_max_b_frame = 0;
    out_stream_info2->m_thread_count = 8;
    out_stream_info2->m_dwChannelCount = 2;
    out_stream_info2->m_dwBitsPerSample = AV_SAMPLE_FMT_S16_t;
    out_stream_info2->m_dwFrequency = 44100;
    out_stream_info2->m_audio_codecID = (int)AV_CODEC_ID_AAC; 
    //out_stream3
    Out_stream_info *out_stream_info3 = NULL;
    out_stream_info3 = new Out_stream_info();
    out_stream_info3->user_stream_id = 12;
    sprintf(out_stream_info3->m_outurlname,"%s",OUTPUTURL12);
    out_stream_info3->m_dwWidth = 352;
    out_stream_info3->m_dwHeight = 288;
    out_stream_info3->m_dbFrameRate = 25;
    out_stream_info3->m_video_codecID = (int)AV_CODEC_ID_H264;
    out_stream_info3->m_video_pixelfromat = (int)AV_PIX_FMT_YUV420P;
    out_stream_info3->m_bit_rate = 400000;
    out_stream_info3->m_gop_size = 125;
    out_stream_info3->m_max_b_frame = 0;
    out_stream_info3->m_thread_count = 8;
    out_stream_info3->m_dwChannelCount = 2;
    out_stream_info3->m_dwBitsPerSample = AV_SAMPLE_FMT_S16_t;
    out_stream_info3->m_dwFrequency = 44100;
    out_stream_info3->m_audio_codecID = (int)AV_CODEC_ID_AAC; 
 
    //申请map
    m_list_out_stream_info[out_stream_info1->user_stream_id] = (out_stream_info1);
    m_list_out_stream_info[out_stream_info2->user_stream_id] = (out_stream_info2);
    m_list_out_stream_info[out_stream_info3->user_stream_id] = (out_stream_info3);
 
    ffmpeg_init_mux(m_list_out_stream_info,out_stream_info1->user_stream_id);
    printf("--------程序运行开始----------\n");
    //
    ffmpeg_transcode(out_stream_info1->user_stream_id);
    //
    ffmpeg_uinit_mux(m_list_out_stream_info,out_stream_info1->user_stream_id);
    ffmpeg_uinit_demux(m_icodec);
 
    //释放map
    if (m_list_out_stream_info.size()> 0)
    {
        map<int,Out_stream_info*> ::iterator result_all;
        Out_stream_info * out_stream_info_all = NULL;
        for (result_all = m_list_out_stream_info.begin();result_all != m_list_out_stream_info.end();)
        {
            out_stream_info_all = result_all->second;
            if(out_stream_info_all)
            {
                delete out_stream_info_all;
                out_stream_info_all = NULL;          
            }
            m_list_out_stream_info.erase(result_all ++);
        }
        m_list_out_stream_info.clear();
    }
    printf("--------程序运行结束----------\n");
    printf("-------请按任意键退出---------\n");
    return getchar();
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值