# HG changeset patch # User fraserofthenight # Date 1247634245 25200 # Node ID 05c88622db6bb92af159b33b02ffb58a6f2e214a # Parent 71ebad05f542d2839049d25212e2fdd1a946181a - Adhoc transcoder now doesn't rely on Platinum - Moved the adhoc transcoder to the main source tree; it can be moved back into test once it's more stable diff -r 71ebad05f542 -r 05c88622db6b .classpath --- a/.classpath Sun Jul 12 03:49:39 2009 -0700 +++ b/.classpath Tue Jul 14 22:04:05 2009 -0700 @@ -2,8 +2,6 @@ - - diff -r 71ebad05f542 -r 05c88622db6b .settings/Hoofbaby - Debug.launch --- a/.settings/Hoofbaby - Debug.launch Sun Jul 12 03:49:39 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - - - diff -r 71ebad05f542 -r 05c88622db6b .settings/Hoofbaby - Release.launch --- a/.settings/Hoofbaby - Release.launch Sun Jul 12 03:49:39 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ - - - - - - diff -r 71ebad05f542 -r 05c88622db6b src/build/frankenbuild.d --- a/src/build/frankenbuild.d Sun Jul 12 03:49:39 2009 -0700 +++ b/src/build/frankenbuild.d Tue Jul 14 22:04:05 2009 -0700 @@ -64,25 +64,24 @@ if(cats.contains("transcode")) { targetFound = true; - cats ~= "platif-debug"; char[] cargs = cbase.dup; cargs ~= " -g"; cargs ~= " -debug -debug=AVBuffer"; cargs ~= " -ofhoofbaby-d/transcode.exe"; cargs ~= " -I../src/test"; - cargs ~= " -oqobjs/debug"; - cargs ~= " ../src/test/hoofbaby/test/adhoc/transcode.d"; - commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); }; + cargs ~= " -oqobjs/transcode"; + cargs ~= " ../src/impl/hoofbaby/app/transcode.d"; commands ~= { return rebuild(cargs); }; } - if(cats.contains("debug")) + /+ if(cats.contains("debug")) { targetFound = true; cats ~= "platif-debug"; char[] cargs = cbase.dup; cargs ~= " -g"; cargs ~= " -debug -debug=AVBuffer"; + cargs ~= " -version=UPnP"; cargs ~= " -ofhoofbaby-d/hoofbaby.exe"; cargs ~= " -oqobjs/debug"; cargs ~= " ../src/impl/hoofbaby/app/main.d"; @@ -96,13 +95,14 @@ cats ~= "platif-release"; char[] cargs = cbase.dup; cargs ~= " -O -inline"; + cargs ~= " -version=UPnP"; cargs ~= " -ofhoofbaby/hoofbaby.exe"; cargs ~= " -oqobjs/release"; cargs ~= " ../src/impl/hoofbaby/app/main.d"; commands ~= { return cpp("../src/platif/platif.h", "../src/impl/hoofbaby/platinum/platif.d"); }; commands ~= { return rebuild(cargs); }; commands ~= { return upx("hoofbaby/hoofbaby.exe"); };// D executables are enormous - } + } +/ if(cats.contains("platif-debug")) { diff -r 71ebad05f542 -r 05c88622db6b src/impl/hoofbaby/app/libs.d --- a/src/impl/hoofbaby/app/libs.d Sun Jul 12 03:49:39 2009 -0700 +++ b/src/impl/hoofbaby/app/libs.d Tue Jul 14 22:04:05 2009 -0700 @@ -17,14 +17,14 @@ import tango.io.Stdout; -import platif = hoofbaby.platinum.platif; +version(UPnP) import platif = hoofbaby.platinum.platif; import libav = hoofbaby.codec.libav.avformat; public bool initLibs() { try { - platif._loadLib(); + version(UPnP) platif._loadLib(); libav.av_register_all(); } catch(Exception e) diff -r 71ebad05f542 -r 05c88622db6b src/impl/hoofbaby/app/main.d --- a/src/impl/hoofbaby/app/main.d Sun Jul 12 03:49:39 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/** - * Hoofbaby -- http://www.dsource.org/projects/hoofbaby - * Copyright (C) 2009 Robert Fraser - * - * This program is free software; you can redistribute it andor - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -module hoofbaby.app.main; - -// Imports for whole program (just link to them) -import NONE_1 = tango.stdc.stdarg; // Must be linked in to prevent strange linker errors -debug import NONE_2 = tango.core.stacktrace.TraceExceptions; -import NONE_3 = hoofbaby.codec.libav.mingw; - -import hoofbaby.app.libs; - -public int main(char[][] args) -{ - initLibs(); - return 0; -} \ No newline at end of file diff -r 71ebad05f542 -r 05c88622db6b src/impl/hoofbaby/app/transcode.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/impl/hoofbaby/app/transcode.d Tue Jul 14 22:04:05 2009 -0700 @@ -0,0 +1,153 @@ +/** + * Hoofbaby -- http://www.dsource.org/projects/hoofbaby + * Copyright (C) 2009 Robert Fraser + * + * This program is free software; you can redistribute it andor + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +module hoofbaby.app.transcode; + +import NONE_1 = tango.stdc.stdarg; // Must be linked in to prevent strange linker errors +debug import NONE_2 = tango.core.stacktrace.TraceExceptions; +import NONE_3 = hoofbaby.codec.libav.mingw; + +import hoofbaby.app.libs; +import hoofbaby.codec.decoder; +import hoofbaby.codec.encoder; + +public int main(char[][] args) +{ + initLibs(); + scope Decoder dec = new Decoder("../../ref/testv-h264-vorbis-ass.mkv"); + scope Encoder enc = new Encoder("trans.wmv"); + // WORKAREA check ffmpeg.c:1742 + return 0; +} + +/+ + +import Math = tango.math.Math; +import hoofbaby.codec.libav.avutil; +import hoofbaby.codec.libav.avcodec; +import hoofbaby.codec.libav.avformat; + +private const int STREAM_FRAME_RATE = 25; +private const double STREAM_DURATION = 5.0; +private const int STREAM_NB_FRAMES = (cast(int) (STREAM_DURATION * STREAM_FRAME_RATE)); +private const int WIDTH = 352; +private const int HEIGHT = 288; +private const int SAMPLE_RATE = 44100; +private int AUDIO_FRAME_SIZE; + +private int frameCount = 0; +private double audioCount = 0.0; +private double audioIncr = 2 * Math.PI * 110.0 / SAMPLE_RATE; +private double audioIncr2 = 2 * Math.PI * 110.0 / SAMPLE_RATE / SAMPLE_RATE; + +private AVFrame* generatePicture(AVFrame* pict, int width, int height) +{ + int x, y, i; + i = frameCount; + + /* Y */ + for(y = 0; y < height; y++) + { + for(x = 0; x < width; x++) + { + pict.data[0][y * pict.linesize[0] + x] = x + y + i * 3; + } + } + + /* Cb and Cr */ + for(y = 0; y < height / 2; y++) + { + for(x = 0; x < width / 2; x++) + { + pict.data[1][y * pict.linesize[1] + x] = 128 + y + i * 2; + pict.data[2][y * pict.linesize[2] + x] = 64 + x + i * 5; + } + } + + return pict; +} + +private short* generateAudio(short* samples) +{ + int j, i, v; + short *q; + + q = samples; + for(j = 0; j < AUDIO_FRAME_SIZE; j++) + { + v = cast(int)(Math.sin(audioCount) * 10000); + for(i = 0; i < 2; i++) // 2 is number of channels + *q++ = v; + audioCount += audioIncr; + audioIncr += audioIncr2; + } + + return samples; +} + +public int main(char[][] args) +{ + initLibs(); + scope Encoder enc = new Encoder("biff_happy.wmv"); + AUDIO_FRAME_SIZE = enc.audioContext.frame_size; + + // Allocate a video frame and audio buffer to store stuff + AVFrame* frame = avpicture_alloc(PIX_FMT_YUV420P, WIDTH, HEIGHT); + assert(frame !is null, "Could not allocate frame"); + scope(exit) if(frame) av_free(frame); + short* samples = cast(short*) av_malloc(AUDIO_FRAME_SIZE * 2 * 2); // AUDIO_FRAME_SIZE * 2 * number of channels + assert(frame !is null, "Could not allocate samples"); + scope(exit) if(samples) av_free(samples); + + // Write header + enc.writeHeader(); + + while(true) + { + double audio_pts = cast(double) enc.audioStream.pts.val * enc.audioStream.time_base.num / enc.audioStream.time_base.den; + double video_pts = cast(double) enc.videoStream.pts.val * enc.videoStream.time_base.num / enc.videoStream.time_base.den; + + if(audio_pts >= STREAM_DURATION && video_pts >= STREAM_DURATION) + break; + + // Write interleaved audio & video + if(audio_pts < video_pts) + { + enc.writeAudioFrame(generateAudio(samples)); + } + else + { + if(frameCount >= STREAM_NB_FRAMES) + { + // no more frame to compress. The codec has a latency of a few + // frames if using B frames, so we get the last frames by + // passing the same picture again + } + else + { + generatePicture(frame, WIDTH, HEIGHT); + } + + enc.writeVideoFrame(frame); + frameCount++; + } + } + + // Write trailer + enc.writeTrailer(); + + return 0; +} ++/ \ No newline at end of file diff -r 71ebad05f542 -r 05c88622db6b src/impl/hoofbaby/codec/decoder.d --- a/src/impl/hoofbaby/codec/decoder.d Sun Jul 12 03:49:39 2009 -0700 +++ b/src/impl/hoofbaby/codec/decoder.d Tue Jul 14 22:04:05 2009 -0700 @@ -22,7 +22,7 @@ import hoofbaby.codec.libav.avcodec; import hoofbaby.codec.libav.avformat; -class Decoder +public final class Decoder { private char[] file; @@ -65,7 +65,7 @@ } assert(videoStream !is null, "Could not find video stream"); videoContext = videoStream.codec; - assert(videoContext !is null, "Null codec context from non-null stream"); + assert(videoContext !is null, "Null codec context from non-null video stream"); videoCodec = avcodec_find_decoder(videoContext.codec_id); assert(videoCodec !is null, "Unsupported video format"); ret = avcodec_open(videoContext, videoCodec); @@ -84,7 +84,7 @@ } assert(audioStream !is null, "Could not find audio stream"); audioContext = audioStream.codec; - assert(audioContext !is null, "Null codec context from non-null stream"); + assert(audioContext !is null, "Null codec context from non-null audio stream"); audioCodec = avcodec_find_decoder(audioContext.codec_id); assert(audioCodec !is null, "Unsupported audio format"); ret = avcodec_open(audioContext, audioCodec); diff -r 71ebad05f542 -r 05c88622db6b src/test/hoofbaby/test/adhoc/transcode.d --- a/src/test/hoofbaby/test/adhoc/transcode.d Sun Jul 12 03:49:39 2009 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/** - * Hoofbaby -- http://www.dsource.org/projects/hoofbaby - * Copyright (C) 2009 Robert Fraser - * - * This program is free software; you can redistribute it andor - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -module hoofbaby.test.adhoc.transcode; - -import NONE_1 = tango.stdc.stdarg; // Must be linked in to prevent strange linker errors -debug import NONE_2 = tango.core.stacktrace.TraceExceptions; -import NONE_3 = hoofbaby.codec.libav.mingw; -import hoofbaby.app.libs; - -import hoofbaby.codec.decoder; -import hoofbaby.codec.encoder; - - -public int main(char[][] args) -{ - initLibs(); - scope Decoder dec = new Decoder("../../ref/testv-h264-vorbis-ass.mkv"); - delete dec; - return 0; -} - -/+ - -import Math = tango.math.Math; -import hoofbaby.codec.libav.avutil; -import hoofbaby.codec.libav.avcodec; -import hoofbaby.codec.libav.avformat; - -private const int STREAM_FRAME_RATE = 25; -private const double STREAM_DURATION = 5.0; -private const int STREAM_NB_FRAMES = (cast(int) (STREAM_DURATION * STREAM_FRAME_RATE)); -private const int WIDTH = 352; -private const int HEIGHT = 288; -private const int SAMPLE_RATE = 44100; -private int AUDIO_FRAME_SIZE; - -private int frameCount = 0; -private double audioCount = 0.0; -private double audioIncr = 2 * Math.PI * 110.0 / SAMPLE_RATE; -private double audioIncr2 = 2 * Math.PI * 110.0 / SAMPLE_RATE / SAMPLE_RATE; - -private AVFrame* generatePicture(AVFrame* pict, int width, int height) -{ - int x, y, i; - i = frameCount; - - /* Y */ - for(y = 0; y < height; y++) - { - for(x = 0; x < width; x++) - { - pict.data[0][y * pict.linesize[0] + x] = x + y + i * 3; - } - } - - /* Cb and Cr */ - for(y = 0; y < height / 2; y++) - { - for(x = 0; x < width / 2; x++) - { - pict.data[1][y * pict.linesize[1] + x] = 128 + y + i * 2; - pict.data[2][y * pict.linesize[2] + x] = 64 + x + i * 5; - } - } - - return pict; -} - -private short* generateAudio(short* samples) -{ - int j, i, v; - short *q; - - q = samples; - for(j = 0; j < AUDIO_FRAME_SIZE; j++) - { - v = cast(int)(Math.sin(audioCount) * 10000); - for(i = 0; i < 2; i++) // 2 is number of channels - *q++ = v; - audioCount += audioIncr; - audioIncr += audioIncr2; - } - - return samples; -} - -public int main(char[][] args) -{ - initLibs(); - scope Encoder enc = new Encoder("biff_happy.wmv"); - AUDIO_FRAME_SIZE = enc.audioContext.frame_size; - - // Allocate a video frame and audio buffer to store stuff - AVFrame* frame = avpicture_alloc(PIX_FMT_YUV420P, WIDTH, HEIGHT); - assert(frame !is null, "Could not allocate frame"); - scope(exit) if(frame) av_free(frame); - short* samples = cast(short*) av_malloc(AUDIO_FRAME_SIZE * 2 * 2); // AUDIO_FRAME_SIZE * 2 * number of channels - assert(frame !is null, "Could not allocate samples"); - scope(exit) if(samples) av_free(samples); - - // Write header - enc.writeHeader(); - - while(true) - { - double audio_pts = cast(double) enc.audioStream.pts.val * enc.audioStream.time_base.num / enc.audioStream.time_base.den; - double video_pts = cast(double) enc.videoStream.pts.val * enc.videoStream.time_base.num / enc.videoStream.time_base.den; - - if(audio_pts >= STREAM_DURATION && video_pts >= STREAM_DURATION) - break; - - // Write interleaved audio & video - if(audio_pts < video_pts) - { - enc.writeAudioFrame(generateAudio(samples)); - } - else - { - if(frameCount >= STREAM_NB_FRAMES) - { - // no more frame to compress. The codec has a latency of a few - // frames if using B frames, so we get the last frames by - // passing the same picture again - } - else - { - generatePicture(frame, WIDTH, HEIGHT); - } - - enc.writeVideoFrame(frame); - frameCount++; - } - } - - // Write trailer - enc.writeTrailer(); - - return 0; -} -+/ \ No newline at end of file