Как мультиплексировать живой поток h264 в формате блока AnnexB nal в контейнер FLV

У меня есть устройство Android, которое будет отправлять необработанный живой поток NAL H264 AnnexB, например [0,0,0,1,103,...][0,0,0,104,...][0,0,0,101,.. .][0,0,0,1,65,...][0,0,0,1,65,...] и попробуйте мультиплексировать их в контейнер flv и отправить в nginx-с использованием модуля rtmp libavформат ffmpeg.

Если я сохраню полученный прямой эфир в локальный файл, скажем, test.h264. Я могу мультиплексировать его на сервер, используя команду ffmpeg «ffmpeg -i test.h264 -f flv rtmp://my/server/url». Но я не знаю, как вести прямую трансляцию.

Я заметил, что в ffmpeg/libavformat/avc.c есть две функции, которые, кажется, достигают моей цели. Но я не уверен.

Вот код ffmpeg

int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
{
    const uint8_t *p = buf_in;
    const uint8_t *end = p + size;
    const uint8_t *nal_start, *nal_end;

    size = 0;
    nal_start = ff_avc_find_startcode(p, end);
    for (;;) {
        while (nal_start < end && !*(nal_start++));
        if (nal_start == end)
            break;

        nal_end = ff_avc_find_startcode(nal_start, end);
        avio_wb32(pb, nal_end - nal_start);
        avio_write(pb, nal_start, nal_end - nal_start);
        size += 4 + nal_end - nal_start;
        nal_start = nal_end;
    }
    return size;
}

int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size)
{
    AVIOContext *pb;
    int ret = avio_open_dyn_buf(&pb);
    if(ret < 0)
        return ret;

    ff_avc_parse_nal_units(pb, buf_in, *size);

    av_freep(buf);
    *size = avio_close_dyn_buf(pb, buf);
    return 0;
}

Любой полезный ответ приветствуется.

Благодарю вас!


person Zhou Yufeng    schedule 18.05.2016    source источник
comment
Я полагаю, вы понимаете, что один NALU - это не то же самое, что один кадр, и что вы уже проработали экстратаду/заголовок последовательности? И что вы должны преобразовать из приложения б.   -  person szatmary    schedule 18.05.2016
comment
все это делается, если вы вызываете H264 AVParser: ffmpeg.org/doxygen/trunk/group__lavc__parsing. html   -  person Ronald S. Bultje    schedule 18.05.2016
comment
@szatmary Я заметил, что кто-то где-то спрашивал, как получить дополнительные данные из модуля H264 NAL, но я не знаю, зачем это делать и что будет дальше после этого шага.   -  person Zhou Yufeng    schedule 19.05.2016
comment
@RonaldS.Bultje Я искал API-интерфейсы AVParser. Кажется, они используются для расшифровки блока H264. Может ли AVParser обрабатывать блок NAL и выводить структуру AVPacket?   -  person Zhou Yufeng    schedule 19.05.2016
comment
@szatmary Прости меня, новичок в H264. Я прочитал ваш ответ о AnnexB и AVVC битовый поток приложения h264 в flv mux ffmpeg библиотеку снова и знаю, что я должен захватить блок SPS и PPS NAL, затем преобразовать их в экстраданные AVCC и передать в экстраданные контекста кодека. Ваш ответ очень полезен! Но все еще остается вопрос: как обрабатывать эти блоки NAL IDR и не-IDR (тип 0x65 или ox41). Моя конечная цель - также мультиплексировать эти блоки NAL в FLV.   -  person Zhou Yufeng    schedule 19.05.2016
comment
Вывод AVParser — это поле uint8_t *data и int size, которые вместе можно использовать для инициализации AVPacket. См., например. этот код: ffmpeg.org/doxygen/trunk/   -  person Ronald S. Bultje    schedule 19.05.2016
comment
@RonaldS.Bultje Я прочитал пример кода (av_parser_parse2) и знаю, что данные и размер можно использовать для инициализации AVPacket. Но как насчет других полей AVPacket, таких как pts и dts.   -  person Zhou Yufeng    schedule 19.05.2016
comment
В приложении B нет временных меток, так что вам придется их как-то придумать. Вы можете использовать параметры VUI в SPS для чтения частоты кадров, но это не всегда присутствует.   -  person Ronald S. Bultje    schedule 19.05.2016
comment
@RonaldS.Bultje Частоту кадров устанавливаю я. Поэтому я думаю, что я должен установить эти поля, такие как pts, dts, вручную.   -  person Zhou Yufeng    schedule 19.05.2016
comment
Правильно, если вы знаете частоту кадров, вы знаете временные метки, и поэтому установка pts/dts вручную должна быть тривиальной.   -  person Ronald S. Bultje    schedule 19.05.2016