Код C ++ компилируется, но умирает проблема (наличие строки (очереди), буфера и, если не пустая проблема) - PullRequest
0 голосов
/ 09 ноября 2010

Итак, у меня есть класс..h файл с некоторыми переменными, такими как:

  struct AudioSample
  { 
    const unsigned char * buffer;
      int len;
  };
        //...
      const unsigned char * VideoFrameBuffer;
      int VideoFrameLen;


  std::queue<AudioSample> AudioSamples;


  bool sampleSendingFinished;
  bool frameSendingFinished;
      //...

и файл .CPP с функциями

void VideoEncoder::UrlWriteData()
{
    while(1){
        if (AudioSamples.empty() && VideoFrameBuffer == NULL)
        {
            Sleep(1);
        }
        else if(!AudioSamples.empty())
        {
            struct AudioSample newAudioSample = AudioSamples.front();
            url_write (url_context, (unsigned char *)newAudioSample.buffer, newAudioSample.len);
        }
        else if (AudioSamples.empty() && VideoFrameBuffer != NULL)
        {
            url_write (url_context, (unsigned char *)VideoFrameBuffer, VideoFrameLen);
        }
    }

}
void VideoEncoder::AddSampleToQueue(const unsigned char *buf, int size )
{

    struct AudioSample newAudioSample;
    newAudioSample.buffer = buf;
    newAudioSample.len = size;
    AudioSamples.push(newAudioSample);
}
void VideoEncoder::AddFrameToQueue(const unsigned char *buf, int size )
{
    VideoFrameBuffer = buf;
    VideoFrameLen = size;
}

, время от времени некоторые функции вызывают AddFrameToQueue и AddSampleToQueue.UrlWriteData живет в отдельном потоке.Мое приложение компилируется.Но моя проблема в том, что когда я запускаю его, он умирает на линии:

        else if(!AudioSamples.empty())
        {
            struct AudioSample newAudioSample = AudioSamples.front();

Почему он умирает и как заставить его не умирать?

Ответы [ 3 ]

1 голос
/ 09 ноября 2010

Вы проследили, какая линия не работает?Где это умирает?Как память вашего буфера управляется?Ваш код синхронизирован?(Между прочим, кажется, что библиотека FFmpeg была исправлена, а url_write теперь является const-правильным. В идеале вам следует использовать const_cast, а не C-бросок, хотя некоторые скажут, что это стиль).

Как общий комментарий к вашему коду:

  • Опрос имеет свои преимущества (на данный момент вы можете обрабатывать несколько элементов очереди), но я не уверен, что это именно то, что вам нужно.Возможно, вы захотите использовать какую-то систему блокировки / ожидания.Если это Windows, это делается с помощью WaitForSingleObject и аналогичных вызовов.В UNIX вы можете либо pthread_cond_wait, либо выбрать вызвать блок.Затем поток будет разбужен, когда ему будет что обрабатывать.
1 голос
/ 09 ноября 2010

Существует потокобезопасная очередь производителя-потребителя, использующая стандартные механизмы многопоточности здесь . Это было бы хорошим введением в концепции потоков, которые вы должны понимать, чтобы заставить этот дизайн работать.

Производитель (и) - это функции, которые добавляют в вашу очередь, а потребитель (ы) - это функция (и), которые читают и (обычно) обрабатывают записи в очереди - UrlWriteData здесь.

1 голос
/ 09 ноября 2010

Я считаю, что вы новичок, вы вырезали + скопировали этот код откуда-то, убрав из него все ненужные вещи, пока он не скомпилирован. И теперь вам интересно, почему это не работает. Я прав?

Ну, просто предварительный список проблем, не вдаваясь в подробности:

  1. Многопоточным приложениям обычно требуются механизмы синусоидальной синхронизации при доступе к одним и тем же данным из разных потоков. Такие как критические секции, мьютексы и т. Д. Или, по крайней мере, блокированные (без блокировки) операции и / или барьеры памяти. Я не вижу ничего подобного в вашем коде.
  2. В вашем конкретном случае AudioSamples является сложным объектом, который управляется из нескольких потоков. Это должно быть защищено критической секцией (или подобной).
  3. То же самое в отношении установки / запроса VideoFrameBuffer и VideoFrameLen.
  4. После того, как вы возьмете следующий аудиосэмпл - вы должны вынуть его из очереди (вызов pop_front).
  5. Оба ваших элемента данных "аудиосэмпла" и "видеокадра" содержат только указатели на фактические данные. Непонятно из вашего дизайна (если был такой) - у кого есть «владение» выделенной памятью. Простыми словами - кто должен освободить выделенную память.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...