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

Reply via email to