/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * RTVideoRec Realtime video recoder and encoder for Linux * * Copyright (C) 2004 Bent Bisballe * Copyright (C) 2004 B. Stultiens * Copyright (C) 2004 Koen Otter and Glenn van der Meyden * * This program is free software; you can redistribute it and/or 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mov_encoder.h" //av_alloc_format_context //av_destruct_packet_nofree MovEncoder::MovEncoder(const char *filename) { //////////////////// GLOBAL INIT av_register_all(); //////////////////// ENCODE INIT AVStream *st; AVCodec *enc_codec; if(!(efc = av_alloc_format_context())) { fprintf(stderr, "Could not alloc output format context\n"); exit(1); } efc->oformat = guess_format("mpeg", NULL, NULL); //efc->oformat = guess_format(NULL, filename, NULL); if(!(st = av_new_stream(efc, 0))) { fprintf(stderr, "Could not alloc stream\n"); switch((int)st) { case AVERROR_UNKNOWN : printf("unknown error\n"); break; case AVERROR_IO : printf("i/o error\n"); break; case AVERROR_NUMEXPECTED : printf("number syntax expected in filename\n"); break; case AVERROR_INVALIDDATA : printf("invalid data found\n"); break; case AVERROR_NOMEM : printf("not enough memory\n"); break; case AVERROR_NOFMT : printf("unknown format\n"); break; case AVERROR_NOTSUPP : printf("operation not supported\n"); break; } exit(1); } enc_codec = avcodec_find_encoder(CODEC_ID_MPEG2VIDEO); if(!enc_codec) { printf("Unsupported codec for output stream\n"); exit(1); } avcodec_get_context_defaults(&st->codec); ecc = &st->codec; ecc->codec_id = CODEC_ID_MPEG2VIDEO; ecc->bit_rate = 8192*1000; ecc->bit_rate_tolerance = 8000*1000; ecc->frame_rate = 25; ecc->frame_rate_base = 1; ecc->width = 720; ecc->height = 576; ecc->pix_fmt = PIX_FMT_YUV420P; ecc->gop_size = 0; ecc->mb_decision = FF_MB_DECISION_SIMPLE; ecc->qmin = 2; ecc->qmax = 31; ecc->mb_qmin = 2; ecc->mb_qmax = 31; ecc->max_qdiff = 3; ecc->qblur = 0.5; ecc->qcompress = 0.5; ecc->rc_eq = "tex^qComp"; ecc->debug= 0; ecc->rc_override_count=0; ecc->rc_max_rate = 0; ecc->rc_min_rate = 0; ecc->rc_buffer_size = 0; ecc->rc_buffer_aggressivity = 1.0; ecc->rc_initial_cplx= 0; ecc->i_quant_factor = -0.8; ecc->b_quant_factor = 1.25; ecc->i_quant_offset = 0.8; ecc->b_quant_offset = 1.25; ecc->dct_algo = 0; ecc->idct_algo = 0; ecc->strict_std_compliance = 0; ecc->me_method = ME_EPZS; if(avcodec_open(&st->codec, enc_codec) < 0) { printf("Error while opening codec for stream\n"); exit(1); } if(url_fopen(&efc->pb, filename, URL_RDWR) < 0) { fprintf(stderr, "Could not open '%s'\n", filename); exit(1); } if(av_set_parameters(efc, NULL) < 0) { fprintf(stderr, "%s: Invalid encoding parameters\n", filename); exit(1); } dump_format(efc, 0, filename, 1); if(av_write_header(efc) < 0) { fprintf(stderr, "Could not write header for output file \n"); exit(1); } video_buffer = (unsigned char *)av_malloc(VIDEO_BUFFER_SIZE); av_init_packet(&epkt); epkt.stream_index = efc->streams[0]->index; // ecc = &efc->streams[0]->codec; //////////////////// DECODE INIT AVCodec *deccodec; // AVCodecContext *dcc= NULL; printf("Video decoding\n"); /* find the dvvideo decoder */ deccodec = avcodec_find_decoder(CODEC_ID_DVVIDEO); if (!deccodec) { fprintf(stderr, "codec not found\n"); exit(1); } dcc= avcodec_alloc_context(); /* open it */ if (avcodec_open(dcc, deccodec) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } } MovEncoder::~MovEncoder() { av_free(video_buffer); url_fclose(&efc->pb); } void MovEncoder::encode(DVFrame *dvframe) { int ret; AVFrame *rawframe = avcodec_alloc_frame(); ///////////////////////// DECODE uint8_t *ptr; int got_picture = 1; int len; ptr = (uint8_t *)dvframe->frame; len = sizeof(dvframe->frame); ret = avcodec_decode_video(dcc,//&dfc->streams[0]->codec, rawframe, &got_picture, ptr, len); if(!ret) { printf("Decoder fuckup!\n"); return; } ///////////////////////// ENCODE ret = avcodec_encode_video(ecc, video_buffer, VIDEO_BUFFER_SIZE, rawframe); if(!ret) { printf("MovEncoder fuckup!\n"); return; } epkt.data = video_buffer; epkt.size = ret; if(ecc->coded_frame) epkt.pts = ecc->coded_frame->pts; if(ecc->coded_frame && ecc->coded_frame->key_frame) epkt.flags |= PKT_FLAG_KEY; av_write_frame(efc, &epkt); av_free(rawframe); }