Я хочу реализовать приложение, которое сначала декодирует мультимедийный файл (например, файл test.mp4, идентификатор видеокодека - H264), получает видеопоток и аудиопоток, а затем делает несколько разных аудиопотоков, наконец, кодирует видеопоток (используйте libx264) и аудиопоток в файл результата (result.mp4). Чтобы повысить эффективность, я опустил декодирование и кодирование видеопотока, я получаю видеопакет с помощью функции «av_read_frame», а затем вывожу его непосредственно в файл результата с помощью функции «av_write_frame». Но в выходном файле нет изображения, и размер выходного файла довольно мал.
Я отследил код ffmpeg и обнаружил, что в функции «av_write_frame->mov_write_packet->ff_mov_write_packet» будет вызываться функция «ff_avc_parse_nal_units», чтобы получить размер конечной единицы, но возвращаемое значение очень маленькое (например, 208 байт).
Я обнаружил, что поток H264 в файле MP4 не хранится в формате Приложения-B, поэтому он не может найти начальный код (0x000001), теперь моя проблема заключается в том, как я могу изменить поток H264 на формат Приложения-B и сделать Это работает?Я добавил стартовый код в начале каждого кадра вручную, но это все еще не работает.
Кто-нибудь может дать мне подсказку? Большое спасибо. Ниже приведены коды, похожие на мой:
// write the stream header, if any
av_write_header(pFormatCtxEnc);
.........
/**
* Init of Encoder and Decoder
*/
bool KeyFlag = false;
bool KeyFlagEx = false;
// Read frames and save frames to disk
int iPts = 1;
av_init_packet(&packet);
while(av_read_frame(pFormatCtxDec, &packet)>=0)
{
if (packet.flags == 1)
KeyFlag = true;
if (!KeyFlag)
continue;
if (m_bStop)
{
break;
}
// Is this a packet from the video stream?
if(packet.stream_index == videoStream)
{
currentframeNum ++;
if (progressCB != NULL && currentframeNum%20 == 0)
{
float fpercent = (float)currentframeNum/frameNum;
progressCB(fpercent,m_pUser);
}
if (currentframeNum >= beginFrame && currentframeNum <= endFrane)
{
if (packet.flags == 1)
KeyFlagEx = true;
if (!KeyFlagEx)
continue;
packet.dts = iPts ++;
av_write_frame(pFormatCtxEnc, &packet);
}
}
// Free the packet that was allocated by av_read_frame
}
// write the trailer, if any
av_write_trailer(pFormatCtxEnc);
/**
* Release of encoder and decoder
*/
return true;
MP4
FFmpeg
можно настроить на прием потоков как со стартовыми кодами, так и без них. Начальные NAL обычно представляют собой наборы параметров и могут быть небольшими.av_write_frame
это правильно. Какой у вас код? Может кто заметит проблему. - person Roman R.   schedule 27.12.2012