* qatar/master:
swfdec: Add support for sample_rate_code 0 (5512 Hz)
dct-test: factor out some common code and do whas was likely intended
doc: library versions need to be bumped in version.h
Revert "ffmpeg: get rid of useless AVInputStream.nb_streams."
Remove some forgotten AVCodecContext.palctrl usage.
lavc/utils: move avcodec_init() higher in the file.
lavc: replace some deprecated FF_*_TYPE with AV_PICTURE_TYPE_*
ac3dec: actually use drc_scale private option
lavc: undeprecate AVPALETTE_SIZE and AVPALETTE_COUNT macros
alsa: add missing header
msmpeg4: remove leftover unused debug variable declaration
Fix assert() calls that need updates after FF_COMMON_FRAME macro elimination.
Fix av_dlog invocations with wrong or missing logging context.
vf_yadif: add support to yuva420p
vf_yadif: correct documentation on the parity parameter
vf_yadif: copy buffer properties like aspect for second frame as well
oma: support for encrypted files
id3v2: add support for non-text and GEOB type tag frames
des: add possibility to calculate DES-CBC-MAC with small buffer
Conflicts:
ffmpeg.c
libavcodec/dct-test.c
libavformat/mpegts.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
| ... | ... |
@@ -310,7 +310,7 @@ send a reminder by email. Your patch should eventually be dealt with. |
| 310 | 310 |
AVInputFormat/AVOutputFormat struct? |
| 311 | 311 |
@item |
| 312 | 312 |
Did you bump the minor version number (and reset the micro version |
| 313 |
- number) in @file{avcodec.h} or @file{avformat.h}?
|
|
| 313 |
+ number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
|
|
| 314 | 314 |
@item |
| 315 | 315 |
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
|
| 316 | 316 |
@item |
| ... | ... |
@@ -176,6 +176,11 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) |
| 176 | 176 |
AC3DecodeContext *s = avctx->priv_data; |
| 177 | 177 |
s->avctx = avctx; |
| 178 | 178 |
|
| 179 |
+#if FF_API_DRC_SCALE |
|
| 180 |
+ if (avctx->drc_scale) |
|
| 181 |
+ s->drc_scale = avctx->drc_scale; |
|
| 182 |
+#endif |
|
| 183 |
+ |
|
| 179 | 184 |
ff_ac3_common_init(); |
| 180 | 185 |
ac3_tables_init(); |
| 181 | 186 |
ff_mdct_init(&s->imdct_256, 8, 1, 1.0); |
| ... | ... |
@@ -788,7 +793,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) |
| 788 | 788 |
do {
|
| 789 | 789 |
if(get_bits1(gbc)) {
|
| 790 | 790 |
s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) * |
| 791 |
- s->avctx->drc_scale)+1.0; |
|
| 791 |
+ s->drc_scale)+1.0; |
|
| 792 | 792 |
} else if(blk == 0) {
|
| 793 | 793 |
s->dynamic_range[i] = 1.0f; |
| 794 | 794 |
} |
| ... | ... |
@@ -3149,6 +3149,8 @@ typedef struct AVPicture {
|
| 3149 | 3149 |
int linesize[4]; ///< number of bytes per line |
| 3150 | 3150 |
} AVPicture; |
| 3151 | 3151 |
|
| 3152 |
+#define AVPALETTE_SIZE 1024 |
|
| 3153 |
+#define AVPALETTE_COUNT 256 |
|
| 3152 | 3154 |
#if FF_API_PALETTE_CONTROL |
| 3153 | 3155 |
/** |
| 3154 | 3156 |
* AVPaletteControl |
| ... | ... |
@@ -3158,8 +3160,6 @@ typedef struct AVPicture {
|
| 3158 | 3158 |
* @deprecated Use AVPacket to send palette changes instead. |
| 3159 | 3159 |
* This is totally broken. |
| 3160 | 3160 |
*/ |
| 3161 |
-#define AVPALETTE_SIZE 1024 |
|
| 3162 |
-#define AVPALETTE_COUNT 256 |
|
| 3163 | 3161 |
typedef struct AVPaletteControl {
|
| 3164 | 3162 |
|
| 3165 | 3163 |
/* Demuxer sets this to 1 to indicate the palette has changed; |
| ... | ... |
@@ -199,6 +199,55 @@ static inline void mmx_emms(void) |
| 199 | 199 |
#endif |
| 200 | 200 |
} |
| 201 | 201 |
|
| 202 |
+static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng, int vals) |
|
| 203 |
+{
|
|
| 204 |
+ int i, j; |
|
| 205 |
+ |
|
| 206 |
+ memset(block, 0, 64 * sizeof(*block)); |
|
| 207 |
+ |
|
| 208 |
+ switch (test) {
|
|
| 209 |
+ case 0: |
|
| 210 |
+ for (i = 0; i < 64; i++) |
|
| 211 |
+ block[i] = (av_lfg_get(prng) % (2*vals)) -vals; |
|
| 212 |
+ if (is_idct) {
|
|
| 213 |
+ ff_ref_fdct(block); |
|
| 214 |
+ for (i = 0; i < 64; i++) |
|
| 215 |
+ block[i] >>= 3; |
|
| 216 |
+ } |
|
| 217 |
+ break; |
|
| 218 |
+ case 1: |
|
| 219 |
+ j = av_lfg_get(prng) % 10 + 1; |
|
| 220 |
+ for (i = 0; i < j; i++) |
|
| 221 |
+ block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % (2*vals) -vals; |
|
| 222 |
+ break; |
|
| 223 |
+ case 2: |
|
| 224 |
+ block[ 0] = av_lfg_get(prng) % (16*vals) - (8*vals); |
|
| 225 |
+ block[63] = (block[0] & 1) ^ 1; |
|
| 226 |
+ break; |
|
| 227 |
+ } |
|
| 228 |
+} |
|
| 229 |
+ |
|
| 230 |
+static void permute(DCTELEM dst[64], const DCTELEM src[64], int perm) |
|
| 231 |
+{
|
|
| 232 |
+ int i; |
|
| 233 |
+ |
|
| 234 |
+ if (perm == MMX_PERM) {
|
|
| 235 |
+ for (i = 0; i < 64; i++) |
|
| 236 |
+ dst[idct_mmx_perm[i]] = src[i]; |
|
| 237 |
+ } else if (perm == MMX_SIMPLE_PERM) {
|
|
| 238 |
+ for (i = 0; i < 64; i++) |
|
| 239 |
+ dst[idct_simple_mmx_perm[i]] = src[i]; |
|
| 240 |
+ } else if (perm == SSE2_PERM) {
|
|
| 241 |
+ for (i = 0; i < 64; i++) |
|
| 242 |
+ dst[(i & 0x38) | idct_sse2_row_perm[i & 7]] = src[i]; |
|
| 243 |
+ } else if (perm == PARTTRANS_PERM) {
|
|
| 244 |
+ for (i = 0; i < 64; i++) |
|
| 245 |
+ dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i]; |
|
| 246 |
+ } else {
|
|
| 247 |
+ for (i = 0; i < 64; i++) |
|
| 248 |
+ dst[i] = src[i]; |
|
| 249 |
+ } |
|
| 250 |
+} |
|
| 202 | 251 |
|
| 203 | 252 |
static int dct_error(const struct algo *dct, int test, int is_idct, int speed, const int bits) |
| 204 | 253 |
{
|
| ... | ... |
@@ -221,46 +270,8 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c |
| 221 | 221 |
for (i = 0; i < 64; i++) |
| 222 | 222 |
sysErr[i] = 0; |
| 223 | 223 |
for (it = 0; it < NB_ITS; it++) {
|
| 224 |
- for (i = 0; i < 64; i++) |
|
| 225 |
- block1[i] = 0; |
|
| 226 |
- switch (test) {
|
|
| 227 |
- case 0: |
|
| 228 |
- for (i = 0; i < 64; i++) |
|
| 229 |
- block1[i] = (av_lfg_get(&prng) % (2*vals)) -vals; |
|
| 230 |
- if (is_idct) {
|
|
| 231 |
- ff_ref_fdct(block1); |
|
| 232 |
- for (i = 0; i < 64; i++) |
|
| 233 |
- block1[i] >>= 3; |
|
| 234 |
- } |
|
| 235 |
- break; |
|
| 236 |
- case 1: {
|
|
| 237 |
- int num = av_lfg_get(&prng) % 10 + 1; |
|
| 238 |
- for (i = 0; i < num; i++) |
|
| 239 |
- block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 240 |
- } |
|
| 241 |
- break; |
|
| 242 |
- case 2: |
|
| 243 |
- block1[0] = av_lfg_get(&prng) % (16*vals) - (8*vals); |
|
| 244 |
- block1[63] = (block1[0] & 1) ^ 1; |
|
| 245 |
- break; |
|
| 246 |
- } |
|
| 247 |
- |
|
| 248 |
- if (dct->format == MMX_PERM) {
|
|
| 249 |
- for (i = 0; i < 64; i++) |
|
| 250 |
- block[idct_mmx_perm[i]] = block1[i]; |
|
| 251 |
- } else if (dct->format == MMX_SIMPLE_PERM) {
|
|
| 252 |
- for (i = 0; i < 64; i++) |
|
| 253 |
- block[idct_simple_mmx_perm[i]] = block1[i]; |
|
| 254 |
- } else if (dct->format == SSE2_PERM) {
|
|
| 255 |
- for (i = 0; i < 64; i++) |
|
| 256 |
- block[(i & 0x38) | idct_sse2_row_perm[i & 7]] = block1[i]; |
|
| 257 |
- } else if (dct->format == PARTTRANS_PERM) {
|
|
| 258 |
- for (i = 0; i < 64; i++) |
|
| 259 |
- block[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = block1[i]; |
|
| 260 |
- } else {
|
|
| 261 |
- for (i = 0; i < 64; i++) |
|
| 262 |
- block[i] = block1[i]; |
|
| 263 |
- } |
|
| 224 |
+ init_block(block1, test, is_idct, &prng, vals); |
|
| 225 |
+ permute(block, block1, dct->format); |
|
| 264 | 226 |
|
| 265 | 227 |
dct->func(block); |
| 266 | 228 |
mmx_emms(); |
| ... | ... |
@@ -317,45 +328,15 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c |
| 317 | 317 |
return 0; |
| 318 | 318 |
|
| 319 | 319 |
/* speed test */ |
| 320 |
- for (i = 0; i < 64; i++) |
|
| 321 |
- block1[i] = 0; |
|
| 322 |
- |
|
| 323 |
- switch (test) {
|
|
| 324 |
- case 0: |
|
| 325 |
- for (i = 0; i < 64; i++) |
|
| 326 |
- block1[i] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 327 |
- if (is_idct) {
|
|
| 328 |
- ff_ref_fdct(block1); |
|
| 329 |
- for (i = 0; i < 64; i++) |
|
| 330 |
- block1[i] >>= 3; |
|
| 331 |
- } |
|
| 332 |
- break; |
|
| 333 |
- case 1: |
|
| 334 |
- case 2: |
|
| 335 |
- block1[0] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 336 |
- block1[1] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 337 |
- block1[2] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 338 |
- block1[3] = av_lfg_get(&prng) % (2*vals) -vals; |
|
| 339 |
- break; |
|
| 340 |
- } |
|
| 341 | 320 |
|
| 342 |
- if (dct->format == MMX_PERM) {
|
|
| 343 |
- for (i = 0; i < 64; i++) |
|
| 344 |
- block[idct_mmx_perm[i]] = block1[i]; |
|
| 345 |
- } else if (dct->format == MMX_SIMPLE_PERM) {
|
|
| 346 |
- for (i = 0; i < 64; i++) |
|
| 347 |
- block[idct_simple_mmx_perm[i]] = block1[i]; |
|
| 348 |
- } else {
|
|
| 349 |
- for (i = 0; i < 64; i++) |
|
| 350 |
- block[i] = block1[i]; |
|
| 351 |
- } |
|
| 321 |
+ init_block(block, test, is_idct, &prng, vals); |
|
| 322 |
+ permute(block1, block, dct->format); |
|
| 352 | 323 |
|
| 353 | 324 |
ti = gettime(); |
| 354 | 325 |
it1 = 0; |
| 355 | 326 |
do {
|
| 356 | 327 |
for (it = 0; it < NB_ITS_SPEED; it++) {
|
| 357 |
- for (i = 0; i < 64; i++) |
|
| 358 |
- block[i] = block1[i]; |
|
| 328 |
+ memcpy(block, block1, sizeof(block)); |
|
| 359 | 329 |
dct->func(block); |
| 360 | 330 |
} |
| 361 | 331 |
it1 += NB_ITS_SPEED; |
| ... | ... |
@@ -620,8 +620,8 @@ retry: |
| 620 | 620 |
} |
| 621 | 621 |
MPV_frame_end(s); |
| 622 | 622 |
|
| 623 |
-assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type); |
|
| 624 |
-assert(s->current_picture.pict_type == s->pict_type); |
|
| 623 |
+assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); |
|
| 624 |
+assert(s->current_picture.f.pict_type == s->pict_type); |
|
| 625 | 625 |
*pict= *(AVFrame*)s->current_picture_ptr; |
| 626 | 626 |
ff_print_debug_info(s, pict); |
| 627 | 627 |
|
| ... | ... |
@@ -2774,7 +2774,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
|
| 2774 | 2774 |
if (s0->first_field) {
|
| 2775 | 2775 |
assert(s0->current_picture_ptr); |
| 2776 | 2776 |
assert(s0->current_picture_ptr->f.data[0]); |
| 2777 |
- assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF); |
|
| 2777 |
+ assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF); |
|
| 2778 | 2778 |
|
| 2779 | 2779 |
/* figure out if we have a complementary field pair */ |
| 2780 | 2780 |
if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {
|
| ... | ... |
@@ -172,7 +172,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
|
| 172 | 172 |
int mv[2]; |
| 173 | 173 |
int list; |
| 174 | 174 |
|
| 175 |
- assert(h->ref_list[1][0].reference&3); |
|
| 175 |
+ assert(h->ref_list[1][0].f.reference & 3); |
|
| 176 | 176 |
|
| 177 | 177 |
await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type)); |
| 178 | 178 |
|
| ... | ... |
@@ -416,7 +416,7 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
|
| 416 | 416 |
unsigned int sub_mb_type; |
| 417 | 417 |
int i8, i4; |
| 418 | 418 |
|
| 419 |
- assert(h->ref_list[1][0].reference&3); |
|
| 419 |
+ assert(h->ref_list[1][0].f.reference & 3); |
|
| 420 | 420 |
|
| 421 | 421 |
await_reference_mb_row(h, &h->ref_list[1][0], s->mb_y + !!IS_INTERLACED(*mb_type)); |
| 422 | 422 |
|
| ... | ... |
@@ -1176,7 +1176,7 @@ static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCode |
| 1176 | 1176 |
if (!ctx->mpeg_enc_ctx_allocated) |
| 1177 | 1177 |
memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext)); |
| 1178 | 1178 |
|
| 1179 |
- if (!(s->pict_type == FF_B_TYPE || s->low_delay)) |
|
| 1179 |
+ if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)) |
|
| 1180 | 1180 |
s->picture_number++; |
| 1181 | 1181 |
|
| 1182 | 1182 |
return 0; |
| ... | ... |
@@ -225,7 +225,7 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) |
| 225 | 225 |
int r; |
| 226 | 226 |
|
| 227 | 227 |
if (s->avctx->hwaccel) {
|
| 228 |
- assert(!pic->hwaccel_picture_private); |
|
| 228 |
+ assert(!pic->f.hwaccel_picture_private); |
|
| 229 | 229 |
if (s->avctx->hwaccel->priv_data_size) {
|
| 230 | 230 |
pic->f.hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size); |
| 231 | 231 |
if (!pic->f.hwaccel_picture_private) {
|
| ... | ... |
@@ -276,7 +276,7 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){
|
| 276 | 276 |
|
| 277 | 277 |
if(shared){
|
| 278 | 278 |
assert(pic->f.data[0]); |
| 279 |
- assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED); |
|
| 279 |
+ assert(pic->f.type == 0 || pic->f.type == FF_BUFFER_TYPE_SHARED); |
|
| 280 | 280 |
pic->f.type = FF_BUFFER_TYPE_SHARED; |
| 281 | 281 |
}else{
|
| 282 | 282 |
assert(!pic->f.data[0]); |
| ... | ... |
@@ -539,7 +539,7 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src |
| 539 | 539 |
s->last_pict_type= s1->pict_type; |
| 540 | 540 |
if (s1->current_picture_ptr) s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality; |
| 541 | 541 |
|
| 542 |
- if(s1->pict_type!=FF_B_TYPE){
|
|
| 542 |
+ if (s1->pict_type != AV_PICTURE_TYPE_B) {
|
|
| 543 | 543 |
s->last_non_b_pict_type= s1->pict_type; |
| 544 | 544 |
} |
| 545 | 545 |
} |
| ... | ... |
@@ -2662,6 +2662,6 @@ void ff_set_qscale(MpegEncContext * s, int qscale) |
| 2662 | 2662 |
|
| 2663 | 2663 |
void MPV_report_decode_progress(MpegEncContext *s) |
| 2664 | 2664 |
{
|
| 2665 |
- if (s->pict_type != FF_B_TYPE && !s->partitioned_frame && !s->error_occurred) |
|
| 2665 |
+ if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->error_occurred) |
|
| 2666 | 2666 |
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, s->mb_y, 0); |
| 2667 | 2667 |
} |
| ... | ... |
@@ -1093,8 +1093,8 @@ static int select_input_picture(MpegEncContext *s){
|
| 1093 | 1093 |
s->input_picture[0]->f.data[i] = NULL; |
| 1094 | 1094 |
s->input_picture[0]->f.type = 0; |
| 1095 | 1095 |
}else{
|
| 1096 |
- assert( s->input_picture[0]->type==FF_BUFFER_TYPE_USER |
|
| 1097 |
- || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); |
|
| 1096 |
+ assert( s->input_picture[0]->f.type == FF_BUFFER_TYPE_USER |
|
| 1097 |
+ || s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL); |
|
| 1098 | 1098 |
|
| 1099 | 1099 |
s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]); |
| 1100 | 1100 |
} |
| ... | ... |
@@ -1220,8 +1220,8 @@ no_output_pic: |
| 1220 | 1220 |
}else{
|
| 1221 | 1221 |
// input is not a shared pix -> reuse buffer for current_pix |
| 1222 | 1222 |
|
| 1223 |
- assert( s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER |
|
| 1224 |
- || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL); |
|
| 1223 |
+ assert( s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_USER |
|
| 1224 |
+ || s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL); |
|
| 1225 | 1225 |
|
| 1226 | 1226 |
s->current_picture_ptr= s->reordered_input_picture[0]; |
| 1227 | 1227 |
for(i=0; i<4; i++){
|
| ... | ... |
@@ -2757,7 +2757,7 @@ static int estimate_qp(MpegEncContext *s, int dry_run){
|
| 2757 | 2757 |
|
| 2758 | 2758 |
/* must be called before writing the header */ |
| 2759 | 2759 |
static void set_frame_distances(MpegEncContext * s){
|
| 2760 |
- assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE); |
|
| 2760 |
+ assert(s->current_picture_ptr->f.pts != AV_NOPTS_VALUE); |
|
| 2761 | 2761 |
s->time = s->current_picture_ptr->f.pts * s->avctx->time_base.num; |
| 2762 | 2762 |
|
| 2763 | 2763 |
if(s->pict_type==AV_PICTURE_TYPE_B){
|
| ... | ... |
@@ -62,10 +62,6 @@ static uint32_t v2_dc_chroma_table[512][2]; |
| 62 | 62 |
/* vc1 externs */ |
| 63 | 63 |
extern const uint8_t wmv3_dc_scale_table[32]; |
| 64 | 64 |
|
| 65 |
-#ifdef DEBUG |
|
| 66 |
-int frame_count = 0; |
|
| 67 |
-#endif |
|
| 68 |
- |
|
| 69 | 65 |
#include "msmpeg4data.h" |
| 70 | 66 |
|
| 71 | 67 |
#if CONFIG_ENCODERS //strangely gcc includes this even if it is not referenced |
| ... | ... |
@@ -448,7 +448,7 @@ static const AVOption options[]={
|
| 448 | 448 |
{"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, 0, INT_MAX, A|D},
|
| 449 | 449 |
#endif |
| 450 | 450 |
#if FF_API_DRC_SCALE |
| 451 |
-{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, {.dbl = 1.0 }, 0.0, 1.0, A|D},
|
|
| 451 |
+{"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, {.dbl = 0.0 }, 0.0, 1.0, A|D},
|
|
| 452 | 452 |
#endif |
| 453 | 453 |
#if FF_API_LAME_GLOBAL_OPTS |
| 454 | 454 |
{"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, {.dbl = CODEC_FLAG2_BIT_RESERVOIR }, INT_MIN, INT_MAX, A|E, "flags2"},
|
| ... | ... |
@@ -544,7 +544,6 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_typ |
| 544 | 544 |
s->pix_fmt= PIX_FMT_NONE; |
| 545 | 545 |
s->sample_fmt= AV_SAMPLE_FMT_NONE; |
| 546 | 546 |
|
| 547 |
- s->palctrl = NULL; |
|
| 548 | 547 |
s->reget_buffer= avcodec_default_reget_buffer; |
| 549 | 548 |
s->reordered_opaque= AV_NOPTS_VALUE; |
| 550 | 549 |
} |
| ... | ... |
@@ -623,7 +622,6 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) |
| 623 | 623 |
/* set values specific to opened codecs back to their default state */ |
| 624 | 624 |
dest->priv_data = NULL; |
| 625 | 625 |
dest->codec = NULL; |
| 626 |
- dest->palctrl = NULL; |
|
| 627 | 626 |
dest->slice_offset = NULL; |
| 628 | 627 |
dest->internal_buffer = NULL; |
| 629 | 628 |
dest->hwaccel = NULL; |
| ... | ... |
@@ -85,6 +85,20 @@ AVCodec *av_codec_next(AVCodec *c){
|
| 85 | 85 |
else return first_avcodec; |
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 |
+#if !FF_API_AVCODEC_INIT |
|
| 89 |
+static |
|
| 90 |
+#endif |
|
| 91 |
+void avcodec_init(void) |
|
| 92 |
+{
|
|
| 93 |
+ static int initialized = 0; |
|
| 94 |
+ |
|
| 95 |
+ if (initialized != 0) |
|
| 96 |
+ return; |
|
| 97 |
+ initialized = 1; |
|
| 98 |
+ |
|
| 99 |
+ dsputil_static_init(); |
|
| 100 |
+} |
|
| 101 |
+ |
|
| 88 | 102 |
void avcodec_register(AVCodec *codec) |
| 89 | 103 |
{
|
| 90 | 104 |
AVCodec **p; |
| ... | ... |
@@ -1144,20 +1158,6 @@ const char *avcodec_license(void) |
| 1144 | 1144 |
return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1; |
| 1145 | 1145 |
} |
| 1146 | 1146 |
|
| 1147 |
-#if !FF_API_AVCODEC_INIT |
|
| 1148 |
-static |
|
| 1149 |
-#endif |
|
| 1150 |
-void avcodec_init(void) |
|
| 1151 |
-{
|
|
| 1152 |
- static int initialized = 0; |
|
| 1153 |
- |
|
| 1154 |
- if (initialized != 0) |
|
| 1155 |
- return; |
|
| 1156 |
- initialized = 1; |
|
| 1157 |
- |
|
| 1158 |
- dsputil_static_init(); |
|
| 1159 |
-} |
|
| 1160 |
- |
|
| 1161 | 1147 |
void avcodec_flush_buffers(AVCodecContext *avctx) |
| 1162 | 1148 |
{
|
| 1163 | 1149 |
if(HAVE_PTHREADS && avctx->active_thread_type&FF_THREAD_FRAME) |
| ... | ... |
@@ -66,63 +66,129 @@ static unsigned int get_size(AVIOContext *s, int len) |
| 66 | 66 |
return v; |
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 |
-static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key) |
|
| 69 |
+/** |
|
| 70 |
+ * Free GEOB type extra metadata. |
|
| 71 |
+ */ |
|
| 72 |
+static void free_geobtag(ID3v2ExtraMetaGEOB *geob) |
|
| 70 | 73 |
{
|
| 71 |
- char *q, dst[512]; |
|
| 72 |
- const char *val = NULL; |
|
| 73 |
- int len, dstlen = sizeof(dst) - 1; |
|
| 74 |
- unsigned genre; |
|
| 75 |
- unsigned int (*get)(AVIOContext*) = avio_rb16; |
|
| 74 |
+ av_free(geob->mime_type); |
|
| 75 |
+ av_free(geob->file_name); |
|
| 76 |
+ av_free(geob->description); |
|
| 77 |
+ av_free(geob->data); |
|
| 78 |
+ av_free(geob); |
|
| 79 |
+} |
|
| 76 | 80 |
|
| 77 |
- dst[0] = 0; |
|
| 78 |
- if (taglen < 1) |
|
| 79 |
- return; |
|
| 81 |
+/** |
|
| 82 |
+ * Decode characters to UTF-8 according to encoding type. The decoded buffer is |
|
| 83 |
+ * always null terminated. |
|
| 84 |
+ * |
|
| 85 |
+ * @param dst Pointer where the address of the buffer with the decoded bytes is |
|
| 86 |
+ * stored. Buffer must be freed by caller. |
|
| 87 |
+ * @param dstlen Pointer to an int where the length of the decoded string |
|
| 88 |
+ * is stored (in bytes, incl. null termination) |
|
| 89 |
+ * @param maxread Pointer to maximum number of characters to read from the |
|
| 90 |
+ * AVIOContext. After execution the value is decremented by the number of bytes |
|
| 91 |
+ * actually read. |
|
| 92 |
+ * @seeknull If true, decoding stops after the first U+0000 character found, if |
|
| 93 |
+ * there is any before maxread is reached |
|
| 94 |
+ * @returns 0 if no error occured, dst is uninitialized on error |
|
| 95 |
+ */ |
|
| 96 |
+static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, |
|
| 97 |
+ uint8_t **dst, int *dstlen, int *maxread, const int seeknull) |
|
| 98 |
+{
|
|
| 99 |
+ int len, ret; |
|
| 100 |
+ uint8_t tmp; |
|
| 101 |
+ uint32_t ch = 1; |
|
| 102 |
+ int left = *maxread; |
|
| 103 |
+ unsigned int (*get)(AVIOContext*) = avio_rb16; |
|
| 104 |
+ AVIOContext *dynbuf; |
|
| 80 | 105 |
|
| 81 |
- taglen--; /* account for encoding type byte */ |
|
| 106 |
+ if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
|
|
| 107 |
+ av_log(s, AV_LOG_ERROR, "Error opening memory stream\n"); |
|
| 108 |
+ return ret; |
|
| 109 |
+ } |
|
| 82 | 110 |
|
| 83 |
- switch (avio_r8(pb)) { /* encoding type */
|
|
| 111 |
+ switch (encoding) {
|
|
| 84 | 112 |
|
| 85 | 113 |
case ID3v2_ENCODING_ISO8859: |
| 86 |
- q = dst; |
|
| 87 |
- while (taglen-- && q - dst < dstlen - 7) {
|
|
| 88 |
- uint8_t tmp; |
|
| 89 |
- PUT_UTF8(avio_r8(pb), tmp, *q++ = tmp;) |
|
| 114 |
+ while (left && (!seeknull || ch)) {
|
|
| 115 |
+ ch = avio_r8(pb); |
|
| 116 |
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) |
|
| 117 |
+ left--; |
|
| 90 | 118 |
} |
| 91 |
- *q = 0; |
|
| 92 | 119 |
break; |
| 93 | 120 |
|
| 94 | 121 |
case ID3v2_ENCODING_UTF16BOM: |
| 95 |
- taglen -= 2; |
|
| 122 |
+ if ((left -= 2) < 0) {
|
|
| 123 |
+ av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n"); |
|
| 124 |
+ avio_close_dyn_buf(dynbuf, (uint8_t **)dst); |
|
| 125 |
+ av_freep(dst); |
|
| 126 |
+ return AVERROR_INVALIDDATA; |
|
| 127 |
+ } |
|
| 96 | 128 |
switch (avio_rb16(pb)) {
|
| 97 | 129 |
case 0xfffe: |
| 98 | 130 |
get = avio_rl16; |
| 99 | 131 |
case 0xfeff: |
| 100 | 132 |
break; |
| 101 | 133 |
default: |
| 102 |
- av_log(s, AV_LOG_ERROR, "Incorrect BOM value in tag %s.\n", key); |
|
| 103 |
- return; |
|
| 134 |
+ av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n"); |
|
| 135 |
+ avio_close_dyn_buf(dynbuf, (uint8_t **)dst); |
|
| 136 |
+ av_freep(dst); |
|
| 137 |
+ *maxread = left; |
|
| 138 |
+ return AVERROR_INVALIDDATA; |
|
| 104 | 139 |
} |
| 105 | 140 |
// fall-through |
| 106 | 141 |
|
| 107 | 142 |
case ID3v2_ENCODING_UTF16BE: |
| 108 |
- q = dst; |
|
| 109 |
- while (taglen > 1 && q - dst < dstlen - 7) {
|
|
| 110 |
- uint32_t ch; |
|
| 111 |
- uint8_t tmp; |
|
| 112 |
- |
|
| 113 |
- GET_UTF16(ch, ((taglen -= 2) >= 0 ? get(pb) : 0), break;) |
|
| 114 |
- PUT_UTF8(ch, tmp, *q++ = tmp;) |
|
| 143 |
+ while ((left > 1) && (!seeknull || ch)) {
|
|
| 144 |
+ GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;) |
|
| 145 |
+ PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) |
|
| 115 | 146 |
} |
| 116 |
- *q = 0; |
|
| 147 |
+ if (left < 0) |
|
| 148 |
+ left += 2; /* did not read last char from pb */ |
|
| 117 | 149 |
break; |
| 118 | 150 |
|
| 119 | 151 |
case ID3v2_ENCODING_UTF8: |
| 120 |
- len = FFMIN(taglen, dstlen); |
|
| 121 |
- avio_read(pb, dst, len); |
|
| 122 |
- dst[len] = 0; |
|
| 152 |
+ while (left && (!seeknull || ch)) {
|
|
| 153 |
+ ch = avio_r8(pb); |
|
| 154 |
+ avio_w8(dynbuf, ch); |
|
| 155 |
+ left--; |
|
| 156 |
+ } |
|
| 123 | 157 |
break; |
| 124 | 158 |
default: |
| 125 |
- av_log(s, AV_LOG_WARNING, "Unknown encoding in tag %s.\n", key); |
|
| 159 |
+ av_log(s, AV_LOG_WARNING, "Unknown encoding\n"); |
|
| 160 |
+ } |
|
| 161 |
+ |
|
| 162 |
+ if (ch) |
|
| 163 |
+ avio_w8(dynbuf, 0); |
|
| 164 |
+ |
|
| 165 |
+ len = avio_close_dyn_buf(dynbuf, (uint8_t **)dst); |
|
| 166 |
+ if (dstlen) |
|
| 167 |
+ *dstlen = len; |
|
| 168 |
+ |
|
| 169 |
+ *maxread = left; |
|
| 170 |
+ |
|
| 171 |
+ return 0; |
|
| 172 |
+} |
|
| 173 |
+ |
|
| 174 |
+/** |
|
| 175 |
+ * Parse a text tag. |
|
| 176 |
+ */ |
|
| 177 |
+static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key) |
|
| 178 |
+{
|
|
| 179 |
+ uint8_t *dst; |
|
| 180 |
+ const char *val = NULL; |
|
| 181 |
+ int len, dstlen; |
|
| 182 |
+ unsigned genre; |
|
| 183 |
+ |
|
| 184 |
+ if (taglen < 1) |
|
| 185 |
+ return; |
|
| 186 |
+ |
|
| 187 |
+ taglen--; /* account for encoding type byte */ |
|
| 188 |
+ |
|
| 189 |
+ if (decode_str(s, pb, avio_r8(pb), &dst, &dstlen, &taglen, 0) < 0) {
|
|
| 190 |
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); |
|
| 191 |
+ return; |
|
| 126 | 192 |
} |
| 127 | 193 |
|
| 128 | 194 |
if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) |
| ... | ... |
@@ -141,6 +207,82 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const cha |
| 141 | 141 |
|
| 142 | 142 |
if (val) |
| 143 | 143 |
av_dict_set(&s->metadata, key, val, AV_DICT_DONT_OVERWRITE); |
| 144 |
+ |
|
| 145 |
+ av_free(dst); |
|
| 146 |
+} |
|
| 147 |
+ |
|
| 148 |
+/** |
|
| 149 |
+ * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct. |
|
| 150 |
+ */ |
|
| 151 |
+static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta) |
|
| 152 |
+{
|
|
| 153 |
+ ID3v2ExtraMetaGEOB *geob_data = NULL; |
|
| 154 |
+ ID3v2ExtraMeta *new_extra = NULL; |
|
| 155 |
+ char encoding; |
|
| 156 |
+ unsigned int len; |
|
| 157 |
+ |
|
| 158 |
+ if (taglen < 1) |
|
| 159 |
+ return; |
|
| 160 |
+ |
|
| 161 |
+ geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB)); |
|
| 162 |
+ if (!geob_data) {
|
|
| 163 |
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB)); |
|
| 164 |
+ return; |
|
| 165 |
+ } |
|
| 166 |
+ |
|
| 167 |
+ new_extra = av_mallocz(sizeof(ID3v2ExtraMeta)); |
|
| 168 |
+ if (!new_extra) {
|
|
| 169 |
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta)); |
|
| 170 |
+ goto fail; |
|
| 171 |
+ } |
|
| 172 |
+ |
|
| 173 |
+ /* read encoding type byte */ |
|
| 174 |
+ encoding = avio_r8(pb); |
|
| 175 |
+ taglen--; |
|
| 176 |
+ |
|
| 177 |
+ /* read MIME type (always ISO-8859) */ |
|
| 178 |
+ if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, NULL, &taglen, 1) < 0 |
|
| 179 |
+ || taglen <= 0) |
|
| 180 |
+ goto fail; |
|
| 181 |
+ |
|
| 182 |
+ /* read file name */ |
|
| 183 |
+ if (decode_str(s, pb, encoding, &geob_data->file_name, NULL, &taglen, 1) < 0 |
|
| 184 |
+ || taglen <= 0) |
|
| 185 |
+ goto fail; |
|
| 186 |
+ |
|
| 187 |
+ /* read content description */ |
|
| 188 |
+ if (decode_str(s, pb, encoding, &geob_data->description, NULL, &taglen, 1) < 0 |
|
| 189 |
+ || taglen < 0) |
|
| 190 |
+ goto fail; |
|
| 191 |
+ |
|
| 192 |
+ if (taglen) {
|
|
| 193 |
+ /* save encapsulated binary data */ |
|
| 194 |
+ geob_data->data = av_malloc(taglen); |
|
| 195 |
+ if (!geob_data->data) {
|
|
| 196 |
+ av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen); |
|
| 197 |
+ goto fail; |
|
| 198 |
+ } |
|
| 199 |
+ if ((len = avio_read(pb, geob_data->data, taglen)) < taglen) |
|
| 200 |
+ av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n"); |
|
| 201 |
+ geob_data->datasize = len; |
|
| 202 |
+ } else {
|
|
| 203 |
+ geob_data->data = NULL; |
|
| 204 |
+ geob_data->datasize = 0; |
|
| 205 |
+ } |
|
| 206 |
+ |
|
| 207 |
+ /* add data to the list */ |
|
| 208 |
+ new_extra->tag = "GEOB"; |
|
| 209 |
+ new_extra->data = geob_data; |
|
| 210 |
+ new_extra->next = *extra_meta; |
|
| 211 |
+ *extra_meta = new_extra; |
|
| 212 |
+ |
|
| 213 |
+ return; |
|
| 214 |
+ |
|
| 215 |
+fail: |
|
| 216 |
+ av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag); |
|
| 217 |
+ free_geobtag(geob_data); |
|
| 218 |
+ av_free(new_extra); |
|
| 219 |
+ return; |
|
| 144 | 220 |
} |
| 145 | 221 |
|
| 146 | 222 |
static int is_number(const char *str) |
| ... | ... |
@@ -189,7 +331,27 @@ finish: |
| 189 | 189 |
av_dict_set(m, "date", date, 0); |
| 190 | 190 |
} |
| 191 | 191 |
|
| 192 |
-static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags) |
|
| 192 |
+/** |
|
| 193 |
+ * Get the corresponding ID3v2EMFunc struct for a tag. |
|
| 194 |
+ * @param isv34 Determines if v2.2 or v2.3/4 strings are used |
|
| 195 |
+ * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise. |
|
| 196 |
+ */ |
|
| 197 |
+static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34) |
|
| 198 |
+{
|
|
| 199 |
+ int i = 0; |
|
| 200 |
+ while (ff_id3v2_extra_meta_funcs[i].tag3) {
|
|
| 201 |
+ if (!memcmp(tag, |
|
| 202 |
+ (isv34 ? |
|
| 203 |
+ ff_id3v2_extra_meta_funcs[i].tag4 : |
|
| 204 |
+ ff_id3v2_extra_meta_funcs[i].tag3), |
|
| 205 |
+ (isv34 ? 4 : 3))) |
|
| 206 |
+ return &ff_id3v2_extra_meta_funcs[i]; |
|
| 207 |
+ i++; |
|
| 208 |
+ } |
|
| 209 |
+ return NULL; |
|
| 210 |
+} |
|
| 211 |
+ |
|
| 212 |
+static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta) |
|
| 193 | 213 |
{
|
| 194 | 214 |
int isv34, unsync; |
| 195 | 215 |
unsigned tlen; |
| ... | ... |
@@ -198,8 +360,10 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t |
| 198 | 198 |
int taghdrlen; |
| 199 | 199 |
const char *reason = NULL; |
| 200 | 200 |
AVIOContext pb; |
| 201 |
+ AVIOContext *pbx; |
|
| 201 | 202 |
unsigned char *buffer = NULL; |
| 202 | 203 |
int buffer_size = 0; |
| 204 |
+ void (*extra_func)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta**) = NULL; |
|
| 203 | 205 |
|
| 204 | 206 |
switch (version) {
|
| 205 | 207 |
case 2: |
| ... | ... |
@@ -264,7 +428,8 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t |
| 264 | 264 |
if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {
|
| 265 | 265 |
av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag); |
| 266 | 266 |
avio_skip(s->pb, tlen); |
| 267 |
- } else if (tag[0] == 'T') {
|
|
| 267 |
+ /* check for text tag or supported special meta tag */ |
|
| 268 |
+ } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)->read))) {
|
|
| 268 | 269 |
if (unsync || tunsync) {
|
| 269 | 270 |
int i, j; |
| 270 | 271 |
av_fast_malloc(&buffer, &buffer_size, tlen); |
| ... | ... |
@@ -280,10 +445,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t |
| 280 | 280 |
} |
| 281 | 281 |
} |
| 282 | 282 |
ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL); |
| 283 |
- read_ttag(s, &pb, j, tag); |
|
| 283 |
+ tlen = j; |
|
| 284 |
+ pbx = &pb; // read from sync buffer |
|
| 284 | 285 |
} else {
|
| 285 |
- read_ttag(s, s->pb, tlen, tag); |
|
| 286 |
+ pbx = s->pb; // read straight from input |
|
| 286 | 287 |
} |
| 288 |
+ if (tag[0] == 'T') |
|
| 289 |
+ /* parse text tag */ |
|
| 290 |
+ read_ttag(s, pbx, tlen, tag); |
|
| 291 |
+ else |
|
| 292 |
+ /* parse special meta tag */ |
|
| 293 |
+ extra_func(s, pbx, tlen, tag, extra_meta); |
|
| 287 | 294 |
} |
| 288 | 295 |
else if (!tag[0]) {
|
| 289 | 296 |
if (tag[1]) |
| ... | ... |
@@ -307,7 +479,7 @@ seek: |
| 307 | 307 |
return; |
| 308 | 308 |
} |
| 309 | 309 |
|
| 310 |
-void ff_id3v2_read(AVFormatContext *s, const char *magic) |
|
| 310 |
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta) |
|
| 311 | 311 |
{
|
| 312 | 312 |
int len, ret; |
| 313 | 313 |
uint8_t buf[ID3v2_HEADER_SIZE]; |
| ... | ... |
@@ -327,7 +499,7 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic) |
| 327 | 327 |
((buf[7] & 0x7f) << 14) | |
| 328 | 328 |
((buf[8] & 0x7f) << 7) | |
| 329 | 329 |
(buf[9] & 0x7f); |
| 330 |
- ff_id3v2_parse(s, len, buf[3], buf[5]); |
|
| 330 |
+ ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta); |
|
| 331 | 331 |
} else {
|
| 332 | 332 |
avio_seek(s->pb, off, SEEK_SET); |
| 333 | 333 |
} |
| ... | ... |
@@ -338,6 +510,30 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic) |
| 338 | 338 |
merge_date(&s->metadata); |
| 339 | 339 |
} |
| 340 | 340 |
|
| 341 |
+void ff_id3v2_read(AVFormatContext *s, const char *magic) |
|
| 342 |
+{
|
|
| 343 |
+ ff_id3v2_read_all(s, magic, NULL); |
|
| 344 |
+} |
|
| 345 |
+ |
|
| 346 |
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta) |
|
| 347 |
+{
|
|
| 348 |
+ ID3v2ExtraMeta *current = *extra_meta, *next; |
|
| 349 |
+ void (*free_func)(ID3v2ExtraMeta*); |
|
| 350 |
+ |
|
| 351 |
+ while (current) {
|
|
| 352 |
+ if ((free_func = get_extra_meta_func(current->tag, 1)->free)) |
|
| 353 |
+ free_func(current->data); |
|
| 354 |
+ next = current->next; |
|
| 355 |
+ av_freep(¤t); |
|
| 356 |
+ current = next; |
|
| 357 |
+ } |
|
| 358 |
+} |
|
| 359 |
+ |
|
| 360 |
+const ID3v2EMFunc ff_id3v2_extra_meta_funcs[] = {
|
|
| 361 |
+ { "GEO", "GEOB", read_geobtag, free_geobtag },
|
|
| 362 |
+ { NULL }
|
|
| 363 |
+}; |
|
| 364 |
+ |
|
| 341 | 365 |
const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
|
| 342 | 366 |
{ "TALB", "album"},
|
| 343 | 367 |
{ "TCOM", "composer"},
|
| ... | ... |
@@ -45,6 +45,27 @@ enum ID3v2Encoding {
|
| 45 | 45 |
ID3v2_ENCODING_UTF8 = 3, |
| 46 | 46 |
}; |
| 47 | 47 |
|
| 48 |
+typedef struct ID3v2ExtraMeta {
|
|
| 49 |
+ const char *tag; |
|
| 50 |
+ void *data; |
|
| 51 |
+ struct ID3v2ExtraMeta *next; |
|
| 52 |
+} ID3v2ExtraMeta; |
|
| 53 |
+ |
|
| 54 |
+typedef struct ID3v2ExtraMetaGEOB {
|
|
| 55 |
+ uint32_t datasize; |
|
| 56 |
+ uint8_t *mime_type; |
|
| 57 |
+ uint8_t *file_name; |
|
| 58 |
+ uint8_t *description; |
|
| 59 |
+ uint8_t *data; |
|
| 60 |
+} ID3v2ExtraMetaGEOB; |
|
| 61 |
+ |
|
| 62 |
+typedef struct ID3v2EMFunc {
|
|
| 63 |
+ const char *tag3; |
|
| 64 |
+ const char *tag4; |
|
| 65 |
+ void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **); |
|
| 66 |
+ void (*free)(); |
|
| 67 |
+} ID3v2EMFunc; |
|
| 68 |
+ |
|
| 48 | 69 |
/** |
| 49 | 70 |
* Detect ID3v2 Header. |
| 50 | 71 |
* @param buf must be ID3v2_HEADER_SIZE byte long |
| ... | ... |
@@ -61,10 +82,25 @@ int ff_id3v2_match(const uint8_t *buf, const char *magic); |
| 61 | 61 |
int ff_id3v2_tag_len(const uint8_t *buf); |
| 62 | 62 |
|
| 63 | 63 |
/** |
| 64 |
- * Read an ID3v2 tag |
|
| 64 |
+ * Read an ID3v2 tag (text tags only) |
|
| 65 | 65 |
*/ |
| 66 | 66 |
void ff_id3v2_read(AVFormatContext *s, const char *magic); |
| 67 | 67 |
|
| 68 |
+/** |
|
| 69 |
+ * Read an ID3v2 tag, including supported extra metadata (currently only GEOB) |
|
| 70 |
+ * @param extra_meta If not NULL, extra metadata is parsed into a list of |
|
| 71 |
+ * ID3v2ExtraMeta structs and *extra_meta points to the head of the list |
|
| 72 |
+ */ |
|
| 73 |
+void ff_id3v2_read_all(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta); |
|
| 74 |
+ |
|
| 75 |
+/** |
|
| 76 |
+ * Free memory allocated parsing special (non-text) metadata. |
|
| 77 |
+ * @param extra_meta Pointer to a pointer to the head of a ID3v2ExtraMeta list, *extra_meta is set to NULL. |
|
| 78 |
+ */ |
|
| 79 |
+void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta); |
|
| 80 |
+ |
|
| 81 |
+extern const ID3v2EMFunc ff_id3v2_extra_meta_funcs[]; |
|
| 82 |
+ |
|
| 68 | 83 |
extern const AVMetadataConv ff_id3v2_34_metadata_conv[]; |
| 69 | 84 |
extern const AVMetadataConv ff_id3v2_4_metadata_conv[]; |
| 70 | 85 |
extern const AVMetadataConv ff_id3v2_2_metadata_conv[]; |
| ... | ... |
@@ -1444,7 +1444,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets) |
| 1444 | 1444 |
|
| 1445 | 1445 |
if (avio_tell(s->pb) != ts->last_pos) {
|
| 1446 | 1446 |
int i; |
| 1447 |
-// av_dlog("Skipping after seek\n");
|
|
| 1447 |
+ av_dlog(ts->stream, "Skipping after seek\n"); |
|
| 1448 | 1448 |
/* seek detected, flush pes buffer */ |
| 1449 | 1449 |
for (i = 0; i < NB_PID_MAX; i++) {
|
| 1450 | 1450 |
if (ts->pids[i]) {
|
| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
* |
| 4 | 4 |
* Copyright (c) 2008 Maxim Poliakovski |
| 5 | 5 |
* 2008 Benjamin Larsson |
| 6 |
+ * 2011 David Goldwich |
|
| 6 | 7 |
* |
| 7 | 8 |
* This file is part of FFmpeg. |
| 8 | 9 |
* |
| ... | ... |
@@ -36,20 +37,19 @@ |
| 36 | 36 |
* - Sound data organized in packets follow the EA3 header |
| 37 | 37 |
* (can be encrypted using the Sony DRM!). |
| 38 | 38 |
* |
| 39 |
- * LIMITATIONS: This version supports only plain (unencrypted) OMA files. |
|
| 40 |
- * If any DRM-protected (encrypted) file is encountered you will get the |
|
| 41 |
- * corresponding error message. Try to remove the encryption using any |
|
| 42 |
- * Sony software (for example SonicStage). |
|
| 43 | 39 |
* CODEC SUPPORT: Only ATRAC3 codec is currently supported! |
| 44 | 40 |
*/ |
| 45 | 41 |
|
| 46 | 42 |
#include "avformat.h" |
| 47 | 43 |
#include "libavutil/intreadwrite.h" |
| 44 |
+#include "libavutil/des.h" |
|
| 48 | 45 |
#include "pcm.h" |
| 49 | 46 |
#include "riff.h" |
| 50 | 47 |
#include "id3v2.h" |
| 51 | 48 |
|
| 52 | 49 |
#define EA3_HEADER_SIZE 96 |
| 50 |
+#define ID3v2_EA3_MAGIC "ea3" |
|
| 51 |
+#define OMA_ENC_HEADER_SIZE 16 |
|
| 53 | 52 |
|
| 54 | 53 |
enum {
|
| 55 | 54 |
OMA_CODECID_ATRAC3 = 0, |
| ... | ... |
@@ -65,7 +65,211 @@ static const AVCodecTag codec_oma_tags[] = {
|
| 65 | 65 |
{ CODEC_ID_MP3, OMA_CODECID_MP3 },
|
| 66 | 66 |
}; |
| 67 | 67 |
|
| 68 |
-#define ID3v2_EA3_MAGIC "ea3" |
|
| 68 |
+static const uint64_t leaf_table[] = {
|
|
| 69 |
+ 0xd79e8283acea4620, 0x7a9762f445afd0d8, |
|
| 70 |
+ 0x354d60a60b8c79f1, 0x584e1cde00b07aee, |
|
| 71 |
+ 0x1573cd93da7df623, 0x47f98d79620dd535 |
|
| 72 |
+}; |
|
| 73 |
+ |
|
| 74 |
+typedef struct OMAContext {
|
|
| 75 |
+ uint64_t content_start; |
|
| 76 |
+ int encrypted; |
|
| 77 |
+ uint16_t k_size; |
|
| 78 |
+ uint16_t e_size; |
|
| 79 |
+ uint16_t i_size; |
|
| 80 |
+ uint16_t s_size; |
|
| 81 |
+ uint32_t rid; |
|
| 82 |
+ uint8_t r_val[24]; |
|
| 83 |
+ uint8_t n_val[24]; |
|
| 84 |
+ uint8_t m_val[8]; |
|
| 85 |
+ uint8_t s_val[8]; |
|
| 86 |
+ uint8_t sm_val[8]; |
|
| 87 |
+ uint8_t e_val[8]; |
|
| 88 |
+ uint8_t iv[8]; |
|
| 89 |
+ struct AVDES av_des; |
|
| 90 |
+} OMAContext; |
|
| 91 |
+ |
|
| 92 |
+static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len) |
|
| 93 |
+{
|
|
| 94 |
+ char buf[33]; |
|
| 95 |
+ len = FFMIN(len, 16); |
|
| 96 |
+ if (av_log_get_level() < level) |
|
| 97 |
+ return; |
|
| 98 |
+ ff_data_to_hex(buf, value, len, 1); |
|
| 99 |
+ buf[len<<1] = '\0'; |
|
| 100 |
+ av_log(s, level, "%s: %s\n", name, buf); |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len) |
|
| 104 |
+{
|
|
| 105 |
+ OMAContext *oc = s->priv_data; |
|
| 106 |
+ |
|
| 107 |
+ if (!r_val && !n_val) |
|
| 108 |
+ return -1; |
|
| 109 |
+ |
|
| 110 |
+ len = FFMIN(len, 16); |
|
| 111 |
+ |
|
| 112 |
+ /* use first 64 bits in the third round again */ |
|
| 113 |
+ if (r_val) {
|
|
| 114 |
+ if (r_val != oc->r_val) {
|
|
| 115 |
+ memset(oc->r_val, 0, 24); |
|
| 116 |
+ memcpy(oc->r_val, r_val, len); |
|
| 117 |
+ } |
|
| 118 |
+ memcpy(&oc->r_val[16], r_val, 8); |
|
| 119 |
+ } |
|
| 120 |
+ if (n_val) {
|
|
| 121 |
+ if (n_val != oc->n_val) {
|
|
| 122 |
+ memset(oc->n_val, 0, 24); |
|
| 123 |
+ memcpy(oc->n_val, n_val, len); |
|
| 124 |
+ } |
|
| 125 |
+ memcpy(&oc->n_val[16], n_val, 8); |
|
| 126 |
+ } |
|
| 127 |
+ |
|
| 128 |
+ return 0; |
|
| 129 |
+} |
|
| 130 |
+ |
|
| 131 |
+static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val) |
|
| 132 |
+{
|
|
| 133 |
+ OMAContext *oc = s->priv_data; |
|
| 134 |
+ unsigned int pos; |
|
| 135 |
+ struct AVDES av_des; |
|
| 136 |
+ |
|
| 137 |
+ if (!enc_header || !r_val) |
|
| 138 |
+ return -1; |
|
| 139 |
+ |
|
| 140 |
+ /* m_val */ |
|
| 141 |
+ av_des_init(&av_des, r_val, 192, 1); |
|
| 142 |
+ av_des_crypt(&av_des, oc->m_val, &enc_header[48], 1, NULL, 1); |
|
| 143 |
+ |
|
| 144 |
+ /* s_val */ |
|
| 145 |
+ av_des_init(&av_des, oc->m_val, 64, 0); |
|
| 146 |
+ av_des_crypt(&av_des, oc->s_val, NULL, 1, NULL, 0); |
|
| 147 |
+ |
|
| 148 |
+ /* sm_val */ |
|
| 149 |
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size; |
|
| 150 |
+ av_des_init(&av_des, oc->s_val, 64, 0); |
|
| 151 |
+ av_des_mac(&av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3)); |
|
| 152 |
+ |
|
| 153 |
+ pos += oc->i_size; |
|
| 154 |
+ |
|
| 155 |
+ return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0; |
|
| 156 |
+} |
|
| 157 |
+ |
|
| 158 |
+static int nprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *n_val) |
|
| 159 |
+{
|
|
| 160 |
+ OMAContext *oc = s->priv_data; |
|
| 161 |
+ uint32_t pos, taglen, datalen; |
|
| 162 |
+ struct AVDES av_des; |
|
| 163 |
+ |
|
| 164 |
+ if (!enc_header || !n_val) |
|
| 165 |
+ return -1; |
|
| 166 |
+ |
|
| 167 |
+ pos = OMA_ENC_HEADER_SIZE + oc->k_size; |
|
| 168 |
+ if (!memcmp(&enc_header[pos], "EKB ", 4)) |
|
| 169 |
+ pos += 32; |
|
| 170 |
+ |
|
| 171 |
+ if (AV_RB32(&enc_header[pos]) != oc->rid) |
|
| 172 |
+ av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); |
|
| 173 |
+ |
|
| 174 |
+ taglen = AV_RB32(&enc_header[pos+32]); |
|
| 175 |
+ datalen = AV_RB32(&enc_header[pos+36]) >> 4; |
|
| 176 |
+ |
|
| 177 |
+ pos += 44 + taglen; |
|
| 178 |
+ |
|
| 179 |
+ av_des_init(&av_des, n_val, 192, 1); |
|
| 180 |
+ while (datalen-- > 0) {
|
|
| 181 |
+ av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); |
|
| 182 |
+ kset(s, oc->r_val, NULL, 16); |
|
| 183 |
+ if (!rprobe(s, enc_header, oc->r_val)) |
|
| 184 |
+ return 0; |
|
| 185 |
+ pos += 16; |
|
| 186 |
+ } |
|
| 187 |
+ |
|
| 188 |
+ return -1; |
|
| 189 |
+} |
|
| 190 |
+ |
|
| 191 |
+static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) |
|
| 192 |
+{
|
|
| 193 |
+ OMAContext *oc = s->priv_data; |
|
| 194 |
+ ID3v2ExtraMetaGEOB *geob = NULL; |
|
| 195 |
+ uint8_t *gdata; |
|
| 196 |
+ |
|
| 197 |
+ oc->encrypted = 1; |
|
| 198 |
+ av_log(s, AV_LOG_INFO, "File is encrypted\n"); |
|
| 199 |
+ |
|
| 200 |
+ /* find GEOB metadata */ |
|
| 201 |
+ while (em) {
|
|
| 202 |
+ if (!strcmp(em->tag, "GEOB") && |
|
| 203 |
+ (geob = em->data) && |
|
| 204 |
+ !strcmp(geob->description, "OMG_LSI") || |
|
| 205 |
+ !strcmp(geob->description, "OMG_BKLSI")) {
|
|
| 206 |
+ break; |
|
| 207 |
+ } |
|
| 208 |
+ em = em->next; |
|
| 209 |
+ } |
|
| 210 |
+ if (!em) {
|
|
| 211 |
+ av_log(s, AV_LOG_ERROR, "No encryption header found\n"); |
|
| 212 |
+ return -1; |
|
| 213 |
+ } |
|
| 214 |
+ |
|
| 215 |
+ if (geob->datasize < 64) {
|
|
| 216 |
+ av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize); |
|
| 217 |
+ return -1; |
|
| 218 |
+ } |
|
| 219 |
+ |
|
| 220 |
+ gdata = geob->data; |
|
| 221 |
+ |
|
| 222 |
+ if (AV_RB16(gdata) != 1) |
|
| 223 |
+ av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n"); |
|
| 224 |
+ |
|
| 225 |
+ oc->k_size = AV_RB16(&gdata[2]); |
|
| 226 |
+ oc->e_size = AV_RB16(&gdata[4]); |
|
| 227 |
+ oc->i_size = AV_RB16(&gdata[6]); |
|
| 228 |
+ oc->s_size = AV_RB16(&gdata[8]); |
|
| 229 |
+ |
|
| 230 |
+ if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) {
|
|
| 231 |
+ av_log(s, AV_LOG_ERROR, "Invalid encryption header\n"); |
|
| 232 |
+ return -1; |
|
| 233 |
+ } |
|
| 234 |
+ oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]); |
|
| 235 |
+ av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid); |
|
| 236 |
+ |
|
| 237 |
+ memcpy(oc->iv, &header[0x58], 8); |
|
| 238 |
+ hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8); |
|
| 239 |
+ |
|
| 240 |
+ hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8); |
|
| 241 |
+ |
|
| 242 |
+ if (s->keylen > 0) {
|
|
| 243 |
+ kset(s, s->key, s->key, s->keylen); |
|
| 244 |
+ } |
|
| 245 |
+ if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) ||
|
|
| 246 |
+ rprobe(s, gdata, oc->r_val) < 0 && |
|
| 247 |
+ nprobe(s, gdata, oc->n_val) < 0) {
|
|
| 248 |
+ int i; |
|
| 249 |
+ for (i = 0; i < sizeof(leaf_table); i += 2) {
|
|
| 250 |
+ uint8_t buf[16]; |
|
| 251 |
+ AV_WL64(buf, leaf_table[i]); |
|
| 252 |
+ AV_WL64(&buf[8], leaf_table[i+1]); |
|
| 253 |
+ kset(s, buf, buf, 16); |
|
| 254 |
+ if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, oc->n_val)) |
|
| 255 |
+ break; |
|
| 256 |
+ } |
|
| 257 |
+ if (i >= sizeof(leaf_table)) {
|
|
| 258 |
+ av_log(s, AV_LOG_ERROR, "Invalid key\n"); |
|
| 259 |
+ return -1; |
|
| 260 |
+ } |
|
| 261 |
+ } |
|
| 262 |
+ |
|
| 263 |
+ /* e_val */ |
|
| 264 |
+ av_des_init(&oc->av_des, oc->m_val, 64, 0); |
|
| 265 |
+ av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0); |
|
| 266 |
+ hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8); |
|
| 267 |
+ |
|
| 268 |
+ /* init e_val */ |
|
| 269 |
+ av_des_init(&oc->av_des, oc->e_val, 64, 1); |
|
| 270 |
+ |
|
| 271 |
+ return 0; |
|
| 272 |
+} |
|
| 69 | 273 |
|
| 70 | 274 |
static int oma_read_header(AVFormatContext *s, |
| 71 | 275 |
AVFormatParameters *ap) |
| ... | ... |
@@ -77,8 +281,10 @@ static int oma_read_header(AVFormatContext *s, |
| 77 | 77 |
uint8_t buf[EA3_HEADER_SIZE]; |
| 78 | 78 |
uint8_t *edata; |
| 79 | 79 |
AVStream *st; |
| 80 |
+ ID3v2ExtraMeta *extra_meta = NULL; |
|
| 81 |
+ OMAContext *oc = s->priv_data; |
|
| 80 | 82 |
|
| 81 |
- ff_id3v2_read(s, ID3v2_EA3_MAGIC); |
|
| 83 |
+ ff_id3v2_read_all(s, ID3v2_EA3_MAGIC, &extra_meta); |
|
| 82 | 84 |
ret = avio_read(s->pb, buf, EA3_HEADER_SIZE); |
| 83 | 85 |
if (ret < EA3_HEADER_SIZE) |
| 84 | 86 |
return -1; |
| ... | ... |
@@ -88,12 +294,17 @@ static int oma_read_header(AVFormatContext *s, |
| 88 | 88 |
return -1; |
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 |
+ oc->content_start = avio_tell(s->pb); |
|
| 92 |
+ |
|
| 93 |
+ /* encrypted file */ |
|
| 91 | 94 |
eid = AV_RB16(&buf[6]); |
| 92 |
- if (eid != -1 && eid != -128) {
|
|
| 93 |
- av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid); |
|
| 95 |
+ if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) {
|
|
| 96 |
+ ff_id3v2_free_extra_meta(&extra_meta); |
|
| 94 | 97 |
return -1; |
| 95 | 98 |
} |
| 96 | 99 |
|
| 100 |
+ ff_id3v2_free_extra_meta(&extra_meta); |
|
| 101 |
+ |
|
| 97 | 102 |
codec_params = AV_RB24(&buf[33]); |
| 98 | 103 |
|
| 99 | 104 |
st = av_new_stream(s, 0); |
| ... | ... |
@@ -159,12 +370,20 @@ static int oma_read_header(AVFormatContext *s, |
| 159 | 159 |
|
| 160 | 160 |
static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 161 | 161 |
{
|
| 162 |
- int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); |
|
| 162 |
+ OMAContext *oc = s->priv_data; |
|
| 163 |
+ int packet_size = s->streams[0]->codec->block_align; |
|
| 164 |
+ int ret = av_get_packet(s->pb, pkt, packet_size); |
|
| 163 | 165 |
|
| 164 |
- pkt->stream_index = 0; |
|
| 165 | 166 |
if (ret <= 0) |
| 166 | 167 |
return AVERROR(EIO); |
| 167 | 168 |
|
| 169 |
+ pkt->stream_index = 0; |
|
| 170 |
+ |
|
| 171 |
+ if (oc->encrypted) {
|
|
| 172 |
+ /* previous unencrypted block saved in IV for the next packet (CBC mode) */ |
|
| 173 |
+ av_des_crypt(&oc->av_des, pkt->data, pkt->data, (packet_size >> 3), oc->iv, 1); |
|
| 174 |
+ } |
|
| 175 |
+ |
|
| 168 | 176 |
return ret; |
| 169 | 177 |
} |
| 170 | 178 |
|
| ... | ... |
@@ -190,16 +409,38 @@ static int oma_read_probe(AVProbeData *p) |
| 190 | 190 |
return 0; |
| 191 | 191 |
} |
| 192 | 192 |
|
| 193 |
+static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags) |
|
| 194 |
+{
|
|
| 195 |
+ OMAContext *oc = s->priv_data; |
|
| 196 |
+ |
|
| 197 |
+ pcm_read_seek(s, stream_index, timestamp, flags); |
|
| 198 |
+ |
|
| 199 |
+ if (oc->encrypted) {
|
|
| 200 |
+ /* readjust IV for CBC */ |
|
| 201 |
+ int64_t pos = avio_tell(s->pb); |
|
| 202 |
+ if (pos < oc->content_start) |
|
| 203 |
+ memset(oc->iv, 0, 8); |
|
| 204 |
+ else {
|
|
| 205 |
+ if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) {
|
|
| 206 |
+ memset(oc->iv, 0, 8); |
|
| 207 |
+ return -1; |
|
| 208 |
+ } |
|
| 209 |
+ } |
|
| 210 |
+ } |
|
| 211 |
+ |
|
| 212 |
+ return 0; |
|
| 213 |
+} |
|
| 193 | 214 |
|
| 194 | 215 |
AVInputFormat ff_oma_demuxer = {
|
| 195 | 216 |
.name = "oma", |
| 196 | 217 |
.long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
|
| 218 |
+ .priv_data_size = sizeof(OMAContext), |
|
| 197 | 219 |
.read_probe = oma_read_probe, |
| 198 | 220 |
.read_header = oma_read_header, |
| 199 | 221 |
.read_packet = oma_read_packet, |
| 200 |
- .read_seek = pcm_read_seek, |
|
| 201 |
- .flags= AVFMT_GENERIC_INDEX, |
|
| 202 |
- .extensions = "oma,aa3", |
|
| 203 |
- .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
|
|
| 222 |
+ .read_seek = oma_read_seek, |
|
| 223 |
+ .flags = AVFMT_GENERIC_INDEX, |
|
| 224 |
+ .extensions = "oma,omg,aa3", |
|
| 225 |
+ .codec_tag = (const AVCodecTag* const []){codec_oma_tags, 0},
|
|
| 204 | 226 |
}; |
| 205 | 227 |
|
| ... | ... |
@@ -136,8 +136,9 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) |
| 136 | 136 |
ast->need_parsing = AVSTREAM_PARSE_FULL; |
| 137 | 137 |
sample_rate_code= (v>>2) & 3; |
| 138 | 138 |
if (!sample_rate_code) |
| 139 |
- return AVERROR(EIO); |
|
| 140 |
- ast->codec->sample_rate = 11025 << (sample_rate_code-1); |
|
| 139 |
+ ast->codec->sample_rate = 5512; |
|
| 140 |
+ else |
|
| 141 |
+ ast->codec->sample_rate = 11025 << (sample_rate_code-1); |
|
| 141 | 142 |
av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); |
| 142 | 143 |
len -= 4; |
| 143 | 144 |
} else if (tag == TAG_VIDEOFRAME) {
|
| ... | ... |
@@ -298,7 +298,7 @@ int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
|
| 298 | 298 |
return 0; |
| 299 | 299 |
} |
| 300 | 300 |
|
| 301 |
-void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
|
|
| 301 |
+static void av_des_crypt_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt, int mac) {
|
|
| 302 | 302 |
uint64_t iv_val = iv ? AV_RB64(iv) : 0; |
| 303 | 303 |
while (count-- > 0) {
|
| 304 | 304 |
uint64_t dst_val; |
| ... | ... |
@@ -321,12 +321,21 @@ void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t |
| 321 | 321 |
} |
| 322 | 322 |
AV_WB64(dst, dst_val); |
| 323 | 323 |
src += 8; |
| 324 |
- dst += 8; |
|
| 324 |
+ if (!mac) |
|
| 325 |
+ dst += 8; |
|
| 325 | 326 |
} |
| 326 | 327 |
if (iv) |
| 327 | 328 |
AV_WB64(iv, iv_val); |
| 328 | 329 |
} |
| 329 | 330 |
|
| 331 |
+void av_des_crypt(AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt) {
|
|
| 332 |
+ av_des_crypt_mac(d, dst, src, count, iv, decrypt, 0); |
|
| 333 |
+} |
|
| 334 |
+ |
|
| 335 |
+void av_des_mac(AVDES *d, uint8_t *dst, const uint8_t *src, int count) {
|
|
| 336 |
+ av_des_crypt_mac(d, dst, src, count, (uint8_t[8]){0}, 0, 1);
|
|
| 337 |
+} |
|
| 338 |
+ |
|
| 330 | 339 |
#ifdef TEST |
| 331 | 340 |
#undef printf |
| 332 | 341 |
#undef rand |
| ... | ... |
@@ -33,7 +33,7 @@ struct AVDES {
|
| 33 | 33 |
* @brief Initializes an AVDES context. |
| 34 | 34 |
* |
| 35 | 35 |
* @param key_bits must be 64 or 192 |
| 36 |
- * @param decrypt 0 for encryption, 1 for decryption |
|
| 36 |
+ * @param decrypt 0 for encryption/CBC-MAC, 1 for decryption |
|
| 37 | 37 |
*/ |
| 38 | 38 |
int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); |
| 39 | 39 |
|
| ... | ... |
@@ -49,4 +49,13 @@ int av_des_init(struct AVDES *d, const uint8_t *key, int key_bits, int decrypt); |
| 49 | 49 |
*/ |
| 50 | 50 |
void av_des_crypt(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt); |
| 51 | 51 |
|
| 52 |
+/** |
|
| 53 |
+ * @brief Calculates CBC-MAC using the DES algorithm. |
|
| 54 |
+ * |
|
| 55 |
+ * @param count number of 8 byte blocks |
|
| 56 |
+ * @param dst destination array, can be equal to src, must be 8-byte aligned |
|
| 57 |
+ * @param src source array, can be equal to dst, must be 8-byte aligned, may be NULL |
|
| 58 |
+ */ |
|
| 59 |
+void av_des_mac(struct AVDES *d, uint8_t *dst, const uint8_t *src, int count); |
|
| 60 |
+ |
|
| 52 | 61 |
#endif /* AVUTIL_DES_H */ |