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

C++

Войти
Регистрация
Восстановить пароль
 
 
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
#1

Ffmpeg изменение bit_rate не влияет на качество записи видео - C++

11.02.2016, 11:58. Просмотров 1171. Ответов 36
Метки нет (Все метки)

имеется код выполняющий кодирование и запись видео в файл
Кликните здесь для просмотра всего текста
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
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->bit_rate = 1234; //===========КАК НЕ МЕНЯЙ - НИЧЕГО НЕ ПРОИСХОДИТ!!!==============
  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;
}

castaway предложил код
Кликните здесь для просмотра всего текста
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 );
    }
}

в моем коде никакие изменения bit_rate не меняют фактического качества видео-записи - она стабильно "хорошего" качества.
в коде castaway изменения bit_rate существенно изменяют фактическое качество видео-записи как и должно быть.
вопрос - что я делаю не так? где то место в котором мои настройки отвергаются ffmpeg и заменяются не пойми на что? грешил на функцию avformat_write_header так как после ее вызова действительно происходят изменения в настройках (корректируется частота), но не уверен...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2016, 11:58     Ffmpeg изменение bit_rate не влияет на качество записи видео
Посмотрите здесь:
Декодирование видео используя ffmpeg, dxva Visual C++
Сделать простенький видео плеер с использованием FFMPEG C++
C++ Builder Качество видео.
Библиотека для записи видео (screencapture + audio) C++
C++ Ffmpeg на С++
C++ ffmpeg
Работа с ffmpeg C++ C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
12.03.2016, 08:42  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #21
У меня при обновлении всего лишь отвергал константы кодека и формата пикселей так как якобы теперь их нельзя писать без префикса AV_ все остальное без проблем вроде было я попробую ещё раз но вы сами понимаете они немогли навернуть апи за три месяца)
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
12.03.2016, 19:55     Ffmpeg изменение bit_rate не влияет на качество записи видео #22
Не могу найти то сообщение, где я приводил пример смены контроля качества.. Вы не помните?
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 08:24  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #23
Собственно в теме приведён и мой и ваш код работу которого я хочу воспроизвести или вы не про это?
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
13.03.2016, 10:54     Ffmpeg изменение bit_rate не влияет на качество записи видео #24
vxg, с использованием своей (более новой) версии FFMPEG ваш пример позволяет менять bitrate.
bitrate = 1024 - размер файла: 592.384
bitrate = 1024 * 64 - размер файла: 1.242.089
Разница в качестве вполне ощутима на глаз.
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 10:58  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #25
Изменения размера я видел но визуально при качестве 1000 в вашем коде изображение рассыпается на пиксели а в моем чуть чуть заметны ступеньки
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
13.03.2016, 11:35     Ffmpeg изменение bit_rate не влияет на качество записи видео #26
Цитата Сообщение от vxg Посмотреть сообщение
но визуально при качестве 1000 в вашем коде
Мой код не идентичен вашему. Разница в качестве может быть вызвана например этим: av_opt_set( avCtx->priv_data, "preset", "slow", 0 );, или этим: avCtx->max_b_frames = 1;.
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 11:42  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #27
Попробую но думаю пресет не влияет и б фрейм тоже маловероятно и сами понимаете что изменение битрейта в сотни раз как то слабенько влияет в моем коде. Субъективно конечно.
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
13.03.2016, 11:47     Ffmpeg изменение bit_rate не влияет на качество записи видео #28
Это может зависеть и от версии FFMPEG. Кстати вы мне так и не ответили почему вы не хотите использовать более свежую версию.
В каких диапазонах вы меняли bit_rate? Дайте два значения, низкое и высокое.
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 12:06  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #29
Потому что нет разницы в поведении новейшей и предыдущей версии. Ориентируясь на ваш код пробовал 1024*256 и 1024
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
13.03.2016, 13:12     Ffmpeg изменение bit_rate не влияет на качество записи видео #30
Цитата Сообщение от vxg Посмотреть сообщение
Потому что нет разницы в поведении новейшей и предыдущей версии.
А откуда вы знаете? Вы сравнивали?
Мне кажется вы беспокоитесь по мелочам. Вы же решили главный вопрос!?
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 13:36  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #31
Главный вопрос этой темы - почему существенное изменение битрейта в моем коде не приводит к изменениям качества настолько же субъективно различимым как при аналогичных изменениях битрейта в вашем коде - не производится ли у меня какой-то скрытой дефолтной подстановки вместо устанавливаемого битрейта некой иной существенно большей стандартной величины. Это вопрос я все ещё не решил.

Добавлено через 1 минуту
Да я сравнивал визуально результаты работы в разных версиях они визуально не различимы
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
13.03.2016, 14:32     Ffmpeg изменение bit_rate не влияет на качество записи видео #32
Цитата Сообщение от vxg Посмотреть сообщение
Главный вопрос этой темы - почему существенное изменение битрейта в моем коде не приводит к изменениям качества настолько же субъективно различимым как при аналогичных изменениях битрейта в вашем коде
Я не могу использовать вашу версию FFMPEG. Честно говоря, я вообще не понимаю зачем вам это надо...

Добавлено через 37 минут
Вы обещали выложить EXE-шники.
Цитата Сообщение от vxg Посмотреть сообщение
Да я сравнивал визуально результаты работы в разных версиях они визуально не различимы
Я не вижу смысла продолжать это разбирательство до тех пор, пока у нас не будет полное соответствие в среде.
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 14:55  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #33
Цитата Сообщение от castaway Посмотреть сообщение
Вы обещали выложить EXE-шники
выкладываю как обещал. exe получены из моего кода который приведен в шапке темы. собраны с теми DLL которые я выкладывал ранее.
дополнительно показываю результаты ffprobe для файлов генерируемых моим и вашим кодом
----
vxg
bitrate=1024*256
filesize=1*277*457
----
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: 1096 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 800x600,
1094 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
----
vxg
bitrate=1024
filesize=601*322
----
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: 516 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 800x600,
514 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
----
castaway
bitrate=1024*256
filesize=301*061
----
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
bitrate=1024
filesize=66*621
----
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
дополнительно прикладываю скрины того что я вижу воспроизводя файлы с разными битрейтами полученные по моему и по вашему коду
Миниатюры
Ffmpeg изменение bit_rate не влияет на качество записи видео   Ffmpeg изменение bit_rate не влияет на качество записи видео   Ffmpeg изменение bit_rate не влияет на качество записи видео  

Ffmpeg изменение bit_rate не влияет на качество записи видео  
Вложения
Тип файла: rar exe.rar (114.8 Кб, 1 просмотров)
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
13.03.2016, 15:01  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #34
...забавно что наш форм превращает пробел в качестве разделителя разрядов в знак умножить...

Добавлено через 3 минуты
...дополнительно проверил - пресет и б фрейм не изменяют ничего в описанной ситуации...
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
14.03.2016, 17:38     Ffmpeg изменение bit_rate не влияет на качество записи видео #35
vxg, у вас ваш код выводит сообщение: [libx264 @ 007ba8a0] non-strictly-monotonic PTS?
vxg
Модератор
3119 / 1921 / 208
Регистрация: 13.01.2012
Сообщений: 7,357
14.03.2016, 18:59  [ТС]     Ffmpeg изменение bit_rate не влияет на качество записи видео #36
Проб не выводит плеем попробую

Добавлено через 37 секунд
Во время кодинга не выводит
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.03.2016, 20:53     Ffmpeg изменение bit_rate не влияет на качество записи видео
Еще ссылки по теме:
Visual C++ Обрезка в FFmpeg
ffmpeg конвертация файла C++
FFMpeg и неправильная кодировка C++
C++ Подключение библиотеки ffmpeg к проекту
Запуск ffmpeg с параметрами из приложения C++ Linux

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

Или воспользуйтесь поиском по форуму:
castaway
Эксперт С++
4881 / 3017 / 370
Регистрация: 10.11.2010
Сообщений: 11,076
Записей в блоге: 10
Завершенные тесты: 1
14.03.2016, 20:53     Ffmpeg изменение bit_rate не влияет на качество записи видео #37
Если честно, то я и сам далеко не гуру в FFMPEG. Некоторые моменты для меня до сих пор остаются загадкой, например PTS. В нём вроде ничего сложного нет, но как его правильно задать я до сих пор не могу понять. Интересный момент, когда я эксперементировал с PTS, у меня менялось качество картинки. Как это связано - я не понимаю. Сейчас загружен работой и думать об этом вообще нет времени.
Попробуйте поэксперементировать, возможно вы и сами найдёте ответ на свой вопрос.
Yandex
Объявления
14.03.2016, 20:53     Ffmpeg изменение bit_rate не влияет на качество записи видео
Ответ Создать тему
Опции темы

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