changeset 7:9fdfe4a64a13

Added the beginnings of a decoder... Soon I'll have a crappier version of ffmpeg written in D!
author fraserofthenight
date Sun, 12 Jul 2009 03:04:27 -0700
parents 270343d824ae
children 71ebad05f542
files ref/testv-h264-vorbis-ass.mkv src/impl/hoofbaby/codec/decoder.d src/test/hoofbaby/test/adhoc/transcode.d
diffstat 3 files changed, 165 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
Binary file ref/testv-h264-vorbis-ass.mkv has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/impl/hoofbaby/codec/decoder.d	Sun Jul 12 03:04:27 2009 -0700
@@ -0,0 +1,158 @@
+/**
+ * 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.codec.decoder;
+
+import tango.stdc.stringz;
+
+import hoofbaby.codec.libav.avutil;
+import hoofbaby.codec.libav.avcodec;
+import hoofbaby.codec.libav.avformat;
+
+class Decoder
+{
+	private AVFormatContext* formatContext;
+	
+	public this(char[] inFilename)
+	{
+		int ret;
+		
+		// Open file & find stream info
+		char* filename = toStringz(inFilename);
+		ret = av_open_input_file(&formatContext, filename, null, 0, null);
+		assert(ret == 0, "Could not open input file");
+		ret = av_find_stream_info(formatContext);
+		assert(ret >= 0, "Could not find stream info");
+		dump_format(formatContext, 0, filename, false);
+	}
+}
+
+/* int main(int argc, char *argv[])
+{
+    AVFormatContext *pFormatCtx;
+    int             i, videoStream;
+    AVCodecContext  *pCodecCtx;
+    AVCodec         *pCodec;
+    AVFrame         *pFrame; 
+    AVFrame         *pFrameRGB;
+    AVPacket        packet;
+    int             frameFinished;
+    int             numBytes;
+    uint8_t         *buffer;
+
+    // Register all formats and codecs
+    av_register_all();
+
+    // Open video file
+    if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
+        return -1; // Couldn't open file
+
+    // Retrieve stream information
+    if(av_find_stream_info(pFormatCtx)<0)
+        return -1; // Couldn't find stream information
+
+    // Dump information about file onto standard error
+    dump_format(pFormatCtx, 0, argv[1], false);
+
+    // Find the first video stream
+    videoStream=-1;
+    for(i=0; i<pFormatCtx.nb_streams; i++)
+        if(pFormatCtx.streams[i].codec.codec_type==CODEC_TYPE_VIDEO)
+        {
+            videoStream=i;
+            break;
+        }
+    if(videoStream==-1)
+        return -1; // Didn't find a video stream
+
+    // Get a pointer to the codec context for the video stream
+    pCodecCtx=&pFormatCtx.streams[videoStream].codec;
+
+    // Find the decoder for the video stream
+    pCodec=avcodec_find_decoder(pCodecCtx.codec_id);
+    if(pCodec==NULL)
+        return -1; // Codec not found
+
+    // Open codec
+    if(avcodec_open(pCodecCtx, pCodec)<0)
+        return -1; // Could not open codec
+
+    // Hack to correct wrong frame rates that seem to be generated by some 
+    // codecs
+    if(pCodecCtx.frame_rate>1000 && pCodecCtx.frame_rate_base==1)
+        pCodecCtx.frame_rate_base=1000;
+
+    // Allocate video frame
+    pFrame=avcodec_alloc_frame();
+
+    // Allocate an AVFrame structure
+    pFrameRGB=avcodec_alloc_frame();
+    if(pFrameRGB==NULL)
+        return -1;
+
+    // Determine required buffer size and allocate buffer
+    numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx.width,
+        pCodecCtx.height);
+    buffer=new uint8_t[numBytes];
+
+    // Assign appropriate parts of buffer to image planes in pFrameRGB
+    avpicture_fill(cast(AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
+        pCodecCtx.width, pCodecCtx.height);
+
+    // Read frames and save first five frames to disk
+    i=0;
+    while(av_read_frame(pFormatCtx, &packet)>=0)
+    {
+        // Is this a packet from the video stream?
+        if(packet.stream_index==videoStream)
+        {
+            // Decode video frame
+            avcodec_decode_video(pCodecCtx, pFrame, &frameFinished, 
+                packet.data, packet.size);
+
+            // Did we get a video frame?
+            if(frameFinished)
+            {
+                // Convert the image from its native format to RGB
+                img_convert(cast(AVPicture *)pFrameRGB, PIX_FMT_RGB24, 
+                    cast(AVPicture*)pFrame, pCodecCtx.pix_fmt, pCodecCtx.width, 
+                    pCodecCtx.height);
+
+                // Save the frame to disk
+                if(++i<=5)
+                    SaveFrame(pFrameRGB, pCodecCtx.width, pCodecCtx.height, 
+                        i);
+            }
+        }
+
+        // Free the packet that was allocated by av_read_frame
+        av_free_packet(&packet);
+    }
+
+    // Free the RGB image
+    delete buffer;
+    av_free(pFrameRGB);
+
+    // Free the YUV frame
+    av_free(pFrame);
+
+    // Close the codec
+    avcodec_close(pCodecCtx);
+
+    // Close the video file
+    av_close_input_file(pFormatCtx);
+
+    return 0;
+} */
\ No newline at end of file
--- a/src/test/hoofbaby/test/adhoc/transcode.d	Thu Jul 09 20:28:13 2009 -0700
+++ b/src/test/hoofbaby/test/adhoc/transcode.d	Sun Jul 12 03:04:27 2009 -0700
@@ -21,6 +21,7 @@
 import hoofbaby.app.libs;
 
 import Math = tango.math.Math;
+import hoofbaby.codec.decoder;
 import hoofbaby.codec.encoder;
 import hoofbaby.codec.libav.avutil;
 import hoofbaby.codec.libav.avcodec;
@@ -107,6 +108,11 @@
 public int main(char[][] args)
 {
 	initLibs();
+	scope Decoder dec = new Decoder("../../ref/testv-h264-vorbis-ass.mkv");
+	return 0;
+	
+	/+ 
+	initLibs();
 	scope Encoder enc = new Encoder("biff_happy.wmv");
 	AUDIO_FRAME_SIZE = enc.audioContext.frame_size;
 
@@ -155,5 +161,5 @@
     // Write trailer
 	enc.writeTrailer();
 	
-	return 0;
+	return 0; +/
 }
\ No newline at end of file