Recherche avancée

Médias (0)

Mot : - Tags -/objet éditorial

Aucun média correspondant à vos critères n’est disponible sur le site.

Autres articles (42)

  • D’autres logiciels intéressants

    12 avril 2011, par

    On ne revendique pas d’être les seuls à faire ce que l’on fait ... et on ne revendique surtout pas d’être les meilleurs non plus ... Ce que l’on fait, on essaie juste de le faire bien, et de mieux en mieux...
    La liste suivante correspond à des logiciels qui tendent peu ou prou à faire comme MediaSPIP ou que MediaSPIP tente peu ou prou à faire pareil, peu importe ...
    On ne les connais pas, on ne les a pas essayé, mais vous pouvez peut être y jeter un coup d’oeil.
    Videopress
    Site Internet : (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • La file d’attente de SPIPmotion

    28 novembre 2010, par

    Une file d’attente stockée dans la base de donnée
    Lors de son installation, SPIPmotion crée une nouvelle table dans la base de donnée intitulée spip_spipmotion_attentes.
    Cette nouvelle table est constituée des champs suivants : id_spipmotion_attente, l’identifiant numérique unique de la tâche à traiter ; id_document, l’identifiant numérique du document original à encoder ; id_objet l’identifiant unique de l’objet auquel le document encodé devra être attaché automatiquement ; objet, le type d’objet auquel (...)

Sur d’autres sites (4698)

  • Use ffmpeg multiple h264_nvenc instances will crash occurs during release

    13 août 2024, par yang zhao

    Use FFMpeg, When multiple threads use multiple h264_nvenc instances(one instance per thread), an exception crash occurs during release(avcodec_free_context), and the final exception occurs in libnvcuvid.so.
I don't know what the reason is ? Please help, thanks.
The same problem exists : ffmpeg v5.0.1 + cuda v11.6 and ffmpeg v7.0.1 + cuda v12.2
operating system:Ubuntu 22.04.4 LTS

    


    The specific code is as follows :

    


    class NvencEncoder {
public:
    NvencEncoder() {}
    ~NvencEncoder { Close(); }
    
    bool Open() {
        auto encoder = avcodec_find_encoder_by_name("h264_nvenc");
        pCodecCtx_ = avcodec_alloc_context3(encoder);
        if (!pCodecCtx_)
            return false;

        int width = 1920;
        int height = 1080;
        int bitrate = 1000000;
        
        pCodecCtx_->codec_type = AVMEDIA_TYPE_VIDEO;
        pCodecCtx_->pix_fmt = AV_PIX_FMT_YUV420P;
        pCodecCtx_->width = width;
        pCodecCtx_->height = height;
        pCodecCtx_->bit_rate = bitrate;
        pCodecCtx_->rc_min_rate = bitrate;
        pCodecCtx_->rc_max_rate = bitrate;
        pCodecCtx_->bit_rate_tolerance = bitrate;
        pCodecCtx_->rc_buffer_size = bitrate / 2;
        pCodecCtx_->time_base = AVRational{ 1, 90000 };
        pCodecCtx_->framerate = AVRational{ 25, 1 };
        pCodecCtx_->gop_size = 50;
        pCodecCtx_->max_b_frames = 0;
        pCodecCtx_->delay = 0;
        pCodecCtx_->refs = 2;
        pCodecCtx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

        av_opt_set_int(pCodecCtx_->priv_data, "gpu", 0, 0);
        av_opt_set(pCodecCtx_->priv_data, "preset", "llhp", 0);
        av_opt_set(pCodecCtx_->priv_data, "rc", "cbr", 0);
        av_opt_set(pCodecCtx_->priv_data, "profile", "main", 0);
        av_opt_set(pCodecCtx_->priv_data, "zerolatency", "1", 0);
        av_opt_set(pCodecCtx_->priv_data, "delay", "0", 0);
        av_opt_set(pCodecCtx_->priv_data, "preset", "medium", 0);

        int ret = avcodec_open2(pCodecCtx_, encoder, nullptr);
        if (ret < 0)
            return false;

        pkt_ = av_packet_alloc();
        if (!pkt_)
            return false;

        char output_mp4[] = "output.mp4";
        ret = avformat_alloc_output_context2(&avMp4Context_, NULL, "mp4", output_mp4);
        if (ret < 0)
            return false;
            
        mp4_stream_ = avformat_new_stream(avMp4Context_, nullptr);
        if (!mp4_stream_)
            return false;

        ret = avcodec_parameters_copy(mp4_stream_->codecpar, out_stream_->codecpar);
        if (ret < 0)
            return false;
            
        mp4_stream_->codecpar->codec_tag = 0;

        if (!(avMp4Context_->oformat->flags & AVFMT_NOFILE)) {
            ret = avio_open(&avMp4Context_->pb, output_mp4_.c_str(), AVIO_FLAG_WRITE);
            if (ret < 0) {
                return false;
        }
        return true;
    }

    void Close() {
        if (pCodecCtx_)
            avcodec_free_context(&pCodecCtx_); // Crash will occur in libnvcuvid.so

        if (avMp4Context_) {
            if (avMp4Context_->oformat && !(avMp4Context_->oformat->flags & AVFMT_NOFILE)) {
                avio_closep(&avMp4Context_->pb);
            }
            avformat_free_context(avMp4Context_);
            avMp4Context_ = nullptr;
        }
        
        if (pkt_)
            av_packet_free(&pkt_);
    }

    bool InputFrame(AVFrame* frame) {
        int ret = avcodec_send_frame(pEncoderVideoCodecCtx_, frame);
        if (ret < 0)
            return false;
            
        while (ret >= 0) {
            ret = avcodec_receive_packet(pEncoderVideoCodecCtx_, pkt_);
            if (ret < 0)
                break;

            if (avNotHeadWrited_) {
                ret = avformat_write_header(avMp4Context_, &opts);
                if (ret < 0) {
                    av_packet_unref(pkt_);
                    break;
                }
                avNotHeadWrited_ = false;
            }

            av_packet_rescale_ts(pkt_, pCodecCtx_->time_base, mp4_stream_->time_base);
            ret = av_write_frame(avMp4Context_, pkt_);
            if (ret < 0) {
                av_packet_unref(pkt_);
                break;
            }

            av_packet_unref(pkt_);
        }
        
        return (ret >= 0);
    }
private:
    AVPacket* pkt_ = nullptr;
    AVCodecContext* pCodecCtx_ = nullptr;
    AVFormatContext* avMp4Context_ = nullptr;
    AVStream* mp4_stream_ = nullptr;
    avNotHeadWrited_ = true;
}

uint8_t* data = nullptr; //a frame of yuv420 data
void Run(int idx);

int main() {
    //Fill a frame of yuv420 data here
    ...

    std::thread th[3];
    for (int i = 0; i < 3; i++) {
        th[i] = std::thread(Run, i);
        sleep(3);
    }

    sleep(35);

    for (int i = 0; i < 3; i++) {
        if (th[i].joinable()) {
            printf("thread %d join()\n", i);
            th[i].join();
        }
    }

    free(data);
    printf("Exit\n");
}

void Run(int idx) {
    printf("Run() thread(%d)\n", idx);
    //cudaSetDevice(0);

    auto nvenc = new NvencEncoder(ffpar, FFOutputCB);
    if (!nvenc->Open()) {
        delete nvenc;
        return;
    }

    auto avframe_ = av_frame_alloc();
    avframe_->width = 1920;
    avframe_->height = 1080;
    avframe_->format = AV_PIX_FMT_YUV420P;

    int ret = av_frame_get_buffer(avframe_, 0);
    if (ret < 0) {
        printf("av_frame_get_buffer() is error %d\n", ret);
        delete nvenc;
        av_frame_free(&avframe_);
        return;
    }

    int frame_size = 1920 * 1080;
    double one_frame_us = 1000000.0 / 25.0;
    unsigned long frame_count = 0;
    struct timeval t1, t2;
    double timeuse;

    AVRational timebase = { ffpar.timebase_num, ffpar.timebase_den };
    std::int64_t llCalcDuration = (double)AV_TIME_BASE / 25.0;
    double in_stream_timebase = av_q2d(timebase);
    std::int64_t duration = (double)llCalcDuration / (double)(in_stream_timebase * AV_TIME_BASE);
    avframe_->time_base = timebase;
    gettimeofday(&t1, NULL);

    while (frame_count < 25*30) { //30 seconds

        avframe_->pts = (double)(frame_count * llCalcDuration) / (double(in_stream_timebase * AV_TIME_BASE));
        //avframe_->duration = duration;
        frame_count++;

        ret = av_frame_make_writable(avframe_);
        if (ret < 0) {
            printf("av_frame_make_writable() is error %d\n", ret);
            break;
        }

        // copy YUV420
        memcpy(avframe_->data[0], data, frame_size);
        memcpy(avframe_->data[1], data + frame_size, frame_size / 4);
        memcpy(avframe_->data[2], data + frame_size * 5 / 4, frame_size / 4);

        ret = nvenc->InputFrame(avframe_);
        if (ret < 0) {
            printf("InputFrame() is error: %d\n", ret);
            break;
        }

        // frame rate
        gettimeofday(&t2, NULL);
        timeuse = (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec); //us
        if (timeuse < one_frame_us) {
            usleep(one_frame_us - timeuse);
        }
        gettimeofday(&t1, NULL);
    }

    if (frame_count > 0) {
        nvenc->WriteTrailer();
    }

    printf("do Close() thread(%d)\n", idx);
    nvenc->Close();  // Crash will occur
    printf("Closed thread(%d)\n", idx);
    delete nvenc;
    av_frame_free(&avframe_);
}


    


  • FFmpeg av_read_frame() interrupt_callback

    14 octobre 2024, par Elija
    class TimeoutHandler_c
{
public:
  TimeoutHandler_c() = default;
  ~TimeoutHandler_c() = default;
        
  void Reset(time_t timeout_microseconds)
  {
    Timeout = timeout_microseconds;
    TimeLast = GET_US_TIME();
  }
        
  bool IsTimeout()
  {
    const time_t duration = GET_US_TIME() - TimeLast;
    LOG(LOG_LEVEL_DEBUG, "Duration = %lli, timeout = %lli, result %i\n", duration, Timeout, duration > Timeout);
    return duration > Timeout;
  }
        
  static int CheckInterrupt(void* t)
  {
    return t && static_cast(t)->IsTimeout();
  }
        
  private:
    time_t Timeout{ 0 }; // microseconds
    time_t TimeLast{ 0 }; // microseconds
};
    
...

TimeoutHandler_c TimeoutHandler; //!< Control maximum time of packets waiting
AvFormatContext->interrupt_callback.opaque = (void*)&TimeoutHandler;
AvFormatContext->interrupt_callback.callback = &TimeoutHandler_c::CheckInterrupt;
    
...

while(1)
{
  ...
  TimeoutHandler.Reset(10000000);
  time_t time_before_av_read_frame = GET_US_TIME(); // microseconds
  int av_res = av_read_frame(AvFormatContext, av_packet.get());
  time_t time_after_av_read_frame = GET_US_TIME(); // microseconds
  LOG(LOG_LEVEL_DEBUG, "av_read_frame() res %i, time %lli, time_limit %lli\n", av_res, time_after_av_read_frame - time_before_av_read_frame, options_open->ReadFrameTimeout);
    
  if (av_res == 0) // packet with frame
  {
    LOG(LOG_LEVEL_DEBUG, "AVPacket(%i): stream_index %i, pts %lli, dts %lli, time_base.num %i, time_base.den %i, duration %lli, size %i, flags 0x%x, pos %lli, side_data_elems %i\n", av_packet_cnt, av_packet->stream_index, av_packet->pts, av_packet->dts, av_packet->time_base.num, av_packet->time_base.den, av_packet->duration, av_packet->size, av_packet->flags, av_packet->pos, av_packet->side_data_elems);
    ++av_packet_cnt;
    av_read_frame_error_count = 0;
  }
  else // no packet
  {
    ++av_read_frame_error_count;
    LOG(LOG_LEVEL_WARNING, "No av_packet, %lli errors in a row. av_read_frame() failed with averror: %s\n", av_read_frame_error_count, av_err2str(av_res));
  }
  ...
}


    


    Logging (times in microseconds) :

    


    10:52:50.234176:Run(925): av_read_frame() res 0, time 20354, time_limit 10000000
10:52:50.234235:Run(931): AVPacket(1695): stream_index 1, pts 661875112, dts 661875112, time_base.num 0, time_base.den 1, duration 1920, size 251, flags 0x1, pos 6341240, side_data_elems 1
10:52:50.234272:Run(925): av_read_frame() res 0, time 1, time_limit 10000000
10:52:50.234293:Run(931): AVPacket(1696): stream_index 1, pts 661877032, dts 661877032, time_base.num 0, time_base.den 1, duration 1920, size 250, flags 0x1, pos -1, side_data_elems 0
10:52:50.234319:Run(925): av_read_frame() res 0, time 1, time_limit 10000000
10:52:50.234338:Run(931): AVPacket(1697): stream_index 1, pts 661878952, dts 661878952, time_base.num 0, time_base.den 1, duration 1920, size 287, flags 0x1, pos -1, side_data_elems 0
10:52:50.234365:Run(925): av_read_frame() res 0, time 0, time_limit 10000000
10:52:50.234393:Run(931): AVPacket(1698): stream_index 1, pts 661880872, dts 661880872, time_base.num 0, time_base.den 1, duration 1920, size 323, flags 0x1, pos -1, side_data_elems 0
10:52:50.234423:IsTimeout(146): Duration = 1, timeout = 10000000, result 0
10:52:50.345009:IsTimeout(146): Duration = 110579, timeout = 10000000, result 0
10:52:50.456198:IsTimeout(146): Duration = 221772, timeout = 10000000, result 0
10:52:50.566359:IsTimeout(146): Duration = 331934, timeout = 10000000, result 0
10:52:50.675843:IsTimeout(146): Duration = 441409, timeout = 10000000, result 0
10:52:50.785050:IsTimeout(146): Duration = 550621, timeout = 10000000, result 0
10:52:50.906415:IsTimeout(146): Duration = 671985, timeout = 10000000, result 0
10:52:51.030219:IsTimeout(146): Duration = 795790, timeout = 10000000, result 0
10:52:51.155401:IsTimeout(146): Duration = 920970, timeout = 10000000, result 0
10:52:51.280220:IsTimeout(146): Duration = 1045789, timeout = 10000000, result 0
10:52:51.405379:IsTimeout(146): Duration = 1170948, timeout = 10000000, result 0
10:52:51.530548:IsTimeout(146): Duration = 1296118, timeout = 10000000, result 0
10:52:51.655525:IsTimeout(146): Duration = 1421099, timeout = 10000000, result 0
10:52:51.780054:IsTimeout(146): Duration = 1545622, timeout = 10000000, result 0
10:52:51.905742:IsTimeout(146): Duration = 1671312, timeout = 10000000, result 0
10:52:52.030028:IsTimeout(146): Duration = 1795598, timeout = 10000000, result 0
10:52:52.156941:IsTimeout(146): Duration = 1922516, timeout = 10000000, result 0
10:52:52.280096:IsTimeout(146): Duration = 2045669, timeout = 10000000, result 0
10:52:52.405634:IsTimeout(146): Duration = 2171209, timeout = 10000000, result 0
10:52:52.530967:IsTimeout(146): Duration = 2296541, timeout = 10000000, result 0
10:52:52.655179:IsTimeout(146): Duration = 2420754, timeout = 10000000, result 0
10:52:52.781832:IsTimeout(146): Duration = 2547403, timeout = 10000000, result 0
10:52:52.905314:IsTimeout(146): Duration = 2670889, timeout = 10000000, result 0
10:52:53.030055:IsTimeout(146): Duration = 2795630, timeout = 10000000, result 0
10:52:53.155874:IsTimeout(146): Duration = 2921448, timeout = 10000000, result 0
10:52:53.281438:IsTimeout(146): Duration = 3047014, timeout = 10000000, result 0
10:52:53.405043:IsTimeout(146): Duration = 3170613, timeout = 10000000, result 0
10:52:53.531218:IsTimeout(146): Duration = 3296793, timeout = 10000000, result 0
10:52:53.656935:IsTimeout(146): Duration = 3422504, timeout = 10000000, result 0
10:52:53.781820:IsTimeout(146): Duration = 3547395, timeout = 10000000, result 0
10:52:53.907028:IsTimeout(146): Duration = 3672600, timeout = 10000000, result 0
10:52:54.030327:IsTimeout(146): Duration = 3795899, timeout = 10000000, result 0
10:52:54.155265:IsTimeout(146): Duration = 3920833, timeout = 10000000, result 0
10:52:54.281383:IsTimeout(146): Duration = 4046958, timeout = 10000000, result 0
10:52:54.405035:IsTimeout(146): Duration = 4170604, timeout = 10000000, result 0
10:52:54.530395:IsTimeout(146): Duration = 4295971, timeout = 10000000, result 0
10:52:54.655403:IsTimeout(146): Duration = 4420976, timeout = 10000000, result 0
10:52:54.780385:IsTimeout(146): Duration = 4545954, timeout = 10000000, result 0
10:52:54.905529:IsTimeout(146): Duration = 4671098, timeout = 10000000, result 0
10:52:55.030476:IsTimeout(146): Duration = 4796050, timeout = 10000000, result 0
10:52:55.155904:IsTimeout(146): Duration = 4921479, timeout = 10000000, result 0
10:52:55.280770:IsTimeout(146): Duration = 5046339, timeout = 10000000, result 0
10:52:55.405693:IsTimeout(146): Duration = 5171254, timeout = 10000000, result 0
10:52:55.530824:IsTimeout(146): Duration = 5296397, timeout = 10000000, result 0
10:52:55.655984:IsTimeout(146): Duration = 5421559, timeout = 10000000, result 0
10:52:55.780807:IsTimeout(146): Duration = 5546382, timeout = 10000000, result 0
10:52:55.905002:IsTimeout(146): Duration = 5670577, timeout = 10000000, result 0
10:52:56.030066:IsTimeout(146): Duration = 5795641, timeout = 10000000, result 0
10:52:56.155151:IsTimeout(146): Duration = 5920726, timeout = 10000000, result 0
10:52:56.281405:IsTimeout(146): Duration = 6046980, timeout = 10000000, result 0
10:52:56.406788:IsTimeout(146): Duration = 6172357, timeout = 10000000, result 0
10:52:56.530478:IsTimeout(146): Duration = 6296054, timeout = 10000000, result 0
10:52:56.656392:IsTimeout(146): Duration = 6421968, timeout = 10000000, result 0
10:52:56.781922:IsTimeout(146): Duration = 6547497, timeout = 10000000, result 0
10:52:56.905743:IsTimeout(146): Duration = 6671311, timeout = 10000000, result 0
10:52:57.031014:IsTimeout(146): Duration = 6796589, timeout = 10000000, result 0
10:52:57.155710:IsTimeout(146): Duration = 6921282, timeout = 10000000, result 0
10:52:57.281593:IsTimeout(146): Duration = 7047168, timeout = 10000000, result 0
10:52:57.406115:IsTimeout(146): Duration = 7171690, timeout = 10000000, result 0
10:52:57.530220:IsTimeout(146): Duration = 7295796, timeout = 10000000, result 0
10:52:57.655566:IsTimeout(146): Duration = 7421135, timeout = 10000000, result 0
10:52:57.780723:IsTimeout(146): Duration = 7546298, timeout = 10000000, result 0
10:52:57.905480:IsTimeout(146): Duration = 7671050, timeout = 10000000, result 0
10:52:58.030799:IsTimeout(146): Duration = 7796375, timeout = 10000000, result 0
10:52:58.155789:IsTimeout(146): Duration = 7921364, timeout = 10000000, result 0
10:52:58.281769:IsTimeout(146): Duration = 8047344, timeout = 10000000, result 0
10:52:58.405858:IsTimeout(146): Duration = 8171427, timeout = 10000000, result 0
10:52:58.531698:IsTimeout(146): Duration = 8297271, timeout = 10000000, result 0
10:52:58.656105:IsTimeout(146): Duration = 8421681, timeout = 10000000, result 0
10:52:58.780503:IsTimeout(146): Duration = 8546072, timeout = 10000000, result 0
10:52:58.905195:IsTimeout(146): Duration = 8670770, timeout = 10000000, result 0
10:52:59.030539:IsTimeout(146): Duration = 8796114, timeout = 10000000, result 0
10:52:59.156909:IsTimeout(146): Duration = 8922482, timeout = 10000000, result 0
10:52:59.281819:IsTimeout(146): Duration = 9047392, timeout = 10000000, result 0
10:52:59.405967:IsTimeout(146): Duration = 9171536, timeout = 10000000, result 0
10:52:59.531362:IsTimeout(146): Duration = 9296937, timeout = 10000000, result 0
10:52:59.655612:IsTimeout(146): Duration = 9421181, timeout = 10000000, result 0
10:52:59.780532:IsTimeout(146): Duration = 9546101, timeout = 10000000, result 0
10:52:59.906761:IsTimeout(146): Duration = 9672331, timeout = 10000000, result 0
10:53:00.030563:IsTimeout(146): Duration = 9796138, timeout = 10000000, result 0
10:53:00.156556:IsTimeout(146): Duration = 9922131, timeout = 10000000, result 0
10:53:00.280257:IsTimeout(146): Duration = 10045828, timeout = 10000000, result 1
10:53:00.280398:Run(925): av_read_frame() res 0, time 10045975, time_limit 10000000
10:53:00.280420:Run(931): AVPacket(1699): stream_index 0, pts 661881817, dts 661874257, time_base.num 0, time_base.den 1, duration 3753, size 1874, flags 0x0, pos 6334472, side_data_elems 1
10:53:00.280480:Run(925): av_read_frame() res 0, time 21, time_limit 10000000
10:53:00.280501:Run(931): AVPacket(1700): stream_index 0, pts 661878037, dts 661878037, time_base.num 0, time_base.den 1, duration 3753, size 1154, flags 0x0, pos 6339924, side_data_elems 0
10:53:00.280533:Run(925): av_read_frame() res -1414092869, time 5, time_limit 10000000
10:53:00.280561:Run(952): No av_packet, 1 errors in a row. av_read_frame() failed with averror: Immediate exit requested
10:53:00.290830:Run(925): av_read_frame() res -1414092869, time 17, time_limit 10000000
10:53:00.290862:Run(952): No av_packet, 2 errors in a row. av_read_frame() failed with averror: Immediate exit requested
10:53:00.301673:Run(925): av_read_frame() res -1414092869, time 25, time_limit 10000000
10:53:00.301725:Run(952): No av_packet, 3 errors in a row. av_read_frame() failed with averror: Immediate exit requested
10:53:00.312259:Run(925): av_read_frame() res -1414092869, time 10, time_limit 10000000
10:53:00.312308:Run(952): No av_packet, 4 errors in a row. av_read_frame() failed with averror: Immediate exit requested
10:53:00.323144:Run(925): av_read_frame() res -1414092869, time 11, time_limit 10000000
10:53:00.323196:Run(952): No av_packet, 5 errors in a row. av_read_frame() failed with averror: Immediate exit requested
10:53:00.334049:Run(925): av_read_frame() res -1414092869, time 9, time_limit 10000000
10:53:00.334101:Run(952): No av_packet, 6 errors in a row. av_read_frame() failed with averror: Immediate exit requested


    


    I start broadcasting to the address udp ://239.0.0.1:6688. I start receiving data successfully. Then I stop broadcasting. As a result, the av_read_frame(), as expected, is blocked for 10 seconds, which I set before calling av_read_frame().
But I have two questions :

    


      

    1. Why, after 10 seconds of blocking and exiting at the maximum waiting time I set, I get 2 good video frames (stream_index 0). Why don't I get these frames earlier ? It seems that the blocking occurs while waiting for elementary audio stream data (stream_index 1), although the elementary video stream data (stream_index 0) is available. But this can't be true, can it ?
    2. 


    3. Why do I get "Immediate exit requested" errors with a frequency of 10 milliseconds, although I set the maximum waiting time to 10 seconds each time before av_read_frame() ? Or is the "Immediate exit requested" error not related to the maximum wait time I set ? How is this situation different from waiting for data for 10 seconds earlier, when the broadcast was also already stopped ? I saw that ffplay in some situations uses a wait of 10 milliseconds (https://ffmpeg.org/doxygen/trunk/ffplay_8c_source.html#l03023)
    4. 


    


  • Frames took with ELP camera has unknown pixel format at FHD ?

    11 novembre 2024, par Marcel Kopera

    I'm trying to take a one frame ever x seconds from my usb camera. Name of the camera is : ELP-USBFHD06H-SFV(5-50).
Code is not 100% done yet, but I'm using it this way right now ↓ (shot fn is called from main.py in a loop)

    


    
import cv2
import subprocess

from time import sleep
from collections import namedtuple

from errors import *

class Camera:
    def __init__(self, cam_index, res_width, res_height, pic_format, day_time_exposure_ms, night_time_exposure_ms):
        Resolution = namedtuple("resolution", ["width", "height"])
        self.manual_mode(True)

        self.cam_index = cam_index
        self.camera_resolution = Resolution(res_width, res_height)
        self.picture_format = pic_format
        self.day_time_exposure_ms = day_time_exposure_ms
        self.night_time_exposure_ms = night_time_exposure_ms

        self.started: bool = False
        self.night_mode = False

        self.cap = cv2.VideoCapture(self.cam_index, cv2.CAP_V4L2)
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.camera_resolution.width)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.camera_resolution.height)
        self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*self.picture_format))

    

    def start(self):
        sleep(1)
        if not self.cap.isOpened():
            return CameraCupError()

        self.set_exposure_time(self.day_time_exposure_ms)
        self.set_brightness(0)
        sleep(0.1)
        
        self.started = True



    def shot(self, picture_name, is_night):
        if not self.started:
            return InitializationError()

        self.configure_mode(is_night)

        # Clear buffer
        for _ in range(5):
            ret, _ = self.cap.read()

        ret, frame = self.cap.read()

        sleep(0.1)

        if ret:
            print(picture_name)
            cv2.imwrite(picture_name, frame)
            return True

        else:
            print("No photo")
            return False


    
    def release(self):
        self.set_exposure_time(156)
        self.set_brightness(0)
        self.manual_mode(False)
        self.cap.release()



    def manual_mode(self, switch: bool):
        if switch:
            subprocess.run(["v4l2-ctl", "--set-ctrl=auto_exposure=1"])
        else:
            subprocess.run(["v4l2-ctl", "--set-ctrl=auto_exposure=3"])
        sleep(1)

    
    
    def configure_mode(self, is_night):
        if is_night == self.night_mode:
            return

        if is_night:
            self.night_mode = is_night
            self.set_exposure_time(self.night_time_exposure_ms)
            self.set_brightness(64)
        else:
            self.night_mode = is_night
            self.set_exposure_time(self.day_time_exposure_ms)
            self.set_brightness(0)
        sleep(0.1)



    def set_exposure_time(self, ms: int):
        ms = int(ms)
        default_val = 156

        if ms < 1 or ms > 5000:
            ms = default_val

        self.cap.set(cv2.CAP_PROP_EXPOSURE, ms)



    def set_brightness(self, value: int):
        value = int(value)
        default_val = 0

        if value < -64 or value > 64:
            value = default_val

        self.cap.set(cv2.CAP_PROP_BRIGHTNESS, value)


    


    Here are settings for the camera (yaml file)

    


    camera:
  camera_index: 0
  res_width: 1920
  res_height: 1080
  picture_format: "MJPG"
  day_time_exposure_ms: 5
  night_time_exposure_ms: 5000
  photos_format: "jpg"



    


    I do some configs like set manual mode for the camera, change exposure/brightness and saving frame.
Also the camera is probably catching the frames to the buffer (it is not saving latest frame in real time : it's more laggish), so I have to clear buffer every time. like this

    


            # Clear buffer from old frames
        for _ in range(5):
            ret, _ = self.cap.read()
        
        # Get a new frame
        ret, frame = self.cap.read()


    


    What I really don't like, but I could find a better way (tldr : setting buffer for 1 frame doesn't work on my camera).

    


    Frames saved this method looks good with 1920x1080 resolution. BUT when I try to run ffmpeg command to make a timelapse from saved jpg file like this

    


    ffmpeg -framerate 20 -pattern_type glob -i "*.jpg" -c:v libx264 output.mp4


    


    I got an error like this one

    


    [image2 @ 0x555609c45240] Could not open file : 08:59:20.jpg
[image2 @ 0x555609c45240] Could not find codec parameters for stream 0 (Video: mjpeg, none(bt470bg/unknown/unknown)): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, image2, from '*.jpg':
  Duration: 00:00:00.05, start: 0.000000, bitrate: N/A
  Stream #0:0: Video: mjpeg, none(bt470bg/unknown/unknown), 20 fps, 20 tbr, 20 tbn
Output #0, mp4, to 'output.mp4':
Output file #0 does not contain any stream


    


    Also when I try to copy the files from Linux to Windows I get some weird copy failing error and option to skip the picture. But even when I press the skip button, the picture is copied and can be opened. I'm not sure what is wrong with the format, but the camera is supporting MPEG at 1920x1080.

    


    >>> v4l2-ctl --all

Driver Info:
        Driver name      : uvcvideo
        Card type        : H264 USB Camera: USB Camera
        Bus info         : usb-xhci-hcd.1-1
        Driver version   : 6.6.51
        Capabilities     : 0x84a00001
                Video Capture
                Metadata Capture
                Streaming
                Extended Pix Format
                Device Capabilities
        Device Caps      : 0x04200001
                Video Capture
                Streaming
                Extended Pix Format
Media Driver Info:
        Driver name      : uvcvideo
        Model            : H264 USB Camera: USB Camera
        Serial           : 2020032801
        Bus info         : usb-xhci-hcd.1-1
        Media version    : 6.6.51
        Hardware revision: 0x00000100 (256)
        Driver version   : 6.6.51
Interface Info:
        ID               : 0x03000002
        Type             : V4L Video
Entity Info:
        ID               : 0x00000001 (1)
        Name             : H264 USB Camera: USB Camera
        Function         : V4L2 I/O
        Flags            : default
        Pad 0x0100000d   : 0: Sink
          Link 0x0200001a: from remote pad 0x1000010 of entity 'Extension 4' (Video Pixel Formatter): Data, Enabled, Immutable
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
        Width/Height      : 1920/1080
        Pixel Format      : 'MJPG' (Motion-JPEG)
        Field             : None
        Bytes per Line    : 0
        Size Image        : 4147789
        Colorspace        : sRGB
        Transfer Function : Default (maps to sRGB)
        YCbCr/HSV Encoding: Default (maps to ITU-R 601)
        Quantization      : Default (maps to Full Range)
        Flags             :
Crop Capability Video Capture:
        Bounds      : Left 0, Top 0, Width 1920, Height 1080
        Default     : Left 0, Top 0, Width 1920, Height 1080
        Pixel Aspect: 1/1
Selection Video Capture: crop_default, Left 0, Top 0, Width 1920, Height 1080, Flags:
Selection Video Capture: crop_bounds, Left 0, Top 0, Width 1920, Height 1080, Flags:
Streaming Parameters Video Capture:
        Capabilities     : timeperframe
        Frames per second: 15.000 (15/1)
        Read buffers     : 0

User Controls

                     brightness 0x00980900 (int)    : min=-64 max=64 step=1 default=0 value=64
                       contrast 0x00980901 (int)    : min=0 max=64 step=1 default=32 value=32
                     saturation 0x00980902 (int)    : min=0 max=128 step=1 default=56 value=56
                            hue 0x00980903 (int)    : min=-40 max=40 step=1 default=0 value=0
        white_balance_automatic 0x0098090c (bool)   : default=1 value=1
                          gamma 0x00980910 (int)    : min=72 max=500 step=1 default=100 value=100
                           gain 0x00980913 (int)    : min=0 max=100 step=1 default=0 value=0
           power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=1 value=1 (50 Hz)
                                0: Disabled
                                1: 50 Hz
                                2: 60 Hz
      white_balance_temperature 0x0098091a (int)    : min=2800 max=6500 step=1 default=4600 value=4600 flags=inactive
                      sharpness 0x0098091b (int)    : min=0 max=6 step=1 default=3 value=3
         backlight_compensation 0x0098091c (int)    : min=0 max=2 step=1 default=1 value=1

Camera Controls

                  auto_exposure 0x009a0901 (menu)   : min=0 max=3 default=3 value=1 (Manual Mode)
                                1: Manual Mode
                                3: Aperture Priority Mode
         exposure_time_absolute 0x009a0902 (int)    : min=1 max=5000 step=1 default=156 value=5000
     exposure_dynamic_framerate 0x009a0903 (bool)   : default=0 value=0


    


    I also tried to save the picture using ffmpeg in a case something is not right with opencv like this :

    


    ffmpeg -f v4l2 -framerate 30 -video_size 1920x1080 -i /dev/video0 -c:v libx264 -preset fast -crf 23 -t 00:01:00 output.mp4



    


    It is saving the picture but also changing its format

    


    [video4linux2,v4l2 @ 0x555659ed92b0] The V4L2 driver changed the video from 1920x1080 to 800x600
[video4linux2,v4l2 @ 0x555659ed92b0] The driver changed the time per frame from 1/30 to 1/15


    


    But the format looks right when set it back to FHD using v4l2

    


    
>>> v4l2-ctl --device=/dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=MJPG
>>> v4l2-ctl --get-fmt-video

Format Video Capture:
        Width/Height      : 1920/1080
        Pixel Format      : 'MJPG' (Motion-JPEG)
        Field             : None
        Bytes per Line    : 0
        Size Image        : 4147789
        Colorspace        : sRGB
        Transfer Function : Default (maps to sRGB)
        YCbCr/HSV Encoding: Default (maps to ITU-R 601)
        Quantization      : Default (maps to Full Range)
        Flags             :


    


    I'm not sure what could be wrong with the format/camera and I don't think I have enough information to figure it out.

    


    I tried to use ffmpeg instead of opencv and also change a few settings in opencv's cup config.