Josef Wolf wrote:
> 
> I am trying to do the equivalent of
> 
>   ffmpeg -f dvd -acodec copy -vcodec copy -scodec copy -i foo.ts foo.mpg
> 
This is incorrect.

Correct is: 
ffmpeg -i foo.ts -f dvd -acodec copy -vcodec copy -scodec copy foo.mpg

All parameters are related to the file named AFTER them. -acodec and -vcodec
in your example are related to the foo.ts 


Josef Wolf wrote:
> 
> Any ideas what I have messed up?
> 

You've forgot something.


Josef Wolf wrote:
> 
> # include <stdlib.h>
> # include <string.h>
> # include <ffmpeg/avformat.h>
> 
> [skip]
> 
> int main (int argc, char *argv[])
> {
>     int i;
> 
>     AVPacket        packet;
>     AVFormatContext *InFmtCtx;
>     AVFormatContext *OutFmtCtx;
> 
>     char *infile  = argv[1];
>     char *outfile = argv[2];
>     progname      = argv[0];
> 
>     if (argc!=3) FATAL (("Usage: tstops <infile> <outfile>"));
> 

This is incorrect, you must first test that enough arguments are given and
then parse them.


Josef Wolf wrote:
> 
>     /* Do I really need to register all formats/codecs/whatever?
>        I only need MPEG-TS and MPEG-PS
>      */
>     av_register_all ();
> 
Yes. This function builds ffmpeg's internal lists of structures, describing
formats, codecs, parsers, etc.
They are already compiled and loaded in memory. 
If you want to disable something, you should do this in configure call when
compiling ffmpeg.


Josef Wolf wrote:
> 
> 
>     /* Open input
>      */
> 
>     if (av_open_input_file (&InFmtCtx, infile, NULL, 0, NULL))
>         FATAL (("Can not open input file '%s'", infile));
> 
>     if (av_find_stream_info (InFmtCtx) < 0)
>         FATAL (("Can not find stream info"));
> 
> 
>     /* Open output
>      */
> 
>     if (!(OutFmtCtx = av_alloc_format_context ()))
>         FATAL (("No memory"));
> 
>     /* "dvd" gives MPEG-PS?  Why not mpegps in analogy to mpegts?
>      */
>     if (!(OutFmtCtx->oformat = guess_format ("dvd", NULL, NULL)))
>         FATAL (("Can not determine output format"));
> 
>     av_strlcpy (OutFmtCtx->filename, outfile, sizeof
> (OutFmtCtx->filename));
> 
I use

  snprintf(tsk->output->filename, sizeof(tsk->output->filename), "file:%s",
tsk->filename);


Josef Wolf wrote:
> 
> 
>     /* Copy all stream information
>      */
>     for (i=0; i<InFmtCtx->nb_streams; i++) {
>         AVStream *st;
> 
>         if (!(st = av_new_stream (OutFmtCtx, i)))
>             FATAL (("Can not add stream %d\n", i));
> 
>         st->codec = InFmtCtx->streams[i]->codec;
>         st->stream_copy = 1;
>     
> 
stream_copy is useless, it is only used in ffmpeg.c

You should also copy all codec information from input to output
AVFormatContext
This is excerpt from my code. 
This code was copied from ffmpeg.c and added with some additional
assignments, just in case

                codec = st->codec;
                icodec = input->streams[i]->codec;
                st->disposition = input->streams[i]->disposition;

                codec->codec_id = icodec->codec_id;
                codec->codec_type = icodec->codec_type;
                codec->sub_id = icodec->sub_id;
                codec->me_method = icodec->me_method;
                codec->sample_fmt = icodec->sample_fmt;

                if(!codec->codec_tag){
                        if(  output->oformat->codec_tag
                                || av_codec_get_id (output->oformat->codec_tag, 
icodec->codec_tag) > 0
                                || av_codec_get_tag(output->oformat->codec_tag, 
icodec->codec_id) <= 0)
                                codec->codec_tag = icodec->codec_tag;
                }

                codec->bit_rate = icodec->bit_rate;
                codec->extradata= icodec->extradata;
                codec->extradata_size= icodec->extradata_size;
                if(av_q2d(icodec->time_base) > 
av_q2d(input->streams[i]->time_base) &&
                        av_q2d(input->streams[i]->time_base) < 1.0/1000)
                        codec->time_base = icodec->time_base;
                else
                        codec->time_base = input->streams[i]->time_base;

                switch(codec->codec_type) {
                case CODEC_TYPE_AUDIO:
                        codec->sample_rate = icodec->sample_rate;
                        codec->channels = icodec->channels;
                        codec->frame_size = icodec->frame_size;
                        codec->block_align= icodec->block_align;
                        if(codec->block_align == 1 && codec->codec_id == 
CODEC_ID_MP3)
                                codec->block_align=0;
                        break;
                case CODEC_TYPE_VIDEO:
                        codec->pix_fmt = icodec->pix_fmt;
                        codec->width = icodec->width;
                        codec->height = icodec->height;
                        codec->has_b_frames = icodec->has_b_frames;
                        if(!codec->width) codec->width=720;
                        if(!codec->height) codec->height=576;
                        break;
                case CODEC_TYPE_SUBTITLE:
                        break;
                default:
                        break;
                }
                st->pts.num=st->time_base.num;
                st->pts.den=st->time_base.den;
        }
//mpegps muxer complains about buffer underflow, when mux_preload and
mux_max_delay are not set.
// I was advised to set these here on the list.

        static float mux_preload= 0.5;  //mux_preload= (36000+3*1200) / 90000.0;
//0.44
        static float mux_max_delay= 0.7;
        output->preload= (int)(mux_preload*AV_TIME_BASE);
        output->max_delay= (int)(mux_max_delay*AV_TIME_BASE);

If you remultiplex a live stream, you should
        input->flags|=AVFMT_NOFILE|AVFMT_FLAG_IGNIDX;

Otherwise libav will generate indices that will eat all memory.


Josef Wolf wrote:
> 
>     /* What is this good for?
>      */
>     if (av_set_parameters (OutFmtCtx, NULL))
>         FATAL (("Invalid output format parameters"));
> 

This is invalid. Don't exactly remember, what this is good for but it seems,
that you erase everything in OutFmtCtx with this call. I don't use it.

Read the sources. Unfortunately they are the only comprehensive source of
information.


Josef Wolf wrote:
> 
>     dump_format (InFmtCtx,  0, infile, 0);
>     dump_format (OutFmtCtx, 0, outfile, 1);
> 
>     if (!(OutFmtCtx->oformat->flags & AVFMT_NOFILE)) {
>         if (url_fopen (&OutFmtCtx->pb, outfile, URL_WRONLY) < 0) {
>             FATAL (("Could not open '%s'\n", outfile));
>         }
>     }
> 
> 
>     /* here we start the conversion
>      */
> 
>     av_write_header (OutFmtCtx);  /* Here I get SIGFPE */
> 
>     while (av_read_frame (InFmtCtx, &packet) >= 0) {
>         if (av_write_frame (OutFmtCtx, &packet))
>             FATAL (("Write frame failed"));
> 
>         av_free_packet (&packet);
>     }
> 

This looks correct until you don't meet PTS rollover in your input stream.
That is, MPEG TS gives 33 bits for time stamps. While processing a stream,
at some moment they drop to 0. 
libav* code doesn't handle this in any way, complains about non-monotone
time stamps and doesn't write packets after that rollover. There was a
discussion a month or two ago, which has given me a useful method to handle
this. I track 33th bit and add it by myself when it becomes 0. After this, I
subtract the first DTS value.


Josef Wolf wrote:
> 
> 
>     /* Close the files
>      */
>     av_close_input_file (InFmtCtx);
>     if (!(OutFmtCtx->oformat->flags & AVFMT_NOFILE))
>         url_fclose (OutFmtCtx->pb);
> 
>     /* Free the streams
>      */
> 

There is a memory leak. You don't free streams and codecs.
Correct is: 
                for(int j=0;j<output->nb_streams;j++) {
                        av_free(output->streams[j]->codec);
                        av_free(output->streams[j]);
                }
                av_free(t->output);


Josef Wolf wrote:
> 
>     av_free (OutFmtCtx);
> 
>     exit (0);
> }
> 
> 
> And here is the gdb output
> 
> [dvd @ 0x400b0400]sample rate not set
> 
> 

I repeat, read the sources.
Add some printfs to them to see the program flow. 
It is not so easy and rather complicated. 
-- 
View this message in context: 
http://www.nabble.com/Remultiplex-MPEG-TS-to-MPEG-PS-tp19294791p19305436.html
Sent from the libav-users mailing list archive at Nabble.com.

_______________________________________________
libav-user mailing list
libav-user@mplayerhq.hu
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to