(FFMPEG) avformat_write_header аварийно завершает работу (MSVC2013) (C++) (Qt)

Я только что скачал FFMPEG и теперь пытаюсь использовать его в Qt с компилятором MSVC2013.

Чтобы понять, как это работает, я начал читать документацию и API. Согласно этому рисунку, я пытался провести небольшой тест с libavformat .

Я сделал все, что они сказали в модуле демультиплексирования, а затем в модуле мультиплексирования. Но моя программа падает, когда я вызываю функцию avformat_write_header().

Я хотел бы знать, что я сделал неправильно, и если бы вы могли помочь мне понять это.

В основном:

av_register_all();

if(!decode())
    return;

Метод декодирования():

bool MainWindow::decode()
{
AVFormatContext *formatContext = NULL;
AVPacket packet;

/**************** muxing varaiables ******************/

AVFormatContext *muxingContext = avformat_alloc_context();
AVOutputFormat *outputFormat = NULL;
AVIOContext *contextIO = NULL;
AVCodec *codecEncode = avcodec_find_encoder(AV_CODEC_ID_WMAV2);
AVStream *avStream =  NULL;
AVCodecContext *codecContext = NULL;


/******************* demuxing **************************/

//open a media file
if(avformat_open_input(&formatContext,"h.mp3",NULL,NULL)!=0)
{
    qDebug() << "paka ouve fichier";
    return false;
}

//function which tries to read and decode a few frames to find missing          
information.
if(avformat_find_stream_info(formatContext,NULL)<0)
{
    qDebug()<<"paka find stream";
    return false;
}


/**************** muxing *************************/

//The oformat field must be set to select the muxer that will be used.
muxingContext->oformat = outputFormat;

//Unless the format is of the AVFMT_NOFILE type, the pb field must be set to
//an opened IO context, either returned from avio_open2() or a custom one.
if(avio_open2(&contextIO,"out.wma",AVIO_FLAG_WRITE,NULL,NULL)<0)
{
    qDebug() <<"paka kreye fichier soti";
    return false;
}
muxingContext->pb = contextIO;

//Unless the format is of the AVFMT_NOSTREAMS type, at least
//one stream must be created with the avformat_new_stream() function.
avStream = avformat_new_stream(muxingContext,codecEncode);

//The caller should fill the stream codec context information,
//such as the codec type, id and other parameters
//(e.g. width / height, the pixel or sample format, etc.) as known

codecContext = avStream->codec;
codecContext->codec_type = AVMEDIA_TYPE_AUDIO;
codecContext->codec_id = AV_CODEC_ID_WMAV2;
codecContext->sample_fmt = codecEncode->sample_fmts[0];
codecContext->bit_rate = 128000;
codecContext->sample_rate = 44000;
codecContext->channels = 2;

//The stream timebase should be set to the timebase that the caller desires
//to use for this stream (note that the timebase actually used by the muxer
//can be different, as will be described later).

avStream->time_base = formatContext->streams[0]->time_base;
qDebug()<<formatContext->streams[0]->time_base.num <<"/" 
<<formatContext-    >streams[0]->time_base.den;


//When the muxing context is fully set up, the caller must call     
//avformat_write_header()
//to initialize the muxer internals and write the file header

qDebug() << "does not crash yet";
if(avformat_write_header(muxingContext,NULL) <0)
{
    qDebug()<<"cannot write header";
    return false;
}
qDebug() << "OOps you can't see me (John Cena)";

///////////////////// Reading from an opened file //////////////////////////
while(av_read_frame(formatContext,&packet)==0)
{
    //The data is then sent to the muxer by repeatedly calling
    //av_write_frame() or av_interleaved_write_frame()
    if(av_write_frame(muxingContext,&packet)<0)
        qDebug()<<"paka write frame";
    else
        qDebug()<<"writing";
}

//Once all the data has been written, the caller must call
//av_write_trailer() to flush any buffered packets and finalize
//the output file, then close the IO context (if any) and finally
//free the muxing context with avformat_free_context().

if(av_write_trailer(muxingContext)!=0)
{
    qDebug()<<"paka ekri trailer";
    return false;
}


return true;
}

Программа показывает сообщение еще не падает. Но не ой, ты меня не видишь (Джон Сина)

И ошибки нет. Я использовал файл MP3 в качестве входных данных и хотел бы вывести его в формате WMA.


person user3502626    schedule 28.04.2015    source источник
comment
Сбой в libavformat/mux.c строке 295, потому что muxingContext->oformat это NULL.   -  person Cornstalks    schedule 28.04.2015
comment
Существует оболочка Qt ffmpeg — code.google.com/p/qtffmpegwrapper.   -  person sashoalm    schedule 28.04.2015
comment
Как я могу создать AVOutputFormat не NULL?   -  person user3502626    schedule 28.04.2015
comment
Оболочка Qt ffmpeg предназначена только для видео. Не аудио   -  person user3502626    schedule 28.04.2015
comment
Я еще не знаю, зачем использовать AVOutputFormat.   -  person user3502626    schedule 28.04.2015


Ответы (1)


Вместо avformat_alloc_context() используйте avformat_alloc_output_context2(). Это установит muxingContext->oformat.

person Ronald S. Bultje    schedule 29.04.2015
comment
Привет, я использовал avformat_alloc_output_context2() перед вызовом (muxingContext->oformat = outputFormat и без muxingContext->oformat = outputFormat) и avformat_write_header(). Но он продолжает падать - person user3502626; 30.04.2015
comment
У вас есть предыстория вашего крушения? - person Ronald S. Bultje; 30.04.2015
comment
Я просто запускаю программу в режиме отладки. Я обнаружил нарушение прав на запись, но не могу понять почему. Я сделал именно то, что прочитал в подробном описании API мультиплексирования. Может это потому что я плохо понимаю это слово Если формат не типа AVFMT_NOFILE. Как узнать, относится ли формат к типу AVFMT_NOFILE или AVFMT_NOSTREAMS. Исключение исходит из AVIOContext, который я открыл с помощью avio_open2(), прежде чем установить для него значение muxingContext->pb, как указано в описании API мультиплексирования. - person user3502626; 01.05.2015
comment
У меня есть файл с примерами. Я проверю их и пойму их. думаю будет лучше - person user3502626; 01.05.2015
comment
Это не обратная трассировка, Visual Studio называет это трассировкой вызовов: msdn.microsoft.com/en-us/library/windows/hardware/ - person Ronald S. Bultje; 02.05.2015
comment
Я не использую Visual Studio IDE, когда вы отлаживаете Qt, он показывает трассировку стека вызовов, когда программа прерывается.. Я не мог показать вам трассировку стека вызовов, потому что не мог скопировать и вставить ее. строка файла функции уровня 0 avformat_write_header avformat_56 0x62ff10e4 1 _unlock mlock.c 368 0xffff754 - person user3502626; 02.05.2015
comment
далее: 0 KiUserExceptionDispatcher ntdll 0x779d6fd2 1 avformat_write_header avformat_56 0x62ff10e4 2 _unlock mlock.c 368 0xffff754 - person user3502626; 03.05.2015
comment
Спасибо за помощь. Я решил проблему. Все, что мне нужно было сделать, это прочитать файл примеров. - person user3502626; 04.05.2015