Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/cmdutils.c b/cmdutils.c
- index 3d428f3eea..b7d55997bf 100644
- --- a/cmdutils.c
- +++ b/cmdutils.c
- @@ -1112,9 +1112,14 @@ static void print_program_info(int flags, int level)
- const char *indent = flags & INDENT? " " : "";
- av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
- - if (flags & SHOW_COPYRIGHT)
- + if (flags & SHOW_COPYRIGHT) {
- av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
- program_birth_year, CONFIG_THIS_YEAR);
- +#if CONFIG_SAMYGO_SRF
- + av_log(NULL, level, "\n srf decryption v0.1.3 (c) 2016-%d bugficks@samygo",
- + CONFIG_THIS_YEAR);
- +#endif
- + }
- av_log(NULL, level, "\n");
- av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
- diff --git a/configure b/configure
- index 9b5789ab83..e8118004bc 100755
- --- a/configure
- +++ b/configure
- @@ -281,11 +281,14 @@ External library support:
- --enable-decklink enable Blackmagic DeckLink I/O support [no]
- --enable-mediacodec enable Android MediaCodec support [no]
- --enable-netcdf enable NetCDF, needed for sofalizer filter [no]
- + --disable-nettle disable Nettle low-level cryptographic library [autodetect]
- --enable-openal enable OpenAL 1.1 capture support [no]
- --enable-opencl enable OpenCL code
- --enable-opengl enable OpenGL rendering [no]
- --enable-openssl enable openssl, needed for https support
- if gnutls is not used [no]
- + --disable-samygo-srf disable SamyGO PVR decryption
- + --disable-samygo-tsaudio disable SamyGO invalid TS audio stream workaround
- --disable-schannel disable SChannel SSP, needed for TLS support on
- Windows if openssl and gnutls are not used [autodetect]
- --disable-sdl2 disable sdl2 [autodetect]
- @@ -1586,6 +1589,7 @@ EXTERNAL_LIBRARY_LIST="
- libzvbi
- mediacodec
- netcdf
- + nettle
- openal
- opencl
- opengl
- @@ -1631,6 +1635,8 @@ FEATURE_LIST="
- hardcoded_tables
- omx_rpi
- runtime_cpudetect
- + samygo_srf
- + samygo_tsaudio
- safe_bitstream_reader
- shared
- small
- @@ -2940,15 +2946,17 @@ matroska_demuxer_suggest="bzlib lzo zlib"
- matroska_muxer_select="iso_media riffenc"
- mmf_muxer_select="riffenc"
- mov_demuxer_select="iso_media riffdec"
- -mov_demuxer_suggest="zlib"
- +mov_demuxer_suggest="zlib nettle"
- mov_muxer_select="iso_media riffenc rtpenc_chain"
- mp3_demuxer_select="mpegaudio_parser"
- mp4_muxer_select="mov_muxer"
- mpegts_demuxer_select="iso_media"
- +mpegts_demuxer_suggest="nettle"
- mpegts_muxer_select="adts_muxer latm_muxer"
- mpegtsraw_demuxer_select="mpegts_demuxer"
- mxf_d10_muxer_select="mxf_muxer"
- mxf_opatom_muxer_select="mxf_muxer"
- +mxf_muxer_suggest="nettle"
- nut_muxer_select="riffenc"
- nuv_demuxer_select="riffdec"
- oga_muxer_select="ogg_muxer"
- @@ -3284,6 +3292,8 @@ enable doc
- enable faan faandct faanidct
- enable optimizations
- enable runtime_cpudetect
- +enable samygo_srf
- +enable samygo_tsaudio
- enable safe_bitstream_reader
- enable static
- enable swscale_alpha
- @@ -5734,6 +5744,11 @@ enabled pthreads &&
- disabled zlib || check_lib zlib.h zlibVersion -lz || disable zlib
- disabled bzlib || check_lib bzlib.h BZ2_bzlibVersion -lbz2 || disable bzlib
- disabled lzma || check_lib lzma.h lzma_version_number -llzma || disable lzma
- +disabled nettle \
- + || require_pkg_config nettle nettle/aes.h nettle_aes_encrypt \
- + || check_lib2 nettle/aes.h nettle_aes_encrypt -lnettle \
- + || disable nettle
- +
- check_lib math.h sin -lm && LIBM="-lm"
- disabled crystalhd || check_lib "stdint.h libcrystalhd/libcrystalhd_if.h" DtsCrystalHDVersion -lcrystalhd || disable crystalhd
- diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
- index d1fe8742ff..8352d766ef 100644
- --- a/ffmpeg_opt.c
- +++ b/ffmpeg_opt.c
- @@ -644,6 +644,36 @@ static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *
- return avcodec_find_decoder(st->codecpar->codec_id);
- }
- +#if CONFIG_SAMYGO_TSAUDIO
- +static void sgo_fix_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
- +{
- + // bugficks@samygo
- + // Some PVRs have audio streams w/ 0 channels which will make ffmpeg abort.
- + // The workaround is to set those audio streams type to unknown and run
- + // ffmpeg w/ '-ignore_unknown' option.
- + if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && !st->codecpar->channel_layout) {
- + int i,j;
- + const AVCodecDescriptor *desc = avcodec_descriptor_get(st->codecpar->codec_id);
- +
- + for(i = 0; i < s->nb_programs; i++)
- + for(j = 0; j < s->programs[i]->nb_stream_indexes; j++)
- + if(s->programs[i]->stream_index[j] == st->index)
- + break;
- +
- + av_log(s, AV_LOG_ERROR, "[SamyGO] Invalid audio stream detected: stream #%d:%d (codec=%s, channels=0)\n", j, st->index, desc->name);
- + av_log(s, AV_LOG_WARNING, "[SamyGO] Setting audio stream codec_type=AVMEDIA_TYPE_UNKNOWN\n");
- +
- + st->codecpar->codec_type = AVMEDIA_TYPE_UNKNOWN;
- + //st->codecpar->codec_id = AV_CODEC_ID_NONE;
- +
- + if(!ignore_unknown_streams) {
- + ignore_unknown_streams = 1;
- + av_log(s, AV_LOG_WARNING, "[SamyGO] Setting option: -ignore_unknown\n");
- + }
- + }
- +}
- +#endif //#if CONFIG_SAMYGO_TSAUDIO
- +
- /* Add all the streams from the given input file to the global
- * list of input streams. */
- static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
- @@ -691,6 +721,11 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
- }
- ist->dec = choose_decoder(o, ic, st);
- +
- +#if CONFIG_SAMYGO_TSAUDIO
- + sgo_fix_decoder(o, ic, st);
- +#endif
- +
- ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec);
- ist->reinit_filters = -1;
- diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
- index 3eff1522bd..2af40229b1 100644
- --- a/libavformat/mpegts.c
- +++ b/libavformat/mpegts.c
- @@ -28,6 +28,7 @@
- #include "libavutil/mathematics.h"
- #include "libavutil/opt.h"
- #include "libavutil/avassert.h"
- +#include "libavutil/aes.h"
- #include "libavcodec/bytestream.h"
- #include "libavcodec/get_bits.h"
- #include "libavcodec/opus.h"
- @@ -159,6 +160,11 @@ struct MpegTSContext {
- /** filters for various streams specified by PMT + for the PAT and PMT */
- MpegTSFilter *pids[NB_PID_MAX];
- int current_pid;
- +
- +#if CONFIG_SAMYGO_SRF
- + struct AVAES *aes_decrypt;
- + uint8_t srf_key[16];
- +#endif
- };
- #define MPEGTS_OPTIONS \
- @@ -245,6 +251,119 @@ typedef struct PESContext {
- extern AVInputFormat ff_mpegts_demuxer;
- +//////////////////////////////////////////////////////////////////////////
- +
- +#if CONFIG_SAMYGO_SRF
- +
- +static int sgo_srf_decrypt_init(
- + AVFormatContext *s, MpegTSContext *ts)
- +{
- + int ret = 0;
- + char pathKey[sizeof(s->filename)] = { 0, };
- + AVIOContext *ioKey = 0;
- +
- + ts->aes_decrypt = 0;
- +
- + // if there is a key from -cryptokey option use that one otherwise try filename.[srf=key]
- + if(s->key)
- + {
- + if(s->keylen != sizeof(ts->srf_key))
- + return AVERROR_INVALIDDATA;
- +
- + memcpy(ts->srf_key, s->key, sizeof(ts->srf_key));
- + }
- + else
- + {
- + char *p = 0;
- + av_strlcpy(pathKey, s->filename, sizeof(pathKey));
- + p = av_strnstr(pathKey, ".srf", sizeof(pathKey));
- + if(!p)
- + return 0;
- +
- + p[1] = 'k';
- + p[2] = 'e';
- + p[3] = 'y';
- +
- + ret = avio_open(&ioKey, pathKey, AVIO_FLAG_READ);
- + if(ret)
- + return ret;
- +
- + ret = avio_read(ioKey, ts->srf_key, sizeof(ts->srf_key));
- + avio_closep(&ioKey);
- +
- + if(ret != sizeof(ts->srf_key))
- + return AVERROR_INVALIDDATA;
- + }
- +
- + av_log(ts->stream, AV_LOG_TRACE, "srf_key: ");
- + av_hex_dump_log(ts->stream, AV_LOG_TRACE, ts->srf_key, sizeof(ts->srf_key));
- +
- + ts->aes_decrypt = av_aes_alloc();
- + if(!ts->aes_decrypt)
- + ret = AVERROR(ENOMEM);
- + else
- + ret = av_aes_init(ts->aes_decrypt, ts->srf_key, sizeof(ts->srf_key) * 8, 1);
- +
- + return ret;
- +}
- +
- +static void sgo_srf_decrypt_deinit(
- + MpegTSContext *ts)
- +{
- + if(ts->aes_decrypt)
- + av_freep(&ts->aes_decrypt);
- +}
- +
- +static int sgo_srf_decrypt_packet(
- + MpegTSContext *ts, const uint8_t *packet)
- +{
- + const int _AES_BLOCK_SIZE = 16;
- +
- + uint8_t has_af = (packet[3] >> 5) & 1;
- + uint8_t scr_ctrl = (packet[3] >> 6) & 3;
- +
- + if(!ts->aes_decrypt)
- + {
- + if(scr_ctrl)
- + {
- + av_log(ts->stream, AV_LOG_ERROR, "sgo_srf_decrypt_packet: missing or invalid key for '%s'.\n", ts->stream->filename);
- + return AVERROR_INVALIDDATA;
- + }
- + }
- + else if(scr_ctrl)
- + {
- + uint8_t *data = (uint8_t *)packet;
- + int offset = 4;
- + int count = 0;
- +
- + if(scr_ctrl == 1)
- + {
- + // Samsung encrypted adaption field
- + has_af = 0;
- + }
- +
- + if(has_af)
- + {
- + // skip adaption field
- + offset += packet[4] + 1;
- + }
- +
- + // remove scrambling bits
- + data[3] &= (~(3 << 6)) & 0xFF;
- +
- + data += offset;
- + count = (TS_PACKET_SIZE - offset) / _AES_BLOCK_SIZE;
- +
- + av_aes_crypt(ts->aes_decrypt, data, data, count, 0, 1);
- + }
- +
- + return 0;
- +}
- +
- +#endif // #if CONFIG_SAMYGO_SRF
- +
- +//////////////////////////////////////////////////////////////////////////
- +
- static struct Program * get_program(MpegTSContext *ts, unsigned int programid)
- {
- int i;
- @@ -2296,6 +2415,11 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
- }
- }
- +#if CONFIG_SAMYGO_SRF
- + if(sgo_srf_decrypt_packet(ts, packet))
- + return AVERROR_INVALIDDATA;
- +#endif
- +
- p = packet + 4;
- if (has_adaptation) {
- int64_t pcr_h;
- @@ -2630,6 +2754,10 @@ static int mpegts_read_header(AVFormatContext *s)
- ts->stream = s;
- ts->auto_guess = 0;
- +#if CONFIG_SAMYGO_SRF
- + sgo_srf_decrypt_init(s, ts);
- +#endif
- +
- if (s->iformat == &ff_mpegts_demuxer) {
- /* normal demux */
- @@ -2797,6 +2925,10 @@ static void mpegts_free(MpegTSContext *ts)
- {
- int i;
- +#if CONFIG_SAMYGO_SRF
- + sgo_srf_decrypt_deinit(ts);
- +#endif
- +
- clear_programs(ts);
- for (i = 0; i < NB_PID_MAX; i++)
- @@ -2896,6 +3028,10 @@ MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s)
- mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
- mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
- +#if CONFIG_SAMYGO_SRF
- + sgo_srf_decrypt_init(s, ts);
- +#endif
- +
- return ts;
- }
- diff --git a/libavutil/aes.c b/libavutil/aes.c
- index 397ea77389..d051265bd2 100644
- --- a/libavutil/aes.c
- +++ b/libavutil/aes.c
- @@ -33,6 +33,54 @@ struct AVAES *av_aes_alloc(void)
- return av_mallocz(sizeof(struct AVAES));
- }
- +#if CONFIG_NETTLE
- +
- +int av_aes_init(
- + struct AVAES *a, const uint8_t *key, int key_bits, int decrypt)
- +{
- + int kl = key_bits >> 3;
- + switch(kl)
- + {
- + case 16:
- + case 24:
- + case 32:
- + break;
- + default:
- + return AVERROR(EINVAL);
- + }
- + if(decrypt)
- + aes_set_decrypt_key(&a->aes_ctx.ctx, kl, key);
- + else
- + aes_set_encrypt_key(&a->aes_ctx.ctx, kl, key);
- +
- + return 0;
- +}
- +
- +void av_aes_crypt(
- + AVAES *a, uint8_t *dst, const uint8_t *src, int count,
- + uint8_t *iv, int decrypt)
- +{
- + size_t len = count * AES_BLOCK_SIZE;
- +
- + if(iv)
- + {
- + CBC_SET_IV(&a->aes_ctx, iv);
- + if(decrypt)
- + CBC_DECRYPT(&a->aes_ctx, aes_decrypt, len, dst, src);
- + else
- + CBC_ENCRYPT(&a->aes_ctx, aes_encrypt, len, dst, src);
- + }
- + else
- + {
- + if(decrypt)
- + aes_decrypt(&a->aes_ctx.ctx, len, dst, src);
- + else
- + aes_encrypt(&a->aes_ctx.ctx, len, dst, src);
- + }
- +}
- +
- +#else /* !CONFIG_NETTLE */
- +
- static const uint8_t rcon[10] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
- };
- @@ -266,3 +314,4 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
- return 0;
- }
- +#endif /* #if CONFIG_NETTLE */
- diff --git a/libavutil/aes_internal.h b/libavutil/aes_internal.h
- index 494425878d..9eb1ddb3e6 100644
- --- a/libavutil/aes_internal.h
- +++ b/libavutil/aes_internal.h
- @@ -24,6 +24,20 @@
- #include "mem.h"
- #include <stdint.h>
- +#if CONFIG_NETTLE
- +
- +#include <nettle/aes.h>
- +#include <nettle/cbc.h>
- +
- +typedef struct AVAES {
- + DECLARE_ALIGNED(16, struct CBC_CTX(struct aes_ctx, AES_BLOCK_SIZE), aes_ctx);
- +
- + void (*crypt)(struct AVAES *ctx, uint8_t *iv_or_ctr, size_t length, uint8_t *dst, const uint8_t *src);
- +
- +} AVAES;
- +
- +#else /* !CONFIG_NETTLE */
- +
- typedef union {
- uint64_t u64[2];
- uint32_t u32[4];
- @@ -40,4 +54,6 @@ typedef struct AVAES {
- void (*crypt)(struct AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int rounds);
- } AVAES;
- +#endif /* #if CONFIG_NETTLE */
- +
- #endif /* AVUTIL_AES_INTERNAL_H */
- diff --git a/version.sh b/version.sh
- index edc4dd33c5..94d822f98b 100755
- --- a/version.sh
- +++ b/version.sh
- @@ -45,7 +45,7 @@ if [ -z "$2" ]; then
- exit
- fi
- -NEW_REVISION="#define FFMPEG_VERSION \"$version\""
- +NEW_REVISION="#define FFMPEG_VERSION \"$version [SamyGO]\""
- OLD_REVISION=$(cat "$2" 2> /dev/null | head -4 | tail -1)
- # String used for preprocessor guard
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement