Hi, Sir/Madam

How are you doing recently?

I have a question how to remux an mp4 file using libav.
Um, as I was able to read from the mp4 file and got each avpacket, I stored
the data from each avpacket to a circular buffer I created.
The problem is that when I wanted to take advantage of the data stored in
my circular buffer, I must use av_malloc and memcpy to create and copy the
data. If I used the data directly from the circular buffer, it did not work.
As I have saw the source code, I found that av_malloc just did the
_aligned_malloc to malloc the data, and I tried that out, but still did not
work.

Attached is my loop doing remux, it is the todo part I wanna figure out. In
particular, I'm using malloc in FrameInfo class, but I have also tried the
_aligned_malloc(size, 16(/32) );

Thank you so much for the help~
// Create a packet to read each frame and a duplicated for buffer
  AVPacket packet;
  AVPacket bufPacket;

  av_init_packet(&packet);
  av_init_packet(&bufPacket);

  int  readAble      = 0;
  bool mux_start     = false;
  bool read_start    = false;
  FrameInfo vInfo    = FrameInfo(VIDEO_BITSTREAM);
  FrameInfo aInfo    = FrameInfo(AUDIO_BITSTREAM);
  FrameInfo tmpVinfo = FrameInfo(VIDEO_BITSTREAM);
  FrameInfo tmpAinfo = FrameInfo(AUDIO_BITSTREAM);

  while ( readAble >= 0 || !AudioCBuf.IsEmptyCBuf() || !VideoCBuf.IsEmptyCBuf() )
  {
    readAble = av_read_frame(srcFormatCtx, &packet);
    // Step 1-0: Write packet data to A/VCBuf
    if (packet.stream_index == video_idx && readAble >= 0)
    {
      vInfo.Set_props(packet.pts, packet.dts, packet.data, packet.size,
        packet.stream_index, packet.flags, packet.duration,
        packet.pos, packet.convergence_duration);
      VideoCBuf.WriteCBuf(&vInfo);
      vInfo.SetDefaultInfo();
    }
    if (packet.stream_index == audio_idx && readAble >= 0)
    {
      aInfo.Set_props(packet.pts, packet.dts, packet.data, packet.size,
        packet.stream_index, packet.flags, packet.duration,
        packet.pos, packet.convergence_duration);
      AudioCBuf.WriteCBuf(&aInfo);
      aInfo.SetDefaultInfo();
    }
    // Step 1-1: If neither CBuf hit 8 and mux not started, continue read
    if ( (AudioCBuf.GetCount() < 8) && (VideoCBuf.GetCount() < 8) && !mux_start)
    {
      continue;
    }

    // Step 2-0: Check the Cbuf whose count is larger than 8
    if (AudioCBuf.GetCount() >= 8)
    {
      // Step 2-1: Process it
      mux_start = true;

      // Prepare data to communicate with ffmpeg
      tmpAinfo = AudioCBuf.ReadCBuf();
      uint8_t* data = (uint8_t*)av_malloc(tmpAinfo.Get_data_size());
      memcpy(data, tmpAinfo.Get_bitstream(), tmpAinfo.Get_data_size());

      // Set avpacket properties
      av_packet_from_data(&bufPacket, data, tmpAinfo.Get_data_size());
      bufPacket.pts = tmpAinfo.Get_pts();
      bufPacket.dts = tmpAinfo.Get_dts();
      bufPacket.pos = tmpAinfo.Get_pos();
      bufPacket.duration = tmpAinfo.Get_duration();
      bufPacket.convergence_duration = tmpAinfo.Get_convergence_duration();
      bufPacket.flags = tmpAinfo.Get_flags();
      bufPacket.stream_index = tmpAinfo.Get_stream_index();

      // Write to output file (seems in memory only, flush when process 
      // av_write_trailer)
      av_interleaved_write_frame(outFmtCtx, &bufPacket);

      tmpAinfo.SetDefaultInfo();
    }
    if (VideoCBuf.GetCount() >= 8)
    {
      // Step 2-1: Process it
      mux_start = true;


      // TODO: IMPLEMENT NOT USING COPIED DATA
      // Prepare data to communicate with ffmpeg
      tmpVinfo = VideoCBuf.ReadCBuf();
      uint8_t* data = (uint8_t*)av_malloc(tmpVinfo.Get_data_size());
      memcpy(data, tmpVinfo.Get_bitstream(), tmpVinfo.Get_data_size());

      // Set avpacket properties
      av_packet_from_data(&bufPacket, data, tmpVinfo.Get_data_size());
      bufPacket.pts = tmpVinfo.Get_pts();
      bufPacket.dts = tmpVinfo.Get_dts();
      bufPacket.pos = tmpVinfo.Get_pos();
      bufPacket.duration = tmpVinfo.Get_duration();
      bufPacket.convergence_duration = tmpVinfo.Get_convergence_duration();
      bufPacket.flags = tmpVinfo.Get_flags();
      bufPacket.stream_index = tmpVinfo.Get_stream_index();

      // Write to output file (seems in memory only, flush when process 
      // av_write_trailer)
      av_interleaved_write_frame(outFmtCtx, &bufPacket);

      tmpVinfo.SetDefaultInfo();
    }

    // Step 3: Process all rest data in the A/VCbuf
    if (readAble < 0)
    {
      while (!VideoCBuf.IsEmptyCBuf() || !AudioCBuf.IsEmptyCBuf() )
      {
        // Process audio and video using the same strategy
        if (!VideoCBuf.IsEmptyCBuf() )
        {
          tmpVinfo = VideoCBuf.ReadCBuf();
          uint8_t* data = (uint8_t*)av_malloc(tmpVinfo.Get_data_size());
          memcpy(data, tmpVinfo.Get_bitstream(), tmpVinfo.Get_data_size());

          av_packet_from_data(&bufPacket, data, tmpVinfo.Get_data_size());
          bufPacket.pts = tmpVinfo.Get_pts();
          bufPacket.dts = tmpVinfo.Get_dts();
          bufPacket.pos = tmpVinfo.Get_pos();
          bufPacket.duration = tmpVinfo.Get_duration();
          bufPacket.convergence_duration = tmpVinfo.Get_convergence_duration();
          bufPacket.flags = tmpVinfo.Get_flags();
          bufPacket.stream_index = tmpVinfo.Get_stream_index();

          av_interleaved_write_frame(outFmtCtx, &bufPacket);

          tmpVinfo.SetDefaultInfo();
        }
        else if (!AudioCBuf.IsEmptyCBuf() )
        {
          tmpAinfo = AudioCBuf.ReadCBuf();
          uint8_t* data = (uint8_t*)av_malloc(tmpAinfo.Get_data_size());
          memcpy(data, tmpAinfo.Get_bitstream(), tmpAinfo.Get_data_size());

          av_packet_from_data(&bufPacket, data, tmpAinfo.Get_data_size());
          bufPacket.pts = tmpAinfo.Get_pts();
          bufPacket.dts = tmpAinfo.Get_dts();
          bufPacket.pos = tmpAinfo.Get_pos();
          bufPacket.duration = tmpAinfo.Get_duration();
          bufPacket.convergence_duration = tmpAinfo.Get_convergence_duration();
          bufPacket.flags = tmpAinfo.Get_flags();
          bufPacket.stream_index = tmpAinfo.Get_stream_index();

          av_interleaved_write_frame(outFmtCtx, &bufPacket);

          tmpAinfo.SetDefaultInfo();
        }
        continue;
      } // Process the rest
    } // Judge if Process rest
  } // Main While loop
  
  av_free_packet(&bufPacket);
  av_free_packet(&packet);

  // Write the trailer info to file
  if (av_write_trailer(outFmtCtx) < 0)
    return -1;
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to