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

C++

Войти
Регистрация
Восстановить пароль
 
 
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
#1

Ffmpeg выдает moov atom not found если прервать процесс кодирования - C++

08.02.2016, 10:27. Просмотров 1323. Ответов 22
Метки нет (Все метки)

имеется код выполняющий кодирование и запись видео в файл (через avio_open2 / avformat_write_header / av_interleaved_write_frame / av_write_trailer / avio_close)
Кликните здесь для просмотра всего текста
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
extern "C" {
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
}
 
#include <stdio.h>
#include <windows.h>
#include <time.h>
 
int main(int argc, char *argv[])
{
  AVFormatContext *ofcx;
  AVOutputFormat *ofmt;
  AVStream *ost;
 
  AVPacket pkt;
 
  const char *sFileOutput = "test.mp4";
 
  // Initialize library
  av_register_all();
  avformat_network_init();
 
  //
  // Output
  //
 
  //open output file
  ofmt = av_guess_format( NULL, sFileOutput, NULL );
  ofcx = avformat_alloc_context();
  ofcx->oformat = ofmt;
 
  int w = 800;
  int h = 600;
  int den = 25;
  int gop_size = 10;
  int codec_id = CODEC_ID_H264;
 
  // Create output stream
  AVCodec *ocodec = avcodec_find_encoder( (AVCodecID)codec_id );
  ost = avformat_new_stream( ofcx, ocodec );
  ost->codec->width = w;
  ost->codec->height = h;
  ost->codec->pix_fmt = ocodec->pix_fmts[0];
  ost->codec->time_base.num = 1; 
  ost->codec->time_base.den = den; 
  ost->time_base.num = 1;
  ost->time_base.den = den;
  ost->codec->gop_size = gop_size; 
  if ( ofcx->oformat->flags & AVFMT_GLOBALHEADER ) ost->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
  avcodec_open2( ost->codec, ocodec, 0 );
  
  AVFrame *frame = av_frame_alloc();
  frame->format = PIX_FMT_YUV420P;
  frame->width = w;
  frame->height = h;
  int buffer_size = avpicture_get_size(PIX_FMT_YUV420P, w, h);
  uint8_t *buffer = (uint8_t *)av_malloc(buffer_size * sizeof(uint8_t));
  avpicture_fill((AVPicture *)frame, 0, PIX_FMT_YUV420P, w, h);
 
  frame->data[0] = buffer;
  frame->data[1] = frame->data[0] + w * h;
  frame->data[2] = frame->data[1] + (w * h) / 4;
  frame->linesize[0] = w;
  frame->linesize[1] = w / 2;
  frame->linesize[2] = w / 2;
 
  avio_open2( &ofcx->pb, sFileOutput, AVIO_FLAG_WRITE, NULL, NULL );
 
  avformat_write_header( ofcx, NULL );
 
  av_init_packet( &pkt );
  for ( int i = 0; i < 25 * 10; i++ )
  {
        /* Y */
        for ( int y = 0; y < ost->codec->height; ++y ) {
            for ( int x = 0; x < ost->codec->width; ++x ) {
                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
            }
        }
 
        /* Cb and Cr */
        for ( int y = 0; y < ost->codec->height / 2; ++y ) {
            for ( int x = 0; x < ost->codec->width / 2; ++x ) {
                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                frame->data[2][y * frame->linesize[2] + x] =  64 + x + i * 5;
            }
        }
 
        frame->pts = av_rescale_q(i, ost->codec->time_base, ost->time_base);
 
        int got_packet;
        if (avcodec_encode_video2(ost->codec, &pkt, frame, &got_packet) != 0) break;
 
        if (got_packet) 
        {
            av_interleaved_write_frame( ofcx, &pkt );
            av_free_packet( &pkt );
            avio_flush(ofcx->pb);
        }
  }
  av_write_trailer( ofcx );
  avio_close( ofcx->pb );
  avformat_free_context( ofcx );
 
  return 0;
}

если прервать процесс кодирования до вызова av_write_trailer (закрыть программу до того как процесс будет завершен, прервать выполнение программы завершив процесс из диспетчера задач, отключить питание ПК), то файл формируется неправильно и не может быть воспроизведен - ffprobe выдает сообщение
[mov,mp4,m4a,3gp,3g2,mj2 @ 00d44c20] moov atom not found
test.mp4: Invalid data found when processing input
castaway предложил код производящий прямую запись пакетов получаемых при кодировании на диск (через fopen / fwrite / fclose)
Кликните здесь для просмотра всего текста
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
 
extern "C" {
 #define __STDC_CONSTANT_MACROS
 #include <libavutil/opt.h>
 #include <libavutil/imgutils.h>
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
}
 
int main()
{
    avcodec_register_all();
    av_register_all();
 
    AVCodec * codec = avcodec_find_encoder( AV_CODEC_ID_H264 );
    if ( codec ) {
        AVCodecContext * avCtx = avcodec_alloc_context3( codec );
        if ( avCtx ) {
 
            /// MUST be set by user.
            avCtx->width    = 720;
            avCtx->height   = 304;
 
            /// Set by user.
            avCtx->pix_fmt  = AV_PIX_FMT_YUV420P;
 
            avCtx->gop_size = 10;
            avCtx->max_b_frames = 1;
 
            /// MUST be set by user.
            avCtx->time_base = (AVRational){ 1, 25 }; // 1/fps
 
            /// Set by user; unused for constant quantizer encoding.
            avCtx->bit_rate = 1024 * 256;
 
            av_opt_set( avCtx->priv_data, "preset", "slow", 0 );
 
            if ( avcodec_open2( avCtx, codec, 0 ) >= 0 ) {
                AVFrame * frame = av_frame_alloc();
                if ( frame ) {
                    frame->format = avCtx->pix_fmt;
                    frame->width  = avCtx->width;
                    frame->height = avCtx->height;
 
                    int ret = av_image_alloc( frame->data, frame->linesize, avCtx->width, avCtx->height, avCtx->pix_fmt, 32 );
                    if ( ret >= 0 ) {
 
                        FILE * fp = fopen( "out.mp4", "wb+" );
                        if ( !fp ) {
                            std::cerr << "can't open output file\n";
                            return 1;
                        }
 
                        AVPacket pkt;
                        int got_output;
                        for ( int i = 0; i < 25 * 10/*seconds*/; ++i ) {
                            av_init_packet( &pkt );
                            pkt.data = NULL; // packet data will be allocated by the encoder
                            pkt.size = 0;
 
                            /* Y */
                            for ( int y = 0; y < avCtx->height; ++y ) {
                                for ( int x = 0; x < avCtx->width; ++x ) {
                                    frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
                                }
                            }
 
                            /* Cb and Cr */
                            for ( int y = 0; y < avCtx->height / 2; ++y ) {
                                for ( int x = 0; x < avCtx->width / 2; ++x ) {
                                    frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                                    frame->data[2][y * frame->linesize[2] + x] =  64 + x + i * 5;
                                }
                            }
                            frame->pts = i;
 
                            ret = avcodec_encode_video2( avCtx, &pkt, frame, &got_output );
                            if ( ret >= 0 && got_output ) {
                                fwrite( pkt.data, 1, pkt.size, fp );
                                av_packet_unref( &pkt );
                            }
                        }
 
                        /* get the delayed frames */
                        do {
                            ret = avcodec_encode_video2( avCtx, &pkt, NULL, &got_output );
                            if ( ret >= 0 && got_output ) {
                                fwrite( pkt.data, 1, pkt.size, fp );
                                av_packet_unref( &pkt );
                            }
                        } while ( got_output );
 
                        fclose( fp );
                    }
 
                    av_frame_free( &frame );
                }
            }
            av_free( avCtx );
        }
        avcodec_close( avCtx );
    }
}

файл формируемый этим кодом может быть воспроизведен даже в случае прерывания процесса кодирования. однако файлы получаемые в результате работы этого кода имеют некие особенности из-за которых они не могут быть воспроизведены например через VLC или KMP. вот что выдает ffprobe для файла формируемого моим кодом
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.30.100
Duration: 00:00:09.32, start: 0.000000, bitrate: 791 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 800x600,
789 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
и вот что выдает ffprobe для кода castaway
Input #0, h264, from 'out.mp4':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p, 720x304, 25 fps, 25 tbr, 1200k tbn
, 50 tbc
видна некая "неполнота" файла...
вопрос - как правильно записывать файл содержащий всю необходимую для воспроизведения информацию что бы прерывание процесса кодирования не приводило к его повреждению? нужна либо правка моего метода делающая его устойчивым к прерыванию кодирования либо правка метода castaway формирующая файл корректно
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.02.2016, 10:27
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ffmpeg выдает moov atom not found если прервать процесс кодирования (C++):

Если первый процесс за заданное время не выполнился, то прервать его и перейти к выполнению второго - C#
Помогите плиз с реализацией. У меня есть допустим 2 процесса. Каждому процессу назначается время на выполнение. Если 1-ый процесс за...

Как прервать процесс по кнопке в форме? - Visual Basic
ЕСТЬ ФОРМА В НЕЙ ДВЕ КНОПКИ ПЕРВАЯ ЗАПУСКАЕТ ЦИКЛ ПО ПЕРЕБОРУ ЗАПИСЕЙ В ТАБЛИЦЕ FOXPRO. ЧТО НУЖНО ПОВЕСТЬ НА ФОРМУ И КНОПКУ ЧТОБЫ ВОВРЕМЯ...

В процессе поиска после 5 итераций запрашиваем прервать процесс или нет - Turbo Pascal
В процессе поиска после 5 итераций запрашиваем прервать процесс или нет подскажите как это в проге написать

Так ли уж слаб Atom, или Atom vs. Pentium 4 - Процессоры
До сих пор Pentium 4 530 является основным моим процессором и менять его на что-то более мощное я совершенно не планировал. Однако жрёт он...

Отобразить процесс использования параметров тригонометрических функций для кодирования битов данных - MS Excel
Необходимо средствами EXСEL с помощью электронной таблицы отобразить процесс использования параметров тригонометрических функций для...

Nw.js. Запустить процесс. Command not found - Node.js
function Start() { const exec = require('child_process').exec; exec(&quot;node -v&quot;, (error, stdout, stderr) =&gt; { if (error) { ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 12:59 #2
Предполагается ОС Windows (со слов vxg).

Обработку простых вариантов (закрытие окна через крестик, обычное выключение ПК, Ctrl-C, ...) можно реализовать через SetConsoleCtrlHandler.
Кликните здесь для просмотра всего текста
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
#include <windows.h>
 
BOOL WINAPI ctrl_handler( DWORD fdwCtrlType ) {
    switch ( fdwCtrlType ) {
        case CTRL_C_EVENT:
        case CTRL_CLOSE_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:
 
            // ... безопасно прекращаем цикл записи ...
 
            return TRUE;
    }
    return FALSE;
}
 
int main() {
    ::SetConsoleCtrlHandler( ctrl_handler, TRUE );
 
    // ... кодируем ...
 
    ::SetConsoleCtrlHandler( ctrl_handler, FALSE );
}


Всё гораздо сложнее обстоит с завершением процесса через диспетчер задач и выключением ПК из розетки.
Событие завершением процесса через диспетчер задач вроде как-то можно отловить нестандартным путём. Об этом надо почитать.
На случай выключения ПК из розетки конечно же лучше иметь ИБП, но этот вариант не рассматривается, поэтому единственный выход который я вижу - периодически закрывать выходной поток данных. Как это лучше сделать тоже надо подумать...
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 13:30  [ТС] #3
Цитата Сообщение от castaway Посмотреть сообщение
Всё гораздо сложнее
как можете прокомментировать необычности в поведении файла формируемого прямой записью пакетов на диск? почему некоторые программы его могут открыть а другие ругаются и почему ffprobe показывает несколько странные данные?
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 16:14 #4
Цитата Сообщение от vxg Посмотреть сообщение
как можете прокомментировать необычности в поведении файла формируемого прямой записью пакетов на диск? почему некоторые программы его могут открыть а другие ругаются и почему ffprobe показывает несколько странные данные?
Насколько мне известно, там должна быть какая-то завершающая последовательность. Если её нет, то файл считается повреждённым.
Просто одни плееры лучше других обрабатывают испорченные файлы.
Кстати, вам принципиально использовать именно этот контейнер? Можно попробовать подобрать другой, с которым может быть меньше проблем.

Добавлено через 2 часа 16 минут
Input #0, h264, from 'out.mp4':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p, 720x304, 25 fps, 25 tbr, 1200k tbn, 50 tbc
Похоже причина в том, что в моём примере пишется сырое видео, без контейнера. Вполне возможно что именно поэтому некоторые плееры его не проигрывают.
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 16:43  [ТС] #5
Цитата Сообщение от castaway Посмотреть сообщение
видео, без контейнера
а как его оставив сырым контейнеризовать)?
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 17:04 #6
Цитата Сообщение от vxg Посмотреть сообщение
а как его оставив сырым контейнеризовать)?
Я имею в виду что кадры тупо пишутся в файл подряд.
Я как раз сейчас думаю над тем, как его 'контейнизировать'...

Добавлено через 8 минут
Цитата Сообщение от vxg Посмотреть сообщение
moov atom not found
Я понял из-за чего появляется это сообщение. Этот атом пишет функция av_write_trailer. Которая естественно не вызывается при прерывании программы.
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 18:14  [ТС] #7
Цитата Сообщение от castaway Посмотреть сообщение
Я понял из-за чего появляется это сообщение. Этот атом пишет функция av_write_trailer. Которая естественно не вызывается при прерывании программы.
я знал об этом и вопрос лишь в том как так сконфигурировать вывод что бы даже без этой функции все было нормально. я знаю что это возможно. я видел программы которые пишут нормальные контейнеры устойчивые к прерыванию кодирования. как они это делают я пока не знаю. ffmpeg как минимум может это делать из командной строки если настроить запись по сегментам. но у меня не получается сделать то же самое из C++
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 18:22 #8
Цитата Сообщение от vxg Посмотреть сообщение
ffmpeg как минимум может это делать из командной строки если настроить запись по сегментам. но у меня не получается сделать то же самое из C++
Даже если прервать через диспетчер задач?
Под записью по сегментам вы подразумеваете несколько выходных файлов? Если так, то это ещё проще.
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 18:43  [ТС] #9
Да даже если прервать. Нет запись идёт одним файлом. Подробнее в описании ключей -f segment и -segment_time N
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 18:55 #10
Пример завершения при закрытии консольного окна
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <windows.h>
#include <iostream>
 
extern "C" {
 #define __STDC_CONSTANT_MACROS
 #include <libavutil/opt.h>
 #include <libavutil/time.h>
 #include <libavutil/imgutils.h>
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
}
 
static BOOL g_bStop = FALSE;
static BOOL g_bCanExit = FALSE;
 
static BOOL WINAPI ctrl_handler( DWORD fdwCtrlType ) {
    switch ( fdwCtrlType ) {
        case CTRL_C_EVENT:
        case CTRL_CLOSE_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:
            g_bStop = TRUE;
            while ( !g_bCanExit ) ::Sleep( 100 );
            return TRUE;
    }
    return FALSE;
}
 
int main()
{
    ::SetConsoleCtrlHandler( ctrl_handler, TRUE );
    av_register_all();
 
    const char * filename = "out.mp4";
 
    AVFormatContext * p_fmt_ctx;
    avformat_alloc_output_context2( &p_fmt_ctx, NULL, NULL, filename );
    if ( !p_fmt_ctx ) {
        std::cerr << "Could not deduce output format from file extension" << std::endl;
    } else {
        enum AVCodecID codec_id = AV_CODEC_ID_H264;
        AVCodec * p_codec = avcodec_find_encoder( codec_id );
        if ( !p_codec ) {
            std::cerr << "Could not find encoder for " << avcodec_get_name( codec_id ) << std::endl;
        } else {
            AVStream * p_stream = avformat_new_stream( p_fmt_ctx, p_codec );
            if ( !p_stream ) {
                std::cerr << "Could not allocate stream" << std::endl;
            } else {
                p_stream->id = p_fmt_ctx->nb_streams - 1;
 
                AVCodecContext * c = p_stream->codec;
                av_opt_set( c->priv_data, "preset", "slow", 0 );
 
                c->codec_id = codec_id;
 
                c->bit_rate = 1024 * 128;
                c->width    = 352;
                c->height   = 288;
 
                p_stream->time_base = (AVRational){ 1, 25 };
                c->time_base = p_stream->time_base;
 
                c->gop_size = 12; /* emit one intra frame every twelve frames at most */
                c->pix_fmt = AV_PIX_FMT_YUV420P;
 
                av_dump_format( p_fmt_ctx, 0, filename, 1 );
 
                /// open file
                avio_open2( &p_fmt_ctx->pb, filename, AVIO_FLAG_WRITE, NULL, NULL );
 
                /// write header
                if ( avformat_write_header( p_fmt_ctx, NULL ) != 0 ) {
                    std::cerr << "Could not write header" << std::endl;
                }
 
                /// open codec
                if ( avcodec_open2( c, p_codec, 0 ) >= 0 ) {
                    AVFrame * p_frame = av_frame_alloc();
                    if ( p_frame ) {
                        p_frame->format = c->pix_fmt;
                        p_frame->width  = c->width;
                        p_frame->height = c->height;
                        if ( av_image_alloc( p_frame->data, p_frame->linesize, c->width, c->height, c->pix_fmt, 32 ) >= 0 ) {
 
                            // ---------------------------------------------
                            AVPacket pkt;
 
                            int got_output;
                            for ( int i = 0; /*i < 25 * 30 &&*/ !g_bStop; ++i ) {
                                av_init_packet( &pkt );
                                pkt.data = NULL; // packet data will be allocated by the encoder
                                pkt.size = 0;
 
                                /* Y */
                                for ( int y = 0; y < c->height; ++y ) {
                                    for ( int x = 0; x < c->width; ++x ) {
                                        p_frame->data[0][y * p_frame->linesize[0] + x] = x + y + i * 3;
                                    }
                                }
 
                                /* Cb and Cr */
                                for ( int y = 0; y < c->height / 2; ++y ) {
                                    for ( int x = 0; x < c->width / 2; ++x ) {
                                        p_frame->data[1][y * p_frame->linesize[1] + x] = 128 + y + i * 2;
                                        p_frame->data[2][y * p_frame->linesize[2] + x] =  64 + x + i * 5;
                                    }
                                }
 
                                p_frame->pts = i * 25 * 30;//21;
                                //p_frame->pts = av_rescale_q( i, (AVRational){ 1, 25 }, (AVRational){ 1, 25 * 25 * 30 } );
 
                                int ret = avcodec_encode_video2( c, &pkt, p_frame, &got_output );
                                if ( ret >= 0 && got_output ) {
                                    av_interleaved_write_frame( p_fmt_ctx, &pkt );
                                    avio_flush( p_fmt_ctx->pb );
                                    av_packet_unref( &pkt );
                                }
                            }
 
                            /* get the delayed frames */
                            do {
                                int ret = avcodec_encode_video2( c, &pkt, NULL, &got_output );
                                if ( ret >= 0 && got_output ) {
                                    av_interleaved_write_frame( p_fmt_ctx, &pkt );
                                    avio_flush( p_fmt_ctx->pb );
                                    av_packet_unref( &pkt );
                                }
                            } while ( got_output && !g_bStop );
 
                            av_freep( &p_frame->data[0] );
                        }
                        av_frame_free( &p_frame );
                    }
                    avcodec_close( c );
                }
 
                /// write trailer etc...
                av_write_trailer( p_fmt_ctx );
                avio_close( p_fmt_ctx->pb );
                avcodec_close( c );
            }
        }
    }
    avformat_free_context( p_fmt_ctx );
    g_bCanExit = TRUE;
    ::SetConsoleCtrlHandler( ctrl_handler, FALSE );
}

А вот при выключении ПК из розетки поток в любом случае останется поврежденным (недописанным).
Как вариант - делить выходной файл на сегменты. Вас это устроит?

Добавлено через 1 минуту
Цитата Сообщение от vxg Посмотреть сообщение
Да даже если прервать.
Мне даже интересно стало. Сейчас попробую проверить как это работает.

Добавлено через 9 минут
vxg, у меня тут кое что не складывается... Вы можете привести пример командной строки перекодирования файла в сегментном режиме?
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 19:02  [ТС] #11
По памяти вроде как -f segment -segment_time 30 для деления каждые 30 с (за второй минус не уверен)
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 19:18 #12
Цитата Сообщение от vxg Посмотреть сообщение
Нет запись идёт одним файлом.
Вы что-то путаете. Эти опции как раз предназначены для того, чтобы на выходе получалось несколько файлов.
Именно такой результат получается с командной строкой: ffmpeg -i in.mp4 -f segment -segment_time 10 -segment_format_options movflags=+faststart out%03d.mp4
И именно такое поведение описано в документации к FFMPEG.
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 19:23  [ТС] #13
А вы пробовали оборвать процесс до завершения формирования сегмента?
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
08.02.2016, 19:31 #14
Цитата Сообщение от vxg Посмотреть сообщение
А вы пробовали оборвать процесс до завершения формирования сегмента?
Да. Завершая процесс через диспетчер задач, ffprobe на последний сегмент говорит: moov atom not found
Что, на самом деле, вполне ожидаемо и логично.
vxg
Модератор
3157 / 1959 / 218
Регистрация: 13.01.2012
Сообщений: 7,492
08.02.2016, 22:25  [ТС] #15
Цитата Сообщение от castaway Посмотреть сообщение
ожидаемо и логично
каюсь, ошибался, действительно этот вариант так же повреждает файл при прерывании кодирования
вот пример файла который формировался программой умеющей обходить повреждения в момент отключения питания компьютера - я ничего необычного в нем не нашел кроме разве что некого [0x1e0] после маркировки потока может у вас что то выйдет?
Вложения
Тип файла: rar test.rar (1.18 Мб, 6 просмотров)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.02.2016, 22:25
Привет! Вот еще темы с ответами:

Прервать выполнение, если сработало условие - C++ Builder
Проблема такого плана, при выполнении if(Q-&gt;IsEmpty()) Memo1-&gt;Lines-&gt;Add(&quot;Постановление № &quot; + StringGrid1-&gt;Cells + &quot; от &quot; +...

Как прервать программу если она зациклилась? - Turbo Pascal
Как прервать программу если она зациклилась? Заголовок темы изменен модератором. Он должен быть информативным, отображая...

Прервать работу батника, если FTP-сервер недоступен - CMD/BAT
У меня реализован батник с работой по фтп. Как прервать работу батника если фтп не доступно echo open 192.168.0.101 &gt;&gt;1.txt ...

javap выдает ошибку class not found - Java
Адрес класса C:\Users\Vitya\IdeaProjects\Security2\src\Main.java Содержание класса public class Main { public static void...


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

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

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