[Libav-user] How to changes resolution to output file.

ABDALLAH Moussa Moussa.ABDALLAH at nexeya.com
Thu Feb 28 17:38:55 EET 2019


After many try to change resolution of my output video file, I failed.. I didn’t understand how to use the function sws_scale() with AVPacket where is my stream video.
Could you help me please ?

This is my source code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <sstream>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libswscale/swscale.h>
}

int main(int argc, char** argv) {

    // Open the initial context variables that are needed
    AVFormatContext* ifcx = NULL;
    AVCodecContext* cctx = NULL;
    AVStream        * ivst = NULL;
    int     i_vindex;
    int     got_key_frame = 0;

    AVFormatContext * ofcx;
    AVOutputFormat  * ofmt;
    AVStream        * ovst = NULL, * oast = NULL;

    AVPacket        pkt;
    int         ix;
    struct SwsContext *resize;

    // pts computing
    AVRational      vPtsFactor, aPtsFactor = { 0, 0 } ;

    // Register everything
   // av_register_all();
   // avformat_network_init();
    printf("1\n");
    //open http
    if (avformat_open_input(&ifcx, "http://192.9.200.121/ipcam/mjpeg.cgi",
            NULL, NULL) != 0) {
        return EXIT_FAILURE;
    }

    if (avformat_find_stream_info(ifcx, NULL) < 0) {
        return EXIT_FAILURE;
    }
    printf("2\n");
    //search video stream
    i_vindex = -1;
    for (ix = 0; ix < (int) ifcx->nb_streams; ix++) {
        // Get the codec
        cctx = ifcx->streams[ ix ]->codec;
        if (cctx->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            ivst = ifcx->streams[ ix ];
            i_vindex = ix;
            continue ;
        }
    }
        if ( i_vindex < 0 )
        {
            printf( "KNC230ERROR: Cannot find input video stream\n" );
            avformat_close_input( &ifcx );
        }
    printf("3\n");

       //open output file -------------------------------------------
        ofmt = av_guess_format( NULL, "/home/Nexeya/capture6.mkv", NULL );
        ofcx = avformat_alloc_context();
        ofcx->oformat = ofmt;
        avio_open2( &ofcx->pb, "/home/Nexeya/capture6.mkv", AVIO_FLAG_WRITE, NULL, NULL );
printf("4\n");
        // Create video output stream -------------------------------------------
        //ovst = avformat_new_stream( ofcx, (AVCodec *) cctx->codec );
        ovst = avformat_new_stream( ofcx, NULL );
        avcodec_copy_context( ovst->codec, cctx);

        ovst->sample_aspect_ratio.num = cctx->sample_aspect_ratio.num;
        ovst->sample_aspect_ratio.den = cctx->sample_aspect_ratio.den;
printf("5\n");
        // Assume r_frame_rate is accurate
        ivst->r_frame_rate.num=25;
        ivst->r_frame_rate.den=1;
        ovst->r_frame_rate      = ivst->r_frame_rate;
        ovst->avg_frame_rate    = ovst->r_frame_rate;
printf("6\n");
        // Initialize many things ...
        avformat_write_header( ofcx, NULL );

        snprintf( ofcx->filename, sizeof( ofcx->filename ), "%s", "/home/Nexeya/capture6.mkv" );

        // Video pts conversion factor
        // The input and output time_base may be different
        vPtsFactor.num = ivst->time_base.num * ovst->time_base.den ;
        vPtsFactor.den = ivst->time_base.den * ovst->time_base.num ;
        ix = (uint32_t) av_gcd (vPtsFactor.num, vPtsFactor.den) ;
        vPtsFactor.num /= ix ;
        vPtsFactor.den /= ix ;
printf("7\n");

        resize = sws_getContext(cctx->width, cctx->height, AV_PIX_FMT_YUV420P, 320, 240, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
        //start reading pkts from stream and write them to file
        printf("Start record\n");
        av_init_packet( &pkt );
        int ii=0;
        while (ii<258)
        {
            if (av_read_frame (ifcx, & pkt) >= 0)
            {
                // Make sure we start on a key video frame
                if (got_key_frame == 0)
                {
                    if (pkt.stream_index == i_vindex)
                    {
                        if (pkt.flags & AV_PKT_FLAG_KEY)
                        {
                            got_key_frame = 1;
                        }
                        else
                            continue ; // Not key frame
                    }
                }

                // Manage pkt

                // pts can be AV_NOPTS_VALUE = 0x8000... at start
                if (pkt.pts == AV_NOPTS_VALUE)
                    pkt.pts = pkt.dts = 0 ;

                if ( pkt.stream_index == i_vindex )
                {
                    // pkt is video

                    pkt.stream_index = ovst->id;

                    // Compute pts
                    pkt.pts = pkt.dts = (pkt.pts * vPtsFactor.num) / vPtsFactor.den ;
                    sws_scale(resize, pkt.data, pkt.linesize, 0, cctx->height, pkt.data, pkt.linesize);
                    av_write_frame( ofcx, &pkt );
                }

                av_free_packet( &pkt );
                av_init_packet( &pkt );
            }
            ii++;
        }
        printf("End record\n");
        // Stop command received
        av_read_pause           ( ifcx );
        av_write_trailer        ( ofcx );
        avio_close              ( ofcx->pb );
        avformat_close_input    ( & ifcx );
        avformat_free_context   ( ofcx );
    return (EXIT_SUCCESS);
}

Thanks you very much for your help.

De : Libav-user <libav-user-bounces at ffmpeg.org> De la part de Michael Armes
Envoyé : mercredi 27 février 2019 22:27
À : This list is about using libavcodec, libavformat, libavutil, libavdevice and libavfilter. <libav-user at ffmpeg.org>
Objet : Re: [Libav-user] How to changes resolution to output file.

I did not find that setting bitrate had any effect in my scenarios with mp4/mov. I had to manually control my color depth and resolution (and set framerate) to hit my desired bitrate. I never did have to convert pixel formats, but my read of the docs is that sws_scale can do this as long as you set your SwsContext appropriately.

On Wed, Feb 27, 2019 at 11:08 AM ABDALLAH Moussa <Moussa.ABDALLAH at nexeya.com<mailto:Moussa.ABDALLAH at nexeya.com>> wrote:
Thanks you for your help!
To change the bit_rate I have to use sw_scale too?

Le 27 févr. 2019 à 18:49, Michael Armes <michael.armes at gmail.com<mailto:michael.armes at gmail.com>> a écrit :
You need to scale *each frame* with sws_scale from lib_av (https://libav.org/documentation/doxygen/master/group__libsws.html#gae531c9754c9205d90ad6800015046d74). I suggest you look at the example code linked in the documentation for reference.

On Wed, Feb 27, 2019 at 9:38 AM ABDALLAH Moussa <Moussa.ABDALLAH at nexeya.com<mailto:Moussa.ABDALLAH at nexeya.com>> wrote:
Hello,

I am trying to record a stream video to a output file mkv. I set my camera with the resolution 1280x720 and I would like to change it with ffmpeg on my program how can I do that please ?

I have success to change the framerate but I failed  with the resolution or other option like bit_rate :

        ivst->r_frame_rate.num=25;
        ivst->r_frame_rate.den=1;
        ovst->r_frame_rate      = ivst->r_frame_rate;
        ovst->avg_frame_rate    = ovst->r_frame_rate;
        ivst->codec->bit_rate = 3000000;
        ovst->codec->bit_rate = 3000000;
        ivst->codec->height = 320;
        ivst->codec->width = 240;
        ovst->codec->height = 320;
        ovst->codec->width = 240;

Thanks you for your help !
_______________________________________________
Libav-user mailing list
Libav-user at ffmpeg.org<mailto:Libav-user at ffmpeg.org>
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
libav-user-request at ffmpeg.org<mailto:libav-user-request at ffmpeg.org> with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
Libav-user at ffmpeg.org<mailto:Libav-user at ffmpeg.org>
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
libav-user-request at ffmpeg.org<mailto:libav-user-request at ffmpeg.org> with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
Libav-user at ffmpeg.org<mailto:Libav-user at ffmpeg.org>
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
libav-user-request at ffmpeg.org<mailto:libav-user-request at ffmpeg.org> with subject "unsubscribe".
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20190228/140dad50/attachment.html>


More information about the Libav-user mailing list