static int seq_read_header(AVFormatContext *s) { int i, rc; SeqDemuxContext *seq = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; /* init internal buffers */ rc = seq_init_frame_buffers(seq, pb); if (rc) return rc; seq->current_frame_offs = 0; /* preload (no audio data, just buffer operations related data) */ for (i = 1; i <= 100; i++) { rc = seq_parse_frame_data(seq, pb); if (rc) return rc; } seq->current_frame_pts = 0; seq->audio_buffer_full = 0; /* initialize the video decoder stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 32, 1, SEQ_FRAME_RATE); seq->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_TIERTEXSEQVIDEO; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = SEQ_FRAME_W; st->codec->height = SEQ_FRAME_H; /* initialize the audio decoder stream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->start_time = 0; avpriv_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE); seq->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; st->codec->codec_tag = 0; /* no tag */ st->codec->channels = 1; st->codec->channel_layout = AV_CH_LAYOUT_MONO; st->codec->sample_rate = SEQ_SAMPLE_RATE; st->codec->bits_per_coded_sample = 16; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample / 8; return 0; }
static int seq_read_packet(AVFormatContext *s, AVPacket *pkt) { int rc; SeqDemuxContext *seq = s->priv_data; AVIOContext *pb = s->pb; if (!seq->audio_buffer_full) { rc = seq_parse_frame_data(seq, pb); if (rc) return rc; /* video packet */ if (seq->current_pal_data_size + seq->current_video_data_size != 0) { if (av_new_packet(pkt, 1 + seq->current_pal_data_size + seq->current_video_data_size)) return AVERROR(ENOMEM); pkt->data[0] = 0; if (seq->current_pal_data_size) { pkt->data[0] |= 1; avio_seek(pb, seq->current_frame_offs + seq->current_pal_data_offs, SEEK_SET); if (avio_read(pb, &pkt->data[1], seq->current_pal_data_size) != seq->current_pal_data_size) return AVERROR(EIO); } if (seq->current_video_data_size) { pkt->data[0] |= 2; memcpy(&pkt->data[1 + seq->current_pal_data_size], seq->current_video_data_ptr, seq->current_video_data_size); } pkt->stream_index = seq->video_stream_index; pkt->pts = seq->current_frame_pts; /* sound buffer will be processed on next read_packet() call */ seq->audio_buffer_full = 1; return 0; } } /* audio packet */ if (seq->current_audio_data_offs == 0) /* end of data reached */ return AVERROR(EIO); avio_seek(pb, seq->current_frame_offs + seq->current_audio_data_offs, SEEK_SET); rc = av_get_packet(pb, pkt, seq->current_audio_data_size); if (rc < 0) return rc; pkt->stream_index = seq->audio_stream_index; seq->current_frame_pts++; seq->audio_buffer_full = 0; return 0; }