Войти
ПрограммированиеФорумОбщее

FFmpeg в коммерческой разработке. (3 стр)

Страницы: 1 2 3
#30
19:10, 27 янв. 2021

Все, вопрос закрыт!

Удалось решить проблему с двух сторон, во первых я вставил  в энкодер сдвиг на 6 байт в начале файла, что бы можно было играть h264 без лишнего геморроя в виде командной строки:

void PollingThread::Run()
{
  RequestStop();
  int skip = 6;  // пропускаем нафиг первые 6 байт.
  AMF_RESULT res = AMF_OK;
  while (active)
  {
    amf::AMFDataPtr data;
    res = m_pEncoder->QueryOutput(&data);
    if (res == AMF_EOF)
    {
      break; // Drain complete
    }
    if (data != NULL)
    {
      amf::AMFBufferPtr buffer(data); // query for buffer interface
      m_pFile.write(reinterpret_cast<char*>(buffer->GetNative()) + skip, buffer->GetSize()-skip);
      skip = 0;
    }
    else
    {
      amf_sleep(1);
    }
  }

  m_pEncoder = NULL;
  m_pContext = NULL;
}

Ну а самое главное это обход AUD в MP4V2 как это сделал entryway:

    while (1)
    {
      len = getNalu(pIn, pBuf);
      if (len <= 0)
        break;

      if (pBuf[0] != 0 || pBuf[1] != 0 || pBuf[2] != 0 || pBuf[3] != 1)
        continue;

      len -= 4;
      pNalu = pBuf + 4;
      naluType = pNalu[0] & 0x1F;

      switch (naluType)
      {
      case 0x07: // SPS

        if (addStream)
        {
          videoId = MP4AddH264VideoTrack(pHandle, timeScale,  timeScale / frameRate,  width,  height, pNalu[1], pNalu[2], pNalu[3], 3);
          if (videoId == MP4_INVALID_TRACK_ID)
          {
            return -1;
          }

          MP4SetVideoProfileLevel(pHandle, 0x7F);

          addStream = 0;
        }

        MP4AddH264SequenceParameterSet(pHandle, videoId, pNalu, len);
        break;

      case 0x08: // PPS
        MP4AddH264PictureParameterSet(pHandle, videoId, pNalu, len);
        break;

      case 0x09: // AUD
        break;

      default:

        pBuf[0] = (len >> 24) & 0xFF;
        pBuf[1] = (len >> 16) & 0xFF;
        pBuf[2] = (len >> 8) & 0xFF;
        pBuf[3] = (len >> 0) & 0xFF;

        MP4WriteSample(pHandle, videoId, pBuf, len + 4, MP4_INVALID_DURATION, 0, 1);

        break;
      }

Из ценных знаний полученных в процессе исследования это то, что AUD это зло. Из mp4 их однозначно нужно выкидывать, да и в h264 они гадят. По крайней мере если стоят в начале файла.


#31
(Правка: 19:45) 19:16, 27 янв. 2021

san
> я вставил в энкодер сдвиг на 6 байт в начале файла
Что-то как-то жестко, не? Завтра обновится AMF и всё сломается?

У меня, кстати, древний mpc-hc.exe за 2012 год не играет mp4, созданные mp4v2 кодом выше. Время показывает, но играть не хочет, ползунок не двигается. А вот те что ты выложил (amd.mp4, nv.mp4) - играет.

А, не, все ок. Просто в коде с примера прописано разрешение неправильное. Вписал правильное - теперь играет.

#32
20:01, 27 янв. 2021

если почитать спецификации mp4, то можно узнать, что в случае h264 в саму тушку mp4 должны записываться только VCL nal units, т.е. idr и не idr фреймы, не надо что нипопадя скармливать в контейнер и все выглядит так, что  ты так и не разобрался с timestamp, aud тем более не надо скрамливать. sps/pps/vps должны лежать только в mp4 хидере и не лежать в тушке mp4 даже елси они постоянно в h264 идут.

#33
(Правка: 20:14) 20:07, 27 янв. 2021

entryway
> Что-то как-то жестко, не? Завтра обновится AMF и всё сломается?
Тоже верно. Нужно просто проверить эти первые 6 байт AUD это или нет. Ну и выкидывать если так.

MAMOHT-92
> все выглядит так, что  ты так и не разобрался с timestamp, aud тем более не надо скрамливать.
После драки все горазды кулаками махать.
Только твои претензии нужно не мне предьявлять, а разработчикам MP4V4, т.е. компании Cisco. Это они "не разобрались". Я в данном случае исправлял их хомут и баг в AMF который вообще не должен был AUD вставлять в файл.

Страницы: 1 2 3
ПрограммированиеФорумОбщее