LINUX.ORG.RU

ffmpeg library оптимизация декодирование H.264 для встраемых систем

 , ,


0

3

Привет сообществу

Встала задача производить декодирование H.264 на mips32 1004K (700MHz). Скачал ffmpeg и прокомпилировал компилятором mips32 (флаги акселераторов выключил). Накидал простинький код для проверки максимальной скорости декодирование видео из файла (HD 720p). После прогона слегка удивился. Всего ~4 fps. На домашней виртуалки было ~200 fps (i686 100MHz)

Вот сижу теперь чешу репу. Кто-то может объяснить где ступил. А может у кого то были подобные задачи и есть какие-то интересные решения.

Заранее спасибо.

Вот код что запускал:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

#include <sys/time.h>
#include <time.h>

#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"

#define INBUF_SIZE 80000


static long get_time_diff(struct timeval time_now) {
   struct timeval time_now2;
   gettimeofday(&time_now2,0);
   return time_now2.tv_sec*1.e6 - time_now.tv_sec*1.e6 + time_now2.tv_usec - time_now.tv_usec;
}

int main(int argc, char **argv)
{
    AVCodec *codec;
    AVCodecContext *c= NULL;
    AVCodecParserContext *parser = NULL;
    int frame, got_picture, len2, len;
    const char *filename;
    FILE *f;
    AVFrame *picture;
    char *arghwtf = malloc(INBUF_SIZE);
    uint64_t in_len;
    int pts, dts;
    struct timeval t,t2;
    float inv_fps = 1e6/23.98;
    AVPacket avpkt;

    // register all the codecs
    avcodec_register_all();

    // log level
    av_log_set_level(AV_LOG_PANIC|AV_LOG_FATAL|AV_LOG_ERROR|AV_LOG_WARNING);

    filename = argv[1];

    av_init_packet(&avpkt);

    printf("Decoding file %s...\n", filename);

    // find the H.264 video decoder
    codec = avcodec_find_decoder(CODEC_ID_H264);
    if (!codec)
    {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

    c = avcodec_alloc_context3(codec);
    picture = avcodec_alloc_frame();

    // skiploopfilter=all
    c->skip_loop_filter = 48;

    AVDictionary* dictionary = NULL;
    if (avcodec_open2(c, codec, &dictionary) < 0)
    {
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }

    // the codec gives us the frame size, in samples
    parser = av_parser_init(c->codec_id);
    parser->flags |= PARSER_FLAG_ONCE;

    f = fopen(filename, "rb");
    if (!f)
    {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }

    frame = 0;
    gettimeofday(&t, 0);
    if(fread(arghwtf, 1, INBUF_SIZE, f) == 0)
    {
        exit(1);
    }

    in_len = 80000;
    gettimeofday(&t2, 0);
    while (in_len > 0 && !feof(f))
    {
        len = av_parser_parse2(parser, c, &avpkt.data, &avpkt.size, arghwtf, in_len, pts, dts, AV_NOPTS_VALUE);

        len2 = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
        if (len2 < 0) {
            fprintf(stderr, "Error while decoding frame %d\n", frame);
            exit(1);
        }

        if (got_picture)
        {
            fprintf(stderr, "\rDisplaying %c %dx%d :frame %3d (%02d:%03d)...", av_get_picture_type_char(picture->pict_type), c->width, c->height, frame, (int)(get_time_diff(t)/1000000), (int)((get_time_diff(t)/1000)%1000));
            fflush(stderr);

            frame++;
        }

        memcpy(arghwtf, arghwtf + len, 80000-len);
        fread(arghwtf + 80000 - len, 1, len, f);
    }

    fclose(f);
    avcodec_close(c);
    av_free(c);
    av_free(picture);
    printf("\n");
    printf("Avarage fps: %d\n", (int)(((double)frame)/(double)(get_time_diff(t)/1000)*1000));

    return 0;
}

производить декодирование H.264 на mips32 1004K (700MHz).

Смотри, чтоб заставить декодироваться 720p софтварно на Core2 T5600 мне пришлось включать многопоток и skiploopfilter.

Так что на этом мипсе софтварно, боюсь, не взлетит.

devl547 ★★★★★
()
Последнее исправление: devl547 (всего исправлений: 1)
Ответ на: комментарий от devl547

а каким способом выполняется многопоточность декодирование в ffmpeg?

я надеюсь вы говорите про декодирование одного поток видео с многопоточностью

pasifus
() автор топика
Ответ на: комментарий от pasifus

Он правильно намекает - без внешнего видеоускорителя на этом слабом мипсе всё будет плохо.

devl547 ★★★★★
()

декодирование H.264 на mips32 1004K (700MHz)

/0

Deleted
()
Ответ на: комментарий от mix_mix

i know that raspberry have GPU to decoding/encoding

покажите мне gpu ENCODING (да-да, именно encoding!) на rpi
аппаратная возможность - не значит теоретическая

reprimand ★★★★★
()
Ответ на: комментарий от devl547

и как с производительностью?
а то я тут недавно решился записать скринкаст - моего core2duo с трудом хватает на 15 fps. И да, я знаю что вменяемые люди пользуются картами видеозахвата... но, опять таки, годных карт под онтопик нет

reprimand ★★★★★
()
Последнее исправление: reprimand (всего исправлений: 1)
Ответ на: комментарий от reprimand

алсо, core2 днище по сравнению с современными 2х ядерниками, а в ходу уже в основном 4х ядерники

anonymous
()
Ответ на: комментарий от anonymous

Nvidia NVENC is the name given to Nvidia's ASIC IP block that performs video encoding. It was introduced with the Kepler-based GeForce 600 series
$ lspci | grep NVI
01:00.0 VGA compatible controller: NVIDIA Corporation GF114 [GeForce GTX 560] (rev a1)

ага, запилил уже, трижды

у amd что-нибудь швободное тоже должно быть

от amd у меня только cpu, да и то, только на сервере

reprimand ★★★★★
()
Ответ на: комментарий от anonymous

алсо, core2 днище по сравнению с современными 2х ядерниками, а в ходу уже в основном 4х ядерники

...и я это прекрасно знаю
на новый проц бабла нет (точнее оно было, но цены разбухли)

даже если я буду энкодить средствами другой машины - x11grab буде жрать немало. Т.ч. тут в любом случае надо карту видеозахвата

reprimand ★★★★★
()
Ответ на: комментарий от devl547

спасибо попробую.мне бы до 10-12 fps дотянутся :)

pasifus
() автор топика
Ответ на: комментарий от pasifus

у rpi аппаратный h264, расчеты выполняет ip-корка на борту процессора

zudwa
()

Если нет hw, придется использовать более простой кодек и/или уменьшать размер кадра

annulen ★★★★★
()
Ответ на: комментарий от devl547

Большое человеческое спасибо. Распаралелил на 4 thread_cont, skip_loop_filter сделал на максимум и скорость дошла до 10 fps. Это конечно не 30 fps, но с этим уже можно работать.

Может есть еще какие-то ухищрения по оптимизации?

pasifus
() автор топика
Ответ на: комментарий от pasifus

Дальше всё плохо. Насколько я понял, у мипсов всё глухо с DSP и SIMD.
Даже официальные доки на последний MIPS Warrior говорят, что SIMD там для галочки для ускорения вещей, которые пока не делаются выделенными сопроцессорами.

Единственное что могу посоветовать - собрать ffmpeg вручную и поиграться с CFLAGS и профайлингом.

devl547 ★★★★★
()
Ответ на: комментарий от devl547

Ну 480p оно может и вытянет на 30fps. С HD и тем более fullHD только аппаратный декодер поможет.

geks
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.