Skip to content

Commit cfb0fb3

Browse files
committed
added audio info, fixed bug related to stream id's in the demuxer
1 parent bd6c091 commit cfb0fb3

File tree

9 files changed

+105
-10
lines changed

9 files changed

+105
-10
lines changed

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/AudioInputStream.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "AudioInputStream.h"
2+
#include "FFmpegException.h"
3+
#include "CodecDeducer.h"
24

35
namespace ffmpegcpp
46
{
@@ -23,7 +25,44 @@ namespace ffmpegcpp
2325

2426
void AudioInputStream::AddStreamInfo(ContainerInfo* containerInfo)
2527
{
26-
// TODO
28+
AudioStreamInfo info;
29+
30+
info.id = stream->id; // the layout of the id's depends on the container format - it doesn't always start from 0 or 1!
31+
32+
AVRational tb = stream->time_base;
33+
34+
StreamData* metaData = new StreamData();
35+
info.timeBase = tb;
36+
37+
AVCodecContext* codecContext = avcodec_alloc_context3(NULL);
38+
if (!codecContext) throw new FFmpegException("Failed to allocate temporary codec context.");
39+
int ret = avcodec_parameters_to_context(codecContext, stream->codecpar);
40+
if (ret < 0)
41+
{
42+
avcodec_free_context(&codecContext);
43+
throw new FFmpegException("Failed to read parameters from stream");
44+
}
45+
46+
codecContext->properties = stream->codec->properties;
47+
codecContext->codec = stream->codec->codec;
48+
codecContext->qmin = stream->codec->qmin;
49+
codecContext->qmax = stream->codec->qmax;
50+
codecContext->coded_width = stream->codec->coded_width;
51+
codecContext->coded_height = stream->codec->coded_height;
52+
53+
info.bitRate = CalculateBitRate(codecContext);
54+
55+
AVCodec* codec = CodecDeducer::DeduceDecoder(codecContext->codec_id);
56+
info.codec = codec;
57+
58+
info.sampleRate = codecContext->sample_rate;
59+
info.channels = codecContext->channels;
60+
info.channelLayout = codecContext->channel_layout;
61+
av_get_channel_layout_string(info.channelLayoutName, 255, codecContext->channels, codecContext->channel_layout);
62+
63+
avcodec_free_context(&codecContext);
64+
65+
containerInfo->audioStreams.push_back(info);
2766
}
2867
}
2968

source/ffmpeg-cpp/ffmpeg-cpp/Demuxing/VideoInputStream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace ffmpegcpp
2222
{
2323
VideoStreamInfo info;
2424

25-
info.id = stream->id - 1; // starts counting from 1!
25+
info.id = stream->id; // the layout of the id's depends on the container format - it doesn't always start from 0 or 1!
2626

2727
AVRational overrideFrameRate;
2828
overrideFrameRate.num = 0;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include "ffmpeg.h"
4+
5+
namespace ffmpegcpp
6+
{
7+
struct AudioStreamInfo
8+
{
9+
int id;
10+
AVRational timeBase;
11+
const AVCodec* codec;
12+
float bitRate;
13+
14+
int sampleRate;
15+
int channels;
16+
17+
uint64_t channelLayout;
18+
char channelLayoutName[255];
19+
20+
};
21+
}

source/ffmpeg-cpp/ffmpeg-cpp/Info/ContainerInfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "ffmpeg.h"
44
#include "VideoStreamInfo.h"
5+
#include "AudioStreamInfo.h"
56
#include "std.h"
67

78
namespace ffmpegcpp
@@ -15,7 +16,7 @@ namespace ffmpegcpp
1516
const AVInputFormat* format;
1617

1718
std::vector<VideoStreamInfo> videoStreams;
18-
// TODO: audio streams!
19+
std::vector<AudioStreamInfo> audioStreams;
1920
};
2021

2122

source/ffmpeg-cpp/ffmpeg-cpp/Sources/Demuxer.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ namespace ffmpegcpp
184184

185185
// The stream doesn't exist but we already processed all our frames, so it makes no sense
186186
// to add it anymore.
187-
if (IsDone()) throw new FFmpegException("Demuxer already fully processed... you cannot use it anymore.");
187+
if (IsDone()) return nullptr;
188188

189189
AVStream* stream = containerContext->streams[streamIndex];
190190
AVCodec* codec = CodecDeducer::DeduceDecoder(stream->codecpar->codec_id);
@@ -203,6 +203,19 @@ namespace ffmpegcpp
203203
return inputStreams[streamIndex];
204204
}
205205

206+
InputStream* Demuxer::GetInputStreamById(int streamId)
207+
{
208+
// map the stream id to an index by going over all the streams and comparing the id
209+
for (int i = 0; i < containerContext->nb_streams; ++i)
210+
{
211+
AVStream* stream = containerContext->streams[i];
212+
if (stream->id == streamId) return GetInputStream(i);
213+
}
214+
215+
// no match found
216+
return nullptr;
217+
}
218+
206219
void Demuxer::PreparePipeline()
207220
{
208221
bool allPrimed = false;
@@ -323,6 +336,6 @@ namespace ffmpegcpp
323336
}
324337

325338
// Return the right stream's frame count.
326-
return GetInputStream(streamId)->GetFramesProcessed();
339+
return GetInputStreamById(streamId)->GetFramesProcessed();
327340
}
328341
}

source/ffmpeg-cpp/ffmpeg-cpp/Sources/Demuxer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ namespace ffmpegcpp
3838

3939
const char* fileName;
4040

41-
InputStream* GetInputStream(int streamId);
41+
InputStream* GetInputStream(int index);
42+
InputStream* GetInputStreamById(int streamId);
4243

4344
//std::vector<StreamInfo> GetStreamInfo(AVMediaType mediaType);
4445
//StreamInfo CreateInfo(int streamIndex, AVStream* stream, AVCodec* codec);

source/ffmpeg-cpp/ffmpeg-cpp/ffmpeg-cpp.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
<ClInclude Include="Frame Sinks\FrameWriter.h" />
199199
<ClInclude Include="Frame Sinks\OneInputFrameSink.h" />
200200
<ClInclude Include="FrameContainer.h" />
201+
<ClInclude Include="Info\AudioStreamInfo.h" />
201202
<ClInclude Include="Info\ContainerInfo.h" />
202203
<ClInclude Include="Info\VideoStreamInfo.h" />
203204
<ClInclude Include="Sources\EncodedFileSource.h" />

source/ffmpeg-cpp/ffmpeg-cpp/ffmpeg-cpp.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@
153153
<ClInclude Include="Frame Sinks\AudioFilter.h">
154154
<Filter>Header Files</Filter>
155155
</ClInclude>
156+
<ClInclude Include="Info\AudioStreamInfo.h">
157+
<Filter>Header Files</Filter>
158+
</ClInclude>
156159
</ItemGroup>
157160
<ItemGroup>
158161
<ClCompile Include="FFmpegException.cpp">

source/ffmpeg-cpp/print_info/print_info.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ using namespace ffmpegcpp;
99
int main()
1010
{
1111
// This example will print info about a video.
12-
/*try
13-
{*/
12+
try
13+
{
1414

1515
// Load a video from a container and read its info.
1616
const char* fileName = "samples/big_buck_bunny.mp4";
@@ -19,6 +19,7 @@ int main()
1919

2020
// Print the data similar to ffmpeg.exe.
2121
cout << "Input " << info.format->name << " from '" << fileName << "'" << endl;
22+
2223
cout << "Video streams:" << endl;
2324
for (int i = 0; i < info.videoStreams.size(); ++i)
2425
{
@@ -34,15 +35,30 @@ int main()
3435
<< endl;
3536
}
3637

38+
cout << "Audio streams:" << endl;
39+
for (int i = 0; i < info.audioStreams.size(); ++i)
40+
{
41+
AudioStreamInfo stream = info.audioStreams[i];
42+
cout << "Stream #" << (i + 1)
43+
<< ": codec " << stream.codec->name
44+
<< ", channel layout " << stream.channelLayoutName
45+
<< ", channels " << stream.channels
46+
<< ", bit rate " << stream.bitRate << "kb/s"
47+
<< ", sample rate " << stream.sampleRate
48+
<< ", time base " << stream.timeBase.num << "/" << stream.timeBase.den
49+
<< ", " << demuxer->GetFrameCount(stream.id) << " frames"
50+
<< endl;
51+
}
52+
3753

3854

39-
/*}
55+
}
4056
catch (FFmpegException e)
4157
{
4258
cerr << "Exception caught!" << endl;
4359
cerr << e.what() << endl;
4460
throw e;
45-
}*/
61+
}
4662

4763
cout << "Encoding complete!" << endl;
4864
cout << "Press any key to continue..." << endl;

0 commit comments

Comments
 (0)