Lines 33-38
Link Here
|
33 |
#include "libswscale/swscale.h" |
33 |
#include "libswscale/swscale.h" |
34 |
#include "libpostproc/postprocess.h" |
34 |
#include "libpostproc/postprocess.h" |
35 |
|
35 |
|
|
|
36 |
#include "libavutil/opt.h" |
37 |
#include "libavutil/channel_layout.h" |
38 |
#include "libavutil/samplefmt.h" |
39 |
#include "libswresample_compat.h" |
40 |
|
36 |
#include "theora/theoraenc.h" |
41 |
#include "theora/theoraenc.h" |
37 |
#include "vorbis/codec.h" |
42 |
#include "vorbis/codec.h" |
38 |
#include "vorbis/vorbisenc.h" |
43 |
#include "vorbis/vorbisenc.h" |
Lines 537-542
void ff2theora_output(ff2theora this) {
Link Here
|
537 |
int synced = this->start_time == 0.0; |
542 |
int synced = this->start_time == 0.0; |
538 |
AVRational display_aspect_ratio, sample_aspect_ratio; |
543 |
AVRational display_aspect_ratio, sample_aspect_ratio; |
539 |
|
544 |
|
|
|
545 |
struct SwrContext *swr_ctx; |
546 |
uint8_t **dst_audio_data = NULL; |
547 |
int dst_linesize; |
548 |
int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples; |
549 |
|
540 |
if (this->audiostream >= 0 && this->context->nb_streams > this->audiostream) { |
550 |
if (this->audiostream >= 0 && this->context->nb_streams > this->audiostream) { |
541 |
AVCodecContext *enc = this->context->streams[this->audiostream]->codec; |
551 |
AVCodecContext *enc = this->context->streams[this->audiostream]->codec; |
542 |
if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { |
552 |
if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { |
Lines 962-983
void ff2theora_output(ff2theora this) {
Link Here
|
962 |
if (acodec != NULL && avcodec_open2 (aenc, acodec, NULL) >= 0) { |
972 |
if (acodec != NULL && avcodec_open2 (aenc, acodec, NULL) >= 0) { |
963 |
if (this->sample_rate != sample_rate |
973 |
if (this->sample_rate != sample_rate |
964 |
|| this->channels != aenc->channels |
974 |
|| this->channels != aenc->channels |
965 |
|| aenc->sample_fmt != AV_SAMPLE_FMT_S16) { |
975 |
|| aenc->sample_fmt != AV_SAMPLE_FMT_FLTP) { |
966 |
// values take from libavcodec/resample.c |
976 |
swr_ctx = swr_alloc(); |
967 |
this->audio_resample_ctx = av_audio_resample_init(this->channels, aenc->channels, |
977 |
/* set options */ |
968 |
this->sample_rate, sample_rate, |
978 |
if (aenc->channel_layout) { |
969 |
AV_SAMPLE_FMT_S16, aenc->sample_fmt, |
979 |
av_opt_set_int(swr_ctx, "in_channel_layout", aenc->channel_layout, 0); |
970 |
16, 10, 0, 0.8); |
980 |
} else { |
971 |
if (!this->audio_resample_ctx) { |
981 |
av_opt_set_int(swr_ctx, "in_channel_layout", av_get_default_channel_layout(aenc->channels), 0); |
972 |
this->channels = aenc->channels; |
982 |
} |
|
|
983 |
av_opt_set_int(swr_ctx, "in_sample_rate", aenc->sample_rate, 0); |
984 |
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", aenc->sample_fmt, 0); |
985 |
|
986 |
av_opt_set_int(swr_ctx, "out_channel_layout", av_get_default_channel_layout(this->channels), 0); |
987 |
av_opt_set_int(swr_ctx, "out_sample_rate", this->sample_rate, 0); |
988 |
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_FLTP, 0); |
989 |
|
990 |
/* initialize the resampling context */ |
991 |
if (swr_init(swr_ctx) < 0) { |
992 |
fprintf(stderr, "Failed to initialize the resampling context\n"); |
993 |
exit(1); |
973 |
} |
994 |
} |
|
|
995 |
|
996 |
max_dst_nb_samples = dst_nb_samples = |
997 |
av_rescale_rnd(src_nb_samples, this->sample_rate, sample_rate, AV_ROUND_UP); |
998 |
|
999 |
if (av_samples_alloc_array_and_samples(&dst_audio_data, &dst_linesize, this->channels, |
1000 |
dst_nb_samples, AV_SAMPLE_FMT_FLTP, 0) < 0) { |
1001 |
fprintf(stderr, "Could not allocate destination samples\n"); |
1002 |
exit(1); |
1003 |
} |
1004 |
|
974 |
if (!info.frontend && this->sample_rate!=sample_rate) |
1005 |
if (!info.frontend && this->sample_rate!=sample_rate) |
975 |
fprintf(stderr, " Resample: %dHz => %dHz\n", sample_rate,this->sample_rate); |
1006 |
fprintf(stderr, " Resample: %dHz => %dHz\n", sample_rate,this->sample_rate); |
976 |
if (!info.frontend && this->channels!=aenc->channels) |
1007 |
if (!info.frontend && this->channels!=aenc->channels) |
977 |
fprintf(stderr, " Channels: %d => %d\n",aenc->channels,this->channels); |
1008 |
fprintf(stderr, " Channels: %d => %d\n",aenc->channels,this->channels); |
978 |
} |
1009 |
} |
979 |
else{ |
1010 |
else{ |
980 |
this->audio_resample_ctx=NULL; |
1011 |
swr_ctx = NULL; |
981 |
} |
1012 |
} |
982 |
} |
1013 |
} |
983 |
else{ |
1014 |
else{ |
Lines 1068-1080
void ff2theora_output(ff2theora this) {
Link Here
|
1068 |
AVPacket pkt; |
1099 |
AVPacket pkt; |
1069 |
AVPacket avpkt; |
1100 |
AVPacket avpkt; |
1070 |
int len1; |
1101 |
int len1; |
1071 |
int got_picture; |
1102 |
int got_frame; |
1072 |
int first = 1; |
1103 |
int first = 1; |
1073 |
int audio_eos = 0, video_eos = 0, audio_done = 0, video_done = 0; |
1104 |
int audio_eos = 0, video_eos = 0, audio_done = 0, video_done = 0; |
1074 |
int ret; |
1105 |
int ret; |
1075 |
int16_t *audio_buf=av_malloc(4*MAX_AUDIO_FRAME_SIZE); |
1106 |
AVFrame *audio_frame = NULL; |
1076 |
int16_t *resampled=av_malloc(4*MAX_AUDIO_FRAME_SIZE); |
1107 |
uint8_t **audio_p = NULL; |
1077 |
int16_t *audio_p=NULL; |
|
|
1078 |
int no_frames; |
1108 |
int no_frames; |
1079 |
int no_samples; |
1109 |
int no_samples; |
1080 |
|
1110 |
|
Lines 1370-1376
void ff2theora_output(ff2theora this) {
Link Here
|
1370 |
first frame decodec in case its not a keyframe |
1400 |
first frame decodec in case its not a keyframe |
1371 |
*/ |
1401 |
*/ |
1372 |
if (pkt.stream_index == this->video_index) { |
1402 |
if (pkt.stream_index == this->video_index) { |
1373 |
avcodec_decode_video2(venc, frame, &got_picture, &pkt); |
1403 |
avcodec_decode_video2(venc, frame, &got_frame, &pkt); |
1374 |
} |
1404 |
} |
1375 |
av_free_packet (&pkt); |
1405 |
av_free_packet (&pkt); |
1376 |
continue; |
1406 |
continue; |
Lines 1389-1397
void ff2theora_output(ff2theora this) {
Link Here
|
1389 |
while(video_eos || avpkt.size > 0) { |
1419 |
while(video_eos || avpkt.size > 0) { |
1390 |
int dups = 0; |
1420 |
int dups = 0; |
1391 |
static th_ycbcr_buffer ycbcr; |
1421 |
static th_ycbcr_buffer ycbcr; |
1392 |
len1 = avcodec_decode_video2(venc, frame, &got_picture, &avpkt); |
1422 |
len1 = avcodec_decode_video2(venc, frame, &got_frame, &avpkt); |
1393 |
if (len1>=0) { |
1423 |
if (len1>=0) { |
1394 |
if (got_picture) { |
1424 |
if (got_frame) { |
1395 |
// this is disabled by default since it does not work |
1425 |
// this is disabled by default since it does not work |
1396 |
// for all input formats the way it should. |
1426 |
// for all input formats the way it should. |
1397 |
if (this->sync == 1 && pkt.dts != AV_NOPTS_VALUE) { |
1427 |
if (this->sync == 1 && pkt.dts != AV_NOPTS_VALUE) { |
Lines 1428-1434
void ff2theora_output(ff2theora this) {
Link Here
|
1428 |
|
1458 |
|
1429 |
if (venc_pix_fmt != this->pix_fmt) { |
1459 |
if (venc_pix_fmt != this->pix_fmt) { |
1430 |
sws_scale(this->sws_colorspace_ctx, |
1460 |
sws_scale(this->sws_colorspace_ctx, |
1431 |
frame->data, frame->linesize, 0, display_height, |
1461 |
(const uint8_t * const*)frame->data, frame->linesize, 0, display_height, |
1432 |
output_tmp->data, output_tmp->linesize); |
1462 |
output_tmp->data, output_tmp->linesize); |
1433 |
} |
1463 |
} |
1434 |
else{ |
1464 |
else{ |
Lines 1472-1478
void ff2theora_output(ff2theora this) {
Link Here
|
1472 |
} |
1502 |
} |
1473 |
if (this->sws_scale_ctx) { |
1503 |
if (this->sws_scale_ctx) { |
1474 |
sws_scale(this->sws_scale_ctx, |
1504 |
sws_scale(this->sws_scale_ctx, |
1475 |
output_cropped->data, |
1505 |
(const uint8_t * const*)output_cropped->data, |
1476 |
output_cropped->linesize, 0, |
1506 |
output_cropped->linesize, 0, |
1477 |
display_height - (this->frame_topBand + this->frame_bottomBand), |
1507 |
display_height - (this->frame_topBand + this->frame_bottomBand), |
1478 |
output_resized->data, |
1508 |
output_resized->data, |
Lines 1500-1506
void ff2theora_output(ff2theora this) {
Link Here
|
1500 |
//now output_resized |
1530 |
//now output_resized |
1501 |
|
1531 |
|
1502 |
if (!first) { |
1532 |
if (!first) { |
1503 |
if (got_picture || video_eos) { |
1533 |
if (got_frame || video_eos) { |
1504 |
prepare_ycbcr_buffer(this, ycbcr, output_buffered); |
1534 |
prepare_ycbcr_buffer(this, ycbcr, output_buffered); |
1505 |
if(dups>0) { |
1535 |
if(dups>0) { |
1506 |
//this only works if dups < keyint, |
1536 |
//this only works if dups < keyint, |
Lines 1520-1530
void ff2theora_output(ff2theora this) {
Link Here
|
1520 |
info.videotime = this->frame_count / av_q2d(this->framerate); |
1550 |
info.videotime = this->frame_count / av_q2d(this->framerate); |
1521 |
} |
1551 |
} |
1522 |
} |
1552 |
} |
1523 |
if (got_picture) { |
1553 |
if (got_frame) { |
1524 |
first=0; |
1554 |
first=0; |
1525 |
av_picture_copy((AVPicture *)output_buffered, (AVPicture *)output_padded, this->pix_fmt, this->frame_width, this->frame_height); |
1555 |
av_picture_copy((AVPicture *)output_buffered, (AVPicture *)output_padded, this->pix_fmt, this->frame_width, this->frame_height); |
1526 |
} |
1556 |
} |
1527 |
if (!got_picture) { |
1557 |
if (!got_frame) { |
1528 |
break; |
1558 |
break; |
1529 |
} |
1559 |
} |
1530 |
} |
1560 |
} |
Lines 1532-1573
void ff2theora_output(ff2theora this) {
Link Here
|
1532 |
if (info.passno!=1) |
1562 |
if (info.passno!=1) |
1533 |
if ((audio_eos && !audio_done) || (ret >= 0 && pkt.stream_index == this->audio_index)) { |
1563 |
if ((audio_eos && !audio_done) || (ret >= 0 && pkt.stream_index == this->audio_index)) { |
1534 |
while((audio_eos && !audio_done) || avpkt.size > 0 ) { |
1564 |
while((audio_eos && !audio_done) || avpkt.size > 0 ) { |
1535 |
int samples=0; |
|
|
1536 |
int samples_out=0; |
1537 |
int data_size = 4*MAX_AUDIO_FRAME_SIZE; |
1538 |
int bytes_per_sample = av_get_bytes_per_sample(aenc->sample_fmt); |
1565 |
int bytes_per_sample = av_get_bytes_per_sample(aenc->sample_fmt); |
1539 |
|
1566 |
|
1540 |
if (avpkt.size > 0) { |
1567 |
if (avpkt.size > 0) { |
1541 |
len1 = avcodec_decode_audio3(astream->codec, audio_buf, &data_size, &avpkt); |
1568 |
if (!audio_frame && !(audio_frame = avcodec_alloc_frame())) { |
|
|
1569 |
fprintf(stderr, "Failed to allocate memory\n"); |
1570 |
exit(1); |
1571 |
} |
1572 |
len1 = avcodec_decode_audio4(astream->codec, audio_frame, &got_frame, &avpkt); |
1542 |
if (len1 < 0) { |
1573 |
if (len1 < 0) { |
1543 |
/* if error, we skip the frame */ |
1574 |
/* if error, we skip the frame */ |
1544 |
break; |
1575 |
break; |
1545 |
} |
1576 |
} |
1546 |
avpkt.size -= len1; |
1577 |
/* Some audio decoders decode only part of the packet, and have to be |
1547 |
avpkt.data += len1; |
1578 |
* called again with the remainder of the packet data. |
1548 |
if (data_size >0) { |
1579 |
* Sample: http://fate-suite.libav.org/lossless-audio/luckynight-partial.shn |
1549 |
samples = data_size / (aenc->channels * bytes_per_sample); |
1580 |
* Also, some decoders might over-read the packet. */ |
1550 |
samples_out = samples; |
1581 |
len1 = FFMIN(len1, avpkt.size); |
1551 |
if (this->audio_resample_ctx) { |
1582 |
if (got_frame) { |
1552 |
samples_out = audio_resample(this->audio_resample_ctx, resampled, audio_buf, samples); |
1583 |
dst_nb_samples = audio_frame->nb_samples; |
1553 |
audio_p = resampled; |
1584 |
if (swr_ctx) { |
|
|
1585 |
dst_nb_samples = av_rescale_rnd(audio_frame->nb_samples, |
1586 |
this->sample_rate, aenc->sample_rate, AV_ROUND_UP); |
1587 |
if (dst_nb_samples > max_dst_nb_samples) { |
1588 |
av_free(dst_audio_data[0]); |
1589 |
if (av_samples_alloc(dst_audio_data, &dst_linesize, this->channels, |
1590 |
dst_nb_samples, AV_SAMPLE_FMT_FLTP, 1) < 0) { |
1591 |
fprintf(stderr, "Error while converting audio\n"); |
1592 |
exit(1); |
1593 |
} |
1594 |
max_dst_nb_samples = dst_nb_samples; |
1595 |
} |
1596 |
if (swr_convert(swr_ctx, dst_audio_data, dst_nb_samples, |
1597 |
(const uint8_t**)audio_frame->extended_data, audio_frame->nb_samples) < 0) { |
1598 |
fprintf(stderr, "Error while converting audio\n"); |
1599 |
exit(1); |
1600 |
} |
1601 |
audio_p = dst_audio_data; |
1602 |
} else { |
1603 |
audio_p = audio_frame->extended_data; |
1554 |
} |
1604 |
} |
1555 |
else |
|
|
1556 |
audio_p = audio_buf; |
1557 |
} |
1605 |
} |
|
|
1606 |
avpkt.size -= len1; |
1607 |
avpkt.data += len1; |
1558 |
} |
1608 |
} |
1559 |
|
1609 |
if(got_frame || audio_eos) { |
1560 |
if (no_samples > 0 && this->sample_count + samples_out > no_samples) { |
1610 |
if (no_samples > 0 && this->sample_count + dst_nb_samples > no_samples) { |
1561 |
audio_eos = 1; |
1611 |
audio_eos = 1; |
1562 |
samples_out = no_samples - this->sample_count; |
1612 |
dst_nb_samples = no_samples - this->sample_count; |
1563 |
if (samples_out <= 0) { |
1613 |
if (dst_nb_samples <= 0) { |
1564 |
break; |
1614 |
break; |
|
|
1615 |
} |
1565 |
} |
1616 |
} |
|
|
1617 |
oggmux_add_audio(&info, audio_p, dst_nb_samples, audio_eos); |
1618 |
avcodec_free_frame(&audio_frame); |
1619 |
this->sample_count += dst_nb_samples; |
1566 |
} |
1620 |
} |
1567 |
|
|
|
1568 |
oggmux_add_audio(&info, audio_p, |
1569 |
samples_out * (this->channels), samples_out, audio_eos); |
1570 |
this->sample_count += samples_out; |
1571 |
if(audio_eos) { |
1621 |
if(audio_eos) { |
1572 |
audio_done = 1; |
1622 |
audio_done = 1; |
1573 |
} |
1623 |
} |
Lines 1752-1759
void ff2theora_output(ff2theora this) {
Link Here
|
1752 |
avcodec_close(venc); |
1802 |
avcodec_close(venc); |
1753 |
} |
1803 |
} |
1754 |
if (this->audio_index >= 0) { |
1804 |
if (this->audio_index >= 0) { |
1755 |
if (this->audio_resample_ctx) |
1805 |
if (swr_ctx) |
1756 |
audio_resample_close(this->audio_resample_ctx); |
1806 |
swr_free(&swr_ctx); |
1757 |
avcodec_close(aenc); |
1807 |
avcodec_close(aenc); |
1758 |
} |
1808 |
} |
1759 |
|
1809 |
|
Lines 1774-1781
void ff2theora_output(ff2theora this) {
Link Here
|
1774 |
frame_dealloc(output_cropped_p); |
1824 |
frame_dealloc(output_cropped_p); |
1775 |
frame_dealloc(output_padded_p); |
1825 |
frame_dealloc(output_padded_p); |
1776 |
} |
1826 |
} |
1777 |
av_free(audio_buf); |
1827 |
if (dst_audio_data) |
1778 |
av_free(resampled); |
1828 |
av_freep(&dst_audio_data[0]); |
|
|
1829 |
av_freep(&dst_audio_data); |
1830 |
if(swr_ctx) { |
1831 |
swr_close(swr_ctx); |
1832 |
} |
1779 |
} |
1833 |
} |
1780 |
else{ |
1834 |
else{ |
1781 |
fprintf(stderr, "No video or audio stream found.\n"); |
1835 |
fprintf(stderr, "No video or audio stream found.\n"); |