2012-12-27 2 views
2

Я хочу реализовать приложение, которое сначала декодирует мультимедийный файл (например, файл test.mp4, идентификатор видеокодека H264), получить видеопоток и аудио потоком, затем сделать несколько разных в аудиопотоке, наконец, закодировать видеопоток (используйте libx264) и аудиопоток в файл результатов (result.mp4). Чтобы повысить эффективность, я пропустил декодирование и кодирование видеопотока, я получил видеопакет через функцию «av_read_frame», а затем вывел его непосредственно в файл результатов с помощью функции «av_write_frame». Но в выходном файле нет изображения, а размер выходного файла довольно мал.Как mux поток H264 в файл MP4 через libavformat

Я отслеживал код 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; 
+0

Мультиплексор 'FFmpeg'' MP4' может быть настроен на прием потоков как со стартовыми кодами, так и без них. Первоначальные NAL - это, как правило, наборы параметров и в порядке, чтобы они были небольшими. 'av_write_frame' - это правильная вещь. Какой у вас код? Может быть, кто-то заметит проблему. –

+0

Спасибо, как настроить мультиплексор MP4 ffmpeg для приема потоков без кода запуска? Нужно ли устанавливать некоторые специальные параметры? Вышеупомянутые коды похожи на мои. Возвращаемое значение функции «ff_avc_parse_nal_units» почти равно 0 для каждого кадра, а большинство кадров выводятся без ничего. – Brian

ответ

0

Вы можете попробовать это: libavcodec/h264_mp4toannexb_bsf.c Он преобразует поток битов без стартовых кодов битов. с помощью кодов начала.

Использование исходного файла, делает ffmpeg -i src.mp4 -vcodec copy -an dst.mp4 работы? Он работает, если вы добавите -bsf h264_mp4toannexb? (все используют ту же версию/сборку ffmpeg, что и вы, конечно, пытаетесь использовать программно)