view src/impl/hoofbaby/codec/decoder.d @ 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
children 71ebad05f542
line wrap: on
line source

/**
 * 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;
} */