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
|
#include "ffmpeg_decoder.h"
#include <iostream>
#include <cstring>
DecoderFFmpeg::DecoderFFmpeg(const std::string& filename) {
av_register_all();
lavf_ctx = NULL;
std::cerr << "Opening file: " << avformat_open_input(&lavf_ctx, filename.c_str(), 0, 0) << std::endl;
av_find_stream_info(lavf_ctx);
av_dump_format(lavf_ctx, 0, filename.c_str(), 0);
lavc_ctx = lavf_ctx->streams[0]->codec;
samplerate = lavc_ctx->sample_rate;
channels = lavc_ctx->channels;
codec = avcodec_find_decoder(lavc_ctx->codec_id);
std::cerr << "Opening decoder: " << avcodec_open(lavc_ctx, codec) << std::endl;
temp_buffer = NULL;
}
DecoderFFmpeg::~DecoderFFmpeg() {
avcodec_close(lavc_ctx);
av_close_input_file(lavf_ctx);
}
std::size_t DecoderFFmpeg::read(char* buf, std::size_t buf_size) {
if(temp_buffer) {
std::size_t buffer_size = std::min(temp_buffer_size - temp_buffer_pos, buf_size);
std::memcpy(buf, temp_buffer + temp_buffer_pos, buffer_size);
temp_buffer_pos += buffer_size;
if(temp_buffer_pos == temp_buffer_size) {
delete[] temp_buffer;
temp_buffer = NULL;
}
return buffer_size;
}
AVPacket packet;
if(av_read_frame(lavf_ctx, &packet) < 0)
return -1;
char local_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
std::size_t local_buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int len = avcodec_decode_audio3(lavc_ctx, (int16_t*)local_buf, (int*)&local_buf_size, &packet);
av_free_packet(&packet);
if(len < 0)
return -1;
if(local_buf_size > buf_size) {
std::memcpy(buf, local_buf, buf_size);
temp_buffer_size = local_buf_size - buf_size;
temp_buffer = new char[temp_buffer_size];
temp_buffer_pos = 0;
memcpy(temp_buffer, local_buf + buf_size, temp_buffer_size);
return buf_size;
} else {
std::memcpy(buf, local_buf, local_buf_size);
return local_buf_size;
}
}
|