Mercurial > projects > hoofbaby
annotate src/test/hoofbaby/test/adhoc/transcode.d @ 6:270343d824ae
The test program now uses the Encoder class.
author | fraserofthenight |
---|---|
date | Thu, 09 Jul 2009 20:28:13 -0700 |
parents | e6cf9f26d0e7 |
children | 9fdfe4a64a13 |
rev | line source |
---|---|
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
1 /** |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
2 * Hoofbaby -- http://www.dsource.org/projects/hoofbaby |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
3 * Copyright (C) 2009 Robert Fraser |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
4 * |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
5 * This program is free software; you can redistribute it andor |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
6 * modify it under the terms of the GNU General Public License |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
7 * as published by the Free Software Foundation; either version 2 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
8 * of the License, or (at your option) any later version. |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
9 * |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
10 * This program is distributed in the hope that it will be useful, |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
13 * GNU General Public License for more details. |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
14 */ |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
15 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
16 module hoofbaby.test.adhoc.transcode; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
17 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
18 import NONE_1 = tango.stdc.stdarg; // Must be linked in to prevent strange linker errors |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
19 debug import NONE_2 = tango.core.stacktrace.TraceExceptions; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
20 import NONE_3 = hoofbaby.codec.libav.mingw; |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
21 import hoofbaby.app.libs; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
22 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
23 import Math = tango.math.Math; |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
24 import hoofbaby.codec.encoder; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
25 import hoofbaby.codec.libav.avutil; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
26 import hoofbaby.codec.libav.avcodec; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
27 import hoofbaby.codec.libav.avformat; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
28 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
29 private const int STREAM_FRAME_RATE = 25; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
30 private const double STREAM_DURATION = 5.0; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
31 private const int STREAM_NB_FRAMES = (cast(int) (STREAM_DURATION * STREAM_FRAME_RATE)); |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
32 private const int WIDTH = 352; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
33 private const int HEIGHT = 288; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
34 private const int SAMPLE_RATE = 44100; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
35 private int AUDIO_FRAME_SIZE; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
36 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
37 private int frameCount = 0; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
38 private double audioCount = 0.0; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
39 private double audioIncr = 2 * Math.PI * 110.0 / SAMPLE_RATE; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
40 private double audioIncr2 = 2 * Math.PI * 110.0 / SAMPLE_RATE / SAMPLE_RATE; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
41 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
42 private AVFrame* allocFrame(int pix_fmt, int width, int height) |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
43 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
44 AVFrame* picture; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
45 char* buf; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
46 int size; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
47 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
48 picture = avcodec_alloc_frame(); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
49 if(!picture) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
50 return null; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
51 size = avpicture_get_size(pix_fmt, width, height); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
52 buf = cast(char*) av_malloc(size); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
53 if(!buf) |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
54 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
55 av_free(picture); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
56 return null; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
57 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
58 avpicture_fill(cast(AVPicture*) picture, buf, pix_fmt, width, height); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
59 return picture; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
60 } |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
61 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
62 private AVFrame* generatePicture(AVFrame* pict, int width, int height) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
63 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
64 int x, y, i; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
65 i = frameCount; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
66 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
67 /* Y */ |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
68 for(y = 0; y < height; y++) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
69 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
70 for(x = 0; x < width; x++) |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
71 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
72 pict.data[0][y * pict.linesize[0] + x] = x + y + i * 3; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
73 } |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
74 } |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
75 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
76 /* Cb and Cr */ |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
77 for(y = 0; y < height / 2; y++) |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
78 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
79 for(x = 0; x < width / 2; x++) |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
80 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
81 pict.data[1][y * pict.linesize[1] + x] = 128 + y + i * 2; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
82 pict.data[2][y * pict.linesize[2] + x] = 64 + x + i * 5; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
83 } |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
84 } |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
85 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
86 return pict; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
87 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
88 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
89 private short* generateAudio(short* samples) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
90 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
91 int j, i, v; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
92 short *q; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
93 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
94 q = samples; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
95 for(j = 0; j < AUDIO_FRAME_SIZE; j++) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
96 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
97 v = cast(int)(Math.sin(audioCount) * 10000); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
98 for(i = 0; i < 2; i++) // 2 is number of channels |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
99 *q++ = v; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
100 audioCount += audioIncr; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
101 audioIncr += audioIncr2; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
102 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
103 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
104 return samples; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
105 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
106 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
107 public int main(char[][] args) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
108 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
109 initLibs(); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
110 scope Encoder enc = new Encoder("biff_happy.wmv"); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
111 AUDIO_FRAME_SIZE = enc.audioContext.frame_size; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
112 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
113 // Allocate a video frame and audio buffer to store stuff |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
114 AVFrame* frame = allocFrame(PIX_FMT_YUV420P, WIDTH, HEIGHT); |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
115 assert(frame !is null, "Could not allocate frame"); |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
116 scope(exit) if(frame) av_free(frame); |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
117 short* samples = cast(short*) av_malloc(AUDIO_FRAME_SIZE * 2 * 2); // AUDIO_FRAME_SIZE * 2 * number of channels |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
118 assert(frame !is null, "Could not allocate samples"); |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
119 scope(exit) if(samples) av_free(samples); |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
120 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
121 // Write header |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
122 enc.writeHeader(); |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
123 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
124 while(true) |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
125 { |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
126 double audio_pts = cast(double) enc.audioStream.pts.val * enc.audioStream.time_base.num / enc.audioStream.time_base.den; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
127 double video_pts = cast(double) enc.videoStream.pts.val * enc.videoStream.time_base.num / enc.videoStream.time_base.den; |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
128 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
129 if(audio_pts >= STREAM_DURATION && video_pts >= STREAM_DURATION) |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
130 break; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
131 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
132 // Write interleaved audio & video |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
133 if(audio_pts < video_pts) |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
134 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
135 enc.writeAudioFrame(generateAudio(samples)); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
136 } |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
137 else |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
138 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
139 if(frameCount >= STREAM_NB_FRAMES) |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
140 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
141 // no more frame to compress. The codec has a latency of a few |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
142 // frames if using B frames, so we get the last frames by |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
143 // passing the same picture again |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
144 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
145 else |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
146 { |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
147 generatePicture(frame, WIDTH, HEIGHT); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
148 } |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
149 |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
150 enc.writeVideoFrame(frame); |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
151 frameCount++; |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
152 } |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
153 } |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
154 |
6
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
155 // Write trailer |
270343d824ae
The test program now uses the Encoder class.
fraserofthenight
parents:
3
diff
changeset
|
156 enc.writeTrailer(); |
3
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
157 |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
158 return 0; |
e6cf9f26d0e7
Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff
changeset
|
159 } |