1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
av_register_all();
std::shared_ptr<AVFormatContext> avFormat(avformat_alloc_context(), &avformat_free_context);
auto avFormatPtr = avFormat.get();
if (avformat_open_input(&avFormatPtr,filename.c_str(),nullptr, nullptr) != 0) {
cerr <<"Rotor: Error while calling avformat_open_input (probably invalid file format)" << endl;
return false;
}
if (avformat_find_stream_info(avFormat.get(), nullptr) < 0) {
cerr << "Rotor: Error while calling avformat_find_stream_info" << endl;
return false;
}
av_dump_format(avFormat.get(), 0, 0, false); //avformat.h line 1256
AVStream* stream = nullptr;
for (unsigned int i = 0; i < avFormat->nb_streams; ++i) {
if (avFormat->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
// we've found a video stream!
stream = avFormat->streams[i];
break;
}
}
if (!stream) {
cerr <<"Rotor: Didn't find any audio stream in the file"<< endl;
return false;
}
// getting the required codec structure
const auto codec = avcodec_find_decoder(stream->codec->codec_id); //returns AVCodec*
if (codec == nullptr) {
cerr <<"Rotor: Audio codec not available"<< endl;
return false;
}
//AVCodecContext?? avFormat->streams[i]->codec
// allocating a structure
std::shared_ptr<AVCodecContext> audioCodec(avcodec_alloc_context3(codec), [](AVCodecContext* c) { avcodec_close(c); av_free(c); });
/* extradata???
// we need to make a copy of videoStream->codec->extradata and give it to the context
// make sure that this vector exists as long as the avVideoCodec exists
std::vector codecContextExtraData(stream->codec->extradata, stream->codec->extradata + stream->codec->extradata_size);
audioCodec->extradata = reinterpret_cast(codecContextExtraData.data());
audioCodec->extradata_size = codecContextExtraData.size();
// initializing the structure by opening the codec
if (avcodec_open2(avVideoCodec.get(), codec, nullptr) < 0) {
cerr <<"Rotor: Could not open codec"<< endl;
return false;
}
*/
//avcodec.h line 1026
Packet packet(avFormat.get());
if (packet.packet.data == nullptr) {
//done
return true;
}
cerr << "audio codec context - sample rate: "<< audioCodec->sample_rate <<", channels: "<<audioCodec->channels<<", sample format: "<<audioCodec->sample_fmt<<endl;
do {
packet.reset(avFormat.get());
if (packet.packet.stream_index != stream->index)
continue; // the packet is not about the video stream we want, let's jump again the start of the loop
} while(0);
// allocating an AVFrame
std::shared_ptr<AVFrame> avFrame(avcodec_alloc_frame(), &av_free);
// the current packet of data
//Packet packet;
// data in the packet of data already processed
size_t offsetInData = 0;
/*
// the decoding loop, running until EOF
while (true) {
// reading a packet using libavformat
if (offsetInData >= packet.packet.size) {
do {
packet.reset(avFormat.get());
if (packet.stream_index != videoStream->index)
continue;
} while(0);
}
// preparing the packet that we will send to libavcodec
AVPacket packetToSend;
packetToSend.data = packet.packet.data + offsetInData;
packetToSend.size = packet.packet.size - offsetInData;
// sending data to libavcodec
int isFrameAvailable = 0;
const auto processedLength = avcodec_decode_video2(avVideoCodec.get(), avFrame.get(), &isFrameAvailable, &packetToSend);
if (processedLength < 0) {
av_free_packet(&packet);
throw std::runtime_error("Error while processing the data");
}
offsetInData += processedLength;
// processing the image if available
if (isFrameAvailable) {
// display image on the screen
// sleeping until next frame
const auto msToWait = avVideoContext->ticks_per_frame * 1000 * avVideoContext->time_base.num / avVideoContext->time_base.den;
std::this_thread::sleep(std::chrono::milliseconds(msToWait));
}
}
*/
|