15.09.2016, 16:59, "Carl Eugen Hoyos" <[email protected]>:
>
> The line is here "if (!avctx->codec->encode2) {" indicating you did not
> initialize the parameter avctx sufficiently (setting up an encoder).
>
> Carl Eugen
> _______________________________________________
> Libav-user mailing list
> [email protected]
> http://ffmpeg.org/mailman/listinfo/libav-user

What I have done was initialize 2 AVCodecContext* arrays (As pointer to 
pointer), one for the decoder and one for the encoder, the number of 
AVCodecContext pointers depends on the number of streams in the input 
AVFormatContext. After that, when processing each stream, the encoder is opened 
using avcodec_open2(encodecontext[i], 
avcodec_find_encoder(decodecontext[i]->codec), NULL); (The same is done 
previously to the decodecontext.) This is done as many as the number of 
existing streams. Can you look at the code and tell me what I have done wrong? 
The reason why aac codec works for audio but avc/mp4 doesn't for video means 
the problem is not from my side, as it is working for another codec.
If you want it on pastebin for better highlighting of the code: 
http://pastebin.com/p405CjbJ
****************************************
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/rational.h>

#include <stdio.h>

int main()
{
    av_register_all();

    //av_log_set_level(-8);


    AVFormatContext *ps = avformat_alloc_context();

    AVFormatContext *ps2 = NULL;//avformat_alloc_context();
    AVOutputFormat *oF = av_guess_format("mp4", NULL, "video/mp4");


    if(avformat_open_input(&ps, "vid.mp4", NULL, NULL) != 0)
    {
        printf("Failed to open input file.\n");
        return -1;
    }

    avformat_alloc_output_context2(&ps2, oF, NULL, "vid2.mp4");

    avformat_find_stream_info(ps, NULL);

    AVCodecContext **pC = (AVCodecContext**)malloc(ps->nb_streams), **p2C = 
(AVCodecContext**)malloc(ps->nb_streams);

    AVStream *oStream = NULL;
    AVStream *iStream = NULL;

    AVCodec *encoder = NULL;
    AVCodec *decoder = NULL;

    unsigned int i;

    avio_open(&ps2->pb, "vid2.mp4", AVIO_FLAG_WRITE);

    for(i = 0; i < ps->nb_streams; i++)
    {
        printf("%d\n", i);

        iStream = ps->streams[i];

        pC[i] = iStream->codec;

        if(pC[i]->codec_type == AVMEDIA_TYPE_UNKNOWN) {
                printf("Skipping bad stream\n");
                continue;
        }

        oStream = avformat_new_stream(ps2, NULL);
        //avcodec_parameters_copy(oStream->codecpar, iStream->codecpar);
        p2C[i] = oStream->codec;

        if(pC[i]->codec_type == AVMEDIA_TYPE_VIDEO || pC[i]->codec_type == 
AVMEDIA_TYPE_AUDIO)
        {
            encoder = avcodec_find_encoder(pC[i]->codec_id);
            if (!encoder) {
                av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
                return AVERROR_INVALIDDATA;
            }

            //AVCodecParameters *pars = avcodec_parameters_alloc();
            //avcodec_parameters_from_context(pars, pC[i]);
            //avcodec_parameters_to_context(p2C[i], pars);

            if(pC[i]->codec_type == AVMEDIA_TYPE_VIDEO) {
                                p2C[i]->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

                p2C[i]->height = pC[i]->height;
                p2C[i]->width = pC[i]->width;
                p2C[i]->sample_aspect_ratio = pC[i]->sample_aspect_ratio;
                p2C[i]->gop_size = pC[i]->gop_size;
                //take first format from list of supported formats
                if (encoder->pix_fmts)
                    p2C[i]->pix_fmt = encoder->pix_fmts[0];
                else
                    p2C[i]->pix_fmt = pC[i]->pix_fmt;
                //video time_base can be set to whatever is handy and supported 
by encoder
                oStream->time_base = iStream->time_base;
                p2C[i]->time_base = pC[i]->time_base;

            } else {
                                p2C[i]->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
                p2C[i]->sample_rate = pC[i]->sample_rate;
                p2C[i]->channel_layout = pC[i]->channel_layout;
                p2C[i]->channels = 
av_get_channel_layout_nb_channels(p2C[i]->channel_layout);
                // take first format from list of supported formats
                p2C[i]->sample_fmt = encoder->sample_fmts[0];
                oStream->time_base = (AVRational){1, p2C[i]->sample_rate};
                p2C[i]->time_base = (AVRational){1, p2C[i]->sample_rate};
            }

            //AVCodecParameters *par = avcodec_parameters_alloc();
            //avcodec_parameters_from_context(par, pC[i]);
            //avcodec_parameters_to_context(p2C[i], par);

            decoder = avcodec_find_decoder(pC[i]->codec_id);
            if(decoder == NULL) printf("Couldn't find decoder\n");

            avcodec_open2(pC[i], decoder, NULL);
            avcodec_open2(p2C[i], encoder, NULL);

            //p2C-> = pC[i]->pts;
        }
        else if (pC[i]->codec_type == AVMEDIA_TYPE_UNKNOWN) {
            av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown 
type, cannot proceed\n", i);
            //return AVERROR_INVALIDDATA;
        }
        else
        {
            avcodec_copy_context(oStream->codec, iStream->codec);
            printf("BUG\n");
        }
    }
    printf("done\n");

    int ret = avformat_write_header(ps2, NULL);
    char err[200];
    av_make_error_string(err, 200, ret);
    printf("Write header %d: %s\n", ret, err);

    unsigned int j = 0;
    for(;; ++j)
    {
        AVPacket pkts;// = av_packet_alloc();
        AVPacket pktr;// = av_packet_alloc();
        AVFrame *rawFrame = av_frame_alloc();
        av_init_packet(&pkts);
        av_init_packet(&pktr);
        if(av_read_frame(ps, &pkts) != 0) break;

        int stream_index = pkts.stream_index;
                pkts.dts = av_rescale_q_rnd(pkts.dts, 
ps2->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
                pkts.pts = av_rescale_q_rnd(pkts.pts, 
ps->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
                pkts.duration = av_rescale_q(pkts.duration, 
ps2->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base);

                pktr.dts = av_rescale_q_rnd(pktr.dts, 
ps2->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
                pktr.pts = av_rescale_q_rnd(pktr.pts, 
ps->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
                pktr.duration = av_rescale_q(pktr.duration, 
ps2->streams[stream_index]->codec->time_base, 
ps2->streams[stream_index]->time_base);

        int got_out;
        if(pkts.stream_index == 0)
        {

            if(avcodec_decode_video2(pC[pkts.stream_index], rawFrame, &got_out, 
&pkts) >= 0)
            {
                if(avcodec_encode_video2(p2C[pkts.stream_index], &pktr, 
rawFrame, &got_out) == 0)
                {
                    if(av_interleaved_write_frame(ps2, &pktr) == 0)
                    {
                        printf("SUCCESSFULLY WROTE PACKET\n");
                        //break;
                    }
                } else printf("Failed to encode video\n");
            } else printf("Failed to decode video\n");
        }
        else
        {
            if(avcodec_decode_audio4(pC[pkts.stream_index], rawFrame, &got_out, 
&pkts) >= 0)
            {
                if(avcodec_encode_audio2(p2C[pkts.stream_index], &pktr, 
rawFrame, &got_out) == 0)
                {
                    if(av_interleaved_write_frame(ps2, &pktr) == 0)
                    {
                        printf("SUCCESSFULLY WROTE PACKET\n");
                        //break;
                    }
                } else printf("Failed to encode audio\n");
            } else printf("Failed to decode audio\n");
        }
        av_frame_free(&rawFrame);
    }



    if(av_write_trailer(ps2) == 0) printf("Wrote trailer\n");
}

****************************************
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to