Hi all,
First of all, I am new to this mailing list, so hi everybody. I want to
make a program that mixes some packets of a couple of .ts files, the
program runs ok but valgrind detects some memory leaks and two of them
are quite big (23,288 bytes) and I do not know what to do.
I think i understand quite well what I am doing (use the right functions
at the right moment), and after having looked at it a lot I can not
figure out what is wrong.
This is Valgrinds ouptut:
==11908== Memcheck, a memory error detector
==11908== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==11908== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==11908== Command: ./CopyTsToTs hola-3.ts salida.ts
==11908==
[mpegts @ 0x4278060] max_analyze_duration 5000000 reached at 5013600
Input #0, mpegts, from 'hola-3.ts':
Duration: 00:00:12.07, start: 25.688000, bitrate: 799 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
Stream #0:0[0x100]: Video: h264 (Constrained Baseline)
([27][0][0][0] / 0x001B), yuv420p, 640x360, 25 fps, 25 tbr, 90k tbn, 50 tbc
Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz,
stereo, s16, 86 kb/s
Output #0, mpegts, to 'salida.ts':
Stream #0:0: Video: h264 ([27][0][0][0] / 0x001B), yuv420p,
640x360, q=2-31, 90k tbn, 25 tbc
Stream #0:1: Audio: aac ([15][0][0][0] / 0x000F), 44100 Hz, stereo,
86 kb/s
[mpegts @ 0x48348a0] muxrate VBR, pcr every 2 pkts, sdt every 200,
pat/pmt every 40 pkts
==11908==
==11908== HEAP SUMMARY:
==11908== in use at exit: 46,622 bytes in 7 blocks
==11908== total heap usage: 5,751 allocs, 5,744 frees, 9,552,334 bytes
allocated
==11908==
==11908== 8 bytes in 1 blocks are indirectly lost in loss record 1 of 7
==11908== at 0x402BE68: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402C007: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86D3B07: av_dict_set (dict.c:82)
==11908== by 0x81232CA: avformat_write_header (utils.c:3446)
==11908== by 0x804AE75: CopyTsPacketByPacket (CopyTsToTs.c:258)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 8 bytes in 1 blocks are indirectly lost in loss record 2 of 7
==11908== at 0x402A420: memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402A4DE: posix_memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86DADEF: av_strdup (mem.c:95)
==11908== by 0x86D3AC6: av_dict_set (dict.c:92)
==11908== by 0x81232CA: avformat_write_header (utils.c:3446)
==11908== by 0x804AE75: CopyTsPacketByPacket (CopyTsToTs.c:258)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 8 bytes in 1 blocks are definitely lost in loss record 3 of 7
==11908== at 0x402BF52: realloc (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x812594E: avformat_new_stream (utils.c:3147)
==11908== by 0x804AA66: add_output_stream (CopyTsToTs.c:82)
==11908== by 0x804AFAF: CopyTsPacketByPacket (CopyTsToTs.c:242)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 14 bytes in 1 blocks are indirectly lost in loss record 4 of 7
==11908== at 0x402A420: memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402A4DE: posix_memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86DADEF: av_strdup (mem.c:95)
==11908== by 0x86D3A35: av_dict_set (dict.c:102)
==11908== by 0x81232CA: avformat_write_header (utils.c:3446)
==11908== by 0x804AE75: CopyTsPacketByPacket (CopyTsToTs.c:258)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 38 (8 direct, 30 indirect) bytes in 1 blocks are definitely
lost in loss record 5 of 7
==11908== at 0x402A420: memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402A4DE: posix_memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86DACAF: av_mallocz (mem.c:95)
==11908== by 0x86D3ADB: av_dict_set (dict.c:70)
==11908== by 0x81232CA: avformat_write_header (utils.c:3446)
==11908== by 0x804AE75: CopyTsPacketByPacket (CopyTsToTs.c:258)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 23,288 bytes in 1 blocks are definitely lost in loss record 6 of 7
==11908== at 0x402A420: memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402A4DE: posix_memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86DACAF: av_mallocz (mem.c:95)
==11908== by 0x812597B: avformat_new_stream (utils.c:3155)
==11908== by 0x804AA66: add_output_stream (CopyTsToTs.c:82)
==11908== by 0x804ADD7: CopyTsPacketByPacket (CopyTsToTs.c:237)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== 23,288 bytes in 1 blocks are definitely lost in loss record 7 of 7
==11908== at 0x402A420: memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x402A4DE: posix_memalign (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11908== by 0x86DACAF: av_mallocz (mem.c:95)
==11908== by 0x812597B: avformat_new_stream (utils.c:3155)
==11908== by 0x804AA66: add_output_stream (CopyTsToTs.c:82)
==11908== by 0x804AFAF: CopyTsPacketByPacket (CopyTsToTs.c:242)
==11908== by 0x804B2BC: main (CopyTsToTs.c:44)
==11908==
==11908== LEAK SUMMARY:
==11908== definitely lost: 46,592 bytes in 4 blocks
==11908== indirectly lost: 30 bytes in 3 blocks
==11908== possibly lost: 0 bytes in 0 blocks
==11908== still reachable: 0 bytes in 0 blocks
==11908== suppressed: 0 bytes in 0 blocks
==11908==
==11908== For counts of detected and suppressed errors, rerun with: -v
==11908== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
I attach a source code that just copyes a .ts file into other .ts file
packet by packet. The compilation, valgrind and mtrace instructions are
on it. I also attach a little .ts file.
It looks like it misses some reference...
Thank you in advance!
Miguel
/*
How to compile --> ffmpeg 1.0.6
gcc CopyTsToTs.c -Wall -O2 -g -o CopyTsToTs -lm -ljpeg -lz -lva -lpthread -L <where ffmpeg is installed>/lib/ -lavformat -lavcodec -lavutil
Valgrind cli
valgrind --leak-check=full --track-origins=yes --show-reachable=yes ./CopyTsToTs hola-3.ts salida.ts
mtrace
export MALLOC_TRACE=<wherever you want>
compile with -g and execute
mtrace CopyTsToTs $MALLOC_TRACE
Memory not freed:
-----------------
Address Size Caller
0x093d6378 0xa at /home/miguel/Escritorio/35_ffmpeg_ts_tcp/programas_c_ffmpeg_ts_tcp/CopyTsToTs.c:245
0x093d9df0 0x8 at /home/miguel/ffmpeg-1.0.6/libavformat/utils.c:4540
0x093da3d0 0x8 at /home/miguel/ffmpeg-1.0.6/libavutil/eval.c:166
0x093da3e0 0x8 at /home/miguel/ffmpeg-1.0.6/libavutil/opt.c:638
0x093de8a0 0xe at /home/miguel/ffmpeg-1.0.6/libavutil/opt.c:63
0x09406ac0 0x5af8 at /home/miguel/ffmpeg-1.0.6/libavutil/opt.c:638
0x0940c5c0 0x5af8 at /home/miguel/ffmpeg-1.0.6/libavutil/opt.c:638
0x0952afe0 0x8 at /home/miguel/ffmpeg-1.0.6/libavutil/opt.c:63
*
*
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mcheck.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
#define TRUE 1
#define FALSE 0
#define MTRACE_FLAG TRUE
/**FUNCTIONS' DECLARATIONS*****************************************************/
static int find_stream_index(int *stream_idx,
AVFormatContext *fmt_ctx,
enum AVMediaType type,
char* src_filename);
static AVStream *add_output_stream(AVFormatContext *output_format_context,
AVStream *input_stream);
int CopyTsPacketByPacket(char* inputTsFilename, char* outputTsFilename);
/**MAIN************************************************************************/
int main(int argc, char **argv)
{
if(argc < 3)
{
printf("Usage: %s <file_in.ts> <file_out.ts>\n", argv[0]);
exit(EXIT_FAILURE);
}
char filename_ts_in[128];
char filename_ts_out[128];
strcpy((char *)filename_ts_in, argv[1]);
strcpy((char *)filename_ts_out, argv[2]);
printf("Copying %s to %s\n", filename_ts_in, filename_ts_out);
if(MTRACE_FLAG)
mtrace();
//Call to the function
CopyTsPacketByPacket(filename_ts_in, filename_ts_out);
if(MTRACE_FLAG)
muntrace();
exit(EXIT_SUCCESS);
}
static int find_stream_index(int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type, char* src_filename)
{
int ret;
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
if (ret < 0)
{
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
av_get_media_type_string(type), src_filename);
return ret;
} else
{
*stream_idx = ret;
return ret;
}
return 0;
}
static AVStream *add_output_stream(AVFormatContext *output_format_context, AVStream *input_stream)
{
AVCodecContext *input_codec_context;
AVCodecContext *output_codec_context;
AVStream *output_stream = NULL;
/*output_stream = av_new_stream(output_format_context, 0);
if (!output_stream) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}*/
//printf("@@@@ outputstream = %x \n", output_format_context);
//cuidao
output_stream = avformat_new_stream(output_format_context, NULL);
if (!output_stream) {
fprintf(stderr, "Could not allocate stream\n");
exit(1);
}
printf("#### outputstream memory address -> 0x%x \n", output_stream);
input_codec_context = input_stream->codec;
output_codec_context = output_stream->codec;
output_codec_context->codec_id = input_codec_context->codec_id;
output_codec_context->codec_type = input_codec_context->codec_type;
output_codec_context->codec_tag = input_codec_context->codec_tag;
output_codec_context->bit_rate = input_codec_context->bit_rate;
output_codec_context->extradata = input_codec_context->extradata;
output_codec_context->extradata_size = input_codec_context->extradata_size;
if(av_q2d(input_codec_context->time_base) * input_codec_context->ticks_per_frame > av_q2d(input_stream->time_base) && av_q2d(input_stream->time_base) < 1.0/1000) {
output_codec_context->time_base = input_codec_context->time_base;
output_codec_context->time_base.num *= input_codec_context->ticks_per_frame;
}
else {
output_codec_context->time_base = input_stream->time_base;
}
switch (input_codec_context->codec_type) {
//case CODEC_TYPE_AUDIO:
case AVMEDIA_TYPE_AUDIO:
output_codec_context->channel_layout = input_codec_context->channel_layout;
output_codec_context->sample_rate = input_codec_context->sample_rate;
output_codec_context->channels = input_codec_context->channels;
output_codec_context->frame_size = input_codec_context->frame_size;
if ((input_codec_context->block_align == 1 && input_codec_context->codec_id == CODEC_ID_MP3) || input_codec_context->codec_id == CODEC_ID_AC3) {
output_codec_context->block_align = 0;
}
else {
output_codec_context->block_align = input_codec_context->block_align;
}
break;
//case CODEC_TYPE_VIDEO:
case AVMEDIA_TYPE_VIDEO:
output_codec_context->pix_fmt = input_codec_context->pix_fmt;
output_codec_context->width = input_codec_context->width;
output_codec_context->height = input_codec_context->height;
output_codec_context->has_b_frames = input_codec_context->has_b_frames;
if (output_format_context->oformat->flags & AVFMT_GLOBALHEADER) {
output_codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
break;
default:
break;
}
return output_stream;
}
int CopyTsPacketByPacket(char* inputTsFilename, char* outputTsFilename)
{
/* Does not check durations, codecs, packets... anything.
*
* It has 2 memory leaks.
*
* It creates file named as outputTsFilename
*/
int i;
////////////////////////////////////// OPEN FILE ORIG.TS
AVFormatContext *avInputFmtCtx = NULL;
AVDictionaryEntry *tag = NULL;
int video_stream_idx = -1, audio_stream_idx = -1;
int ret;
// Inicializacion del ffmpeg
av_register_all();
// Apertura del archivo
if ((ret = avformat_open_input(&avInputFmtCtx, inputTsFilename, NULL, NULL)))
{
fprintf(stderr, "Could not open source file %s\n", inputTsFilename);
return ret;
}
// Saca los metadatos
while ((tag = av_dict_get(avInputFmtCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
printf("%s=%s\n", tag->key, tag->value);
// Info de las streams
if (avformat_find_stream_info(avInputFmtCtx, NULL) < 0)
{
fprintf(stderr, "Could not find stream information\n");
exit(1);
}
find_stream_index(&video_stream_idx, avInputFmtCtx, AVMEDIA_TYPE_VIDEO, inputTsFilename);
find_stream_index(&audio_stream_idx, avInputFmtCtx, AVMEDIA_TYPE_AUDIO, inputTsFilename);
// Volcado de informacion al stderr
av_dump_format(avInputFmtCtx, 0, inputTsFilename, 0);
////////////////////////////////////// END OPEN ARCHIVO ORIG.TS
////////////////////////////////////// OPEN FILE OUTPUT.TS
AVOutputFormat *ofmt =NULL;
AVFormatContext *oc= NULL;
int video_index;
int audio_index;
int decode_done;
// allocate the output media context
/*
avformat_alloc_output_context2(&oc, NULL, NULL, "miguel.ts");
if (!oc)
{
printf("Could not deduce output format from file extension: using MPEGTS.\n");
avformat_alloc_output_context2(&oc, NULL, "mpegts", "miguel.ts");
}
if (!oc)
{
return 1;
}
ofmt = oc->oformat;
*/
ofmt = av_guess_format("mpegts", NULL, NULL);
if (!ofmt)
{
fprintf(stderr, "Could not find MPEG-TS muxer\n");
exit(1);
}
oc = avformat_alloc_context();
if (!oc)
{
fprintf(stderr, "Could not allocated output context");
exit(1);
}
oc->oformat = ofmt;
video_index = -1;
audio_index = -1;
for (i = 0; i < avInputFmtCtx->nb_streams && (video_index < 0 || audio_index < 0); i++)
{
//printf("@\n");
switch (avInputFmtCtx->streams[i]->codec->codec_type)
{
case AVMEDIA_TYPE_VIDEO:
video_index = i;
avInputFmtCtx->streams[i]->discard = AVDISCARD_NONE;
add_output_stream(oc, avInputFmtCtx->streams[i]);
break;
case AVMEDIA_TYPE_AUDIO:
audio_index = i;
avInputFmtCtx->streams[i]->discard = AVDISCARD_NONE;
add_output_stream(oc, avInputFmtCtx->streams[i]);
break;
default:
avInputFmtCtx->streams[i]->discard = AVDISCARD_ALL;
break;
}
}
av_dump_format(oc, 0, outputTsFilename, 1);
if (avio_open(&oc->pb, outputTsFilename, AVIO_FLAG_WRITE ) < 0)
{
fprintf(stderr, "Could not open '%s'\n", outputTsFilename);
exit(1);
}
if (avformat_write_header(oc, NULL))
{//Hay que poner un dictionary en vez de NULL?
fprintf(stderr, "Could not write mpegts header to first output file\n");
exit(1);
}
//Is it necessary to open the codec_context?
do
{
AVPacket packet;
decode_done = av_read_frame(avInputFmtCtx, &packet);
if (decode_done < 0)
{
break;
}
if (av_dup_packet(&packet) < 0)
{
fprintf(stderr, "Could not duplicate packet");
av_free_packet(&packet);
break;
}
ret = av_interleaved_write_frame(oc, &packet);
if (ret < 0)
{
fprintf(stderr, "Warning: Could not write frame of stream\n");
}
else if (ret > 0)
{
fprintf(stderr, "End of stream requested\n");
av_free_packet(&packet);
break;
}
av_free_packet(&packet);
}
while (!decode_done);
av_write_trailer(oc);
printf("######## stream0 (video) memory address -> 0x%x\n", oc->streams[0]);
printf("######## stream1 (audio) memory address -> 0x%x\n", oc->streams[1]);
for(i = 0; i < oc->nb_streams; i++)
{
// av_freep(&oc->streams[i]->codec);
// free(oc->streams[i]->priv_data);
avcodec_close((oc->streams[i]->codec));
av_free((oc->streams[i]->codec));
// av_freep(&(oc->streams[i]));
free((oc->streams[i]));
}
avio_close(oc->pb);
av_free(oc);
//Se cierra el input
avformat_close_input(&avInputFmtCtx);
printf("END\n");
return 0;
}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user