音视频开发(五)——转码2


我的大部分学习都来自雷神,没有基础去雷神博客转转,每次都有很多收获。
https://blog.csdn.net/leixiaohua1020/article/details/42658139

转码,就是将一个不需要的格式转换成为自己需要的格式。

上次研究不带编解码的转码,这次是带编解码的,经过解码后重新编码变换格式。
本次实验把avi转码为mp4。

一、输入初始化

// 1.初始化输入ic

AVFormatContext *ic = avformat_alloc_context();

if(avformat_open_input(&ic, in_file, 0, 0) != 0)
{
    cout << "can not open file : " << in_file << endl;
    return -1;
}
if(avformat_find_stream_info(ic, 0) < 0)
{
    cout << "no stream information" << endl;
    return -1;
}

av_dump_format(ic, 0, in_file, 0);

二、寻找音视频流

这步比较简单,利用for循环遍历就好

// 2.寻找音视频流
unsigned int i;
for(i = 0; i < ic->nb_streams; i++)
{
    if(ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
        vIndex = i;
    else if(ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
        aIndex = i;
}

三、解码器

寻找并打开解码器

1. 视频解码器

AVCodec *v_dec = avcodec_find_decoder(ic->streams[vIndex]->codecpar->codec_id);

AVCodecContext *vDec = avcodec_alloc_context3(v_dec);
avcodec_parameters_to_context(vDec, ic->streams[vIndex]->codecpar);
if(avcodec_open2(vDec, v_dec, 0) != 0)
{
    cout << "can not open video decoder" << endl;
    return -1;
}

2. 音频解码器

AVCodec *a_dec = avcodec_find_decoder(ic->streams[aIndex]->codecpar->codec_id);

AVCodecContext *aDec = avcodec_alloc_context3(a_dec);
avcodec_parameters_to_context(aDec, ic->streams[aIndex]->codecpar);

if(avcodec_open2(aDec, a_dec, 0) != 0)
{
    cout << "can not open audio decoder" << endl;
    return -1;
}

四、编码器

寻找、设置并打开编码器

1. 视频编码器

	AVCodec *v_enc = avcodec_find_encoder(AV_CODEC_ID_MPEG4);

    AVCodecContext *vEnc = avcodec_alloc_context3(v_enc);

    vEnc->codec_id = AV_CODEC_ID_MPEG4;
    vEnc->codec_type = AVMEDIA_TYPE_VIDEO;
    vEnc->pix_fmt = AV_PIX_FMT_YUV420P;
    vEnc->width = 800;
    vEnc->height =600;
    vEnc->time_base.num = 1;
    vEnc->time_base.den = 25;
    vEnc->bit_rate = 468000;
    vEnc->gop_size = 250;
    vEnc->qmin = 10;
    vEnc->qmax = 51;
    vEnc->max_b_frames = 0;

    if (avcodec_open2(vEnc, v_enc, 0) < 0)
    {
        cout << "can not open video encoder" << endl;
        return -1;
    }

2. 音频编码器

AVCodec *a_enc = avcodec_find_encoder(AV_CODEC_ID_MP3);

AVCodecContext *aEnc = avcodec_alloc_context3(a_enc);

aEnc->codec_id = AV_CODEC_ID_MP3;
aEnc->codec_type = AVMEDIA_TYPE_AUDIO;
aEnc->sample_fmt = AV_SAMPLE_FMT_S16P;
aEnc->channel_layout = AV_CH_LAYOUT_STEREO;
aEnc->bit_rate = 64000;
aEnc->sample_rate = 44100;
aEnc->channels = 2;

if (avcodec_open2(aEnc, a_enc, 0) < 0)
{
    cout << "can not open audio encoder" << endl;
    return -1;
}

五、输出初始化

AVFormatContext *oc;
avformat_alloc_output_context2(&oc, NULL, "mp4", path);
if(oc == NULL)
{
    cout << "creat output context failed" << endl;
    return -1;
}

六、创建输出流、复制

AVStream *vStream = avformat_new_stream(oc, v_enc);
if(vStream == NULL)
{
    cout << "creat video stream failed" << endl;
    return -1;
}
AVStream *aStream = avformat_new_stream(oc, a_enc);
if(aStream == NULL)
{
    cout << "creat audio stream failed" << endl;
    return -1;
}

vStream->codecpar->codec_tag = 0;
if(avcodec_parameters_from_context(vStream->codecpar, vEnc) < 0)
{
    cout << "copy video context failed" << endl;
    return -1;
}
aStream->codecpar->codec_tag = 0;
if(avcodec_parameters_from_context(aStream->codecpar, aEnc) < 0)
{
    cout << "copy audio context failed" << endl;
    return -1;
}

七、输出控制

if(avio_open(&oc->pb, path, AVIO_FLAG_WRITE) < 0)
{
    cout << "open output file failed" << endl;
    return -1;
}

av_dump_format(oc, 0, path, 1);

八、视频scale和音频sample

SwsContext *enc_sws = sws_alloc_context();
enc_sws = sws_getCachedContext(enc_sws, vDec->width, vDec->height, vEnc->pix_fmt,
                               vEnc->width, vEnc->height, vEnc->pix_fmt,
                               SWS_BICUBIC, 0, 0, 0);

SwrContext *enc_swr = swr_alloc();
enc_swr = swr_alloc_set_opts(enc_swr, aEnc->channel_layout, aEnc->sample_fmt,
                             aEnc->sample_rate, aDec->channel_layout,
                             aDec->sample_fmt, aDec->sample_rate, 0, 0);
swr_init(enc_swr);

九、核心解码、编码

 //解码
ret = avcodec_send_packet(vDec, dec_pkt);
if(ret < 0)
{
	cout << "ret = " << ret << endl;
    return -1;
}
ret = avcodec_receive_frame(vDec, frame);
if(ret < 0)
{
	cout << "ret = " << ret << endl;
	return -1;
}
//解码结束

sws_scale(enc_sws, (const uint8_t* const*)frame->data, frame->linesize,
             0, vDec->height, yuv->data, yuv->linesize);

//编码
ret = avcodec_send_frame(vEnc, yuv);
if(ret < 0)
{
	cout << "ret = " << ret << endl;
    return -1;
}
while(!ret)
{
	ret = avcodec_receive_packet(vEnc, enc_pkt);
	if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
		break;
	else if(ret < 0)
	{
     	cout << "ret = " << ret << endl;
     	return -1;
    }

    //pts,dts设置
    enc_pkt->stream_index = vStream->index;

    AVStream *in_stream = ic->streams[vIndex];
    AVRational time_base = in_stream->time_base;
    AVRational r_framerate1 = in_stream->r_frame_rate;
    AVRational time_base_q = { 1, AV_TIME_BASE };

    int64_t calc_duration = (double)(AV_TIME_BASE) / av_q2d(r_framerate1);
    enc_pkt->pts = av_rescale_q(dec_pkt->pts * calc_duration,
                                 time_base_q,
                                 time_base);

    enc_pkt->dts = enc_pkt->pts;
    enc_pkt->duration = av_rescale_q(calc_duration,
                                 time_base_q,
                                 time_base);

    enc_pkt->pos = -1;
     {
     	int64_t pts_time = av_rescale_q(enc_pkt->dts,
                                 time_base,
                                 time_base_q);
        int64_t now_time = av_gettime() - start_time;
         if (pts_time > now_time)
         	av_usleep(pts_time - now_time);
      }

      enc_pkt->pts = av_rescale_q_rnd(enc_pkt->pts,
      							 in_stream->time_base,
                                 vStream->time_base,
                                 (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

      enc_pkt->dts = av_rescale_q_rnd(enc_pkt->dts,
                                 in_stream->time_base,
                                 vStream->time_base,
                                 (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

      enc_pkt->duration = av_rescale_q(enc_pkt->duration,
                                 in_stream->time_base,
                                 vStream->time_base);

      //写入文件
      av_interleaved_write_frame(oc, enc_pkt);
}

下载地址:https://download.csdn.net/download/mr__hu/11255840
修改不了下载积分,还是

附源码

设计是面向过程的,当然,感兴趣的可以设计为面向对象

int main()
{
    avformat_network_init();

    int ret, vIndex = -1, aIndex = -1;

    const char *in_file = "E:/workspace/my.avi";

    const char *path = "out.avi";

    // 1.初始化输入ic
    AVFormatContext *ic = avformat_alloc_context();

    if(avformat_open_input(&ic, in_file, 0, 0) != 0)
    {
        cout << "can not open file : " << in_file << endl;
        return -1;
    }
    if(avformat_find_stream_info(ic, 0) < 0)
    {
        cout << "no stream information" << endl;
        return -1;
    }

    av_dump_format(ic, 0, in_file, 0);

    // 2.寻找音视频流
    unsigned int i;
    for(i = 0; i < ic->nb_streams; i++)
    {
        if(ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
            vIndex = i;
        else if(ic->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
            aIndex = i;
    }

    if(vIndex == -1)
    {
        cout << "no video stream" << endl;
    }
    if(aIndex == -1)
    {
        cout << "no audio stream" << endl;
    }

    // 3.寻找视频解码器
    AVCodec *v_dec = avcodec_find_decoder(ic->streams[vIndex]->codecpar->codec_id);
    if(v_dec == NULL)
    {
        cout << "no video decoder" << endl;
        return -1;
    }
    AVCodecContext *vDec = avcodec_alloc_context3(v_dec);
    if(avcodec_parameters_to_context(vDec, ic->streams[vIndex]->codecpar) < 0)
    {
        cout << "can not copy video codec" << endl;
        return -1;
    }

    // 4.打开视频解码器
    if(avcodec_open2(vDec, v_dec, 0) != 0)
    {
        cout << "can not open video decoder" << endl;
        return -1;
    }

    // 5.寻找音频解码器
    AVCodec *a_dec = avcodec_find_decoder(ic->streams[aIndex]->codecpar->codec_id);
    if(a_dec == NULL)
    {
        cout << "no audio decoder" << endl;
        return -1;
    }
    AVCodecContext *aDec = avcodec_alloc_context3(a_dec);
    ret = avcodec_parameters_to_context(aDec, ic->streams[aIndex]->codecpar);
    if(ret < 0)
    {
        cout << "can not copy audio codec" << endl;
        return -1;
    }

    // 6.打开音频解码器
    if(avcodec_open2(aDec, a_dec, 0) != 0)
    {
        cout << "can not open audio decoder" << endl;
        return -1;
    }

    // 7.寻找视频编码器
    AVCodec *v_enc = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
    if(v_enc == NULL)
    {
        cout << "no video encoder" << endl;
        return -1;
    }
    AVCodecContext *vEnc = avcodec_alloc_context3(v_enc);
    if(vEnc == NULL)
    {
        cout << "can not creat video codec" << endl;
        return -1;
    }
    vEnc->codec_id = AV_CODEC_ID_MPEG4;
    vEnc->codec_type = AVMEDIA_TYPE_VIDEO;
    vEnc->pix_fmt = AV_PIX_FMT_YUV420P;
    vEnc->width = 800;
    vEnc->height =600;
    vEnc->time_base.num = 1;
    vEnc->time_base.den = 25;
    vEnc->bit_rate = 468000;
    vEnc->gop_size = 250;
    vEnc->qmin = 10;
    vEnc->qmax = 51;
    vEnc->max_b_frames = 0;

    // 8.打开视频编码器
    if (avcodec_open2(vEnc, v_enc, 0) < 0)
    {
        cout << "can not open video encoder" << endl;
        return -1;
    }

    // 9.查找音频编码器
    AVCodec *a_enc = avcodec_find_encoder(AV_CODEC_ID_MP3);
    if(a_enc == NULL)
    {
        cout << "no audio encoder" << endl;
        return -1;
    }
    AVCodecContext *aEnc = avcodec_alloc_context3(a_enc);
    if(aEnc == NULL)
    {
        cout << "can not creat audio codec" << endl;
        return -1;
    }
    aEnc->codec_id = AV_CODEC_ID_MP3;
    aEnc->codec_type = AVMEDIA_TYPE_AUDIO;
    aEnc->sample_fmt = AV_SAMPLE_FMT_S16P;
    aEnc->channel_layout = AV_CH_LAYOUT_STEREO;
    aEnc->bit_rate = 64000;
    aEnc->sample_rate = 44100;
    aEnc->channels = 2;

    // 10.打开音频编码器
    if (avcodec_open2(aEnc, a_enc, 0) < 0)
    {
        cout << "can not open audio encoder" << endl;
        return -1;
    }

    // 11.初始化输出oc
    AVFormatContext *oc;
    avformat_alloc_output_context2(&oc, NULL, "mpegts", path);
    if(oc == NULL)
    {
        cout << "creat output context failed" << endl;
        return -1;
    }

    // 12.创建输出流
    AVStream *vStream = avformat_new_stream(oc, v_enc);
    if(vStream == NULL)
    {
        cout << "creat video stream failed" << endl;
        return -1;
    }
    AVStream *aStream = avformat_new_stream(oc, a_enc);
    if(aStream == NULL)
    {
        cout << "creat audio stream failed" << endl;
        return -1;
    }

    // 13.复制视编码上下文
    vStream->codecpar->codec_tag = 0;
    if(avcodec_parameters_from_context(vStream->codecpar, vEnc) < 0)
    {
        cout << "copy video context failed" << endl;
        return -1;
    }
    aStream->codecpar->codec_tag = 0;
    if(avcodec_parameters_from_context(aStream->codecpar, aEnc) < 0)
    {
        cout << "copy audio context failed" << endl;
        return -1;
    }

    // 14.打开输出控制
    if(avio_open(&oc->pb, path, AVIO_FLAG_WRITE) < 0)
    {
        cout << "open output file failed" << endl;
        return -1;
    }

    av_dump_format(oc, 0, path, 1);

    // 15.转码上下文
    SwsContext *enc_sws = sws_alloc_context();
    enc_sws = sws_getCachedContext(enc_sws, vDec->width, vDec->height, vEnc->pix_fmt,
                                   vEnc->width, vEnc->height, vEnc->pix_fmt,
                                   SWS_BICUBIC, 0, 0, 0);

    SwrContext *enc_swr = swr_alloc();
    enc_swr = swr_alloc_set_opts(enc_swr, aEnc->channel_layout, aEnc->sample_fmt,
                                 aEnc->sample_rate, aDec->channel_layout,
                                 aDec->sample_fmt, aDec->sample_rate, 0, 0);
    swr_init(enc_swr);

    // 16.初始化存储位置
    AVFrame *yuv = av_frame_alloc();
    yuv->width = vEnc->width;
    yuv->height = vEnc->height;
    yuv->format = vEnc->pix_fmt;
    av_frame_get_buffer(yuv, 0);

    AVFrame *pcm = av_frame_alloc();
    pcm->format = aEnc->sample_fmt;
    pcm->nb_samples = aEnc->frame_size;
    pcm->channel_layout = aEnc->channel_layout;
    av_frame_get_buffer(pcm, 0);

    AVPacket *dec_pkt = (AVPacket*)av_malloc(sizeof(AVPacket));  //解码前pkt
    AVPacket *enc_pkt = (AVPacket*)av_malloc(192000 * 4);  //编码后pkt
    AVFrame *frame = av_frame_alloc();   //解码暂存

    avformat_write_header(oc, NULL);

    int64_t start_time = av_gettime();
    int64_t frameIndex = 0;
    for(;;)
    {
        if(av_read_frame(ic, dec_pkt) >= 0)
        {
            frameIndex = dec_pkt->pts;
            if(dec_pkt->stream_index == vIndex)
            {
                //解码
                ret = avcodec_send_packet(vDec, dec_pkt);
                if(ret < 0)
                {
                    cout << "ret = " << ret << endl;
                    return -1;
                }
                ret = avcodec_receive_frame(vDec, frame);
                if(ret < 0)
                {
                    cout << "ret = " << ret << endl;
                    return -1;
                }
                //解码结束

                cout << "decode 1 video frame ok" << endl;
                sws_scale(enc_sws, (const uint8_t* const*)frame->data, frame->linesize,
                          0, vDec->height, yuv->data, yuv->linesize);

                //编码
                ret = avcodec_send_frame(vEnc, yuv);
                if(ret < 0)
                {

                    cout << "ret = " << ret << endl;
                    return -1;
                }
                while(!ret)
                {
                    ret = avcodec_receive_packet(vEnc, enc_pkt);
                    if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                        break;
                    else if(ret < 0)
                    {
                        cout << "ret = " << ret << endl;
                        return -1;
                    }

                    //pts,dts设置
                    enc_pkt->stream_index = vStream->index;

                    AVStream *in_stream = ic->streams[vIndex];
                    AVRational time_base = in_stream->time_base;
                    AVRational r_framerate1 = in_stream->r_frame_rate;
                    AVRational time_base_q = { 1, AV_TIME_BASE };

                    int64_t calc_duration = (double)(AV_TIME_BASE) / av_q2d(r_framerate1);
                    enc_pkt->pts = av_rescale_q(dec_pkt->pts * calc_duration,
                                                time_base_q,
                                                time_base);

                    enc_pkt->dts = enc_pkt->pts;
                    enc_pkt->duration = av_rescale_q(calc_duration,
                                                     time_base_q,
                                                     time_base);

                    enc_pkt->pos = -1;

                    {
                        int64_t pts_time = av_rescale_q(enc_pkt->dts,
                                                        time_base,
                                                        time_base_q);

                        int64_t now_time = av_gettime() - start_time;
                        if (pts_time > now_time)
                            av_usleep(pts_time - now_time);
                    }

                    enc_pkt->pts = av_rescale_q_rnd(enc_pkt->pts,
                                                    in_stream->time_base,
                                                    vStream->time_base,
                                                    (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

                    enc_pkt->dts = av_rescale_q_rnd(enc_pkt->dts,
                                                    in_stream->time_base,
                                                    vStream->time_base,
                                                    (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

                    enc_pkt->duration = av_rescale_q(enc_pkt->duration,
                                                     in_stream->time_base,
                                                     vStream->time_base);

                    //写入文件
                    av_interleaved_write_frame(oc, enc_pkt);
                    cout << "encode 1 video frame ok" << endl;
                    av_packet_unref(enc_pkt);
                }
            }
            else if(dec_pkt->stream_index == aIndex)
            {
                //解码
                ret = avcodec_send_packet(aDec, dec_pkt);
                if(ret < 0)
                {
                    cout << "ret = " << ret << endl;
                    return -1;
                }
                ret = avcodec_receive_frame(aDec, frame);
                if(ret < 0)
                {
                    cout << "ret = " << ret << endl;
                    return -1;
                }
                //解码结束

                cout << "decode 1 audio frame ok" << endl;
                AVAudioFifo *fifo = av_audio_fifo_alloc(aEnc->sample_fmt, aEnc->channels,
                                                        aEnc->frame_size);
                int finishFlag = 0;
                while(av_audio_fifo_size(fifo) < aEnc->frame_size)
                {
                    uint8_t ** audioBuffer = NULL;
                    av_samples_alloc_array_and_samples(&audioBuffer, NULL,
                                                       aEnc->channels, frame->nb_samples,
                                                       aEnc->sample_fmt, 1);
                    swr_convert(enc_swr, audioBuffer, frame->nb_samples,
                                (const uint8_t**)frame->data, frame->nb_samples);
                    av_audio_fifo_realloc(fifo, av_audio_fifo_size(fifo) + frame->nb_samples);
                    av_audio_fifo_write(fifo, (void**)audioBuffer, frame->nb_samples);
                    if(audioBuffer)
                    {
                        av_free(audioBuffer[0]);
                        av_free(audioBuffer);
                    }
                    else
                    {
                        finishFlag = 1;
                        break;
                    }
                }
                while(av_audio_fifo_size(fifo) >= aEnc->frame_size ||
                      (finishFlag == 1 && av_audio_fifo_size(fifo) > 0))
                {
                    int size = FFMIN(av_audio_fifo_size(fifo), aEnc->frame_size);
                    pcm->nb_samples = size;
                    pcm->channel_layout = aEnc->channel_layout;
                    pcm->sample_rate = aEnc->sample_rate;
                    pcm->format = aEnc->sample_fmt;
                    av_frame_get_buffer(pcm, 0);
                    av_audio_fifo_read(fifo, (void**)pcm->data, pcm->nb_samples);
                }
                if(finishFlag == 1 && av_audio_fifo_size(fifo) == 0)
                    av_audio_fifo_free(fifo);

                //编码
                ret = avcodec_send_frame(aEnc, pcm);
                if(ret < 0)
                {

                    cout << "ret = " << ret << endl;
                    return -1;
                }
           		while(!ret)
            	{
                	ret = avcodec_receive_packet(aEnc, enc_pkt);
                	if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                    	break;
                	else if(ret < 0)
               		{
                    	cout << "ret = " << ret << endl;
                    	return -1;
                	}

                	//pts,dts设置
                	enc_pkt->stream_index = aStream->index;

                	AVStream *in_stream = ic->streams[aIndex];
                	AVRational time_base1 = in_stream->time_base;
                	AVRational time_base_q = { 1, AV_TIME_BASE };
                	double frame_size = in_stream->codecpar->frame_size;
                	double sample_rate = in_stream->codecpar->sample_rate;

                	int64_t calc_duration=(double)(AV_TIME_BASE) * (frame_size/sample_rate);
                	enc_pkt->pts = av_rescale_q(dec_pkt->pts * calc_duration,
                                       		time_base_q,
                                       		time_base1);
                	enc_pkt->dts = enc_pkt->pts;
               		enc_pkt->duration = av_rescale_q(calc_duration,
                                           		time_base_q,
                                            	time_base1);
                	enc_pkt->pos = -1;

                enc_pkt->pts = av_rescale_q_rnd(enc_pkt->pts,
                                                in_stream->time_base,
                                                aStream->time_base,
                                                (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

                	enc_pkt->dts = av_rescale_q_rnd(enc_pkt->dts,
                                                	in_stream->time_base,
                                                	aStream->time_base,
                                               		(enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

                	enc_pkt->duration = av_rescale_q(enc_pkt->duration,
                                                	in_stream->time_base,
                                                 	aStream->time_base);

                	//写入文件
                	av_interleaved_write_frame(oc, enc_pkt);
                	cout << "encode 1 audio frame ok" << endl;
                	av_packet_unref(enc_pkt);
            	}
        	}
        	av_packet_unref(dec_pkt);
    	}
    	else
	        break;
	}

	while(1)
	{
    	frameIndex++;
    	ret = avcodec_send_frame(aEnc, NULL);
    	if(ret < 0)
    	{
    	    cout << "ret = " << ret << endl;
    	    break;
    	}
    	while(!ret)
    	{
        	ret = avcodec_receive_packet(aEnc, enc_pkt);
        	if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
        	    break;
        	else if(ret < 0)
        	{
            	cout << "ret = " << ret << endl;
            	return -1;
        	}

        	//pts,dts设置
        	enc_pkt->stream_index = aStream->index;

        	AVStream *in_stream = ic->streams[aIndex];
        	AVRational time_base1 = in_stream->time_base;
        	AVRational time_base_q = { 1, AV_TIME_BASE };
        	double frame_size = in_stream->codecpar->frame_size;
        	double sample_rate = in_stream->codecpar->sample_rate;

        	int64_t calc_duration=(double)(AV_TIME_BASE) * (frame_size/sample_rate);
        	enc_pkt->pts = av_rescale_q(frameIndex * calc_duration,
        	                       time_base_q,
        	                       time_base1);
        	enc_pkt->dts = enc_pkt->pts;
        	enc_pkt->duration = av_rescale_q(calc_duration,
                	                    time_base_q,
            	                        time_base1);
        	enc_pkt->pos = -1;

         	enc_pkt->pts = av_rescale_q_rnd(enc_pkt->pts,
                                         	in_stream->time_base,
	                                     	aStream->time_base,
                                            (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

        	enc_pkt->dts = av_rescale_q_rnd(enc_pkt->dts,
                	                        in_stream->time_base,
            	                            aStream->time_base,
        	                                (enum AVRounding)(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

        	enc_pkt->duration = av_rescale_q(enc_pkt->duration,
        	                                 in_stream->time_base,
        	                                 aStream->time_base);

        	//写入文件
        	av_interleaved_write_frame(oc, enc_pkt);
         	cout << "finish encode 1 audio frame ok" << endl;
         	av_packet_unref(enc_pkt);
    	}
	}

	av_write_trailer(oc);

	av_frame_free(&frame);
	av_frame_free(&yuv);
	av_frame_free(&pcm);

	avcodec_free_context(&vDec);
	avcodec_free_context(&vEnc);
	avcodec_free_context(&aDec);
	avcodec_free_context(&aEnc);

	sws_freeContext(enc_sws);
	swr_free(&enc_swr);

	avformat_close_input(&ic);
	avio_close(oc->pb);
	avformat_free_context(oc);

	cout << "Hello World!" << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Mr__Hu/article/details/93471835