Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.58
nikphil87
0 / 0 / 0
Регистрация: 03.01.2010
Сообщений: 182
#1

ffmpeg конвертация файла - C++

15.08.2013, 16:07. Просмотров 1717. Ответов 9
Метки нет (Все метки)

Всем привет! Делаю первые шаги в ffmpeg'e. Для начала просто решил без конвертации раскодировать один файл и сделать другой.
Вот код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void work_with_video()
{
    AVFormatContext *pFormatCtx = NULL;
    AVPacket avpkt;
    AVCodec *pCodec;
    AVCodecContext *pCodecCtx;
    FILE *f;
    AVFrame *pFrame;
    int videoStream, i, frameFinished, got_output;
 
    av_register_all();
 
    avformat_open_input(&pFormatCtx,"001.avi",NULL,NULL);
    
    avformat_find_stream_info(pFormatCtx,NULL);
 
    videoStream=-1;
 
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 
    {
      videoStream=i;
      break;
    }
 
    pCodecCtx = pFormatCtx->streams[videoStream]->codec;
 
    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
 
    avcodec_open2(pCodecCtx,pCodec,NULL);
    
    pFrame = avcodec_alloc_frame();
 
    i=0;
    while(av_read_frame(pFormatCtx, &avpkt)>=0) 
    {
        if(avpkt.stream_index==videoStream) 
        {
             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &avpkt);
             if(frameFinished) 
             {
             avcodec_encode_video2(pCodecCtx, &avpkt, pFrame,&got_output);
             }
        }
    }
 
}
Ломается на первом обращении avcodec_encode_video2.
Делаю в консоли прочитать ошибку не получается окно сворачивается сразу же.
Подскажите в чем может быть проблема.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2013, 16:07
Здравствуйте! Я подобрал для вас темы с ответами на вопрос ffmpeg конвертация файла (C++):

Чтение файла (с кракозябрами) с однобайтовой кодировкой, конвертация в UTF-8 и вывод в другой файл - C++
Добрый день, форумчане. Может у кого есть заготовка или кто поделится советом, необходимо прочитать файл (с кракозябрами) с однобайтовой...

ffmpeg - C++
Всем привет, помогите начинающему разобраться с такой проблемой: ffmpeg + sdl - очень долго приложение сидит в функции av_find_stream_info...

Ffmpeg конфликт библиотек - C++
В проекте возникает потребность пользоваться одновременно (или хотя бы поочерёдно) этими библиотеками #include &lt;libavcodec/avcodec.h&gt; ...

Подключение библиотеки ffmpeg к проекту - C++
Здравствуйте. Я начал разбираться с библиотекой ffmpeg. Но не пойму как ее можно подключить к проекту в С++ и можно ее подключить и...

Обработка массива байт проходящих с ip -камеры ffmpeg' ом - C++
Всем доброго времени суток. С обработкой видео которое сохранено в файле ffmpeg'ом все понятно. А как можно обработать массив байт,...

Фильтры в ffmpeg: нужно ли отдельными функциями заполнять AVFilterContext? - C++
Здравствуйте. В интернете в статье программирования на базе ffmpeg приводился пример с использованием функция для заполнения...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
nikphil87
0 / 0 / 0
Регистрация: 03.01.2010
Сообщений: 182
15.08.2013, 17:38  [ТС] #2
А вот и ошибка
0
Миниатюры
ffmpeg конвертация файла  
mcSHLANG
5 / 5 / 0
Регистрация: 04.04.2013
Сообщений: 44
15.08.2013, 22:13 #3
Здравствуйте.
Прошу прощение что не особо по теме, но на днях тоже начал этим заниматься. И не пойму как подключить ffmpeg к проекту. Не подскажите как это сделать?
0
Fyret
184 / 170 / 13
Регистрация: 30.07.2013
Сообщений: 359
16.08.2013, 00:16 #4
Цитата Сообщение от nikphil87 Посмотреть сообщение
Ломается на первом обращении avcodec_encode_video2.
Вы пытаетесь декодировать и енкодировать в одном контексте. Не могу утверждать, что так делать нельзя, но я бы точно не стал. Плюс, Вы нашил декодер с помощью avcodec_find_decoder. А енкодер? Это разные вещи. Есть avcodec_find_encoder и avcodec_find_encoder_by_name.
0
nikphil87
0 / 0 / 0
Регистрация: 03.01.2010
Сообщений: 182
16.08.2013, 10:23  [ТС] #5
Спасибо, модификацией кода удалось устранить ошибкой вот работающий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
void work_with_video()
{
    AVFormatContext *pFormatCtx = NULL;
    AVPacket avpkt;
    AVPacket avpkt1;
    AVCodec *pDCodec;
    AVCodec *pECodec;
    AVCodecContext *pCodecCtx;
    AVCodecContext *pECodecCtx;
    AVCodecContext *pDCodecCtx;
    FILE *f;
    AVFrame *pFrame;
    int videoStream, i, frameFinished, got_output;
    AVRational avrat;
 
 
    av_register_all();
 
    av_init_packet(&avpkt);
    
 
 
    avformat_open_input(&pFormatCtx,"001.avi",NULL,NULL);
 
    avformat_find_stream_info(pFormatCtx,NULL);
 
    videoStream=-1;
 
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) 
    {
      videoStream=i;
      break;
    }
 
    pDCodecCtx = pFormatCtx->streams[videoStream]->codec;
 
    pECodecCtx = pFormatCtx->streams[videoStream]->codec;
 
    pDCodec = avcodec_find_decoder(pDCodecCtx->codec_id);
 
    pDCodecCtx = avcodec_alloc_context3(pDCodec);
 
    pECodec = avcodec_find_encoder(pECodecCtx->codec_id);
 
    pECodecCtx = avcodec_alloc_context3(pECodec);
    
    pECodecCtx -> bit_rate = 400000;
    pECodecCtx -> width = 352;
    pECodecCtx -> height = 288;
    avrat.num=1;
    avrat.den=25;
    pECodecCtx -> time_base= (AVRational)avrat;
    pECodecCtx -> gop_size = 10;
    pECodecCtx -> max_b_frames=1;
    pECodecCtx -> pix_fmt = AV_PIX_FMT_YUV420P;
 
    f = fopen("002.avi", "wb");
 
 
    avcodec_open2(pDCodecCtx,pDCodec,NULL);
 
 
    avcodec_open2(pECodecCtx,pECodec,NULL);
    
 
    pFrame = avcodec_alloc_frame();
 
    i=0;
    while(av_read_frame(pFormatCtx, &avpkt)>=0) 
    {
        if(avpkt.stream_index==videoStream) 
        {
             avcodec_decode_video2(pDCodecCtx, pFrame, &frameFinished, &avpkt);
             if(frameFinished) 
             {
             av_init_packet(&avpkt1);
             avcodec_encode_video2(pECodecCtx, &avpkt1, pFrame, &got_output);
             if (got_output) 
             {
             printf("Write frame %3d (size=%5d)\n", i, avpkt1.size);
             fwrite(avpkt1.data, 1, avpkt1.size, f);
             av_free_packet(&avpkt1);
             }
             av_free_packet(&avpkt1);
             }
        }
    }
    fclose(f);
}
В результате получился файл 002.avi. При его проигрывании возникает ошибка "can not renderer file", открыл в hexe заголовок у файла отсутсвует. Каким образом записывается заголовок, в экземплах нигде найти не могу.
0
Fyret
184 / 170 / 13
Регистрация: 30.07.2013
Сообщений: 359
16.08.2013, 12:09 #6
Цитата Сообщение от nikphil87 Посмотреть сообщение
Каким образом записывается заголовок
Название функции слегка меняется от версии к версии, сейчас это вроде avformat_write_header (перед началом записи пакетов) и av_write_trailer (после записи всех пакетов.)
0
nikphil87
0 / 0 / 0
Регистрация: 03.01.2010
Сообщений: 182
16.08.2013, 12:22  [ТС] #7
Ну вот я использую avformat_write_header(pFormatCtx,NULL); - формируется ошибка, я так понимаю из-за неправильного использования pFormatCtx, который я беру функцией avformat_open_input(&pFormatCtx,"001.avi",NULL,NULL);
А хидер должен относится к файлу 002.avi
То есть аргумент pFormatCtx тоже надо получать какой-то специальной функцией для второго файла
0
Fyret
184 / 170 / 13
Регистрация: 30.07.2013
Сообщений: 359
16.08.2013, 13:45 #8
Вот как схематично у меня выглядит запись пакетов в файл. Только запись, енкодинг, т.е. создание пакетов, успешно совершается в другом месте:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
av_register_all();
 
AVOutputFormat* muxer = av_guess_format( ext, NULL, NULL );
 
AVFormatContext* formatCtx = NULL;
avformat_alloc_output_context2( &formatCtx, muxer, NULL, filename.c_str() );
 
avio_open( &formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE );
 
avformat_write_header( formatCtx, NULL );
 
// ...
av_write_frame( formatCtx, &pkt )
// ...
 
av_write_trailer( formatCtx );
И я снова рекомендую использовать разные контексты (AVFormatContext) для разных файлов.
1
nikphil87
0 / 0 / 0
Регистрация: 03.01.2010
Сообщений: 182
19.08.2013, 10:00  [ТС] #9
Попробовал по твоему образу и подобию, хидер не пишет и выдает сообщение на вызове функции avformat_write_header - no streams
0
Fyret
184 / 170 / 13
Регистрация: 30.07.2013
Сообщений: 359
19.08.2013, 15:36 #10
Я забыл указать, что между avio_open и avformat_write_header создаются потоки. Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// video stream
AVStream* stream = av_new_stream( formatCtx, streamId );
AVCodecContext* codecCtx = stream->codec;
avcodec_get_context_defaults2( codecCtx, AVMEDIA_TYPE_VIDEO );
 
codecCtx->codec_id = codecId;
codecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
codecCtx->time_base.num = fps.den;
codecCtx->time_base.den = fps.num;
 
// extradata
if( !extraData.empty() )
{
    codecCtx->extradata = ( uint8_t* ) av_malloc( extraData.size() );
    memcpy( codecCtx->extradata,  ( void* ) &extraData[ 0 ], extraData.size() );
    codecCtx->extradata_size = extraData.size();
}
 
codecCtx->width = width;
codecCtx->height = height;
codecCtx->pix_fmt = static_cast< PixelFormat >( pixFormat );
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// audio stream
AVStream* stream = av_new_stream( formatCtx, streamId );
AVCodecContext* codecCtx = stream->codec;
avcodec_get_context_defaults2( codecCtx, AVMEDIA_TYPE_AUDIO );
 
codecCtx->codec_id = codecId;
codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
codecCtx->time_base.num = rate.den;
codecCtx->time_base.den = rate.num;
 
// extradata
if( !extraData.empty() )
{
    codecCtx->extradata = ( uint8_t* ) av_malloc( extraData.size() );
    memcpy( codecCtx->extradata,  ( void* ) &extraData[ 0 ], extraData.size() );
    codecCtx->extradata_size = extraData.size();
}
 
codecCtx->sample_rate = rate.num;
codecCtx->channels = channels;
codecCtx->frame_size = frameSize;
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2013, 15:36
Привет! Вот еще темы с ответами:

Ffmpeg изменение bit_rate не влияет на качество записи видео - C++
имеется код выполняющий кодирование и запись видео в файл extern &quot;C&quot; { #include &lt;libavformat/avformat.h&gt; #include...

Ffmpeg выдает moov atom not found если прервать процесс кодирования - C++
имеется код выполняющий кодирование и запись видео в файл (через avio_open2 / avformat_write_header / av_interleaved_write_frame /...

Конвертация - C++
Подскажите пожалуйста код как считать в бинарном виде файл и вывести его в виде 0 и 1 и соответственно записать файл в бинарном виде

Конвертация строк. - C++
Существует задача преобразования текста, читаемого из файла в кодировке ANSI в кодировку ASCII, чтобы русский текст нормально отражался в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
19.08.2013, 15:36
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru