summaryrefslogtreecommitdiff
path: root/avcodec_audio_example3-c++11.c
blob: ddb88db9a5f746f1d4ea1301f8ad81b61630e7f3 (plain)
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));
		}
	}
	*/