transcoding of audio is now working, but without resampling
This commit is contained in:
parent
990527481d
commit
a9e042eb4f
@ -67,6 +67,13 @@ namespace ffcpp {
|
||||
return _codecCtx->frame_size;
|
||||
}
|
||||
|
||||
int Codec::channels() const {
|
||||
return _codecCtx->channels;
|
||||
}
|
||||
|
||||
int Codec::sampleRate() const {
|
||||
return _codecCtx->sample_rate;
|
||||
}
|
||||
|
||||
void Codec::setWidth(int width) {
|
||||
_codecCtx->width = width;
|
||||
@ -102,7 +109,10 @@ namespace ffcpp {
|
||||
if(res < 0) throw std::runtime_error("cannot decode packet");
|
||||
}
|
||||
|
||||
if(_codecCtx->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
frame.guessPts();
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,8 @@ namespace ffcpp {
|
||||
AVPixelFormat pixelFormat() const;
|
||||
AVSampleFormat sampleFormat() const;
|
||||
int frameSize() const;
|
||||
int channels() const;
|
||||
int sampleRate() const;
|
||||
|
||||
void setWidth(int width);
|
||||
void setHeight(int height);
|
||||
|
||||
@ -55,4 +55,8 @@ namespace ffcpp {
|
||||
return _frame->nb_samples;
|
||||
}
|
||||
|
||||
void Frame::setPts(int pts) {
|
||||
_frame->pts = pts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ namespace ffcpp {
|
||||
void guessPts();
|
||||
void setPictureType(AVPictureType type);
|
||||
int samplesCount() const;
|
||||
void setPts(int pts);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ namespace ffcpp {
|
||||
return _streams.back();
|
||||
}
|
||||
|
||||
Stream& MediaFile::addAudioStream(AVCodecID codecID) {
|
||||
Stream& MediaFile::addAudioStream(AVCodecID codecID, int channels, int sampleRate) {
|
||||
AVCodec* codec = avcodec_find_encoder(codecID);
|
||||
if(!codec) throw std::runtime_error("cannot find codec");
|
||||
|
||||
@ -119,9 +119,9 @@ namespace ffcpp {
|
||||
AVCodecContext* ctx = stream->codec;
|
||||
ctx->sample_fmt = codec->sample_fmts[0];
|
||||
ctx->global_quality = 10;
|
||||
ctx->channels = 6;
|
||||
ctx->channel_layout = (uint64_t)av_get_default_channel_layout(ctx->channels);
|
||||
ctx->sample_rate = 48000;
|
||||
ctx->channels = channels;
|
||||
ctx->channel_layout = (uint64_t)av_get_default_channel_layout(channels);
|
||||
ctx->sample_rate = sampleRate;
|
||||
|
||||
_streams.emplace_back(stream, codec);
|
||||
return _streams.back();
|
||||
|
||||
@ -34,7 +34,7 @@ namespace ffcpp {
|
||||
Stream& videoStream(size_t index = 0);
|
||||
Stream& audioStream(size_t index = 0);
|
||||
Stream& addVideoStream(AVCodecID codecID, int width, int height, AVPixelFormat pixelFormat);
|
||||
Stream& addAudioStream(AVCodecID codecID);
|
||||
Stream& addAudioStream(AVCodecID codecID, int channels, int sampleRate);
|
||||
Packet readPacket();
|
||||
AVMediaType packetType(const Packet& packet);
|
||||
|
||||
|
||||
23
main.cpp
23
main.cpp
@ -5,7 +5,6 @@
|
||||
|
||||
constexpr int VIDEO_STREAM_INDEX = 0;
|
||||
constexpr int AUDIO_STREAM_INDEX = 1;
|
||||
constexpr int AUDIO_CHANNELS_COUNT = 6;
|
||||
|
||||
namespace ff = ffcpp;
|
||||
|
||||
@ -33,16 +32,23 @@ int main(int argc, char** argv) {
|
||||
ff::Codec& vDecoder = vStream.codec();
|
||||
ff::Codec& aDecoder = aStream.codec();
|
||||
|
||||
ff::Stream& outVStream = output.addVideoStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(),
|
||||
AV_PIX_FMT_YUV420P);
|
||||
outVStream.setTimeBase(vDecoder.timeBase());
|
||||
ff::Stream& outVStream = output.addVideoStream(AV_CODEC_ID_H264, vDecoder.width(), vDecoder.height(), AV_PIX_FMT_YUV420P);
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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()) {
|
||||
AVMediaType packetType = input.packetType(packet);
|
||||
if(packetType == AVMEDIA_TYPE_AUDIO) {
|
||||
@ -53,10 +59,12 @@ int main(int argc, char** argv) {
|
||||
while(fifo.enoughSamples()) {
|
||||
auto frame = aEncoder.createAudioFrame();
|
||||
fifo.readFrame(frame);
|
||||
frame.setPts(aPts);
|
||||
aPts += frame.samplesCount();
|
||||
auto encPacket = aEncoder.encode(frame);
|
||||
if(!encPacket) continue;
|
||||
encPacket.setStreamIndex(AUDIO_STREAM_INDEX);
|
||||
encPacket.rescaleTimestamps(vStream.timeBase(), outVStream.timeBase());
|
||||
encPacket.rescaleTimestamps(aDecoder.timeBase(), outAStream.timeBase());
|
||||
output.writePacket(encPacket);
|
||||
}
|
||||
} 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, aEncoder, aStream, outAStream, AUDIO_STREAM_INDEX);
|
||||
output.writeTrailer();
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user