annotate ref/codec_adhoc.d @ 3:e6cf9f26d0e7

Added a separate "transcode" app for testing transcoding
author fraserofthenight
date Wed, 08 Jul 2009 07:29:48 -0700
parents
children
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 module hoofbaby.app.codec_adhoc;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
16
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
17 import hoofbaby.util.buffer;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
18 import tango.stdc.stdio;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
19 import tango.stdc.stringz;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
20 import Math = tango.math.Math;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
21 import tango.io.device.File;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
22 import tango.time.StopWatch;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
23
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
24 import hoofbaby.codec.libav.avutil;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
25 import hoofbaby.codec.libav.avcodec;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
26 import hoofbaby.codec.libav.avformat;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
27 import hoofbaby.codec.libav.avbuffer;
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));
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
32 private const int OUTBUF_SIZE = 100000;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
33
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
34 int codec_main()
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
35 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
36 StopWatch sw;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
37 int frameCount = 0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
38 double audioCount, audioIncr, audioIncr2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
39 char* voutbuf, aoutbuf;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
40 int res;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
41
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
42 AVFrame* allocFrame(int pix_fmt, int width, int height)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
43 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
44 AVFrame* picture;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
45 char* buf;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
46 int size;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
47
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
48 picture = avcodec_alloc_frame();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
49 if(!picture)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
50 return null;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
51 size = avpicture_get_size(pix_fmt, width, height);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
52 buf = cast(char*) av_malloc(size);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
53 if(!buf)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
54 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
55 av_free(picture);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
56 return null;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
57 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
58 avpicture_fill(cast(AVPicture*) picture, buf, pix_fmt, width, height);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
59 return picture;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
60 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
61
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
62 void generatePicture(AVFrame* pict, int width, int height)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
63 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
64 int x, y, i;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
65 i = frameCount;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
66
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
67 /* Y */
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
68 for(y = 0; y < height; y++)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
69 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
70 for(x = 0; x < width; x++)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
71 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
72 pict.data[0][y * pict.linesize[0] + x] = x + y + i * 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
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
76 /* Cb and Cr */
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
77 for(y = 0; y < height / 2; y++)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
78 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
79 for(x = 0; x < width / 2; x++)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
80 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
81 pict.data[1][y * pict.linesize[1] + x] = 128 + y + i * 2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
82 pict.data[2][y * pict.linesize[2] + x] = 64 + x + i * 5;
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 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
86
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
87 int writeVideoFrame(AVFormatContext* ctx, AVStream* stream, AVFrame* picture)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
88 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
89 AVCodecContext* vcodec = stream.codec;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
90 int ret = 0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
91
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
92 if(frameCount >= STREAM_NB_FRAMES)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
93 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
94 // no more frame to compress. The codec has a latency of a few
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
95 // frames if using B frames, so we get the last frames by
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
96 // passing the same picture again
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
97 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
98 else
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
99 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
100 generatePicture(picture, vcodec.width, vcodec.height);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
101 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
102
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
103 // Encode it!
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
104 int outSize = avcodec_encode_video(vcodec, voutbuf, OUTBUF_SIZE, picture);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
105 // if zero size, it means the image was buffered.. if not, write that ****!
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
106 if(outSize > 0)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
107 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
108 AVPacket pkt;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
109 av_init_packet(&pkt);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
110
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
111 pkt.pts = av_rescale_q(vcodec.coded_frame.pts, vcodec.time_base, stream.time_base);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
112 if(vcodec.coded_frame.key_frame)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
113 pkt.flags |= PKT_FLAG_KEY;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
114 pkt.stream_index = stream.index;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
115 pkt.data = voutbuf;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
116 pkt.size = outSize;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
117
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
118 // oh yeah!
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
119 ret = av_write_frame(ctx, &pkt);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
120 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
121 else
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
122 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
123 ret = 0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
124 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
125
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
126 frameCount++;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
127 assert(!ret, "Error writing video frame");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
128 return ret;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
129 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
130
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
131 int writeAudioFrame(AVFormatContext* ctx, AVStream* stream, short* samples)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
132 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
133 AVCodecContext* acodec = stream.codec;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
134
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
135 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
136 int j, i, v;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
137 short *q;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
138
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
139 q = samples;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
140 for(j = 0; j < acodec.frame_size; j++)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
141 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
142 v = cast(int)(Math.sin(audioCount) * 10000);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
143 for(i = 0; i < 2; i++) // 2 is number of channels
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
144 *q++ = v;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
145 audioCount += audioIncr;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
146 audioIncr += audioIncr2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
147 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
148 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
149
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
150 AVPacket pkt;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
151 av_init_packet(&pkt);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
152 pkt.size = avcodec_encode_audio(acodec, aoutbuf, OUTBUF_SIZE, samples);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
153 //pkt.pts = av_rescale_q(acodec.coded_frame.pts, acodec.time_base, acodec.time_base);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
154 pkt.flags |= PKT_FLAG_KEY;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
155 pkt.stream_index = stream.index;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
156 pkt.data = aoutbuf;
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 int res = av_write_frame(ctx, &pkt) != 0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
159 assert(res == 0, "Error writing audio frame");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
160 return res;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
161 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
162
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
163 //--------------------------------------------------------------------------
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
164 // Container format
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
165
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
166 sw.start();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
167
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
168 AVOutputFormat* fmt = guess_format("asf", null, null);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
169 assert(fmt !is null, "Could not find format");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
170
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
171 AVFormatContext* ctx = av_alloc_format_context();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
172 assert(ctx !is null, "Could not allocate format context");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
173 scope(exit) if(ctx) av_free(ctx);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
174 ctx.oformat = fmt;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
175 //ctx.preload = cast(int) (0.5 * AV_TIME_BASE);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
176 ctx.max_delay = cast(int) (0.7 * AV_TIME_BASE);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
177 ctx.loop_output = AVFMT_NOOUTPUTLOOP;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
178 ctx.flags |= AVFMT_FLAG_NONBLOCK;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
179
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
180 AVFormatParameters params;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
181 params.prealloced_context = 1;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
182 params.video_codec_id = CODEC_ID_WMV2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
183 params.audio_codec_id = CODEC_ID_WMAV2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
184 params.width = 352;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
185 params.height = 288;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
186 params.time_base.num = 1;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
187 params.time_base.den = STREAM_FRAME_RATE;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
188 params.pix_fmt = PIX_FMT_YUV420P;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
189 params.channels = 2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
190 params.sample_rate = 44100;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
191 res = av_set_parameters(ctx, null);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
192 assert(res >= 0, "Could not set parameters");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
193
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
194 //--------------------------------------------------------------------------
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
195 // Video stream
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
196
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
197 AVStream* vstream = av_new_stream(ctx, 0);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
198 assert(vstream !is null, "Could not allocate video stream");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
199 ctx.streams[0] = vstream;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
200
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
201 AVCodec* vcodecName = avcodec_find_encoder(CODEC_ID_WMV2);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
202 assert(vcodecName, "Could not find video codec");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
203 AVCodecContext* vcodec = vstream.codec;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
204 vcodec.codec_id = CODEC_ID_WMV2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
205 vcodec.codec_type = CODEC_TYPE_VIDEO;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
206 vcodec.bit_rate = 400000;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
207 vcodec.width = 352;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
208 vcodec.height = 288;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
209 vcodec.gop_size = 12;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
210 vcodec.qmin = 3;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
211 vcodec.time_base.den = STREAM_FRAME_RATE;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
212 vcodec.time_base.num = 1;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
213 vcodec.pix_fmt = PIX_FMT_YUV420P;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
214 vcodec.flags |= CODEC_FLAG_GLOBAL_HEADER;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
215 res = avcodec_open(vcodec, vcodecName);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
216 assert(res >= 0, "Could not open video codec");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
217
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
218 //--------------------------------------------------------------------------
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
219 // Audio stream
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
220
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
221 AVStream* astream = av_new_stream(ctx, 0);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
222 assert(astream !is null, "Could not allocate audio stream");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
223 ctx.streams[1] = astream;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
224
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
225 AVCodec* acodecName = avcodec_find_encoder(CODEC_ID_WMAV2);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
226 assert(acodecName, "Could not find audio codec");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
227 AVCodecContext* acodec = astream.codec;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
228 acodec.codec_id = CODEC_ID_WMAV2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
229 acodec.codec_type = CODEC_TYPE_AUDIO;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
230 acodec.bit_rate = 64000;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
231 acodec.sample_rate = 44100;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
232 acodec.channels = 2;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
233 acodec.flags |= CODEC_FLAG_GLOBAL_HEADER;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
234 audioCount = 0.0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
235 audioIncr = 2 * Math.PI * 110.0 / acodec.sample_rate;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
236 audioIncr2 = 2 * Math.PI * 110.0 / acodec.sample_rate / acodec.sample_rate;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
237 res = avcodec_open(acodec, acodecName);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
238 assert(res >= 0, "Could not open audio codec");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
239
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
240 //--------------------------------------------------------------------------
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
241 // Actually doing stuff
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
242
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
243 // Open output file
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
244 RingBuffer ringBuf = RingBuffer(1 << 24); // 16 MB
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
245 scope(exit) ringBuf.free();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
246 ctx.pb = getBioContext(&ringBuf, 1 << 24);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
247 assert(ctx.pb !is null);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
248 assert(ctx.pb.opaque !is null);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
249
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
250 // Allocate a video frame and audio buffer to store stuff
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
251 AVFrame* frame = allocFrame(PIX_FMT_YUV420P, vcodec.width, vcodec.height);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
252 assert(frame !is null, "Could not allocate frame");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
253 scope(exit) if(frame) av_free(frame);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
254 short* samples = cast(short*) av_malloc(acodec.frame_size * 2 * acodec.channels);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
255 assert(frame !is null, "Could not allocate samples");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
256 scope(exit) if(samples) av_free(samples);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
257
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
258 // Allocate some output buffers
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
259 voutbuf = cast(char*) av_malloc(OUTBUF_SIZE);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
260 assert(voutbuf !is null, "Could not allocate video output buffer");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
261 scope(exit) if(voutbuf) av_free(voutbuf);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
262 aoutbuf = cast(char*) av_malloc(OUTBUF_SIZE);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
263 assert(aoutbuf !is null, "Could not allocate audio output buffer");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
264 scope(exit) if(aoutbuf) av_free(voutbuf);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
265
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
266 printf("Setup time %f\n", sw.stop());
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
267 sw.start();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
268
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
269 // Write the header
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
270 res = av_write_header(ctx);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
271 assert(res >= 0, "Could not write header for output file (incorrect codec paramters?)");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
272
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
273 while(true)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
274 {
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
275 double audio_pts = cast(double) astream.pts.val * astream.time_base.num / astream.time_base.den;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
276 double video_pts = cast(double) vstream.pts.val * vstream.time_base.num / vstream.time_base.den;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
277
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
278 if(audio_pts >= STREAM_DURATION && video_pts >= STREAM_DURATION)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
279 break;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
280
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
281 // Write interleaved audio & video
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
282 if(audio_pts < video_pts)
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
283 writeAudioFrame(ctx, astream, samples);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
284 else
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
285 writeVideoFrame(ctx, vstream, frame);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
286 }
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
287
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
288 res = av_write_trailer(ctx);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
289 assert(res >= 0, "Could not write trailer for output file");
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
290
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
291 printf("Encoding time %f\n", sw.stop());
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
292 sw.start();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
293
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
294 scope File file = new File("biff_happy.wmv", File.WriteCreate);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
295 uint available = ringBuf.available;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
296 auto addr = ringBuf.beginRead(available);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
297 file.write(addr[0 .. available]);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
298 ringBuf.endRead(available);
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
299 file.close();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
300
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
301 printf("IO time %f\n", sw.stop());
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
302 sw.start();
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
303
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
304 return 0;
e6cf9f26d0e7 Added a separate "transcode" app for testing transcoding
fraserofthenight
parents:
diff changeset
305 }