transcoding of audio is now working, but without resampling

This commit is contained in:
Selim Mustafaev 2016-10-30 01:30:53 +03:00
parent 990527481d
commit a9e042eb4f
7 changed files with 39 additions and 13 deletions

View File

@ -67,6 +67,13 @@ namespace ffcpp {
return _codecCtx->frame_size; return _codecCtx->frame_size;
} }
int Codec::channels() const {
return _codecCtx->channels;
}
int Codec::sampleRate() const {
return _codecCtx->sample_rate;
}
void Codec::setWidth(int width) { void Codec::setWidth(int width) {
_codecCtx->width = width; _codecCtx->width = width;
@ -102,7 +109,10 @@ namespace ffcpp {
if(res < 0) throw std::runtime_error("cannot decode packet"); if(res < 0) throw std::runtime_error("cannot decode packet");
} }
frame.guessPts(); if(_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO) {
frame.guessPts();
}
return frame; return frame;
} }

View File

@ -36,6 +36,8 @@ namespace ffcpp {
AVPixelFormat pixelFormat() const; AVPixelFormat pixelFormat() const;
AVSampleFormat sampleFormat() const; AVSampleFormat sampleFormat() const;
int frameSize() const; int frameSize() const;
int channels() const;
int sampleRate() const;
void setWidth(int width); void setWidth(int width);
void setHeight(int height); void setHeight(int height);

View File

@ -55,4 +55,8 @@ namespace ffcpp {
return _frame->nb_samples; return _frame->nb_samples;
} }
void Frame::setPts(int pts) {
_frame->pts = pts;
}
} }

View File

@ -24,6 +24,7 @@ namespace ffcpp {
void guessPts(); void guessPts();
void setPictureType(AVPictureType type); void setPictureType(AVPictureType type);
int samplesCount() const; int samplesCount() const;
void setPts(int pts);
}; };
} }

View File

@ -108,7 +108,7 @@ namespace ffcpp {
return _streams.back(); return _streams.back();
} }
Stream& MediaFile::addAudioStream(AVCodecID codecID) { Stream& MediaFile::addAudioStream(AVCodecID codecID, int channels, int sampleRate) {
AVCodec* codec = avcodec_find_encoder(codecID); AVCodec* codec = avcodec_find_encoder(codecID);
if(!codec) throw std::runtime_error("cannot find codec"); if(!codec) throw std::runtime_error("cannot find codec");
@ -119,9 +119,9 @@ namespace ffcpp {
AVCodecContext* ctx = stream->codec; AVCodecContext* ctx = stream->codec;
ctx->sample_fmt = codec->sample_fmts[0]; ctx->sample_fmt = codec->sample_fmts[0];
ctx->global_quality = 10; ctx->global_quality = 10;
ctx->channels = 6; ctx->channels = channels;
ctx->channel_layout = (uint64_t)av_get_default_channel_layout(ctx->channels); ctx->channel_layout = (uint64_t)av_get_default_channel_layout(channels);
ctx->sample_rate = 48000; ctx->sample_rate = sampleRate;
_streams.emplace_back(stream, codec); _streams.emplace_back(stream, codec);
return _streams.back(); return _streams.back();

View File

@ -34,7 +34,7 @@ namespace ffcpp {
Stream& videoStream(size_t index = 0); Stream& videoStream(size_t index = 0);
Stream& audioStream(size_t index = 0); Stream& audioStream(size_t index = 0);
Stream& addVideoStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat); Stream& addVideoStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat);
Stream& addAudioStream(AVCodecID codecID); Stream& addAudioStream(AVCodecID codecID, int channels, int sampleRate);
Packet readPacket(); Packet readPacket();
AVMediaType packetType(const Packet& packet); AVMediaType packetType(const Packet& packet);

View File

@ -5,7 +5,6 @@
constexpr int VIDEO_STREAM_INDEX = 0; constexpr int VIDEO_STREAM_INDEX = 0;
constexpr int AUDIO_STREAM_INDEX = 1; constexpr int AUDIO_STREAM_INDEX = 1;
constexpr int AUDIO_CHANNELS_COUNT = 6;
namespace ff = ffcpp; namespace ff = ffcpp;
@ -33,16 +32,23 @@ int main(int argc, char** argv) {
ff::Codec& vDecoder = vStream.codec(); ff::Codec& vDecoder = vStream.codec();
ff::Codec& aDecoder = aStream.codec(); ff::Codec& aDecoder = aStream.codec();
ff::Stream& outVStream = output.addVideoStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), ff::Stream& outVStream = output.addVideoStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P);
AV_PIX_FMT_YUV420P);
outVStream.setTimeBase(vDecoder.timeBase());
ff::Codec& vEncoder = outVStream.codec(); ff::Codec& vEncoder = outVStream.codec();
ff::Stream& outAStream = output.addAudioStream(AV_CODEC_ID_VORBIS);
ff::Stream& outAStream = output.addAudioStream(AV_CODEC_ID_VORBIS, aDecoder.channels(), aDecoder.sampleRate());
ff::Codec& aEncoder = outAStream.codec(); ff::Codec& aEncoder = outAStream.codec();
auto aEncTimeBase = aEncoder.timeBase();
if(aEncTimeBase.den/aEncTimeBase.num != aEncoder.sampleRate()) {
std::cout << "audio encoder time base is not based on sample rate" << std::endl;
std::cout << "exiting" << std::endl;
return 0;
}
output.writeHeader(); output.writeHeader();
ff::FifoQueue fifo(aEncoder.sampleFormat(), AUDIO_CHANNELS_COUNT, aEncoder.frameSize()); int64_t aPts = 0;
ff::FifoQueue fifo(aEncoder.sampleFormat(), aEncoder.channels(), aEncoder.frameSize());
while(auto packet = input.readPacket()) { while(auto packet = input.readPacket()) {
AVMediaType packetType = input.packetType(packet); AVMediaType packetType = input.packetType(packet);
if(packetType == AVMEDIA_TYPE_AUDIO) { if(packetType == AVMEDIA_TYPE_AUDIO) {
@ -53,10 +59,12 @@ int main(int argc, char** argv) {
while(fifo.enoughSamples()) { while(fifo.enoughSamples()) {
auto frame = aEncoder.createAudioFrame(); auto frame = aEncoder.createAudioFrame();
fifo.readFrame(frame); fifo.readFrame(frame);
frame.setPts(aPts);
aPts += frame.samplesCount();
auto encPacket = aEncoder.encode(frame); auto encPacket = aEncoder.encode(frame);
if(!encPacket) continue; if(!encPacket) continue;
encPacket.setStreamIndex(AUDIO_STREAM_INDEX); encPacket.setStreamIndex(AUDIO_STREAM_INDEX);
encPacket.rescaleTimestamps(vStream.timeBase(), outVStream.timeBase()); encPacket.rescaleTimestamps(aDecoder.timeBase(), outAStream.timeBase());
output.writePacket(encPacket); output.writePacket(encPacket);
} }
} else if(packetType == AVMEDIA_TYPE_VIDEO) { } else if(packetType == AVMEDIA_TYPE_VIDEO) {
@ -71,6 +79,7 @@ int main(int argc, char** argv) {
} }
flushEncoder(output, vEncoder, vStream, outVStream, VIDEO_STREAM_INDEX); flushEncoder(output, vEncoder, vStream, outVStream, VIDEO_STREAM_INDEX);
flushEncoder(output, aEncoder, aStream, outAStream, AUDIO_STREAM_INDEX);
output.writeTrailer(); output.writeTrailer();
return 0; return 0;