fprintf(fp,"#!/bin/bash -ex\n");
fprintf(fp,"mkdir -p $1/udfs\n");
fprintf(fp,"sz=`du -sb $1/bd.m2ts | sed -e 's/[ \t].*//'`\n");
- fprintf(fp,"blks=$((sz/2048 + 512))\n");
+ fprintf(fp,"blks=$((sz/2048 + 4096))\n");
fprintf(fp,"mkudffs $1/bd.udfs $blks\n");
fprintf(fp,"mount -o loop $1/bd.udfs $1/udfs\n");
fprintf(fp,"%s/bdwrite $1/udfs $1/bd.m2ts\n",exe_path);
fprintf(fp,"umount $1/udfs\n");
fprintf(fp,"echo To burn bluray, load blank media and run:\n");
- fprintf(fp,"echo dd if=$1/bd.udfs 0f=/dev/bd bs=2048000\n");
+ fprintf(fp,"echo dd if=$1/bd.udfs of=/dev/bd bs=2048000\n");
fprintf(fp,"\n");
fclose(fp);
int write();
mpls_pi() {}
- ~mpls_pi() {}
+ ~mpls_pi() {
+ clip.remove_all_objects();
+ }
};
class _mpls_plm {
strcpy(filename, fn);
brk = 0; pidx = 0; pgm_pid = -1; still = 0;
}
- ~media_info() { streams.remove_all_objects(); }
+ ~media_info() {
+ streams.remove_all_objects();
+ programs.remove_all_objects();
+ }
int scan();
int scan(AVFormatContext *fmt_ctx);
av_dict_set(&fopts, "threads", "auto", 0);
int ret = avformat_open_input(&fmt_ctx, filename, NULL, &fopts);
av_dict_free(&fopts);
+ if( ret < 0 ) return ret;
+ ret = avformat_find_stream_info(fmt_ctx, NULL);
- if( ret >= 0 )
- ret = avformat_find_stream_info(fmt_ctx, NULL);
-
- if( ret >= 0 ) {
- bit_rate = fmt_ctx->bit_rate;
- }
+ bit_rate = fmt_ctx->bit_rate;
int ep_pid = -1;
for( int i=0; ret>=0 && i<(int)fmt_ctx->nb_streams; ++i ) {
pgm->ep_pid = ep_pid;
pgm->pmt_pid = 0x1000;
pgm->pcr_pid = 0x100;
- for( int jj=0; jj<streams.size(); ++jj )
+ pgm->duration = 0;
+ for( int jj=0; jj<streams.size(); ++jj ) {
+ AVStream *st = fmt_ctx->streams[jj];
+ AVMediaType type = st->codec->codec_type;
+ switch( type ) {
+ case AVMEDIA_TYPE_VIDEO:
+ case AVMEDIA_TYPE_AUDIO:
+ break;
+ default:
+ continue;
+ }
pgm->strm_idx.append(jj);
+ if( pgm->duration < st->duration )
+ pgm->duration = av_rescale_q(st->duration, st->time_base, clk45k);
+ }
+ programs.append(pgm);
}
for( int ii=0; ii<npgm; ++ii ) {
if( ret >= 0 )
ret = scan(fmt_ctx);
- if( fmt_ctx )
- avformat_close_input(&fmt_ctx);
+ for( int i=0; i<(int)fmt_ctx->nb_streams; ++i )
+ avcodec_close(fmt_ctx->streams[i]->codec);
+ avformat_close_input(&fmt_ctx);
return ret;
}
return ret;
}
+int FFStream::write_packet(FFPacket &pkt)
+{
+ bs_filter(pkt);
+ av_packet_rescale_ts(pkt, st->codec->time_base, st->time_base);
+ pkt->stream_index = st->index;
+ return av_interleaved_write_frame(ffmpeg->fmt_ctx, pkt);
+}
+
+int FFStream::flush()
+{
+ int ret = 0;
+ while( ret >= 0 ) {
+ FFPacket pkt;
+ int got_packet = 0;
+ ret = encode_frame(pkt, 0, got_packet);
+ if( ret < 0 || !got_packet ) break;
+ ret = write_packet(pkt);
+ }
+ if( ret < 0 )
+ ff_err(ret, "FFStream::flush");
+ return ret >= 0 ? 0 : 1;
+}
+
FFAudioStream::FFAudioStream(FFMPEG *ffmpeg, AVStream *strm, int idx)
: FFStream(ffmpeg, strm, idx)
{
return ret >= 0 ? 0 : 1;
}
+int FFAudioStream::encode_frame(FFPacket &pkt, AVFrame *frame, int &got_packet)
+{
+ int ret = avcodec_encode_audio2(st->codec, pkt, frame, &got_packet);
+ if( ret < 0 ) {
+ ff_err(ret, "FFAudioStream::encode_frame: encode audio failed\n");
+ return -1;
+ }
+ return ret;
+}
+
FFVideoStream::FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx)
: FFStream(ffmpeg, strm, idx)
{
return ret >= 0 ? 0 : 1;
}
+int FFVideoStream::encode_frame(FFPacket &pkt, AVFrame *frame, int &got_packet)
+{
+ int ret = avcodec_encode_video2(st->codec, pkt, frame, &got_packet);
+ if( ret < 0 ) {
+ ff_err(ret, "FFVideoStream::encode_frame: encode video failed\n");
+ return -1;
+ }
+ return ret;
+}
PixelFormat FFVideoStream::color_model_to_pix_fmt(int color_model)
{
int FFMPEG::mux_audio(FFrame *frm)
{
FFPacket pkt;
- AVStream *st = frm->fst->st;
- AVCodecContext *ctx = st->codec;
+ FFStream *fst = frm->fst;
+ AVCodecContext *ctx = fst->st->codec;
AVFrame *frame = *frm;
AVRational tick_rate = {1, ctx->sample_rate};
frame->pts = av_rescale_q(frm->position, tick_rate, ctx->time_base);
int got_packet = 0;
- int ret = avcodec_encode_audio2(ctx, pkt, frame, &got_packet);
- if( ret >= 0 && got_packet ) {
- frm->fst->bs_filter(pkt);
- av_packet_rescale_ts(pkt, ctx->time_base, st->time_base);
- pkt->stream_index = st->index;
- ret = av_interleaved_write_frame(fmt_ctx, pkt);
- }
+ int ret = fst->encode_frame(pkt, frame, got_packet);
+ if( ret >= 0 && got_packet )
+ ret = fst->write_packet(pkt);
if( ret < 0 )
ff_err(ret, "FFMPEG::mux_audio");
return ret >= 0 ? 0 : 1;
int FFMPEG::mux_video(FFrame *frm)
{
FFPacket pkt;
- AVStream *st = frm->fst->st;
+ FFStream *fst = frm->fst;
AVFrame *frame = *frm;
frame->pts = frm->position;
int ret = 1, got_packet = 0;
if( fmt_ctx->oformat->flags & AVFMT_RAWPICTURE ) {
/* a hack to avoid data copy with some raw video muxers */
pkt->flags |= AV_PKT_FLAG_KEY;
- pkt->stream_index = st->index;
+ pkt->stream_index = fst->st->index;
AVPicture *picture = (AVPicture *)frame;
pkt->data = (uint8_t *)picture;
pkt->size = sizeof(AVPicture);
got_packet = 1;
}
else
- ret = avcodec_encode_video2(st->codec, pkt, frame, &got_packet);
- if( ret >= 0 && got_packet ) {
- frm->fst->bs_filter(pkt);
- av_packet_rescale_ts(pkt, st->codec->time_base, st->time_base);
- pkt->stream_index = st->index;
- ret = av_interleaved_write_frame(fmt_ctx, pkt);
- }
+ ret = fst->encode_frame(pkt, frame, got_packet);
+ if( ret >= 0 && got_packet )
+ ret = fst->write_packet(pkt);
if( ret < 0 )
ff_err(ret, "FFMPEG::mux_video");
return ret >= 0 ? 0 : 1;
if( !done ) mux();
}
mux();
+ for( int i=0; i<ffaudio.size(); ++i )
+ ffaudio[i]->flush();
+ for( int i=0; i<ffvideo.size(); ++i )
+ ffvideo[i]->flush();
}
virtual int encode_activate();
virtual int decode_activate();
int read_packet();
+ int write_packet(FFPacket &pkt);
+ int flush();
int decode(AVFrame *frame);
virtual int decode_frame(AVFrame *frame, int &got_frame) = 0;
+ virtual int encode_frame(FFPacket &pkt, AVFrame *frame, int &got_frame) = 0;
virtual int init_frame(AVFrame *frame) = 0;
virtual int create_filter(const char *filter_spec,
AVCodecContext *src_ctx, AVCodecContext *sink_ctx) = 0;
virtual ~FFAudioStream();
int load_history(uint8_t **data, int len);
int decode_frame(AVFrame *frame, int &got_frame);
+ int encode_frame(FFPacket &pkt, AVFrame *frame, int &got_frame);
int create_filter(const char *filter_spec,
AVCodecContext *src_ctx, AVCodecContext *sink_ctx);
FFVideoStream(FFMPEG *ffmpeg, AVStream *strm, int idx);
virtual ~FFVideoStream();
int decode_frame(AVFrame *frame, int &got_frame);
+ int encode_frame(FFPacket &pkt, AVFrame *frame, int &got_frame);
int create_filter(const char *filter_spec,
AVCodecContext *src_ctx, AVCodecContext *sink_ctx);