I am developing an application, capable to capture the MPEG2 Transport stream 
from a DVB-S card and store its parts to a file, for example, a video stream 
from a program and one accompanying audio stream from that program.

I am able to determine the desired elementary PIDs, capture TS packets with 
these PIDs, parse ther PES headers and extract payload (PES payload, which, if 
I understand correctly, consists of coded audio and video data).

Now, I don't want to decode and encode again that audio and video data, but 
simply want to store them in a file (of any container format, I tried "avi" and 
"dvd" in guess_format).

Basically, my algorithm is following

1. Initialization
/* open output file*/
m_pFormatCtx = av_alloc_format_context();

snprintf(urlname, sizeof(urlname), "file:%s", m_filename);
m_outfmt = guess_format("avi", (const char *)m_filename, NULL);
m_pFormatCtx->oformat = m_outfmt;
        
snprintf(m_pFormatCtx->filename, sizeof(m_pFormatCtx->filename), 
          "%s", m_filename);

if((err = url_fopen(&m_pFormatCtx->pb, urlname, URL_WRONLY)) < 0) {
 [handle error]
}


[then add streams]

for each stream {
  switch((*pel)->stream_type){ //table 2-29 from ISO/IEC 13818-1:2000
    case 0x02:  //mpeg2 video
      codec_id   = CODEC_ID_MPEG2VIDEO;
      codec_type = CODEC_TYPE_VIDEO;
      codec_name = "mpeg2 video";
      break;
   case 0x03: case 0x04:        //audio
      codec_name = "mpeg audio";
      codec_id = CODEC_ID_MP3;
      codec_type = CODEC_TYPE_AUDIO;
      break;
   default : 
      break;
  }

  AVCodec *codec = avcodec_find_decoder(codec_id);
  AVStream *st = av_new_stream(m_pFormatCtx,m_pFormatCtx->nb_streams);
  AVCodecContext *ctx=st->codec;
  ctx->codec_id   = codec_id;
  ctx->codec_type = codec_type;
  if(avcodec_open(ctx, codec) < 0) {
     [handle error]
  }
  [store pointer AVStream *st]
}

/* set the rest of output parameters*/
av_set_parameters(m_pFormatCtx,NULL);

2. Main loop
[accumulate, store and parse data, in separate buffer for each stream]

if([the PES packet is complete]){

 [recover stored pointer AVStream *st;]
 [recover accumulated PES payload to buffer]

 AVCodecContext *codec_ctx=st->codec;

 parser_ctx=av_parser_init(codec_ctx->codec_id);
 int r=av_parser_parse(parser_ctx,codec_ctx,&samples,&frame_size,
                       buffer,payload_size,m_PTS,.m_DTS);
 av_parser_close(parser_ctx);

 if(frame_size>0){ // if get complete frame, write it to file
  if(!m_header_written) {
    av_write_header(m_pFormatCtx);
    m_header_written=true;
  }

//then form a packet and write it to                                            
  AVPacket avpkt;       
  av_init_packet(&avpkt);
  avpkt.stream_index = m_stream_index; 
  struct AVRational avtbq;
  avtbq.den=1;
  avtbq.num=AV_TIME_BASE; // AV_TIME_BASE_Q

  avpkt.dts = av_rescale_q(m_DTS, avtbq, st->time_base);  
  avpkt.pts = av_rescale_q(m_DTS, avtbq, st->time_base);  
  avpkt.duration = 0;

  int r = av_interleaved_write_frame(m_pFormatCtx, &avpkt);
  } //if (frame_size>0) 
} //if([the PES packet is complete])

However, av_write_header dumps the warning
[avi @ 6A5B0980]time base not set
or 
[dvd @ address ]time base not set

and av_interleaved_write_frame() causes the error "division by 0"

What is the problem?
What am I missing?

Thanks!


_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to