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