AdtsReader.smali
.class public final Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;
.super Ljava/lang/Object;
.source "AdtsReader.java"
# interfaces
.implements Lcom/google/android/exoplayer2/extractor/ts/ElementaryStreamReader;
# static fields
.field private static final CRC_SIZE:I = 0x2
.field private static final HEADER_SIZE:I = 0x5
.field private static final ID3_HEADER_SIZE:I = 0xa
.field private static final ID3_IDENTIFIER:[B
.field private static final ID3_SIZE_OFFSET:I = 0x6
.field private static final MATCH_STATE_FF:I = 0x200
.field private static final MATCH_STATE_I:I = 0x300
.field private static final MATCH_STATE_ID:I = 0x400
.field private static final MATCH_STATE_START:I = 0x100
.field private static final MATCH_STATE_VALUE_SHIFT:I = 0x8
.field private static final STATE_CHECKING_ADTS_HEADER:I = 0x1
.field private static final STATE_FINDING_SAMPLE:I = 0x0
.field private static final STATE_READING_ADTS_HEADER:I = 0x3
.field private static final STATE_READING_ID3_HEADER:I = 0x2
.field private static final STATE_READING_SAMPLE:I = 0x4
.field private static final TAG:Ljava/lang/String; = "AdtsReader"
.field private static final VERSION_UNSET:I = -0x1
# instance fields
.field private final adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
.field private bytesRead:I
.field private currentFrameVersion:I
.field private currentOutput:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.field private currentSampleDuration:J
.field private final exposeId3:Z
.field private firstFrameSampleRateIndex:I
.field private firstFrameVersion:I
.field private formatId:Ljava/lang/String;
.field private foundFirstFrame:Z
.field private hasCrc:Z
.field private hasOutputFormat:Z
.field private final id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
.field private id3Output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.field private final language:Ljava/lang/String;
.field private matchState:I
.field private output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.field private sampleDurationUs:J
.field private sampleSize:I
.field private state:I
.field private timeUs:J
# direct methods
.method static constructor <clinit>()V
.registers 1
.line 59
const/4 v0, 0x3
new-array v0, v0, [B
fill-array-data v0, :array_a
sput-object v0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->ID3_IDENTIFIER:[B
return-void
nop
:array_a
.array-data 1
0x49t
0x44t
0x33t
.end array-data
.end method
.method public constructor <init>(Z)V
.registers 3
.param p1, "exposeId3" # Z
.line 100
const/4 v0, 0x0
invoke-direct {p0, p1, v0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;-><init>(ZLjava/lang/String;)V
.line 101
return-void
.end method
.method public constructor <init>(ZLjava/lang/String;)V
.registers 6
.param p1, "exposeId3" # Z
.param p2, "language" # Ljava/lang/String;
.line 107
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 108
new-instance v0, Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v1, 0x7
new-array v1, v1, [B
invoke-direct {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;-><init>([B)V
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
.line 109
new-instance v0, Lcom/google/android/exoplayer2/util/ParsableByteArray;
sget-object v1, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->ID3_IDENTIFIER:[B
const/16 v2, 0xa
invoke-static {v1, v2}, Ljava/util/Arrays;->copyOf([BI)[B
move-result-object v1
invoke-direct {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;-><init>([B)V
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
.line 110
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setFindingSampleState()V
.line 111
const/4 v0, -0x1
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameVersion:I
.line 112
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
.line 113
const-wide v0, -0x7fffffffffffffffL # -4.9E-324
iput-wide v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleDurationUs:J
.line 114
iput-boolean p1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->exposeId3:Z
.line 115
iput-object p2, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->language:Ljava/lang/String;
.line 116
return-void
.end method
.method private checkAdtsHeader(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.registers 6
.param p1, "buffer" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.line 323
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->bytesLeft()I
move-result v0
if-nez v0, :cond_7
.line 325
return-void
.line 328
:cond_7
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
iget-object v0, v0, Lcom/google/android/exoplayer2/util/ParsableBitArray;->data:[B
const/4 v1, 0x0
iget-object v2, p1, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->getPosition()I
move-result v3
aget-byte v2, v2, v3
aput-byte v2, v0, v1
.line 330
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v1, 0x2
invoke-virtual {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->setPosition(I)V
.line 331
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v1, 0x4
invoke-virtual {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v0
.line 332
.local v0, "currentFrameSampleRateIndex":I
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
const/4 v2, -0x1
if-eq v1, v2, :cond_2e
if-eq v0, v1, :cond_2e
.line 335
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->resetSync()V
.line 336
return-void
.line 339
:cond_2e
iget-boolean v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->foundFirstFrame:Z
if-nez v1, :cond_3b
.line 340
const/4 v1, 0x1
iput-boolean v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->foundFirstFrame:Z
.line 341
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentFrameVersion:I
iput v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameVersion:I
.line 342
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
.line 344
:cond_3b
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setReadingAdtsHeaderState()V
.line 345
return-void
.end method
.method private checkSyncPositionValid(Lcom/google/android/exoplayer2/util/ParsableByteArray;I)Z
.registers 12
.param p1, "pesBuffer" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.param p2, "syncPositionCandidate" # I
.line 371
add-int/lit8 v0, p2, 0x1
invoke-virtual {p1, v0}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 372
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
iget-object v0, v0, Lcom/google/android/exoplayer2/util/ParsableBitArray;->data:[B
const/4 v1, 0x1
invoke-direct {p0, p1, v0, v1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->tryRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
move-result v0
const/4 v2, 0x0
if-nez v0, :cond_12
.line 373
return v2
.line 376
:cond_12
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v3, 0x4
invoke-virtual {v0, v3}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->setPosition(I)V
.line 377
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
invoke-virtual {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v0
.line 378
.local v0, "currentFrameVersion":I
iget v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameVersion:I
const/4 v5, -0x1
if-eq v4, v5, :cond_26
if-eq v0, v4, :cond_26
.line 379
return v2
.line 382
:cond_26
iget v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
if-eq v4, v5, :cond_4b
.line 383
iget-object v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
iget-object v4, v4, Lcom/google/android/exoplayer2/util/ParsableBitArray;->data:[B
invoke-direct {p0, p1, v4, v1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->tryRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
move-result v4
if-nez v4, :cond_35
.line 384
return v1
.line 386
:cond_35
iget-object v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v6, 0x2
invoke-virtual {v4, v6}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->setPosition(I)V
.line 387
iget-object v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
invoke-virtual {v4, v3}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v4
.line 388
.local v4, "currentFrameSampleRateIndex":I
iget v6, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
if-eq v4, v6, :cond_46
.line 389
return v2
.line 391
:cond_46
add-int/lit8 v6, p2, 0x2
invoke-virtual {p1, v6}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 396
.end local v4 # "currentFrameSampleRateIndex":I
:cond_4b
iget-object v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
iget-object v4, v4, Lcom/google/android/exoplayer2/util/ParsableBitArray;->data:[B
invoke-direct {p0, p1, v4, v3}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->tryRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
move-result v3
if-nez v3, :cond_56
.line 397
return v1
.line 399
:cond_56
iget-object v3, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/16 v4, 0xe
invoke-virtual {v3, v4}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->setPosition(I)V
.line 400
iget-object v3, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/16 v4, 0xd
invoke-virtual {v3, v4}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v3
.line 401
.local v3, "frameSize":I
const/4 v4, 0x6
if-gt v3, v4, :cond_69
.line 403
return v2
.line 405
:cond_69
add-int v4, p2, v3
.line 406
.local v4, "nextSyncPosition":I
add-int/lit8 v6, v4, 0x1
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->limit()I
move-result v7
if-lt v6, v7, :cond_74
.line 407
return v1
.line 409
:cond_74
iget-object v6, p1, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
aget-byte v6, v6, v4
iget-object v7, p1, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
add-int/lit8 v8, v4, 0x1
aget-byte v7, v7, v8
invoke-direct {p0, v6, v7}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->isAdtsSyncBytes(BB)Z
move-result v6
if-eqz v6, :cond_95
iget v6, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameVersion:I
if-eq v6, v5, :cond_94
iget-object v5, p1, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
add-int/lit8 v6, v4, 0x1
aget-byte v5, v5, v6
and-int/lit8 v5, v5, 0x8
shr-int/lit8 v5, v5, 0x3
if-ne v5, v0, :cond_95
:cond_94
goto :goto_96
:cond_95
const/4 v1, 0x0
:goto_96
return v1
.end method
.method private continueRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
.registers 6
.param p1, "source" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.param p2, "target" # [B
.param p3, "targetLength" # I
.line 206
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->bytesLeft()I
move-result v0
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
sub-int v1, p3, v1
invoke-static {v0, v1}, Ljava/lang/Math;->min(II)I
move-result v0
.line 207
.local v0, "bytesToRead":I
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
invoke-virtual {p1, p2, v1, v0}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->readBytes([BII)V
.line 208
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
add-int/2addr v1, v0
iput v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 209
if-ne v1, p3, :cond_1a
const/4 v1, 0x1
goto :goto_1b
:cond_1a
const/4 v1, 0x0
:goto_1b
return v1
.end method
.method private findNextSample(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.registers 10
.param p1, "pesBuffer" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.line 270
iget-object v0, p1, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
.line 271
.local v0, "adtsData":[B
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->getPosition()I
move-result v1
.line 272
.local v1, "position":I
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->limit()I
move-result v2
.line 273
.local v2, "endOffset":I
:goto_a
if-ge v1, v2, :cond_7e
.line 274
add-int/lit8 v3, v1, 0x1
.end local v1 # "position":I
.local v3, "position":I
aget-byte v1, v0, v1
and-int/lit16 v1, v1, 0xff
.line 275
.local v1, "data":I
iget v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
const/16 v5, 0x200
if-ne v4, v5, :cond_4a
int-to-byte v4, v1
const/4 v6, -0x1
invoke-direct {p0, v6, v4}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->isAdtsSyncBytes(BB)Z
move-result v4
if-eqz v4, :cond_4a
.line 276
iget-boolean v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->foundFirstFrame:Z
if-nez v4, :cond_2c
add-int/lit8 v4, v3, -0x2
.line 277
invoke-direct {p0, p1, v4}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->checkSyncPositionValid(Lcom/google/android/exoplayer2/util/ParsableByteArray;I)Z
move-result v4
if-eqz v4, :cond_4a
.line 278
:cond_2c
and-int/lit8 v4, v1, 0x8
shr-int/lit8 v4, v4, 0x3
iput v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentFrameVersion:I
.line 279
and-int/lit8 v4, v1, 0x1
if-nez v4, :cond_38
const/4 v4, 0x1
goto :goto_39
:cond_38
const/4 v4, 0x0
:goto_39
iput-boolean v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->hasCrc:Z
.line 280
iget-boolean v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->foundFirstFrame:Z
if-nez v4, :cond_43
.line 281
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setCheckingAdtsHeaderState()V
goto :goto_46
.line 283
:cond_43
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setReadingAdtsHeaderState()V
.line 285
:goto_46
invoke-virtual {p1, v3}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 286
return-void
.line 290
:cond_4a
iget v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
or-int v6, v4, v1
const/16 v7, 0x149
if-eq v6, v7, :cond_77
const/16 v7, 0x1ff
if-eq v6, v7, :cond_74
const/16 v5, 0x344
if-eq v6, v5, :cond_6f
const/16 v5, 0x433
if-eq v6, v5, :cond_68
.line 305
const/16 v5, 0x100
if-eq v4, v5, :cond_7c
.line 308
iput v5, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
.line 309
add-int/lit8 v3, v3, -0x1
move v1, v3
goto :goto_7d
.line 301
:cond_68
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setReadingId3HeaderState()V
.line 302
invoke-virtual {p1, v3}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 303
return-void
.line 298
:cond_6f
const/16 v4, 0x400
iput v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
.line 299
goto :goto_7c
.line 292
:cond_74
iput v5, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
.line 293
goto :goto_7c
.line 295
:cond_77
const/16 v4, 0x300
iput v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
.line 296
nop
.line 313
.end local v1 # "data":I
:cond_7c
:goto_7c
move v1, v3
.end local v3 # "position":I
.local v1, "position":I
:goto_7d
goto :goto_a
.line 314
:cond_7e
invoke-virtual {p1, v1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 315
return-void
.end method
.method private isAdtsSyncBytes(BB)Z
.registers 5
.param p1, "firstByte" # B
.param p2, "secondByte" # B
.line 415
and-int/lit16 v0, p1, 0xff
shl-int/lit8 v0, v0, 0x8
and-int/lit16 v1, p2, 0xff
or-int/2addr v0, v1
.line 416
.local v0, "syncWord":I
invoke-static {v0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->isAdtsSyncWord(I)Z
move-result v1
return v1
.end method
.method public static isAdtsSyncWord(I)Z
.registers 3
.param p0, "candidateSyncWord" # I
.line 120
const v0, 0xfff6
and-int/2addr v0, p0
const v1, 0xfff0
if-ne v0, v1, :cond_b
const/4 v0, 0x1
goto :goto_c
:cond_b
const/4 v0, 0x0
:goto_c
return v0
.end method
.method private parseAdtsHeader()V
.registers 21
.annotation system Ldalvik/annotation/Throws;
value = {
Lcom/google/android/exoplayer2/ParserException;
}
.end annotation
.line 442
move-object/from16 v6, p0
iget-object v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v1, 0x0
invoke-virtual {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->setPosition(I)V
.line 444
iget-boolean v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->hasOutputFormat:Z
const/4 v1, 0x5
const/4 v2, 0x2
if-nez v0, :cond_86
.line 445
iget-object v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
invoke-virtual {v0, v2}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v0
const/4 v3, 0x1
add-int/2addr v0, v3
.line 446
.local v0, "audioObjectType":I
if-eq v0, v2, :cond_34
.line 456
new-instance v4, Ljava/lang/StringBuilder;
invoke-direct {v4}, Ljava/lang/StringBuilder;-><init>()V
const-string v5, "Detected audio object type: "
invoke-virtual {v4, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {v4, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
const-string v5, ", but assuming AAC LC."
invoke-virtual {v4, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {v4}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v4
const-string v5, "AdtsReader"
invoke-static {v5, v4}, Lcom/google/android/exoplayer2/util/Log;->w(Ljava/lang/String;Ljava/lang/String;)V
.line 457
const/4 v0, 0x2
.line 460
:cond_34
iget-object v4, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
invoke-virtual {v4, v1}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->skipBits(I)V
.line 461
iget-object v4, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v5, 0x3
invoke-virtual {v4, v5}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v4
.line 463
.local v4, "channelConfig":I
iget v5, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->firstFrameSampleRateIndex:I
.line 464
invoke-static {v0, v5, v4}, Lcom/google/android/exoplayer2/util/CodecSpecificDataUtil;->buildAacAudioSpecificConfig(III)[B
move-result-object v5
.line 466
.local v5, "audioSpecificConfig":[B
invoke-static {v5}, Lcom/google/android/exoplayer2/util/CodecSpecificDataUtil;->parseAacAudioSpecificConfig([B)Landroid/util/Pair;
move-result-object v7
.line 469
.local v7, "audioParams":Landroid/util/Pair;, "Landroid/util/Pair<Ljava/lang/Integer;Ljava/lang/Integer;>;"
iget-object v8, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->formatId:Ljava/lang/String;
const/4 v10, 0x0
const/4 v11, -0x1
const/4 v12, -0x1
iget-object v9, v7, Landroid/util/Pair;->second:Ljava/lang/Object;
check-cast v9, Ljava/lang/Integer;
.line 470
invoke-virtual {v9}, Ljava/lang/Integer;->intValue()I
move-result v13
iget-object v9, v7, Landroid/util/Pair;->first:Ljava/lang/Object;
check-cast v9, Ljava/lang/Integer;
invoke-virtual {v9}, Ljava/lang/Integer;->intValue()I
move-result v14
.line 471
invoke-static {v5}, Ljava/util/Collections;->singletonList(Ljava/lang/Object;)Ljava/util/List;
move-result-object v15
const/16 v16, 0x0
const/16 v17, 0x0
iget-object v9, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->language:Ljava/lang/String;
.line 469
const-string v18, "audio/mp4a-latm"
move-object/from16 v19, v9
move-object/from16 v9, v18
move-object/from16 v18, v19
invoke-static/range {v8 .. v18}, Lcom/google/android/exoplayer2/Format;->createAudioSampleFormat(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIILjava/util/List;Lcom/google/android/exoplayer2/drm/DrmInitData;ILjava/lang/String;)Lcom/google/android/exoplayer2/Format;
move-result-object v8
.line 474
.local v8, "format":Lcom/google/android/exoplayer2/Format;
const-wide/32 v9, 0x3d090000
iget v11, v8, Lcom/google/android/exoplayer2/Format;->sampleRate:I
int-to-long v11, v11
div-long/2addr v9, v11
iput-wide v9, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleDurationUs:J
.line 475
iget-object v9, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
invoke-interface {v9, v8}, Lcom/google/android/exoplayer2/extractor/TrackOutput;->format(Lcom/google/android/exoplayer2/Format;)V
.line 476
iput-boolean v3, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->hasOutputFormat:Z
.line 477
.end local v0 # "audioObjectType":I
.end local v4 # "channelConfig":I
.end local v5 # "audioSpecificConfig":[B
.end local v7 # "audioParams":Landroid/util/Pair;, "Landroid/util/Pair<Ljava/lang/Integer;Ljava/lang/Integer;>;"
.end local v8 # "format":Lcom/google/android/exoplayer2/Format;
goto :goto_8d
.line 478
:cond_86
iget-object v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/16 v3, 0xa
invoke-virtual {v0, v3}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->skipBits(I)V
.line 481
:goto_8d
iget-object v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/4 v3, 0x4
invoke-virtual {v0, v3}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->skipBits(I)V
.line 482
iget-object v0, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
const/16 v3, 0xd
invoke-virtual {v0, v3}, Lcom/google/android/exoplayer2/util/ParsableBitArray;->readBits(I)I
move-result v0
sub-int/2addr v0, v2
sub-int/2addr v0, v1
.line 483
.local v0, "sampleSize":I
iget-boolean v1, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->hasCrc:Z
if-eqz v1, :cond_a5
.line 484
add-int/lit8 v0, v0, -0x2
move v7, v0
goto :goto_a6
.line 483
:cond_a5
move v7, v0
.line 487
.end local v0 # "sampleSize":I
.local v7, "sampleSize":I
:goto_a6
iget-object v1, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
iget-wide v2, v6, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleDurationUs:J
const/4 v4, 0x0
move-object/from16 v0, p0
move v5, v7
invoke-direct/range {v0 .. v5}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setReadingSampleState(Lcom/google/android/exoplayer2/extractor/TrackOutput;JII)V
.line 488
return-void
.end method
.method private parseId3Header()V
.registers 10
.line 432
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3Output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
iget-object v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
const/16 v2, 0xa
invoke-interface {v0, v1, v2}, Lcom/google/android/exoplayer2/extractor/TrackOutput;->sampleData(Lcom/google/android/exoplayer2/util/ParsableByteArray;I)V
.line 433
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
const/4 v1, 0x6
invoke-virtual {v0, v1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 434
iget-object v4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3Output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
.line 435
invoke-virtual {v0}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->readSynchSafeInt()I
move-result v0
add-int/lit8 v8, v0, 0xa
.line 434
const-wide/16 v5, 0x0
const/16 v7, 0xa
move-object v3, p0
invoke-direct/range {v3 .. v8}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setReadingSampleState(Lcom/google/android/exoplayer2/extractor/TrackOutput;JII)V
.line 436
return-void
.end method
.method private readSample(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.registers 11
.param p1, "data" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.line 494
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->bytesLeft()I
move-result v0
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleSize:I
iget v2, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
sub-int/2addr v1, v2
invoke-static {v0, v1}, Ljava/lang/Math;->min(II)I
move-result v0
.line 495
.local v0, "bytesToRead":I
iget-object v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentOutput:Lcom/google/android/exoplayer2/extractor/TrackOutput;
invoke-interface {v1, p1, v0}, Lcom/google/android/exoplayer2/extractor/TrackOutput;->sampleData(Lcom/google/android/exoplayer2/util/ParsableByteArray;I)V
.line 496
iget v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
add-int/2addr v1, v0
iput v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 497
iget v6, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleSize:I
if-ne v1, v6, :cond_2f
.line 498
iget-object v2, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentOutput:Lcom/google/android/exoplayer2/extractor/TrackOutput;
iget-wide v3, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->timeUs:J
const/4 v5, 0x1
const/4 v7, 0x0
const/4 v8, 0x0
invoke-interface/range {v2 .. v8}, Lcom/google/android/exoplayer2/extractor/TrackOutput;->sampleMetadata(JIIILcom/google/android/exoplayer2/extractor/TrackOutput$CryptoData;)V
.line 499
iget-wide v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->timeUs:J
iget-wide v3, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentSampleDuration:J
add-long/2addr v1, v3
iput-wide v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->timeUs:J
.line 500
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setFindingSampleState()V
.line 502
:cond_2f
return-void
.end method
.method private resetSync()V
.registers 2
.line 192
const/4 v0, 0x0
iput-boolean v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->foundFirstFrame:Z
.line 193
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->setFindingSampleState()V
.line 194
return-void
.end method
.method private setCheckingAdtsHeaderState()V
.registers 2
.line 259
const/4 v0, 0x1
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
.line 260
const/4 v0, 0x0
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 261
return-void
.end method
.method private setFindingSampleState()V
.registers 2
.line 216
const/4 v0, 0x0
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
.line 217
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 218
const/16 v0, 0x100
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->matchState:I
.line 219
return-void
.end method
.method private setReadingAdtsHeaderState()V
.registers 2
.line 253
const/4 v0, 0x3
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
.line 254
const/4 v0, 0x0
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 255
return-void
.end method
.method private setReadingId3HeaderState()V
.registers 3
.line 226
const/4 v0, 0x2
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
.line 227
sget-object v0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->ID3_IDENTIFIER:[B
array-length v0, v0
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 228
const/4 v0, 0x0
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleSize:I
.line 229
iget-object v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
invoke-virtual {v1, v0}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->setPosition(I)V
.line 230
return-void
.end method
.method private setReadingSampleState(Lcom/google/android/exoplayer2/extractor/TrackOutput;JII)V
.registers 7
.param p1, "outputToUse" # Lcom/google/android/exoplayer2/extractor/TrackOutput;
.param p2, "currentSampleDuration" # J
.param p4, "priorReadBytes" # I
.param p5, "sampleSize" # I
.line 242
const/4 v0, 0x4
iput v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
.line 243
iput p4, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->bytesRead:I
.line 244
iput-object p1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentOutput:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.line 245
iput-wide p2, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->currentSampleDuration:J
.line 246
iput p5, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleSize:I
.line 247
return-void
.end method
.method private tryRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
.registers 6
.param p1, "source" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.param p2, "target" # [B
.param p3, "targetLength" # I
.line 421
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->bytesLeft()I
move-result v0
const/4 v1, 0x0
if-ge v0, p3, :cond_8
.line 422
return v1
.line 424
:cond_8
invoke-virtual {p1, p2, v1, p3}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->readBytes([BII)V
.line 425
const/4 v0, 0x1
return v0
.end method
# virtual methods
.method public consume(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.registers 4
.param p1, "data" # Lcom/google/android/exoplayer2/util/ParsableByteArray;
.annotation system Ldalvik/annotation/Throws;
value = {
Lcom/google/android/exoplayer2/ParserException;
}
.end annotation
.line 150
:cond_0
:goto_0
invoke-virtual {p1}, Lcom/google/android/exoplayer2/util/ParsableByteArray;->bytesLeft()I
move-result v0
if-lez v0, :cond_4d
.line 151
iget v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->state:I
if-eqz v0, :cond_49
const/4 v1, 0x1
if-eq v0, v1, :cond_45
const/4 v1, 0x2
if-eq v0, v1, :cond_35
const/4 v1, 0x3
if-eq v0, v1, :cond_20
const/4 v1, 0x4
if-ne v0, v1, :cond_1a
.line 170
invoke-direct {p0, p1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->readSample(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.line 171
goto :goto_0
.line 173
:cond_1a
new-instance v0, Ljava/lang/IllegalStateException;
invoke-direct {v0}, Ljava/lang/IllegalStateException;-><init>()V
throw v0
.line 164
:cond_20
iget-boolean v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->hasCrc:Z
if-eqz v0, :cond_26
const/4 v0, 0x7
goto :goto_27
:cond_26
const/4 v0, 0x5
.line 165
.local v0, "targetLength":I
:goto_27
iget-object v1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->adtsScratch:Lcom/google/android/exoplayer2/util/ParsableBitArray;
iget-object v1, v1, Lcom/google/android/exoplayer2/util/ParsableBitArray;->data:[B
invoke-direct {p0, p1, v1, v0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->continueRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
move-result v1
if-eqz v1, :cond_0
.line 166
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->parseAdtsHeader()V
goto :goto_0
.line 156
.end local v0 # "targetLength":I
:cond_35
iget-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3HeaderBuffer:Lcom/google/android/exoplayer2/util/ParsableByteArray;
iget-object v0, v0, Lcom/google/android/exoplayer2/util/ParsableByteArray;->data:[B
const/16 v1, 0xa
invoke-direct {p0, p1, v0, v1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->continueRead(Lcom/google/android/exoplayer2/util/ParsableByteArray;[BI)Z
move-result v0
if-eqz v0, :cond_0
.line 157
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->parseId3Header()V
goto :goto_0
.line 161
:cond_45
invoke-direct {p0, p1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->checkAdtsHeader(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.line 162
goto :goto_0
.line 153
:cond_49
invoke-direct {p0, p1}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->findNextSample(Lcom/google/android/exoplayer2/util/ParsableByteArray;)V
.line 154
goto :goto_0
.line 176
:cond_4d
return-void
.end method
.method public createTracks(Lcom/google/android/exoplayer2/extractor/ExtractorOutput;Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;)V
.registers 8
.param p1, "extractorOutput" # Lcom/google/android/exoplayer2/extractor/ExtractorOutput;
.param p2, "idGenerator" # Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;
.line 130
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->generateNewId()V
.line 131
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->getFormatId()Ljava/lang/String;
move-result-object v0
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->formatId:Ljava/lang/String;
.line 132
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->getTrackId()I
move-result v0
const/4 v1, 0x1
invoke-interface {p1, v0, v1}, Lcom/google/android/exoplayer2/extractor/ExtractorOutput;->track(II)Lcom/google/android/exoplayer2/extractor/TrackOutput;
move-result-object v0
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.line 133
iget-boolean v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->exposeId3:Z
if-eqz v0, :cond_36
.line 134
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->generateNewId()V
.line 135
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->getTrackId()I
move-result v0
const/4 v1, 0x4
invoke-interface {p1, v0, v1}, Lcom/google/android/exoplayer2/extractor/ExtractorOutput;->track(II)Lcom/google/android/exoplayer2/extractor/TrackOutput;
move-result-object v0
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3Output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.line 136
invoke-virtual {p2}, Lcom/google/android/exoplayer2/extractor/ts/TsPayloadReader$TrackIdGenerator;->getFormatId()Ljava/lang/String;
move-result-object v1
const/4 v2, -0x1
const/4 v3, 0x0
const-string v4, "application/id3"
invoke-static {v1, v4, v3, v2, v3}, Lcom/google/android/exoplayer2/Format;->createSampleFormat(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILcom/google/android/exoplayer2/drm/DrmInitData;)Lcom/google/android/exoplayer2/Format;
move-result-object v1
invoke-interface {v0, v1}, Lcom/google/android/exoplayer2/extractor/TrackOutput;->format(Lcom/google/android/exoplayer2/Format;)V
goto :goto_3d
.line 139
:cond_36
new-instance v0, Lcom/google/android/exoplayer2/extractor/DummyTrackOutput;
invoke-direct {v0}, Lcom/google/android/exoplayer2/extractor/DummyTrackOutput;-><init>()V
iput-object v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->id3Output:Lcom/google/android/exoplayer2/extractor/TrackOutput;
.line 141
:goto_3d
return-void
.end method
.method public getSampleDurationUs()J
.registers 3
.line 188
iget-wide v0, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->sampleDurationUs:J
return-wide v0
.end method
.method public packetFinished()V
.registers 1
.line 181
return-void
.end method
.method public packetStarted(JI)V
.registers 4
.param p1, "pesTimeUs" # J
.param p3, "flags" # I
.line 145
iput-wide p1, p0, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->timeUs:J
.line 146
return-void
.end method
.method public seek()V
.registers 1
.line 125
invoke-direct {p0}, Lcom/google/android/exoplayer2/extractor/ts/AdtsReader;->resetSync()V
.line 126
return-void
.end method