forked from multimediamike/dreamroq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest-dreamroq.c
executable file
·161 lines (139 loc) · 4.42 KB
/
test-dreamroq.c
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* Dreamroq by Mike Melanson
*
* This is a simple, sample program that helps test the Dreamroq library.
*/
#include <stdio.h>
#include "dreamroqlib.h"
int quit_cb()
{
/* big, fat no-op for command line tool */
return 0;
}
void video_callback(unsigned short* buf, int width, int height, int stride, int texture_height)
{
static int count = 0;
FILE *out;
char filename[20];
int x, y;
unsigned int pixel;
unsigned short *buf_rgb565 = (unsigned short*)buf;
sprintf(filename, "extract/%04d.pnm", count);
printf("writing frame %d to file %s\n", count, filename);
count++;
out = fopen(filename, "wb");
if (!out)
return;
fprintf(out, "P6\n%d %d\n255\n", width, height);
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
pixel = *buf_rgb565++;
fputc(((pixel >> 11) << 3) & 0xFF, out); /* red */
fputc(((pixel >> 5) << 2) & 0xFF, out); /* green */
fputc(((pixel >> 0) << 3) & 0xFF, out); /* blue */
}
buf_rgb565 += (stride - width);
}
fclose(out);
}
#define AUDIO_FILENAME "extract/roq-audio.wav"
static char wav_header[] = {
'R', 'I', 'F', 'F', /* RIFF header */
0, 0, 0, 0, /* file size will be filled in later */
'W', 'A', 'V', 'E', /* more header stuff */
'f', 'm', 't', 0x20,
0x10, 0, 0, 0, /* length of format chunk */
1, 0, /* format = 1 (PCM) */
0, 0, /* channel count will be filled in later */
0x22, 0x56, 0, 0, /* frequency is always 0x5622 = 22050 Hz */
0, 0, 0, 0, /* byte rate will be filled in later */
1, 0, 0x10, 0, /* data alignment and bits per sample */
'd', 'a', 't', 'a', /* start of data chunk */
0, 0, 0, 0 /* data block size will be filled in later */
};
#define WAV_HEADER_SIZE 44
#define SAMPLE_RATE 22050
static FILE *wav_output;
static int data_size = 0;
static int audio_output_initialized = 0;
void audio_callback(unsigned char* buf_rgb565, int samples, int channels)
{
int byte_rate;
if (!audio_output_initialized)
{
wav_output = fopen(AUDIO_FILENAME, "wb");
if (!wav_output)
return;
/* fill in channels and data rate fields */
if (channels != 1 && channels != 2)
return;
wav_header[22] = channels;
byte_rate = SAMPLE_RATE * 2 * channels;
wav_header[0x1C] = (byte_rate >> 0) & 0xFF;
wav_header[0x1D] = (byte_rate >> 8) & 0xFF;
wav_header[0x1E] = (byte_rate >> 16) & 0xFF;
wav_header[0x1F] = (byte_rate >> 24) & 0xFF;
/* write the header */
if (fwrite(wav_header, WAV_HEADER_SIZE, 1, wav_output) != 1)
{
fclose(wav_output);
}
audio_output_initialized = 1;
}
/* dump the data and account for the amount */
if (fwrite(buf_rgb565, samples, 1, wav_output) != 1)
{
fclose(wav_output);
}
data_size += samples;
}
int finish_cb()
{
if (audio_output_initialized)
{
/* rewind and rewrite the header with the known parameters */
printf("Wrote %d (0x%X) bytes to %s\n", data_size, data_size,
AUDIO_FILENAME);
fseek(wav_output, 0, SEEK_SET);
wav_header[40] = (data_size >> 0) & 0xFF;
wav_header[41] = (data_size >> 8) & 0xFF;
wav_header[42] = (data_size >> 16) & 0xFF;
wav_header[43] = (data_size >> 24) & 0xFF;
data_size += WAV_HEADER_SIZE - 8;
wav_header[4] = (data_size >> 0) & 0xFF;
wav_header[5] = (data_size >> 8) & 0xFF;
wav_header[6] = (data_size >> 16) & 0xFF;
wav_header[7] = (data_size >> 24) & 0xFF;
if (fwrite(wav_header, WAV_HEADER_SIZE, 1, wav_output) != 1)
{
fclose(wav_output);
return ROQ_CLIENT_PROBLEM;
}
}
return ROQ_SUCCESS;
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("USAGE: test-dreamroq <file.roq>\n");
return 1;
}
roq_t *roq = roq_create_with_filename(argv[1]);
// Install the video & audio decode callbacks
roq_set_video_decode_callback(roq, video_callback);
roq_set_audio_decode_callback(roq, audio_callback);
// Decode
do {
if(quit_cb())
break;
// Decode
roq_decode(roq);
} while (!roq_has_ended(roq));
printf("DONE");
// All done
roq_destroy(roq);
return 0;
}