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