Все, вопрос закрыт!
Удалось решить проблему с двух сторон, во первых я вставил в энкодер сдвиг на 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 они гадят. По крайней мере если стоят в начале файла.
san
> я вставил в энкодер сдвиг на 6 байт в начале файла
Что-то как-то жестко, не? Завтра обновится AMF и всё сломается?
У меня, кстати, древний mpc-hc.exe за 2012 год не играет mp4, созданные mp4v2 кодом выше. Время показывает, но играть не хочет, ползунок не двигается. А вот те что ты выложил (amd.mp4, nv.mp4) - играет.
А, не, все ок. Просто в коде с примера прописано разрешение неправильное. Вписал правильное - теперь играет.
если почитать спецификации mp4, то можно узнать, что в случае h264 в саму тушку mp4 должны записываться только VCL nal units, т.е. idr и не idr фреймы, не надо что нипопадя скармливать в контейнер и все выглядит так, что ты так и не разобрался с timestamp, aud тем более не надо скрамливать. sps/pps/vps должны лежать только в mp4 хидере и не лежать в тушке mp4 даже елси они постоянно в h264 идут.
entryway
> Что-то как-то жестко, не? Завтра обновится AMF и всё сломается?
Тоже верно. Нужно просто проверить эти первые 6 байт AUD это или нет. Ну и выкидывать если так.
MAMOHT-92
> все выглядит так, что ты так и не разобрался с timestamp, aud тем более не надо скрамливать.
После драки все горазды кулаками махать.
Только твои претензии нужно не мне предьявлять, а разработчикам MP4V4, т.е. компании Cisco. Это они "не разобрались". Я в данном случае исправлял их хомут и баг в AMF который вообще не должен был AUD вставлять в файл.
Тема в архиве.