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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }