/************************************************************************
* Copyright(c) 2012 Yang Xian
* All rights reserved.
*
* File: AudioEncode.cpp
* Brief: 音频的编码
* Version: 1.0
* Author: Yang Xian
* Email: yang_xian521@163.com
* Date: 2012/06/28
* History:
************************************************************************/
#include <stdlib.h>
#include <stdio.h>
extern "C"
{
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
};
void main()
{
int16_t *samples;
uint8_t *audio_outbuf;
int audio_outbuf_size;
int audio_input_frame_size;
double audio_pts;
const char* filename = "test.wav";
FILE *fin = fopen("result.pcm", "rb"); //音频源文件
AVOutputFormat *fmt;
AVFormatContext *oc;
AVStream * audio_st;
av_register_all();
fmt = guess_format(NULL, filename, NULL);
oc = av_alloc_format_context();
oc->oformat = fmt;
snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
audio_st = NULL;
if (fmt->audio_codec != CODEC_ID_NONE)
{
AVCodecContext *c;
audio_st = av_new_stream(oc, 1);
c = audio_st->codec;
c->codec_id = fmt->audio_codec;
c->codec_type = CODEC_TYPE_AUDIO;
c->bit_rate = 128000;
c->sample_rate = 44100;
c->channels = 2;
}
if (av_set_parameters(oc, NULL) < 0)
{
return;
}
dump_format(oc, 0, filename, 1);
if (audio_st)
{
AVCodecContext* c;
AVCodec* codec;
c = audio_st->codec;
codec = avcodec_find_encoder(c->codec_id);
avcodec_open(c, codec);
audio_outbuf_size = 10000;
audio_outbuf = (uint8_t*)av_malloc(audio_outbuf_size);
if (c->frame_size <= 1)
{
audio_input_frame_size = audio_outbuf_size / c->channels;
switch (audio_st->codec->codec_id)
{
case CODEC_ID_PCM_S16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_U16BE:
audio_input_frame_size >>= 1;
break;
default:
break;
}
}
else
{
audio_input_frame_size = c->frame_size;
}
samples = (int16_t*)av_malloc(audio_input_frame_size*2*c->channels);
}
if (!fmt->flags & AVFMT_NOFILE)
{
if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
{
return;
}
}
av_write_header(oc);
for (;;)
{
if (audio_st)
{
audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
}
else
{
audio_pts = 0.0;
}
if (!audio_st || audio_pts >= 360.0)
{
break;
}
if (fread(samples, 1, audio_input_frame_size*2*audio_st->codec->channels, fin) <= 0)
{
break;
}
AVCodecContext* c;
AVPacket pkt;
av_init_packet(&pkt);
c = audio_st->codec;
pkt.size = avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_st->time_base);
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index = audio_st->index;
pkt.data = audio_outbuf;
if (av_write_frame(oc, &pkt) != 0)
{
return;
}
}
if (audio_st)
{
avcodec_close(audio_st->codec);
av_free(samples);
av_free(audio_outbuf);
}
av_write_trailer(oc);
for (int i=0; i<oc->nb_streams; i++)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
if (!(fmt->flags & AVFMT_NOFILE))
{
url_fclose(oc->pb);
}
av_free(oc);
fclose(fin);
}
评论0
最新资源