|
|
|
@ -1100,165 +1100,165 @@ static int output_packet(AVInputStream *ist, int ist_index, |
|
|
|
|
goto fail_decode; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
switch(ist->st->codec->codec_type) { |
|
|
|
|
case CODEC_TYPE_AUDIO: |
|
|
|
|
ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / |
|
|
|
|
(ist->st->codec->sample_rate * ist->st->codec->channels); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_VIDEO: |
|
|
|
|
if (ist->st->codec->time_base.num != 0) { |
|
|
|
|
ist->next_pts += ((int64_t)AV_TIME_BASE * |
|
|
|
|
ist->st->codec->time_base.num) / |
|
|
|
|
ist->st->codec->time_base.den; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
switch(ist->st->codec->codec_type) { |
|
|
|
|
case CODEC_TYPE_AUDIO: |
|
|
|
|
ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) / |
|
|
|
|
(ist->st->codec->sample_rate * ist->st->codec->channels); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_VIDEO: |
|
|
|
|
if (ist->st->codec->time_base.num != 0) { |
|
|
|
|
ist->next_pts += ((int64_t)AV_TIME_BASE * |
|
|
|
|
ist->st->codec->time_base.num) / |
|
|
|
|
ist->st->codec->time_base.den; |
|
|
|
|
} |
|
|
|
|
data_buf = ptr; |
|
|
|
|
data_size = len; |
|
|
|
|
ret = len; |
|
|
|
|
len = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer_to_free = NULL; |
|
|
|
|
if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) { |
|
|
|
|
pre_process_video_frame(ist, (AVPicture *)&picture, |
|
|
|
|
&buffer_to_free); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// preprocess audio (volume)
|
|
|
|
|
if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) { |
|
|
|
|
if (audio_volume != 256) { |
|
|
|
|
short *volp; |
|
|
|
|
volp = samples; |
|
|
|
|
for(i=0;i<(data_size / sizeof(short));i++) { |
|
|
|
|
int v = ((*volp) * audio_volume + 128) >> 8; |
|
|
|
|
if (v < -32768) v = -32768; |
|
|
|
|
if (v > 32767) v = 32767; |
|
|
|
|
*volp++ = v; |
|
|
|
|
} |
|
|
|
|
data_buf = ptr; |
|
|
|
|
data_size = len; |
|
|
|
|
ret = len; |
|
|
|
|
len = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
buffer_to_free = NULL; |
|
|
|
|
if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) { |
|
|
|
|
pre_process_video_frame(ist, (AVPicture *)&picture, |
|
|
|
|
&buffer_to_free); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// preprocess audio (volume)
|
|
|
|
|
if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) { |
|
|
|
|
if (audio_volume != 256) { |
|
|
|
|
short *volp; |
|
|
|
|
volp = samples; |
|
|
|
|
for(i=0;i<(data_size / sizeof(short));i++) { |
|
|
|
|
int v = ((*volp) * audio_volume + 128) >> 8; |
|
|
|
|
if (v < -32768) v = -32768; |
|
|
|
|
if (v > 32767) v = 32767; |
|
|
|
|
*volp++ = v; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* frame rate emulation */ |
|
|
|
|
if (ist->st->codec->rate_emu) { |
|
|
|
|
int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den); |
|
|
|
|
int64_t now = av_gettime() - ist->start; |
|
|
|
|
if (pts > now) |
|
|
|
|
usleep(pts - now); |
|
|
|
|
/* frame rate emulation */ |
|
|
|
|
if (ist->st->codec->rate_emu) { |
|
|
|
|
int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec->time_base.num, 1000000, ist->st->codec->time_base.den); |
|
|
|
|
int64_t now = av_gettime() - ist->start; |
|
|
|
|
if (pts > now) |
|
|
|
|
usleep(pts - now); |
|
|
|
|
|
|
|
|
|
ist->frame++; |
|
|
|
|
} |
|
|
|
|
ist->frame++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
/* mpeg PTS deordering : if it is a P or I frame, the PTS
|
|
|
|
|
is the one of the next displayed one */ |
|
|
|
|
/* XXX: add mpeg4 too ? */ |
|
|
|
|
if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) { |
|
|
|
|
if (ist->st->codec->pict_type != B_TYPE) { |
|
|
|
|
int64_t tmp; |
|
|
|
|
tmp = ist->last_ip_pts; |
|
|
|
|
ist->last_ip_pts = ist->frac_pts.val; |
|
|
|
|
ist->frac_pts.val = tmp; |
|
|
|
|
} |
|
|
|
|
/* mpeg PTS deordering : if it is a P or I frame, the PTS
|
|
|
|
|
is the one of the next displayed one */ |
|
|
|
|
/* XXX: add mpeg4 too ? */ |
|
|
|
|
if (ist->st->codec->codec_id == CODEC_ID_MPEG1VIDEO) { |
|
|
|
|
if (ist->st->codec->pict_type != B_TYPE) { |
|
|
|
|
int64_t tmp; |
|
|
|
|
tmp = ist->last_ip_pts; |
|
|
|
|
ist->last_ip_pts = ist->frac_pts.val; |
|
|
|
|
ist->frac_pts.val = tmp; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
/* if output time reached then transcode raw format,
|
|
|
|
|
encode packets and output them */ |
|
|
|
|
if (start_time == 0 || ist->pts >= start_time) |
|
|
|
|
for(i=0;i<nb_ostreams;i++) { |
|
|
|
|
int frame_size; |
|
|
|
|
/* if output time reached then transcode raw format,
|
|
|
|
|
encode packets and output them */ |
|
|
|
|
if (start_time == 0 || ist->pts >= start_time) |
|
|
|
|
for(i=0;i<nb_ostreams;i++) { |
|
|
|
|
int frame_size; |
|
|
|
|
|
|
|
|
|
ost = ost_table[i]; |
|
|
|
|
if (ost->source_index == ist_index) { |
|
|
|
|
os = output_files[ost->file_index]; |
|
|
|
|
ost = ost_table[i]; |
|
|
|
|
if (ost->source_index == ist_index) { |
|
|
|
|
os = output_files[ost->file_index]; |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
printf("%d: got pts=%0.3f %0.3f\n", i, |
|
|
|
|
(double)pkt->pts / AV_TIME_BASE, |
|
|
|
|
((double)ist->pts / AV_TIME_BASE) - |
|
|
|
|
((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den)); |
|
|
|
|
printf("%d: got pts=%0.3f %0.3f\n", i, |
|
|
|
|
(double)pkt->pts / AV_TIME_BASE, |
|
|
|
|
((double)ist->pts / AV_TIME_BASE) - |
|
|
|
|
((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den)); |
|
|
|
|
#endif |
|
|
|
|
/* set the input output pts pairs */ |
|
|
|
|
//ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
|
|
|
|
|
|
|
|
|
|
if (ost->encoding_needed) { |
|
|
|
|
switch(ost->st->codec->codec_type) { |
|
|
|
|
case CODEC_TYPE_AUDIO: |
|
|
|
|
do_audio_out(os, ost, ist, data_buf, data_size); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_VIDEO: |
|
|
|
|
do_video_out(os, ost, ist, &picture, &frame_size); |
|
|
|
|
video_size += frame_size; |
|
|
|
|
if (do_vstats && frame_size) |
|
|
|
|
do_video_stats(os, ost, frame_size); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_SUBTITLE: |
|
|
|
|
do_subtitle_out(os, ost, ist, &subtitle, |
|
|
|
|
pkt->pts); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_abort(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
AVFrame avframe; //FIXME/XXX remove this
|
|
|
|
|
AVPacket opkt; |
|
|
|
|
av_init_packet(&opkt); |
|
|
|
|
|
|
|
|
|
/* no reencoding needed : output the packet directly */ |
|
|
|
|
/* force the input stream PTS */ |
|
|
|
|
|
|
|
|
|
avcodec_get_frame_defaults(&avframe); |
|
|
|
|
ost->st->codec->coded_frame= &avframe; |
|
|
|
|
avframe.key_frame = pkt->flags & PKT_FLAG_KEY; |
|
|
|
|
|
|
|
|
|
if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO) |
|
|
|
|
audio_size += data_size; |
|
|
|
|
else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) { |
|
|
|
|
video_size += data_size; |
|
|
|
|
ost->sync_opts++; |
|
|
|
|
} |
|
|
|
|
/* set the input output pts pairs */ |
|
|
|
|
//ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index] - start_time)/ AV_TIME_BASE;
|
|
|
|
|
|
|
|
|
|
opkt.stream_index= ost->index; |
|
|
|
|
if(pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
else |
|
|
|
|
opkt.pts= AV_NOPTS_VALUE; |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
int64_t dts; |
|
|
|
|
if (pkt->dts == AV_NOPTS_VALUE) |
|
|
|
|
dts = ist->next_pts; |
|
|
|
|
else |
|
|
|
|
dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); |
|
|
|
|
opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
} |
|
|
|
|
opkt.flags= pkt->flags; |
|
|
|
|
if (ost->encoding_needed) { |
|
|
|
|
switch(ost->st->codec->codec_type) { |
|
|
|
|
case CODEC_TYPE_AUDIO: |
|
|
|
|
do_audio_out(os, ost, ist, data_buf, data_size); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_VIDEO: |
|
|
|
|
do_video_out(os, ost, ist, &picture, &frame_size); |
|
|
|
|
video_size += frame_size; |
|
|
|
|
if (do_vstats && frame_size) |
|
|
|
|
do_video_stats(os, ost, frame_size); |
|
|
|
|
break; |
|
|
|
|
case CODEC_TYPE_SUBTITLE: |
|
|
|
|
do_subtitle_out(os, ost, ist, &subtitle, |
|
|
|
|
pkt->pts); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
av_abort(); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
AVFrame avframe; //FIXME/XXX remove this
|
|
|
|
|
AVPacket opkt; |
|
|
|
|
av_init_packet(&opkt); |
|
|
|
|
|
|
|
|
|
/* no reencoding needed : output the packet directly */ |
|
|
|
|
/* force the input stream PTS */ |
|
|
|
|
|
|
|
|
|
avcodec_get_frame_defaults(&avframe); |
|
|
|
|
ost->st->codec->coded_frame= &avframe; |
|
|
|
|
avframe.key_frame = pkt->flags & PKT_FLAG_KEY; |
|
|
|
|
|
|
|
|
|
if(ost->st->codec->codec_type == CODEC_TYPE_AUDIO) |
|
|
|
|
audio_size += data_size; |
|
|
|
|
else if (ost->st->codec->codec_type == CODEC_TYPE_VIDEO) { |
|
|
|
|
video_size += data_size; |
|
|
|
|
ost->sync_opts++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
|
|
|
|
if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY)) |
|
|
|
|
opkt.destruct= av_destruct_packet; |
|
|
|
|
opkt.stream_index= ost->index; |
|
|
|
|
if(pkt->pts != AV_NOPTS_VALUE) |
|
|
|
|
opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
else |
|
|
|
|
opkt.pts= AV_NOPTS_VALUE; |
|
|
|
|
|
|
|
|
|
write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][pkt->stream_index]); |
|
|
|
|
ost->st->codec->frame_number++; |
|
|
|
|
ost->frame_number++; |
|
|
|
|
av_free_packet(&opkt); |
|
|
|
|
{ |
|
|
|
|
int64_t dts; |
|
|
|
|
if (pkt->dts == AV_NOPTS_VALUE) |
|
|
|
|
dts = ist->next_pts; |
|
|
|
|
else |
|
|
|
|
dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); |
|
|
|
|
opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
|
|
|
} |
|
|
|
|
opkt.flags= pkt->flags; |
|
|
|
|
|
|
|
|
|
//FIXME remove the following 2 lines they shall be replaced by the bitstream filters
|
|
|
|
|
if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & PKT_FLAG_KEY)) |
|
|
|
|
opkt.destruct= av_destruct_packet; |
|
|
|
|
|
|
|
|
|
write_frame(os, &opkt, ost->st->codec, bitstream_filters[ost->file_index][pkt->stream_index]); |
|
|
|
|
ost->st->codec->frame_number++; |
|
|
|
|
ost->frame_number++; |
|
|
|
|
av_free_packet(&opkt); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
av_free(buffer_to_free); |
|
|
|
|
/* XXX: allocate the subtitles in the codec ? */ |
|
|
|
|
if (subtitle_to_free) { |
|
|
|
|
if (subtitle_to_free->rects != NULL) { |
|
|
|
|
for (i = 0; i < subtitle_to_free->num_rects; i++) { |
|
|
|
|
av_free(subtitle_to_free->rects[i].bitmap); |
|
|
|
|
av_free(subtitle_to_free->rects[i].rgba_palette); |
|
|
|
|
} |
|
|
|
|
av_freep(&subtitle_to_free->rects); |
|
|
|
|
} |
|
|
|
|
av_free(buffer_to_free); |
|
|
|
|
/* XXX: allocate the subtitles in the codec ? */ |
|
|
|
|
if (subtitle_to_free) { |
|
|
|
|
if (subtitle_to_free->rects != NULL) { |
|
|
|
|
for (i = 0; i < subtitle_to_free->num_rects; i++) { |
|
|
|
|
av_free(subtitle_to_free->rects[i].bitmap); |
|
|
|
|
av_free(subtitle_to_free->rects[i].rgba_palette); |
|
|
|
|
} |
|
|
|
|
subtitle_to_free->num_rects = 0; |
|
|
|
|
subtitle_to_free = NULL; |
|
|
|
|
av_freep(&subtitle_to_free->rects); |
|
|
|
|
} |
|
|
|
|
subtitle_to_free->num_rects = 0; |
|
|
|
|
subtitle_to_free = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
discard_packet: |
|
|
|
|
if (pkt == NULL) { |
|
|
|
|
/* EOF handling */ |
|
|
|
|