

class FFMpegMuxModule : public SimpleModule {
public:
    FFMpegMuxModule() : outputFileContext( 0 )
    {           
    }
    
    void init()
    {
printf("A %i\n", __LINE__);
        av_register_all();
        
        outputFileContext = av_alloc_format_context();
        outputFileContext->oformat = guess_format("avi", 0, 0);
        AVStream *videoStream = av_new_stream( outputFileContext, outputFileContext->nb_streams+1 );
        //AVStream *audioStream = av_new_stream( AVFormatContext, outputFileContext->nb_streams+1 );
printf("A %i\n", __LINE__);

        assert( videoStream );
        assert( outputFileContext->oformat );

        AVCodecContext *video_enc = &videoStream->codec;
        
        AVCodec *codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
        assert( codec );
        assert( avcodec_open( video_enc, codec ) >= 0 );
        
        video_enc->codec_type = CODEC_TYPE_VIDEO;
        video_enc->codec_id = CODEC_ID_MPEG1VIDEO;//CODEC_ID_MPEG4; // CODEC_ID_H263, CODEC_ID_H263P
//        video_enc->bit_rate = video_bit_rate;
//        video_enc->bit_rate_tolerance = video_bit_rate_tolerance;

        video_enc->frame_rate = 10;//25;//frame_rate; 
        video_enc->frame_rate_base = 1;//frame_rate_base; 
        video_enc->width = WIDTH;//frame_width + frame_padright + frame_padleft;
        video_enc->height = HEIGHT;//frame_height + frame_padtop + frame_padbottom;

        video_enc->pix_fmt = PIX_FMT_YUV420P;
        
        if( av_set_parameters( outputFileContext, NULL ) < 0 ) {
            cerr << "Invalid output format parameters\n";
         exit(1);
        }
    
printf("A %i\n", __LINE__);
//        strcpy( outputFileContext->comment, "Created With Project Carmack" );
//        strcpy( outputFileContext->filename, "blah.avi" );
        
//        if ( url_fopen( &outputFileContext->pb, outputFileContext->filename, URL_WRONLY ) < 0 ) {
        if ( url_fopen( &outputFileContext->pb, "blah2.avi", URL_WRONLY ) < 0 ) {
            printf( "Couldn't open output file: %s\n", outputFileContext->filename );
            exit( 1 );
        }
printf("A %i\n", __LINE__);

        if ( av_write_header( outputFileContext ) < 0 ) {
            printf( "Could not write header for output file %s\n", outputFileContext->filename );
            exit( 1 );
        }

printf("A %i\n", __LINE__);
    }

    void process( const Frame &frame ) 
    {
printf("B %i\n", __LINE__);
        AVPacket *pkt = ((FFMpegStreamPacket*)frame.data())->packet;
        //av_dup_packet( pkt ); 

        if ( !outputFileContext ) {
            printf("can't process video data without a context\n");
            return;
        }
        
/*
            pkt.stream_index= ost->index;
            pkt.data= audio_out;
            pkt.size= ret;
            if(enc->coded_frame)
                pkt.pts= enc->coded_frame->pts;
            pkt.flags |= PKT_FLAG_KEY;
*/          
printf("B %i\n", __LINE__);
        if ( pkt->data ) {
printf("B %i\n", __LINE__);
            av_interleaved_write_frame(outputFileContext, pkt);
        } else {
            printf( "End of data\n" );
            av_write_trailer(outputFileContext);
            exit( 0 );
        }
printf("B %i\n", __LINE__);
        
        frame.deref();
    }
    
    const char *name() { return "AVI Muxer"; }
    Format inputFormat() { return "FRAME_ID_MPEG1_VIDEO_PACKET"; }
    Format outputFormat() { return "FRAME_ID_URL_SINK"; }
    bool isBlocking() { return true; }

private:
    AVFormatContext *outputFileContext;
};

