mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: rtmp: Add support for SWFVerification api-example: use new video encoding API. x86: avcodec: Appropriately name files containing only init functions mpegvideo_mmx_template: drop some commented-out cruft libavresample: add mix level normalization option w32pthreads: Add missing #includes to make header compile standalone rtmp: Gracefully ignore _checkbw errors by tracking them rtmp: Do not send _checkbw calls as notifications prores: interlaced ProRes encoding Conflicts: doc/examples/decoding_encoding.c libavcodec/proresenc_kostya.c libavcodec/w32pthreads.h libavcodec/x86/Makefile libavformat/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
9e89bc37ed
@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <libavutil/imgutils.h>
|
|
||||||
#include <libavutil/opt.h>
|
#include <libavutil/opt.h>
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavutil/audioconvert.h>
|
#include <libavutil/audioconvert.h>
|
||||||
|
#include <libavutil/imgutils.h>
|
||||||
#include <libavutil/mathematics.h>
|
#include <libavutil/mathematics.h>
|
||||||
#include <libavutil/samplefmt.h>
|
#include <libavutil/samplefmt.h>
|
||||||
|
|
||||||
@ -315,11 +315,11 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
{
|
{
|
||||||
AVCodec *codec;
|
AVCodec *codec;
|
||||||
AVCodecContext *c= NULL;
|
AVCodecContext *c= NULL;
|
||||||
int i, out_size, x, y, outbuf_size;
|
int i, ret, x, y, got_output;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
AVFrame *picture;
|
AVFrame *picture;
|
||||||
uint8_t *outbuf;
|
AVPacket pkt;
|
||||||
int had_output=0;
|
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||||
|
|
||||||
printf("Encode video file %s\n", filename);
|
printf("Encode video file %s\n", filename);
|
||||||
|
|
||||||
@ -359,17 +359,25 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc image and output buffer */
|
|
||||||
outbuf_size = 100000 + 12*c->width*c->height;
|
|
||||||
outbuf = malloc(outbuf_size);
|
|
||||||
|
|
||||||
/* the image can be allocated by any means and av_image_alloc() is
|
/* the image can be allocated by any means and av_image_alloc() is
|
||||||
* just the most convenient way if av_malloc() is to be used */
|
* just the most convenient way if av_malloc() is to be used */
|
||||||
av_image_alloc(picture->data, picture->linesize,
|
ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height,
|
||||||
c->width, c->height, c->pix_fmt, 1);
|
c->pix_fmt, 32);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "could not alloc raw picture buffer\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
picture->format = c->pix_fmt;
|
||||||
|
picture->width = c->width;
|
||||||
|
picture->height = c->height;
|
||||||
|
|
||||||
/* encode 1 second of video */
|
/* encode 1 second of video */
|
||||||
for(i=0;i<25;i++) {
|
for(i=0;i<25;i++) {
|
||||||
|
av_init_packet(&pkt);
|
||||||
|
pkt.data = NULL; // packet data will be allocated by the encoder
|
||||||
|
pkt.size = 0;
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
/* prepare a dummy image */
|
/* prepare a dummy image */
|
||||||
/* Y */
|
/* Y */
|
||||||
@ -387,35 +395,46 @@ static void video_encode_example(const char *filename, int codec_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
picture->pts = i;
|
||||||
|
|
||||||
/* encode the image */
|
/* encode the image */
|
||||||
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
|
ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
|
||||||
had_output |= out_size;
|
if (ret < 0) {
|
||||||
printf("encoding frame %3d (size=%5d)\n", i, out_size);
|
fprintf(stderr, "error encoding frame\n");
|
||||||
fwrite(outbuf, 1, out_size, f);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_output) {
|
||||||
|
printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_free_packet(&pkt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the delayed frames */
|
/* get the delayed frames */
|
||||||
for(; out_size || !had_output; i++) {
|
for (got_output = 1; got_output; i++) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
|
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
|
||||||
had_output |= out_size;
|
if (ret < 0) {
|
||||||
printf("write frame %3d (size=%5d)\n", i, out_size);
|
fprintf(stderr, "error encoding frame\n");
|
||||||
fwrite(outbuf, 1, out_size, f);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (got_output) {
|
||||||
|
printf("write frame %3d (size=%5d)\n", i, pkt.size);
|
||||||
|
fwrite(pkt.data, 1, pkt.size, f);
|
||||||
|
av_free_packet(&pkt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add sequence end code to have a real mpeg file */
|
/* add sequence end code to have a real mpeg file */
|
||||||
outbuf[0] = 0x00;
|
fwrite(endcode, 1, sizeof(endcode), f);
|
||||||
outbuf[1] = 0x00;
|
|
||||||
outbuf[2] = 0x01;
|
|
||||||
outbuf[3] = 0xb7;
|
|
||||||
fwrite(outbuf, 1, 4, f);
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
free(outbuf);
|
|
||||||
|
|
||||||
avcodec_close(c);
|
avcodec_close(c);
|
||||||
av_free(c);
|
av_free(c);
|
||||||
av_free(picture->data[0]);
|
av_freep(&picture->data[0]);
|
||||||
av_free(picture);
|
av_free(picture);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,12 @@ Name of live stream to subscribe to. By default no value will be sent.
|
|||||||
It is only sent if the option is specified or if rtmp_live
|
It is only sent if the option is specified or if rtmp_live
|
||||||
is set to live.
|
is set to live.
|
||||||
|
|
||||||
|
@item rtmp_swfhash
|
||||||
|
SHA256 hash of the decompressed SWF file (32 bytes).
|
||||||
|
|
||||||
|
@item rtmp_swfsize
|
||||||
|
Size of the decompressed SWF file, required for SWFVerification.
|
||||||
|
|
||||||
@item rtmp_swfurl
|
@item rtmp_swfurl
|
||||||
URL of the SWF player for the media. By default no value will be sent.
|
URL of the SWF player for the media. By default no value will be sent.
|
||||||
|
|
||||||
|
@ -406,10 +406,15 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
|
|||||||
int total_size = 0;
|
int total_size = 0;
|
||||||
const uint16_t *src;
|
const uint16_t *src;
|
||||||
int slice_width_factor = av_log2(mbs_per_slice);
|
int slice_width_factor = av_log2(mbs_per_slice);
|
||||||
int num_cblocks, pwidth, linesize, line_offset;
|
int num_cblocks, pwidth, linesize, line_add;
|
||||||
int plane_factor, is_chroma;
|
int plane_factor, is_chroma;
|
||||||
uint16_t *qmat;
|
uint16_t *qmat;
|
||||||
|
|
||||||
|
if (ctx->pictures_per_frame == 1)
|
||||||
|
line_add = 0;
|
||||||
|
else
|
||||||
|
line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
|
||||||
|
|
||||||
if (ctx->force_quant) {
|
if (ctx->force_quant) {
|
||||||
qmat = ctx->quants[0];
|
qmat = ctx->quants[0];
|
||||||
} else if (quant < MAX_STORED_Q) {
|
} else if (quant < MAX_STORED_Q) {
|
||||||
@ -437,15 +442,14 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
|
|||||||
pwidth = avctx->width >> 1;
|
pwidth = avctx->width >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
line_offset = ((ctx->cur_picture_idx ^ !pic->top_field_first) &
|
|
||||||
(ctx->pictures_per_frame - 1)) * pic->linesize[i];
|
|
||||||
linesize = pic->linesize[i] * ctx->pictures_per_frame;
|
linesize = pic->linesize[i] * ctx->pictures_per_frame;
|
||||||
src = (const uint16_t*)(pic->data[i] + yp * linesize + line_offset) + xp;
|
src = (const uint16_t*)(pic->data[i] + yp * linesize +
|
||||||
|
line_add * pic->linesize[i]) + xp;
|
||||||
|
|
||||||
get_slice_data(ctx, src, linesize, xp, yp,
|
get_slice_data(ctx, src, linesize, xp, yp,
|
||||||
pwidth, avctx->height / ctx->pictures_per_frame,
|
pwidth, avctx->height / ctx->pictures_per_frame,
|
||||||
ctx->blocks[0], ctx->emu_buf, mbs_per_slice,
|
ctx->blocks[0], ctx->emu_buf,
|
||||||
num_cblocks, is_chroma);
|
mbs_per_slice, num_cblocks, is_chroma);
|
||||||
sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
|
sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
|
||||||
mbs_per_slice, ctx->blocks[0],
|
mbs_per_slice, ctx->blocks[0],
|
||||||
num_cblocks, plane_factor,
|
num_cblocks, plane_factor,
|
||||||
@ -579,8 +583,12 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
|||||||
int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
|
int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
|
||||||
int overquant;
|
int overquant;
|
||||||
uint16_t *qmat;
|
uint16_t *qmat;
|
||||||
int linesize[4], line_offset;
|
int linesize[4], line_add;
|
||||||
|
|
||||||
|
if (ctx->pictures_per_frame == 1)
|
||||||
|
line_add = 0;
|
||||||
|
else
|
||||||
|
line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
|
||||||
mbs = x + mbs_per_slice;
|
mbs = x + mbs_per_slice;
|
||||||
|
|
||||||
for (i = 0; i < ctx->num_planes; i++) {
|
for (i = 0; i < ctx->num_planes; i++) {
|
||||||
@ -600,15 +608,14 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
|||||||
pwidth = avctx->width >> 1;
|
pwidth = avctx->width >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
line_offset = ((ctx->cur_picture_idx ^ !pic->top_field_first) &
|
|
||||||
(ctx->pictures_per_frame - 1)) * pic->linesize[i];
|
|
||||||
linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
|
linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
|
||||||
src = (const uint16_t*)(pic->data[i] + yp * linesize[i] + line_offset) + xp;
|
src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
|
||||||
|
line_add * pic->linesize[i]) + xp;
|
||||||
|
|
||||||
get_slice_data(ctx, src, linesize[i], xp, yp,
|
get_slice_data(ctx, src, linesize[i], xp, yp,
|
||||||
pwidth, avctx->height / ctx->pictures_per_frame,
|
pwidth, avctx->height / ctx->pictures_per_frame,
|
||||||
td->blocks[i], td->emu_buf, mbs_per_slice,
|
td->blocks[i], td->emu_buf,
|
||||||
num_cblocks[i], is_chroma[i]);
|
mbs_per_slice, num_cblocks[i], is_chroma[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (q = min_quant; q < max_quant + 2; q++) {
|
for (q = min_quant; q < max_quant + 2; q++) {
|
||||||
@ -767,9 +774,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
bytestream_put_be16 (&buf, avctx->height);
|
bytestream_put_be16 (&buf, avctx->height);
|
||||||
|
|
||||||
frame_flags = ctx->chroma_factor << 6;
|
frame_flags = ctx->chroma_factor << 6;
|
||||||
if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
|
if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)
|
||||||
frame_flags |= pic->top_field_first ? 0x04 : 0x08;
|
frame_flags |= pic->top_field_first ? 0x04 : 0x08;
|
||||||
}
|
|
||||||
bytestream_put_byte (&buf, frame_flags);
|
bytestream_put_byte (&buf, frame_flags);
|
||||||
|
|
||||||
bytestream_put_byte (&buf, 0); // reserved
|
bytestream_put_byte (&buf, 0); // reserved
|
||||||
@ -791,7 +797,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
}
|
}
|
||||||
bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
|
bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
|
||||||
|
|
||||||
for (ctx->cur_picture_idx = 0; ctx->cur_picture_idx < ctx->pictures_per_frame; ++ctx->cur_picture_idx) {
|
for (ctx->cur_picture_idx = 0;
|
||||||
|
ctx->cur_picture_idx < ctx->pictures_per_frame;
|
||||||
|
ctx->cur_picture_idx++) {
|
||||||
// picture header
|
// picture header
|
||||||
picture_size_pos = buf + 1;
|
picture_size_pos = buf + 1;
|
||||||
bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
|
bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
|
||||||
@ -845,7 +853,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
frame_size = buf - orig_buf;
|
frame_size = buf - orig_buf;
|
||||||
bytestream_put_be32(&orig_buf, frame_size);
|
bytestream_put_be32(&orig_buf, frame_size);
|
||||||
|
|
||||||
|
|
||||||
pkt->size = frame_size;
|
pkt->size = frame_size;
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||||
*got_packet = 1;
|
*got_packet = 1;
|
||||||
@ -927,7 +934,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
|||||||
if (!ctx->force_quant) {
|
if (!ctx->force_quant) {
|
||||||
if (!ctx->bits_per_mb) {
|
if (!ctx->bits_per_mb) {
|
||||||
for (i = 0; i < NUM_MB_LIMITS - 1; i++)
|
for (i = 0; i < NUM_MB_LIMITS - 1; i++)
|
||||||
if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height * ctx->pictures_per_frame)
|
if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
|
||||||
|
ctx->pictures_per_frame)
|
||||||
break;
|
break;
|
||||||
ctx->bits_per_mb = ctx->profile_info->br_tab[i];
|
ctx->bits_per_mb = ctx->profile_info->br_tab[i];
|
||||||
} else if (ctx->bits_per_mb < 128) {
|
} else if (ctx->bits_per_mb < 128) {
|
||||||
@ -991,12 +999,15 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
|||||||
ctx->frame_size_upper_bound = ctx->pictures_per_frame *
|
ctx->frame_size_upper_bound = ctx->pictures_per_frame *
|
||||||
ctx->slices_per_picture *
|
ctx->slices_per_picture *
|
||||||
(2 + 2 * ctx->num_planes +
|
(2 + 2 * ctx->num_planes +
|
||||||
(mps * ctx->bits_per_mb) / 8) + 200;
|
(mps * ctx->bits_per_mb) / 8)
|
||||||
|
+ 200;
|
||||||
|
|
||||||
avctx->codec_tag = ctx->profile_info->tag;
|
avctx->codec_tag = ctx->profile_info->tag;
|
||||||
|
|
||||||
av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices/pic, %d pics/frame, %d bits per MB\n",
|
av_log(avctx, AV_LOG_DEBUG,
|
||||||
ctx->profile, ctx->slices_per_picture, ctx->pictures_per_frame, ctx->bits_per_mb);
|
"profile %d, %d slices, interlacing: %s, %d bits per MB\n",
|
||||||
|
ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
|
||||||
|
interlaced ? "yes" : "no", ctx->bits_per_mb);
|
||||||
av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
|
av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
|
||||||
ctx->frame_size_upper_bound);
|
ctx->frame_size_upper_bound);
|
||||||
|
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
|
#include "libavutil/internal.h"
|
||||||
|
#include "libavutil/mem.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *handle;
|
void *handle;
|
||||||
|
@ -5,7 +5,7 @@ OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
|
|||||||
|
|
||||||
MMX-OBJS += x86/dsputil_mmx.o \
|
MMX-OBJS += x86/dsputil_mmx.o \
|
||||||
x86/fdct_mmx.o \
|
x86/fdct_mmx.o \
|
||||||
x86/fmtconvert_mmx.o \
|
x86/fmtconvert_init.o \
|
||||||
x86/idct_mmx_xvid.o \
|
x86/idct_mmx_xvid.o \
|
||||||
x86/idct_sse2_xvid.o \
|
x86/idct_sse2_xvid.o \
|
||||||
x86/motion_est_mmx.o \
|
x86/motion_est_mmx.o \
|
||||||
@ -13,15 +13,15 @@ MMX-OBJS += x86/dsputil_mmx.o \
|
|||||||
x86/simple_idct_mmx.o \
|
x86/simple_idct_mmx.o \
|
||||||
|
|
||||||
MMX-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp_init.o
|
MMX-OBJS-$(CONFIG_AAC_DECODER) += x86/sbrdsp_init.o
|
||||||
MMX-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_mmx.o
|
MMX-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_init.o
|
||||||
MMX-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp_mmx.o
|
MMX-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp_mmx.o
|
||||||
MMX-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhd_mmx.o
|
MMX-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhd_mmx.o
|
||||||
MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o \
|
MMX-OBJS-$(CONFIG_DWT) += x86/snowdsp_mmx.o \
|
||||||
x86/dwt.o
|
x86/dwt.o
|
||||||
MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o
|
MMX-OBJS-$(CONFIG_ENCODERS) += x86/dsputilenc_mmx.o
|
||||||
MMX-OBJS-$(CONFIG_FFT) += x86/fft.o
|
MMX-OBJS-$(CONFIG_FFT) += x86/fft_init.o
|
||||||
MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o
|
MMX-OBJS-$(CONFIG_GPL) += x86/idct_mmx.o
|
||||||
MMX-OBJS-$(CONFIG_H264DSP) += x86/h264dsp_mmx.o
|
MMX-OBJS-$(CONFIG_H264DSP) += x86/h264dsp_init.o
|
||||||
MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o
|
MMX-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o
|
||||||
MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o
|
MMX-OBJS-$(CONFIG_LPC) += x86/lpc_mmx.o
|
||||||
MMX-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodec_mmx.o
|
MMX-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodec_mmx.o
|
||||||
|
@ -360,13 +360,5 @@ static int RENAME(dct_quantize)(MpegEncContext *s,
|
|||||||
block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
|
block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F];
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
/*
|
|
||||||
for(i=0; i<last_non_zero_p1; i++)
|
|
||||||
{
|
|
||||||
int j= zigzag_direct_noperm[i];
|
|
||||||
block[block_permute_op(j)]= temp_block[j];
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return last_non_zero_p1 - 1;
|
return last_non_zero_p1 - 1;
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,6 @@
|
|||||||
#define HMAC_IPAD_VAL 0x36
|
#define HMAC_IPAD_VAL 0x36
|
||||||
#define HMAC_OPAD_VAL 0x5C
|
#define HMAC_OPAD_VAL 0x5C
|
||||||
|
|
||||||
/**
|
|
||||||
* A non-zero transaction id requires the server to send back
|
|
||||||
* a _result or _error response.
|
|
||||||
* Setting it to 0 marks the message as a notification not
|
|
||||||
* requiring feedback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RTMP_NOTIFICATION 0
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* emulated Flash client version - 9.0.124.2 on Linux
|
* emulated Flash client version - 9.0.124.2 on Linux
|
||||||
* @{
|
* @{
|
||||||
|
@ -91,7 +91,11 @@ typedef struct RTMPContext {
|
|||||||
int nb_invokes; ///< keeps track of invoke messages
|
int nb_invokes; ///< keeps track of invoke messages
|
||||||
char* tcurl; ///< url of the target stream
|
char* tcurl; ///< url of the target stream
|
||||||
char* flashver; ///< version of the flash plugin
|
char* flashver; ///< version of the flash plugin
|
||||||
|
char* swfhash; ///< SHA256 hash of the decompressed SWF file (32 bytes)
|
||||||
|
int swfhash_len; ///< length of the SHA256 hash
|
||||||
|
int swfsize; ///< size of the decompressed SWF file
|
||||||
char* swfurl; ///< url of the swf player
|
char* swfurl; ///< url of the swf player
|
||||||
|
char swfverification[42]; ///< hash of the SWF verification
|
||||||
char* pageurl; ///< url of the web page
|
char* pageurl; ///< url of the web page
|
||||||
char* subscribe; ///< name of live stream to subscribe
|
char* subscribe; ///< name of live stream to subscribe
|
||||||
int server_bw; ///< server bandwidth
|
int server_bw; ///< server bandwidth
|
||||||
@ -592,6 +596,27 @@ static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
|
|||||||
return rtmp_send_packet(rt, &pkt, 0);
|
return rtmp_send_packet(rt, &pkt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate SWF verification message and send it to the server.
|
||||||
|
*/
|
||||||
|
static int gen_swf_verification(URLContext *s, RTMPContext *rt)
|
||||||
|
{
|
||||||
|
RTMPPacket pkt;
|
||||||
|
uint8_t *p;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
|
||||||
|
if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
|
||||||
|
0, 44)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
p = pkt.data;
|
||||||
|
bytestream_put_be16(&p, 27);
|
||||||
|
memcpy(p, rt->swfverification, 42);
|
||||||
|
|
||||||
|
return rtmp_send_packet(rt, &pkt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate server bandwidth message and send it to the server.
|
* Generate server bandwidth message and send it to the server.
|
||||||
*/
|
*/
|
||||||
@ -626,10 +651,10 @@ static int gen_check_bw(URLContext *s, RTMPContext *rt)
|
|||||||
|
|
||||||
p = pkt.data;
|
p = pkt.data;
|
||||||
ff_amf_write_string(&p, "_checkbw");
|
ff_amf_write_string(&p, "_checkbw");
|
||||||
ff_amf_write_number(&p, RTMP_NOTIFICATION);
|
ff_amf_write_number(&p, ++rt->nb_invokes);
|
||||||
ff_amf_write_null(&p);
|
ff_amf_write_null(&p);
|
||||||
|
|
||||||
return rtmp_send_packet(rt, &pkt, 0);
|
return rtmp_send_packet(rt, &pkt, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -776,6 +801,30 @@ static int rtmp_validate_digest(uint8_t *buf, int off)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
|
||||||
|
uint8_t *buf)
|
||||||
|
{
|
||||||
|
uint8_t *p;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (rt->swfhash_len != 32) {
|
||||||
|
av_log(s, AV_LOG_ERROR,
|
||||||
|
"Hash of the decompressed SWF file is not 32 bytes long.\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = &rt->swfverification[0];
|
||||||
|
bytestream_put_byte(&p, 1);
|
||||||
|
bytestream_put_byte(&p, 1);
|
||||||
|
bytestream_put_be32(&p, rt->swfsize);
|
||||||
|
bytestream_put_be32(&p, rt->swfsize);
|
||||||
|
|
||||||
|
if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform handshake with the server by means of exchanging pseudorandom data
|
* Perform handshake with the server by means of exchanging pseudorandom data
|
||||||
* signed with HMAC-SHA2 digest.
|
* signed with HMAC-SHA2 digest.
|
||||||
@ -866,6 +915,14 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
|
||||||
|
* key are the last 32 bytes of the server handshake. */
|
||||||
|
if (rt->swfsize) {
|
||||||
|
if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
|
||||||
|
RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
|
ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
|
||||||
rtmp_server_key, sizeof(rtmp_server_key),
|
rtmp_server_key, sizeof(rtmp_server_key),
|
||||||
digest);
|
digest);
|
||||||
@ -1001,6 +1058,13 @@ static int handle_ping(URLContext *s, RTMPPacket *pkt)
|
|||||||
if (t == 6) {
|
if (t == 6) {
|
||||||
if ((ret = gen_pong(s, rt, pkt)) < 0)
|
if ((ret = gen_pong(s, rt, pkt)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
} else if (t == 26) {
|
||||||
|
if (rt->swfsize) {
|
||||||
|
if ((ret = gen_swf_verification(s, rt)) < 0)
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1055,15 +1119,27 @@ static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
|
|||||||
static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
|
static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
|
||||||
{
|
{
|
||||||
const uint8_t *data_end = pkt->data + pkt->data_size;
|
const uint8_t *data_end = pkt->data + pkt->data_size;
|
||||||
|
char *tracked_method = NULL;
|
||||||
|
int level = AV_LOG_ERROR;
|
||||||
uint8_t tmpstr[256];
|
uint8_t tmpstr[256];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (!ff_amf_get_field_value(pkt->data + 9, data_end,
|
if (!ff_amf_get_field_value(pkt->data + 9, data_end,
|
||||||
"description", tmpstr, sizeof(tmpstr))) {
|
"description", tmpstr, sizeof(tmpstr))) {
|
||||||
av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
|
if (tracked_method && !strcmp(tracked_method, "_checkbw")) {
|
||||||
return -1;
|
/* Ignore _checkbw errors. */
|
||||||
|
level = AV_LOG_WARNING;
|
||||||
|
ret = 0;
|
||||||
|
} else
|
||||||
|
ret = -1;
|
||||||
|
av_log(s, level, "Server error: %s\n", tmpstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
av_free(tracked_method);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
|
static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
|
||||||
@ -1705,6 +1781,8 @@ static const AVOption rtmp_options[] = {
|
|||||||
{"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
|
{"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
|
||||||
{"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
{"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
||||||
{"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
|
{"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
|
||||||
|
{"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
|
||||||
|
{"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {0}, 0, INT_MAX, DEC},
|
||||||
{"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
{"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
||||||
{"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
{"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
|
||||||
{ NULL },
|
{ NULL },
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_MAJOR 54
|
#define LIBAVFORMAT_VERSION_MAJOR 54
|
||||||
#define LIBAVFORMAT_VERSION_MINOR 23
|
#define LIBAVFORMAT_VERSION_MINOR 23
|
||||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
#define LIBAVFORMAT_VERSION_MICRO 101
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||||
LIBAVFORMAT_VERSION_MINOR, \
|
LIBAVFORMAT_VERSION_MINOR, \
|
||||||
|
@ -335,7 +335,9 @@ int ff_audio_mix_init(AVAudioResampleContext *avr)
|
|||||||
avr->out_channel_layout,
|
avr->out_channel_layout,
|
||||||
avr->center_mix_level,
|
avr->center_mix_level,
|
||||||
avr->surround_mix_level,
|
avr->surround_mix_level,
|
||||||
avr->lfe_mix_level, 1, matrix_dbl,
|
avr->lfe_mix_level,
|
||||||
|
avr->normalize_mix_level,
|
||||||
|
matrix_dbl,
|
||||||
avr->in_channels,
|
avr->in_channels,
|
||||||
avr->matrix_encoding);
|
avr->matrix_encoding);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -45,6 +45,7 @@ struct AVAudioResampleContext {
|
|||||||
double center_mix_level; /**< center mix level */
|
double center_mix_level; /**< center mix level */
|
||||||
double surround_mix_level; /**< surround mix level */
|
double surround_mix_level; /**< surround mix level */
|
||||||
double lfe_mix_level; /**< lfe mix level */
|
double lfe_mix_level; /**< lfe mix level */
|
||||||
|
int normalize_mix_level; /**< enable mix level normalization */
|
||||||
int force_resampling; /**< force resampling */
|
int force_resampling; /**< force resampling */
|
||||||
int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
|
int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */
|
||||||
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
|
int phase_shift; /**< log2 of the number of entries in the resampling polyphase filterbank */
|
||||||
|
@ -47,6 +47,7 @@ static const AVOption options[] = {
|
|||||||
{ "center_mix_level", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM },
|
{ "center_mix_level", "Center Mix Level", OFFSET(center_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM },
|
||||||
{ "surround_mix_level", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM },
|
{ "surround_mix_level", "Surround Mix Level", OFFSET(surround_mix_level), AV_OPT_TYPE_DOUBLE, { M_SQRT1_2 }, -32.0, 32.0, PARAM },
|
||||||
{ "lfe_mix_level", "LFE Mix Level", OFFSET(lfe_mix_level), AV_OPT_TYPE_DOUBLE, { 0.0 }, -32.0, 32.0, PARAM },
|
{ "lfe_mix_level", "LFE Mix Level", OFFSET(lfe_mix_level), AV_OPT_TYPE_DOUBLE, { 0.0 }, -32.0, 32.0, PARAM },
|
||||||
|
{ "normalize_mix_level", "Normalize Mix Level", OFFSET(normalize_mix_level), AV_OPT_TYPE_INT, { 1 }, 0, 1, PARAM },
|
||||||
{ "force_resampling", "Force Resampling", OFFSET(force_resampling), AV_OPT_TYPE_INT, { 0 }, 0, 1, PARAM },
|
{ "force_resampling", "Force Resampling", OFFSET(force_resampling), AV_OPT_TYPE_INT, { 0 }, 0, 1, PARAM },
|
||||||
{ "filter_size", "Resampling Filter Size", OFFSET(filter_size), AV_OPT_TYPE_INT, { 16 }, 0, 32, /* ??? */ PARAM },
|
{ "filter_size", "Resampling Filter Size", OFFSET(filter_size), AV_OPT_TYPE_INT, { 16 }, 0, 32, /* ??? */ PARAM },
|
||||||
{ "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift), AV_OPT_TYPE_INT, { 10 }, 0, 30, /* ??? */ PARAM },
|
{ "phase_shift", "Resampling Phase Shift", OFFSET(phase_shift), AV_OPT_TYPE_INT, { 10 }, 0, 30, /* ??? */ PARAM },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user