FORUMS: list search recent posts

Decoding then Encoding video: very low quality output: why ??

COW Forums : FFmpeg

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
Dhirendra Ambani
Decoding then Encoding video: very low quality output: why ??
on Jun 21, 2011 at 7:25:42 am

I have coded to decode a video and then to encode it back with most of the parameters similar to original one( so that I could interfere with the frames so produced). The method is successful, but the so produced video is of very low quality and size 1/4th of the original.
I am pasting my code here.

#include "stdafx.h"
#include
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"

#ifdef __cplusplus
}
#endif

AVCodecContext *pCodecCtx_decode;
AVCodec *pCodec2;
int outbuf_size=100000,frame_count=0;
uint8_t *outbuffer;

static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
{
AVCodecContext *c;
AVStream *st;

st = av_new_stream(oc, 0);

c=st->codec;
c->codec_id=pCodecCtx_decode->codec_id;
c->codec_type=AVMEDIA_TYPE_VIDEO;
c->bit_rate = pCodecCtx_decode->bit_rate;
c->width =pCodecCtx_decode->width;
c->height = pCodecCtx_decode->height;
c->time_base.num=pCodecCtx_decode->time_base.num;
c->time_base.den=pCodecCtx_decode->time_base.den;
c->gop_size = pCodecCtx_decode->gop_size;
c->pix_fmt = pCodecCtx_decode->pix_fmt;
c->bit_rate_tolerance=40000000;//pCodecCtx_decode->bit_rate_tolerance;

if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
c->max_b_frames = 2;
}
if (c->codec_id == CODEC_ID_MPEG1VIDEO){
c->mb_decision=2;
}

return st;
}

static void open_video(AVFormatContext *oc, AVStream *st)
{
AVCodec *codec;
AVCodecContext *c;

c = st->codec;

codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}

/* open the codec */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}

outbuffer = NULL;
if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
outbuf_size = 200000;
outbuffer = (uint8_t*)av_malloc(outbuf_size);
}
}

static void write_video_frame(AVFormatContext *oc, AVStream *st, AVFrame *pFrame,AVPacket * avpkt_dec)
{
int out_size, ret;
AVCodecContext *c;

c = st->codec;

out_size = avcodec_encode_video(c, outbuffer, outbuf_size, pFrame);
if (out_size > 0) {
AVPacket pkt;
av_init_packet(&pkt);

if (c->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
if(c->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;

pkt.pts=avpkt_dec->pts;pkt.dts = pkt.pts;
pkt.stream_index= st->index;
pkt.data= outbuffer;
pkt.size= out_size;
printf("encoding frame %3d (size=%5d)\n", frame_count, out_size);
ret=av_interleaved_write_frame(oc,&pkt);
if(!ret)
ret= url_ferror(oc->pb);

av_free_packet(&pkt);
} else {
ret = 0;
}

if (ret != 0) {
fprintf(stderr, "Error while writing video frame\n");
exit(1);
}
}
int myconverter(const char * infile,const char * outfile)
{
AVFormatContext *pFormatCtx;
int i, videoStream;

AVCodec *pCodec1;
AVFrame *pFrame;
AVPacket packet;
int frameFinished;

avcodec_init();
av_register_all();
if(av_open_input_file(&pFormatCtx,infile, NULL, 0, NULL)!=0)
{fprintf(stderr," Couldn't open file %s ",infile);return -1; }

if(av_find_stream_info(pFormatCtx)<0)
{printf("Couldn't find stream information");return -1;} //

dump_format(pFormatCtx, 0, infile, 0);

videoStream=-1;
for(i=0; i<(pFormatCtx->nb_streams); i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
{printf("Didn't find a video stream");return -1;}

// Get a pointer to the codec context for the video stream
pCodecCtx_decode=pFormatCtx->streams[videoStream]->codec;

pCodec1=avcodec_find_decoder(pCodecCtx_decode->codec_id);
if(pCodec1==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1;
}
if(avcodec_open(pCodecCtx_decode, pCodec1)<0)
return -1;

pFrame=avcodec_alloc_frame();

AVOutputFormat *fmt;
AVFormatContext *oc;
int out_size;
AVStream *video_st = NULL;


oc=avformat_alloc_output_context(NULL,NULL,outfile);
if (!oc) {
printf("Could not deduce output format from file extension: using MPEG.\n");
oc=avformat_alloc_output_context("mpeg", NULL, outfile);
}
if (!oc) {
exit(1);
}
fmt=oc->oformat;


if (fmt->video_codec != CODEC_ID_NONE) {
video_st = add_video_stream(oc, fmt->video_codec);
}

av_dump_format(oc, 0, outfile, 1);

if (video_st)
open_video(oc, video_st);

/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
if (avio_open(&oc->pb, outfile, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "Could not open '%s'\n", outfile);
exit(1);
}
}

av_write_header(oc);
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
if(packet.stream_index==videoStream) {
AVPacket avpkt_dec;
av_init_packet(&avpkt_dec);
avpkt_dec.data = packet.data;
avpkt_dec.size = packet.size;
avpkt_dec.flags = AV_PKT_FLAG_KEY;
avcodec_decode_video2(pCodecCtx_decode, pFrame, &frameFinished,&avpkt_dec);

if(pFrame->pict_type==AV_PICTURE_TYPE_I ||(frameFinished && ((frame_count++)%2==0))) {
write_video_frame(oc, video_st, pFrame,&avpkt_dec);

}
}

av_free_packet(&packet);
}
av_write_trailer(oc);


/* free the streams */
for(i = 0; i < oc->nb_streams; i++) {
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}

if(video_st){
//avcodec_close(video_st->codec);
av_free(outbuffer);
}
if (!(fmt->flags & AVFMT_NOFILE)) {
avio_close(oc->pb);
}
av_free(oc);
av_free(pFrame);
avcodec_close(pCodecCtx_decode);
av_close_input_file(pFormatCtx);
return 0;
}


int main(int argc, char *argv[])
{
const char *infile,*outfile;

infile = "D:\\Video\\crawling.avi"; //input file name
outfile="D:\\Video\\converted.avi"; // output file name
myconverter(infile,outfile);
return 0;
}


help of any kind is appreciated


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 CreativeCOW.net All Rights Reserved
[TOP]