#include <QtCore/QCoreApplication>
#include <QtMultimedia/QAudioFormat>
#include <QtMultimedia/QAudioOutput>
#include <QtCore/QFile>
#include <iostream>
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
#include "libavfilter/avfilter.h"
#include "libavutil/avutil.h"
#ifdef __cplusplus
};
#endif // __cplusplus
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avfilter.lib")
#pragma comment(lib, "swscale.lib")
#pragma comment(lib, "swresample.lib")
#define MAX_AUDIO_FRAME_SIZE (19200)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QAudioFormat audioFormat;
audioFormat.setSampleRate(44100);
audioFormat.setChannelCount(2);
audioFormat.setSampleSize(16);
audioFormat.setCodec("audio/pcm");
audioFormat.setByteOrder(QAudioFormat::LittleEndian);
audioFormat.setSampleType(QAudioFormat::UnSignedInt);
QAudioOutput* audio = new QAudioOutput(audioFormat);
QIODevice* io = audio->start();
int size = audio->periodSize();
if (size <= 0)
{
return -1;
}
int ret = -1;
std::string strUrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
strUrl = "rtsp://192.168.13.100:8554/sht.mp3";
AVDictionary *opts = NULL;
av_dict_set(&opts, "buffer_size", "1024000", 0);
av_dict_set(&opts, "max_delay", "50000", 0);
av_dict_set(&opts, "stimeout", "200000000", 0);
av_dict_set(&opts, "rtsp_transport", "tcp", 0);
AVFormatContext* ifmtCtx = NULL;
int out_buffer_size;
AVFrame* pFrame_Resample = av_frame_alloc();
AVFrame* frame = av_frame_alloc();
AVCodecContext* pACodecCtx = NULL;
struct SwrContext *pSwrCtx = NULL;
do
{
if (ret = avformat_open_input(&ifmtCtx, strUrl.c_str(), 0, &opts) < 0)
{
av_log(NULL, AV_LOG_ERROR, "Could not open input stream file '%s'\n", strUrl.c_str());
break;
}
ret = avformat_find_stream_info(ifmtCtx, NULL);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "avformat_find_stream_info fail!\n");
break;
}
int nAStreamIndex = -1;
nAStreamIndex = av_find_best_stream(ifmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
av_dump_format(ifmtCtx, 0 ,strUrl.c_str(), 0);
pACodecCtx = ifmtCtx->streams[nAStreamIndex]->codec;
AVCodec* pCodec = avcodec_find_decoder(pACodecCtx->codec_id);
if (avcodec_open2(pACodecCtx, pCodec, NULL) < 0)
{
av_log(NULL, AV_LOG_ERROR, "Error open codec!\n");
break;
}
uint8_t* out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE);
uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;
enum AVSampleFormat in_sample_fmt = pACodecCtx->sample_fmt;
int in_sample_rate = pACodecCtx->sample_rate;
int out_sample_rate = 44100;
int in_channels = pACodecCtx->channels;
int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);
int in_channel_layout = av_get_default_channel_layout(pACodecCtx->channels);
pSwrCtx = swr_alloc();
pSwrCtx = swr_alloc_set_opts(NULL, out_channel_layout, out_sample_fmt, out_sample_rate,
in_channel_layout, in_sample_fmt, in_sample_rate, 0, NULL);
ret = swr_init(pSwrCtx);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "swr init fail!\n");
break;
}
AVPacket pkt;
av_init_packet(&pkt);
//AVRational rt = { 1, in_sample_rate };
while (1)
{
ret = av_read_frame(ifmtCtx, &pkt);
if (ret < 0)
{
break;
}
if (pkt.stream_index != nAStreamIndex)
{
av_packet_unref(&pkt);
continue;
}
ret = avcodec_send_packet(pACodecCtx, &pkt);
if (ret < 0)
{
av_packet_unref(&pkt);
av_log(NULL, AV_LOG_ERROR, "Error sending a packet!\n");
}
else
{
while (ret >= 0)
{
ret = avcodec_receive_frame(pACodecCtx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
ret = -1;
break;
}
else if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Error dufing decoding!\n");
ret = -1;
break;
}
if (pFrame_Resample->nb_samples != frame->nb_samples)
{
pFrame_Resample->pts = frame->pts;
//double second = frame->pts * av_q2d(rt);
pFrame_Resample->nb_samples = av_rescale_rnd(swr_get_delay(pSwrCtx, out_sample_rate) + frame->nb_samples,
out_sample_rate, in_sample_rate, AV_ROUND_UP);
av_samples_fill_arrays(pFrame_Resample->data, pFrame_Resample->linesize, out_buffer, out_channels,
pFrame_Resample->nb_samples, out_sample_fmt, 0);
}
int len = swr_convert(pSwrCtx, pFrame_Resample->data, pFrame_Resample->nb_samples, (const uint8_t**)frame->data, frame->nb_samples);
out_buffer_size = len * out_channels * av_get_bytes_per_sample(out_sample_fmt);
char *buf = (char *)out_buffer;
int len2 = out_buffer_size;
while (1)
{
if (len2 <= 0)
{
break;
}
if (len2 <= size)
{
io->write(buf, len2);
len2 -= len2;
}
else
{
io->write(buf, size);
len2 -= size;
buf += size;
}
}
}
}
av_packet_unref(&pkt);
}
av_frame_free(&frame);
} while (0);
if (pACodecCtx != NULL)
{
avcodec_close(pACodecCtx);
}
if (ifmtCtx != NULL)
{
avformat_close_input(&ifmtCtx);
}
if (pFrame_Resample != NULL)
{
av_frame_free(&pFrame_Resample);
}
if (pSwrCtx != NULL)
{
swr_free(&pSwrCtx);
}
return a.exec();
}