diff options
| author | Comment <tim@gray.(none)> | 2013-03-21 22:05:38 +0000 |
|---|---|---|
| committer | Comment <tim@gray.(none)> | 2013-03-21 22:05:38 +0000 |
| commit | 49993e6f9c77bf4c610b53e3abc4ce5651c7700b (patch) | |
| tree | 1243bb08fbdb3f1c8b2c395727e190646c56ae96 /avcodec_audio_example3-c++11.c | |
| parent | d7b3e313c43420e5914349831fdd14486846e161 (diff) | |
wrestling with libavcodec
Diffstat (limited to 'avcodec_audio_example3-c++11.c')
| -rw-r--r-- | avcodec_audio_example3-c++11.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/avcodec_audio_example3-c++11.c b/avcodec_audio_example3-c++11.c new file mode 100644 index 0000000..ddb88db --- /dev/null +++ b/avcodec_audio_example3-c++11.c @@ -0,0 +1,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)); + } + } + */
\ No newline at end of file |
