Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Compression Techniques Decoding then Encoding video: very low quality output: why ??

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

    Posted by Dhirendra Ambani on June 21, 2011 at 7:25 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

    Dhirendra Ambani replied 15 years, 2 months ago 1 Member · 0 Replies
  • 0 Replies

Sorry, there were no replies found.

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy