summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-03-01 23:11:31 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-03-01 23:11:31 +0100
commit1eb7f39c7b8172e02a7c95073036a2c327215db8 (patch)
treec3323cf0b704cdc2eda65bb202af3329a8973e2a
parent75d11b55d7c6f9417c047500171b8aa42b8b8f50 (diff)
parent0ce4fe482c27abfa7eac503a52fdc50b70ccd871 (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: h264: error out on invalid bitdepth. aacsbr: use a swap index for the Y matrix rather than copy buffers. huffyuv: do not abort on unknown pix_fmt; instead, return an error. lcl: return negative error codes on decode_init() errors. rtpenc: Use MB info side data for splitting H263 packets for RFC 2190 h263enc: Add an option for outputting info about MBs as side data avpacket: Add a function for shrinking already allocated side data nellymoserdec: Saner and faster IMDCT windowing Conflicts: doc/APIchanges libavcodec/avpacket.c libavcodec/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--doc/APIchanges6
-rw-r--r--libavcodec/aacsbr.c33
-rw-r--r--libavcodec/avcodec.h30
-rw-r--r--libavcodec/avpacket.c16
-rw-r--r--libavcodec/h264.c17
-rw-r--r--libavcodec/huffyuv.c2
-rw-r--r--libavcodec/lcldec.c14
-rw-r--r--libavcodec/mpegvideo.h4
-rw-r--r--libavcodec/mpegvideo_enc.c56
-rw-r--r--libavcodec/nellymoserdec.c16
-rw-r--r--libavcodec/sbr.h1
-rw-r--r--libavcodec/version.h2
-rw-r--r--libavformat/rtpenc.c6
-rw-r--r--libavformat/rtpenc.h3
-rw-r--r--libavformat/rtpenc_h263_rfc2190.c111
15 files changed, 265 insertions, 52 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index 5818f6a8ec..b579e826c1 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,7 +13,6 @@ libavutil: 2011-04-18
API changes, most recent first:
-<<<<<<< HEAD
2012-02-21 - xxxxxxx - lavc 54.4.100
Add av_get_pcm_codec() function.
@@ -36,8 +35,9 @@ API changes, most recent first:
2012-01-24 - xxxxxxx - lavfi 2.60.100
Add avfilter_graph_dump.
-||||||| merged common ancestors
-=======
+2012-xx-xx - xxxxxxx - lavc 54.3.0 - avcodec.h
+ Add av_packet_shrink_side_data.
+
2012-xx-xx - xxxxxxx - lavf 54.2.0 - avformat.h
Add AVStream.attached_pic and AV_DISPOSITION_ATTACHED_PIC,
used for dealing with attached pictures/cover art.
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index 71bd2ceda5..fc87d3dbce 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -1353,8 +1353,8 @@ static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
/// Generate the subband filtered lowband
static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
- const float X_low[32][40][2], const float Y[2][38][64][2],
- int ch)
+ const float Y0[38][64][2], const float Y1[38][64][2],
+ const float X_low[32][40][2], int ch)
{
int k, i;
const int i_f = 32;
@@ -1368,8 +1368,8 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
}
for (; k < sbr->kx[0] + sbr->m[0]; k++) {
for (i = 0; i < i_Temp; i++) {
- X[0][i][k] = Y[0][i + i_f][k][0];
- X[1][i][k] = Y[0][i + i_f][k][1];
+ X[0][i][k] = Y0[i + i_f][k][0];
+ X[1][i][k] = Y0[i + i_f][k][1];
}
}
@@ -1381,8 +1381,8 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
}
for (; k < sbr->kx[1] + sbr->m[1]; k++) {
for (i = i_Temp; i < i_f; i++) {
- X[0][i][k] = Y[1][i][k][0];
- X[1][i][k] = Y[1][i][k][1];
+ X[0][i][k] = Y1[i][k][0];
+ X[1][i][k] = Y1[i][k][1];
}
}
return 0;
@@ -1542,7 +1542,8 @@ static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
}
/// Assembling HF Signals (14496-3 sp04 p220)
-static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2],
+static void sbr_hf_assemble(float Y1[38][64][2],
+ const float X_high[64][40][2],
SpectralBandReplication *sbr, SBRData *ch_data,
const int e_a[2])
{
@@ -1564,7 +1565,6 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
int indexnoise = ch_data->f_indexnoise;
int indexsine = ch_data->f_indexsine;
- memcpy(Y[0], Y[1], sizeof(Y[0]));
if (sbr->reset) {
for (i = 0; i < h_SL; i++) {
@@ -1607,18 +1607,18 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
q_filt = q_temp[i];
}
- sbr->dsp.hf_g_filt(Y[1][i] + kx, X_high + kx, g_filt, m_max,
+ sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
i + ENVELOPE_ADJUSTMENT_OFFSET);
if (e != e_a[0] && e != e_a[1]) {
- sbr->dsp.hf_apply_noise[indexsine](Y[1][i] + kx, sbr->s_m[e],
+ sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
q_filt, indexnoise,
kx, m_max);
} else {
for (m = 0; m < m_max; m++) {
- Y[1][i][m + kx][0] +=
+ Y1[i][m + kx][0] +=
sbr->s_m[e][m] * phi[0][indexsine];
- Y[1][i][m + kx][1] +=
+ Y1[i][m + kx][1] +=
sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign);
phi_sign = -phi_sign;
}
@@ -1658,12 +1658,17 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
- sbr_hf_assemble(sbr->data[ch].Y, sbr->X_high, sbr, &sbr->data[ch],
+ sbr->data[ch].Ypos ^= 1;
+ sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
+ sbr->X_high, sbr, &sbr->data[ch],
sbr->data[ch].e_a);
}
/* synthesis */
- sbr_x_gen(sbr, sbr->X[ch], sbr->X_low, sbr->data[ch].Y, ch);
+ sbr_x_gen(sbr, sbr->X[ch],
+ sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+ sbr->data[ch].Y[ sbr->data[ch].Ypos],
+ sbr->X_low, ch);
}
if (ac->m4ac.ps == 1) {
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 39f69eee44..007f08248d 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -772,6 +772,7 @@ enum AVPacketSideDataType {
AV_PKT_DATA_PALETTE,
AV_PKT_DATA_NEW_EXTRADATA,
AV_PKT_DATA_PARAM_CHANGE,
+ AV_PKT_DATA_H263_MB_INFO,
};
typedef struct AVPacket {
@@ -854,6 +855,24 @@ typedef struct AVPacket {
* s32le height
*/
+/**
+ * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of
+ * structures with info about macroblocks relevant to splitting the
+ * packet into smaller packets on macroblock edges (e.g. as for RFC 2190).
+ * That is, it does not necessarily contain info about all macroblocks,
+ * as long as the distance between macroblocks in the info is smaller
+ * than the target payload size.
+ * Each MB info structure is 12 bytes, and is laid out as follows:
+ * u32le bit offset from the start of the packet
+ * u8 current quantizer at the start of the macroblock
+ * u8 GOB number
+ * u16le macroblock address within the GOB
+ * u8 horizontal MV predictor
+ * u8 vertical MV predictor
+ * u8 horizontal MV predictor for block number 3
+ * u8 vertical MV predictor for block number 3
+ */
+
enum AVSideDataParamChangeFlags {
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
@@ -3150,6 +3169,17 @@ uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
int size);
/**
+ * Shrink the already allocated side data buffer
+ *
+ * @param pkt packet
+ * @param type side information type
+ * @param size new side information size
+ * @return 0 on success, < 0 on failure
+ */
+int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size);
+
+/**
* Get side information from packet.
*
* @param pkt packet
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 5a51900ebf..425b040b6c 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -279,3 +279,19 @@ int av_packet_split_side_data(AVPacket *pkt){
}
return 0;
}
+
+int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size)
+{
+ int i;
+
+ for (i = 0; i < pkt->side_data_elems; i++) {
+ if (pkt->side_data[i].type == type) {
+ if (size > pkt->side_data[i].size)
+ return AVERROR(ENOMEM);
+ pkt->side_data[i].size = size;
+ return 0;
+ }
+ }
+ return AVERROR(ENOENT);
+}
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index e1d8c5fe59..20daa2e0a8 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2692,11 +2692,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
s->avctx->level = h->sps.level_idc;
s->avctx->refs = h->sps.ref_frame_count;
- if(h == h0 && h->dequant_coeff_pps != pps_id){
- h->dequant_coeff_pps = pps_id;
- init_dequant_tables(h);
- }
-
s->mb_width= h->sps.mb_width;
s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
@@ -2791,7 +2786,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
else
s->avctx->pix_fmt = PIX_FMT_YUV420P10;
break;
- default:
+ case 8:
if (CHROMA444){
s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P;
if (s->avctx->colorspace == AVCOL_SPC_RGB) {
@@ -2810,6 +2805,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
hwaccel_pixfmt_list_h264_jpeg_420 :
ff_hwaccel_pixfmt_list_420);
}
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unsupported bit depth: %d\n", h->sps.bit_depth_luma);
+ return AVERROR_INVALIDDATA;
}
s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt);
@@ -2855,6 +2855,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
}
}
+ if(h == h0 && h->dequant_coeff_pps != pps_id){
+ h->dequant_coeff_pps = pps_id;
+ init_dequant_tables(h);
+ }
+
h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);
h->mb_mbaff = 0;
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index ca94fc9042..d6bda7b69a 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -543,7 +543,7 @@ s->bgr32=1;
}
break;
default:
- assert(0);
+ return AVERROR_INVALIDDATA;
}
alloc_temp(s);
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 88567f6a98..158fafee89 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -488,7 +488,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
avcodec_get_frame_defaults(&c->pic);
if (avctx->extradata_size < 8) {
av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Check codec type */
@@ -537,7 +537,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Detect compression method */
@@ -554,7 +554,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
- return 1;
+ return AVERROR_INVALIDDATA;
}
break;
#if CONFIG_ZLIB_DECODER
@@ -572,7 +572,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
default:
if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
- return 1;
+ return AVERROR_INVALIDDATA;
}
av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
}
@@ -580,14 +580,14 @@ static av_cold int decode_init(AVCodecContext *avctx)
#endif
default:
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Allocate decompression buffer */
if (c->decomp_size) {
if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
- return 1;
+ return AVERROR(ENOMEM);
}
}
@@ -613,7 +613,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
if (zret != Z_OK) {
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
av_freep(&c->decomp_buf);
- return 1;
+ return AVERROR_UNKNOWN;
}
}
#endif
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 02f15da433..14a298bc46 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -511,6 +511,10 @@ typedef struct MpegEncContext {
int gob_index;
int obmc; ///< overlapped block motion compensation
int showed_packed_warning; ///< flag for having shown the warning about divxs invalid b frames
+ int mb_info; ///< interval for outputting info about mb offsets as side data
+ int prev_mb_info, last_mb_info;
+ uint8_t *mb_info_ptr;
+ int mb_info_size;
/* H.263+ specific */
int umvplus; ///< == H263+ && unrestricted_mv
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index c780ffb598..af57644626 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -43,6 +43,7 @@
#include "flv.h"
#include "mpeg4video.h"
#include "internal.h"
+#include "bytestream.h"
#include <limits.h>
#include "sp5x.h"
@@ -1437,6 +1438,12 @@ int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
if (!pkt->data &&
(ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)
return ret;
+ if (s->mb_info) {
+ s->mb_info_ptr = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_H263_MB_INFO,
+ s->mb_width*s->mb_height*12);
+ s->prev_mb_info = s->last_mb_info = s->mb_info_size = 0;
+ }
for (i = 0; i < context_count; i++) {
int start_y = s->thread_context[i]->start_mb_y;
@@ -1604,6 +1611,8 @@ vbv_retry:
pkt->dts = pkt->pts;
if (s->current_picture.f.key_frame)
pkt->flags |= AV_PKT_FLAG_KEY;
+ if (s->mb_info)
+ av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);
} else {
assert((put_bits_ptr(&s->pb) == s->pb.buf));
s->frame_bits = 0;
@@ -2348,6 +2357,49 @@ static void write_slice_end(MpegEncContext *s){
s->misc_bits+= get_bits_diff(s);
}
+static void write_mb_info(MpegEncContext *s)
+{
+ uint8_t *ptr = s->mb_info_ptr + s->mb_info_size - 12;
+ int offset = put_bits_count(&s->pb);
+ int mba = s->mb_x + s->mb_width * (s->mb_y % s->gob_index);
+ int gobn = s->mb_y / s->gob_index;
+ int pred_x, pred_y;
+ if (CONFIG_H263_ENCODER)
+ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+ bytestream_put_le32(&ptr, offset);
+ bytestream_put_byte(&ptr, s->qscale);
+ bytestream_put_byte(&ptr, gobn);
+ bytestream_put_le16(&ptr, mba);
+ bytestream_put_byte(&ptr, pred_x); /* hmv1 */
+ bytestream_put_byte(&ptr, pred_y); /* vmv1 */
+ /* 4MV not implemented */
+ bytestream_put_byte(&ptr, 0); /* hmv2 */
+ bytestream_put_byte(&ptr, 0); /* vmv2 */
+}
+
+static void update_mb_info(MpegEncContext *s, int startcode)
+{
+ if (!s->mb_info)
+ return;
+ if (put_bits_count(&s->pb) - s->prev_mb_info*8 >= s->mb_info*8) {
+ s->mb_info_size += 12;
+ s->prev_mb_info = s->last_mb_info;
+ }
+ if (startcode) {
+ s->prev_mb_info = put_bits_count(&s->pb)/8;
+ /* This might have incremented mb_info_size above, and we return without
+ * actually writing any info into that slot yet. But in that case,
+ * this will be called again at the start of the after writing the
+ * start code, actually writing the mb info. */
+ return;
+ }
+
+ s->last_mb_info = put_bits_count(&s->pb)/8;
+ if (!s->mb_info_size)
+ s->mb_info_size += 12;
+ write_mb_info(s);
+}
+
static int encode_thread(AVCodecContext *c, void *arg){
MpegEncContext *s= *(void**)arg;
int mb_x, mb_y, pdif = 0;
@@ -2498,6 +2550,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x;
s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb);
}
+ update_mb_info(s, 1);
switch(s->codec_id){
case CODEC_ID_MPEG4:
@@ -2541,6 +2594,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
s->mb_skipped=0;
s->dquant=0; //only for QP_RD
+ update_mb_info(s, 0);
+
if (mb_type & (mb_type-1) || (s->mpv_flags & FF_MPV_FLAG_QP_RD)) { // more than 1 MB type possible or FF_MPV_FLAG_QP_RD
int next_block=0;
int pb_bits_count, pb2_bits_count, tex_pb_bits_count;
@@ -4117,6 +4172,7 @@ int ff_dct_quantize_c(MpegEncContext *s,
static const AVOption h263_options[] = {
{ "obmc", "use overlapped block motion compensation.", OFFSET(obmc), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE },
{ "structured_slices","Write slice start position at every GOB header instead of just GOB number.", OFFSET(h263_slice_structured), AV_OPT_TYPE_INT, { 0 }, 0, 1, VE},
+ { "mb_info", "emit macroblock info for RFC 2190 packetization, the parameter value is the maximum payload size", OFFSET(mb_info), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, VE },
FF_MPV_COMMON_OPTS
{ NULL },
};
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index c74d54ec19..9d37983866 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -49,14 +49,15 @@ typedef struct NellyMoserDecodeContext {
AVCodecContext* avctx;
AVFrame frame;
float *float_buf;
- DECLARE_ALIGNED(16, float, state)[NELLY_BUF_LEN];
AVLFG random_state;
GetBitContext gb;
float scale_bias;
DSPContext dsp;
FFTContext imdct_ctx;
FmtConvertContext fmt_conv;
- DECLARE_ALIGNED(32, float, imdct_out)[NELLY_BUF_LEN * 2];
+ DECLARE_ALIGNED(32, float, imdct_buf)[2][NELLY_BUF_LEN];
+ float *imdct_out;
+ float *imdct_prev;
} NellyMoserDecodeContext;
static void nelly_decode_block(NellyMoserDecodeContext *s,
@@ -106,12 +107,9 @@ static void nelly_decode_block(NellyMoserDecodeContext *s,
memset(&aptr[NELLY_FILL_LEN], 0,
(NELLY_BUF_LEN - NELLY_FILL_LEN) * sizeof(float));
- s->imdct_ctx.imdct_calc(&s->imdct_ctx, s->imdct_out, aptr);
- /* XXX: overlapping and windowing should be part of a more
- generic imdct function */
- s->dsp.vector_fmul_reverse(s->state, s->state, ff_sine_128, NELLY_BUF_LEN);
- s->dsp.vector_fmul_add(aptr, s->imdct_out, ff_sine_128, s->state, NELLY_BUF_LEN);
- memcpy(s->state, s->imdct_out + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN);
+ s->imdct_ctx.imdct_half(&s->imdct_ctx, s->imdct_out, aptr);
+ s->dsp.vector_fmul_window(aptr, s->imdct_prev + NELLY_BUF_LEN/2, s->imdct_out, ff_sine_128, NELLY_BUF_LEN/2);
+ FFSWAP(float *, s->imdct_out, s->imdct_prev);
}
}
@@ -119,6 +117,8 @@ static av_cold int decode_init(AVCodecContext * avctx) {
NellyMoserDecodeContext *s = avctx->priv_data;
s->avctx = avctx;
+ s->imdct_out = s->imdct_buf[0];
+ s->imdct_prev = s->imdct_buf[1];
av_lfg_init(&s->random_state, 0);
ff_mdct_init(&s->imdct_ctx, 8, 1, 1.0);
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index 1fe47fcebe..01d7a97442 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -88,6 +88,7 @@ typedef struct {
///QMF values of the original signal
float W[2][32][32][2];
///QMF output of the HF adjustor
+ int Ypos;
DECLARE_ALIGNED(16, float, Y)[2][38][64][2];
DECLARE_ALIGNED(16, float, g_temp)[42][48];
float q_temp[42][48];
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 238866be6b..1b72037572 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -21,7 +21,7 @@
#define AVCODEC_VERSION_H
#define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 4
+#define LIBAVCODEC_VERSION_MINOR 5
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index 88a0527566..9f3fd08a55 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -453,7 +453,11 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
break;
case CODEC_ID_H263:
if (s->flags & FF_RTP_FLAG_RFC2190) {
- ff_rtp_send_h263_rfc2190(s1, pkt->data, size);
+ int mb_info_size = 0;
+ const uint8_t *mb_info =
+ av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO,
+ &mb_info_size);
+ ff_rtp_send_h263_rfc2190(s1, pkt->data, size, mb_info, mb_info_size);
break;
}
/* Fallthrough */
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index c28377fec0..080bf2154d 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -78,7 +78,8 @@ void ff_rtp_send_data(AVFormatContext *s1, const uint8_t *buf1, int len, int m);
void ff_rtp_send_h264(AVFormatContext *s1, const uint8_t *buf1, int size);
void ff_rtp_send_h263(AVFormatContext *s1, const uint8_t *buf1, int size);
-void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf1, int size);
+void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf1, int size,
+ const uint8_t *mb_info, int mb_info_size);
void ff_rtp_send_aac(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_latm(AVFormatContext *s1, const uint8_t *buff, int size);
void ff_rtp_send_amr(AVFormatContext *s1, const uint8_t *buff, int size);
diff --git a/libavformat/rtpenc_h263_rfc2190.c b/libavformat/rtpenc_h263_rfc2190.c
index 305c1a27c8..f714d010f4 100644
--- a/libavformat/rtpenc_h263_rfc2190.c
+++ b/libavformat/rtpenc_h263_rfc2190.c
@@ -34,8 +34,15 @@ struct H263Info {
int tr;
};
+struct H263State {
+ int gobn;
+ int mba;
+ int hmv1, vmv1, hmv2, vmv2;
+ int quant;
+};
+
static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
- const uint8_t *buf, int len, int m)
+ const uint8_t *buf, int len, int ebits, int m)
{
RTPMuxContext *s = s1->priv_data;
PutBitContext pb;
@@ -44,7 +51,7 @@ static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
put_bits(&pb, 1, 0); /* F - 0, mode A */
put_bits(&pb, 1, 0); /* P - 0, normal I/P */
put_bits(&pb, 3, 0); /* SBIT - 0 bits */
- put_bits(&pb, 3, 0); /* EBIT - 0 bits */
+ put_bits(&pb, 3, ebits); /* EBIT */
put_bits(&pb, 3, info->src); /* SRC - source format */
put_bits(&pb, 1, info->i); /* I - inter/intra */
put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
@@ -60,12 +67,47 @@ static void send_mode_a(AVFormatContext *s1, const struct H263Info *info,
ff_rtp_send_data(s1, s->buf, len + 4, m);
}
-void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size)
+static void send_mode_b(AVFormatContext *s1, const struct H263Info *info,
+ const struct H263State *state, const uint8_t *buf,
+ int len, int sbits, int ebits, int m)
+{
+ RTPMuxContext *s = s1->priv_data;
+ PutBitContext pb;
+
+ init_put_bits(&pb, s->buf, 64);
+ put_bits(&pb, 1, 1); /* F - 1, mode B */
+ put_bits(&pb, 1, 0); /* P - 0, mode B */
+ put_bits(&pb, 3, sbits); /* SBIT - 0 bits */
+ put_bits(&pb, 3, ebits); /* EBIT - 0 bits */
+ put_bits(&pb, 3, info->src); /* SRC - source format */
+ put_bits(&pb, 5, state->quant); /* QUANT - quantizer for the first MB */
+ put_bits(&pb, 5, state->gobn); /* GOBN - GOB number */
+ put_bits(&pb, 9, state->mba); /* MBA - MB address */
+ put_bits(&pb, 2, 0); /* R - reserved */
+ put_bits(&pb, 1, info->i); /* I - inter/intra */
+ put_bits(&pb, 1, info->u); /* U - unrestricted motion vector */
+ put_bits(&pb, 1, info->s); /* S - syntax-baesd arithmetic coding */
+ put_bits(&pb, 1, info->a); /* A - advanced prediction */
+ put_bits(&pb, 7, state->hmv1); /* HVM1 - horizontal motion vector 1 */
+ put_bits(&pb, 7, state->vmv1); /* VMV1 - vertical motion vector 1 */
+ put_bits(&pb, 7, state->hmv2); /* HVM2 - horizontal motion vector 2 */
+ put_bits(&pb, 7, state->vmv2); /* VMV2 - vertical motion vector 2 */
+ flush_put_bits(&pb);
+ memcpy(s->buf + 8, buf, len);
+
+ ff_rtp_send_data(s1, s->buf, len + 8, m);
+}
+
+void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size,
+ const uint8_t *mb_info, int mb_info_size)
{
RTPMuxContext *s = s1->priv_data;
- int len;
+ int len, sbits = 0, ebits = 0;
GetBitContext gb;
struct H263Info info = { 0 };
+ struct H263State state = { 0 };
+ int mb_info_pos = 0, mb_info_count = mb_info_size / 12;
+ const uint8_t *buf_base = buf;
s->timestamp = s->cur_timestamp;
@@ -83,22 +125,71 @@ void ff_rtp_send_h263_rfc2190(AVFormatContext *s1, const uint8_t *buf, int size)
}
while (size > 0) {
- len = FFMIN(s->max_payload_size - 4, size);
+ struct H263State packet_start_state = state;
+ len = FFMIN(s->max_payload_size - 8, size);
/* Look for a better place to split the frame into packets. */
if (len < size) {
const uint8_t *end = ff_h263_find_resync_marker_reverse(buf,
buf + len);
len = end - buf;
- if (len == s->max_payload_size - 4)
- av_log(s1, AV_LOG_WARNING,
- "No GOB boundary found within MTU size, splitting at "
- "a random boundary\n");
+ if (len == s->max_payload_size - 8) {
+ /* Skip mb info prior to the start of the current ptr */
+ while (mb_info_pos < mb_info_count) {
+ uint32_t pos = AV_RL32(&mb_info[12*mb_info_pos])/8;
+ if (pos >= buf - buf_base)
+ break;
+ mb_info_pos++;
+ }
+ /* Find the first mb info past the end pointer */
+ while (mb_info_pos + 1 < mb_info_count) {
+ uint32_t pos = AV_RL32(&mb_info[12*(mb_info_pos + 1)])/8;
+ if (pos >= end - buf_base)
+ break;
+ mb_info_pos++;
+ }
+ if (mb_info_pos < mb_info_count) {
+ const uint8_t *ptr = &mb_info[12*mb_info_pos];
+ uint32_t bit_pos = AV_RL32(ptr);
+ uint32_t pos = (bit_pos + 7)/8;
+ if (pos <= end - buf_base) {
+ state.quant = ptr[4];
+ state.gobn = ptr[5];
+ state.mba = AV_RL16(&ptr[6]);
+ state.hmv1 = (int8_t) ptr[8];
+ state.vmv1 = (int8_t) ptr[9];
+ state.hmv2 = (int8_t) ptr[10];
+ state.vmv2 = (int8_t) ptr[11];
+ ebits = 8 * pos - bit_pos;
+ len = pos - (buf - buf_base);
+ mb_info_pos++;
+ } else {
+ av_log(s1, AV_LOG_ERROR,
+ "Unable to split H263 packet, use -mb_info %d "
+ "or lower.\n", s->max_payload_size - 8);
+ }
+ } else {
+ av_log(s1, AV_LOG_ERROR, "Unable to split H263 packet, "
+ "use -mb_info %d or -ps 1.\n",
+ s->max_payload_size - 8);
+ }
+ }
}
- send_mode_a(s1, &info, buf, len, len == size);
+ if (size > 2 && !buf[0] && !buf[1])
+ send_mode_a(s1, &info, buf, len, ebits, len == size);
+ else
+ send_mode_b(s1, &info, &packet_start_state, buf, len, sbits,
+ ebits, len == size);
+ if (ebits) {
+ sbits = 8 - ebits;
+ len--;
+ } else {
+ sbits = 0;
+ }
buf += len;
size -= len;
+ ebits = 0;
}
}