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

C++

Войти
Регистрация
Восстановить пароль
 
 
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
#1

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

11.02.2016, 11:58. Просмотров 1300. Ответов 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 так как после ее вызова действительно происходят изменения в настройках (корректируется частота), но не уверен...
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2016, 11:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ffmpeg изменение bit_rate не влияет на качество записи видео (C++):

Качество видео. - C++ Builder
Как увеличить качество видео? Я пользуюсь компонентами Panel , MediaPlayer. При проигрывании видео, заметно что посравнению с другими...

Декодирование видео используя ffmpeg, dxva - Visual C++
Привет. Мне нужно декодировать видео с помощью ffmpeg, задействовав аппаратное ускорение. ffmpeg для этих целей поддерживает dxva и...

Сделать простенький видео плеер с использованием FFMPEG - C++
Ситуация такая. я программист новичок, и вот передо мной задача, имеется QT Creator C++, пытаюсь сделать простенький видео плеер с...

Влияет ли операционная система на качество картинки при видеосъемке? - Сетевое оборудование
Заказал замечательный комплект видео оборудования: видеорегистратор PRO-N5208 и 3 видеокамеры аналоговые 4 IP видеокамеры, у одного...

Стеганография в jpg: как влияет степень сжатия на качество результата - C#
Есть программа которая вшивает текст в картинку формата BMP, после чего можно также извлечь вшитый текст, но нужно сделать это для формата...

Влияет ли на качество картинки масштабирование, если картинка не смарт-объект? - Photoshop
Хотелось бы узнать, влияет ли на качество картинки масштабирование, если картинка не смарт-объект? Т.е. допустим мне нужно применить...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
18.02.2016, 13:22 #2
Цитата Сообщение от vxg Посмотреть сообщение
в моем коде никакие изменения bit_rate не меняют фактического качества видео-записи - она стабильно "хорошего" качества.
Попробуйте обновить FFMPEG, т.к. у меня качество видео меняется.
Так же советую не использовать deprecated функции.
1
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
18.02.2016, 14:54  [ТС] #3
Меняется при использовании моего кода?
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
18.02.2016, 15:05 #4
Да.

Добавлено через 45 секунд
В каких диапазонах вы его (bitrate) меняете?
1
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
18.02.2016, 15:52  [ТС] #5
От тысячи до двухста тысяч
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
18.02.2016, 15:54 #6
Ну тогда я вам могу лишь посоветовать избавится от deprecated функций. Если не поможет то обновить FFMPEG.
1
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
18.02.2016, 18:10  [ТС] #7
Какая версия у вас (ссылка)
0
castaway
Эксперт С++
4884 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
18.02.2016, 18:39 #8
Я качал отсюда. На тот момент версия была ffmpeg-20160205-git-6632802.
0
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
25.02.2016, 14:02  [ТС] #9
Цитата Сообщение от castaway Посмотреть сообщение
Я качал отсюда. На тот момент версия была ffmpeg-20160205-git-6632802.
пробовал скачать последнюю версию ffmpeg-20160225-git-ad17b9d - битая, видать ребята еще 23-е празднуют
пробовал ставить ту что я качал самой последней но не пробовал еще (ffmpeg-20151213-git-906c0b7, версии DLL вроде того же порядка - 57/55/4/2) - качество не меняется
пробовал ставить четко вашу версию - качество НЕ меняется (!!!) - во всяком случае я не увидел такого апокалиптического качества как при использовании вашего кода
расскажите как оно у вас поменялось - что то у нас с вами должно отличаться...

Добавлено через 1 час 55 минут
вот такую странную фразу вычитал не знаю как с ней жить
... each encoder has its own profile and the bitrate you provide is a hint. If your bitrate is a valid value (not too small and not too big), the codec will just select a supported bitrate in his profile list.
0
HighPredator
5542 / 1848 / 345
Регистрация: 10.12.2010
Сообщений: 5,450
Записей в блоге: 2
26.02.2016, 11:35 #10
Цитата Сообщение от vxg Посмотреть сообщение
вот такую странную фразу вычитал не знаю как с ней жить
Вроде хака мозга и передачи управления моторных функций человека на инструкцию заготовки мыла и веревки в ней не содержится.. В чем проблема? В понимании? Или?
0
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
26.02.2016, 12:43  [ТС] #11
Цитата Сообщение от HighPredator Посмотреть сообщение
В чем проблема?
проблема, уважаемый поэт, в том что есть подозрения (да да программирование это такая область где есть место и теории вероятности и теории заговора) в том что битрейт не ставится (или вернее не ставится так как я желаю) потому что FFMPEG берет мой битрейт и ищет в своем профиле ближайший подходящий. но. фраза которую я привел нагуглена в тридевятом царстве и не есть истина в манах. посему - люди сведующие просветите:
- верна ли гипотиза
- если верна как узнать битрейты профиля
- как код castaway умудряется плевать на профиль и кодить именно с тем битрейтом который задан
0
Avazart
26.02.2016, 12:54
  #12

Не по теме:

Цитата Сообщение от vxg Посмотреть сообщение
- если верна как узнать битрейты профиля
Может поискать спец программы что бы видеть что получается на выходе?

0
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
26.02.2016, 13:05  [ТС] #13
Цитата Сообщение от Avazart Посмотреть сообщение
Может поискать спец программы что бы видеть что получается на выходе?
спец программ масса начиная от KMP и заканчивая разными микроскопами вроде ffprobe - речь в данном смысле о такой абстракции как список битрейтов профиля если такая сущность действительно имеется в природе...

Не по теме:

а почему без аватара и прочих регалий)?

0
HighPredator
5542 / 1848 / 345
Регистрация: 10.12.2010
Сообщений: 5,450
Записей в блоге: 2
26.02.2016, 13:16 #14
Цитата Сообщение от vxg Посмотреть сообщение
вернее не ставится так как я желаю
Так в вашей цитате ровно это и написано. То есть то, что вы ему подали является не более чем "рекомендацией".
0
vxg
Модератор
3162 / 1965 / 220
Регистрация: 13.01.2012
Сообщений: 7,523
26.02.2016, 16:31  [ТС] #15
Цитата Сообщение от HighPredator Посмотреть сообщение
Так в вашей цитате ровно это и написано. То есть то, что вы ему подали является не более чем "рекомендацией".
я сомневаюсь в цитате ибо это не МАН. вы знаете где в манах написано то же самое и как прикинуть тогда список классных битрейтов?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.02.2016, 16:31
Привет! Вот еще темы с ответами:

Ffmpeg не режет видео - PHP
Здравствуйте. Не могу заставить ffmpeg резать ролик на кадры. Выполняю avconv -ss 00:00:02 -i /01.flv -r 5 -t 00:00:01 -f image2 ...

Потоковое видео с ffmpeg - Программирование
Есть несжатое видео с камеры 320x240, и его нужно передавать на удалённый компьютер в реальном времени, качество не очень важно....

Сжатие видео. Не запускается ffmpeg - C#
Добрый вечер, форумчане. Столкнулся с проблемой того, что не запускается ffmpeg. Подскажите, с чем может быть связана ошибка. Ниже фрагмент...

Ffmpeg wrapper. Не обрезаются длинные видео - C#
Здравствуйте! Мне нужно программно обрезать видеофайл. Как напрямую работать с ffmpeg я не разобралась, но нашла C# ffmpeg wrapper...


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

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

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