av_register_all(); std::shared_ptr 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 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: "<channels<<", sample format: "<sample_fmt<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(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)); } } */