Live555 усекает закодированные данные FFMpeg

Я пытаюсь передавать данные на основе H264, используя Live555 через RTSP.

Я собираю данные с помощью V4L2, а затем кодирую их с помощью FFMPEG, а затем передаю данные в файл DeviceSource Live555, в котором я использую класс H264VideoStreamFramer,

Ниже приведены мои настройки кодека для настройки AVCodecContext кодировщика,

codec = avcodec_find_encoder_by_name(CODEC_NAME);
if (!codec) {
    cerr << "Codec " << codec_name << " not found\n";
    exit(1);
}

c = avcodec_alloc_context3(codec);
if (!c) {
    cerr << "Could not allocate video codec context\n";
    exit(1);
}

pkt = av_packet_alloc();
if (!pkt)
    exit(1);

/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = PIC_HEIGHT;
c->height = PIC_WIDTH;
/* frames per second */
c->time_base = (AVRational){1, FPS};
c->framerate = (AVRational){FPS, 1};
c->gop_size = 10;
c->max_b_frames = 1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
c->rtp_payload_size = 30000;
if (codec->id == AV_CODEC_ID_H264)
    av_opt_set(c->priv_data, "preset", "fast", 0);
av_opt_set_int(c->priv_data, "slice-max-size", 30000, 0);
/* open it */
ret = avcodec_open2(c, codec, NULL);
if (ret < 0) {
    cerr << "Could not open codec\n";
    exit(1);
}

И я получаю закодированные данные, используя функцию avcodec_receive_packet(). который вернет AVPacket.

И я передаю данные AVPacket в файл DeviceSource ниже, это фрагмент кода моего кода Live555:

void DeviceSource::deliverFrame() {
    if (!isCurrentlyAwaitingData()) return; // we're not ready for the data yet

    u_int8_t* newFrameDataStart = (u_int8_t*) pkt->data;
    unsigned newFrameSize = pkt->size; //%%% TO BE WRITTEN %%%
    // Deliver the data here:
    if (newFrameSize > fMaxSize) { // Condition becomes true many times
        fFrameSize = fMaxSize;
        fNumTruncatedBytes = newFrameSize - fMaxSize;
    } else {
        fFrameSize = newFrameSize;
    }
    gettimeofday(&fPresentationTime, NULL); // If you have a more accurate time - e.g., from an encoder - then use that instead.
    // If the device is *not* a 'live source' (e.g., it comes instead from a file or buffer), then set "fDurationInMicroseconds" here.
    memmove(fTo, newFrameDataStart, fFrameSize);
}

Но здесь иногда размер моего пакета становится больше, чем значение fMaxSize, и в соответствии с логикой LIVE555 он усекает данные кадра, поэтому иногда я получаю плохие кадры на своем VLC,

Из форума Live555 я узнаю, что кодировщик не должен отправлять пакет, размер которого превышает значение fMaxSize, поэтому мой вопрос:

Как ограничить кодировщик, чтобы ограничить размер пакета?

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

Харшил


person Harshil Makwana    schedule 13.12.2018    source источник
comment
смогли ли вы определить проблему. Я тоже застрял с тем же.   -  person iamrameshkumar    schedule 05.11.2019


Ответы (1)


Вы можете увеличить максимально допустимый размер выборки, изменив «maxSize» в классе OutPacketBuffer в MediaSink.cpp. Это сработало для меня. В некоторых случаях нам может потребоваться потоковое видео высокого качества, я не думаю, что мы всегда сможем ограничить кодировщик, чтобы он не создавал выборки размером больше определенного значения, что приведет к проблемам с качеством видео. На самом деле выборки фрагментируются приемником UDP live555, чтобы соответствовать MTU по умолчанию (1500), поэтому увеличение максимального размера выборки не имеет побочных эффектов.

person iamrameshkumar    schedule 22.11.2019