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