| 3122 | bool AvFormatDecoder::PreProcessVideoPacket(AVPacket *pkt, AVStream *stream) |
| 3123 | { |
| 3124 | |
| 3125 | AVCodecContext *ctx = stream->codec; |
| 3126 | bool on_frame = true; |
| 3127 | |
| 3128 | if (CODEC_IS_FFMPEG_MPEG(ctx->codec_id)) |
| 3129 | { |
| 3130 | if (!ringBuffer->isDVD()) |
| 3131 | MpegPreProcessPkt(stream, pkt); |
| 3132 | } |
| 3133 | else if (CODEC_IS_H264(ctx->codec_id)) |
| 3134 | on_frame = H264PreProcessPkt(stream, pkt); |
| 3135 | else |
| 3136 | { |
| 3137 | if (pkt->flags & PKT_FLAG_KEY) |
| 3138 | { |
| 3139 | HandleGopStart(pkt, false); |
| 3140 | seen_gop = true; |
| 3141 | } |
| 3142 | else |
| 3143 | { |
| 3144 | seq_count++; |
| 3145 | if (!seen_gop && seq_count > 1) |
| 3146 | HandleGopStart(pkt, false); |
| 3147 | } |
| 3148 | } |
| 3149 | |
| 3150 | if (framesRead == 0 && !justAfterChange && !(pkt->flags & PKT_FLAG_KEY)) |
| 3151 | { |
| 3152 | av_free_packet(pkt); |
| 3153 | return false; |
| 3154 | } |
| 3155 | |
| 3156 | if (on_frame) |
| 3157 | framesRead++; |
| 3158 | justAfterChange = false; |
| 3159 | |
| 3160 | if (exitafterdecoded) |
| 3161 | gotvideo = 1; |
| 3162 | |
| 3163 | return true; |
| 3164 | } |
| 3165 | |
| 3166 | int AvFormatDecoder::ProcessVideoPacket(const AVPacket *pkt, |
| 3167 | const AVStream *stream, |
| 3168 | long long pts, bool firstloop) |
| 3169 | { |
| 3170 | AVCodecContext *ctx = stream->codec; |
| 3171 | uchar *ptr = pkt->data; |
| 3172 | int len = pkt->size; |
| 3173 | int ret = 0; |
| 3174 | |
| 3175 | if (pkt->stream_index != selectedVideoIndex) |
| 3176 | return len; |
| 3177 | |
| 3178 | if (firstloop && pts != (int64_t) AV_NOPTS_VALUE) |
| 3179 | lastccptsu = (long long) |
| 3180 | (av_q2d(stream->time_base) * pkt->pts * 1000000); |
| 3181 | |
| 3182 | if (!wantvideo) |
| 3183 | { |
| 3184 | framesPlayed++; |
| 3185 | gotvideo = 1; |
| 3186 | return len; |
| 3187 | } |
| 3188 | |
| 3189 | AVFrame mpa_pic; |
| 3190 | bzero(&mpa_pic, sizeof(AVFrame)); |
| 3191 | |
| 3192 | int gotpicture = 0; |
| 3193 | |
| 3194 | avcodeclock->lock(); |
| 3195 | if (d->HasDecoder()) |
| 3196 | { |
| 3197 | if (decodeStillFrame) |
| 3198 | { |
| 3199 | int count = 0; |
| 3200 | // HACK |
| 3201 | while (!gotpicture && count < 5) |
| 3202 | { |
| 3203 | ret = d->DecodeMPEG2Video(ctx, &mpa_pic, &gotpicture, ptr, len); |
| 3204 | count++; |
| 3205 | } |
| 3206 | } |
| 3207 | else |
| 3208 | ret = d->DecodeMPEG2Video(ctx, &mpa_pic, &gotpicture, ptr, len); |
| 3209 | } |
| 3210 | else |
| 3211 | { |
| 3212 | ret = avcodec_decode_video(ctx, &mpa_pic, &gotpicture, ptr, len); |
| 3213 | // Reparse it to not drop the DVD still frame |
| 3214 | if (decodeStillFrame) |
| 3215 | ret = avcodec_decode_video(ctx, &mpa_pic, &gotpicture, ptr, len); |
| 3216 | } |
| 3217 | avcodeclock->unlock(); |
| 3218 | |
| 3219 | if (ret < 0) |
| 3220 | { |
| 3221 | VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown decoding error"); |
| 3222 | return len; |
| 3223 | } |
| 3224 | |
| 3225 | if (!gotpicture) |
| 3226 | return len; |
| 3227 | |
| 3228 | // Decode CEA-608 and CEA-708 captions |
| 3229 | for (uint i = 0; i < (uint)mpa_pic.atsc_cc_len; |
| 3230 | i += ((mpa_pic.atsc_cc_buf[i] & 0x1f) * 3) + 2) |
| 3231 | DecodeDTVCC(mpa_pic.atsc_cc_buf + i, mpa_pic.atsc_cc_len - i); |
| 3232 | |
| 3233 | VideoFrame *picframe = (VideoFrame *)(mpa_pic.opaque); |
| 3234 | |
| 3235 | if (!directrendering) |
| 3236 | { |
| 3237 | AVPicture tmppicture; |
| 3238 | |
| 3239 | VideoFrame *xf = picframe; |
| 3240 | picframe = GetNVP()->GetNextVideoFrame(false); |
| 3241 | |
| 3242 | unsigned char *buf = picframe->buf; |
| 3243 | avpicture_fill(&tmppicture, buf, PIX_FMT_YUV420P, |
| 3244 | ctx->width, ctx->height); |
| 3245 | tmppicture.data[0] = buf + picframe->offsets[0]; |
| 3246 | tmppicture.data[1] = buf + picframe->offsets[1]; |
| 3247 | tmppicture.data[2] = buf + picframe->offsets[2]; |
| 3248 | tmppicture.linesize[0] = picframe->pitches[0]; |
| 3249 | tmppicture.linesize[1] = picframe->pitches[1]; |
| 3250 | tmppicture.linesize[2] = picframe->pitches[2]; |
| 3251 | |
| 3252 | sws_ctx = sws_getCachedContext(sws_ctx, ctx->width, |
| 3253 | ctx->height, ctx->pix_fmt, |
| 3254 | ctx->width, ctx->height, |
| 3255 | PIX_FMT_YUV420P, SWS_FAST_BILINEAR, |
| 3256 | NULL, NULL, NULL); |
| 3257 | if (!sws_ctx) |
| 3258 | { |
| 3259 | VERBOSE(VB_IMPORTANT, LOC_ERR + |
| 3260 | "Failed to allocate sws context"); |
| 3261 | return -1; |
| 3262 | } |
| 3263 | sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, |
| 3264 | 0, ctx->height, tmppicture.data, |
| 3265 | tmppicture.linesize); |
| 3266 | |
| 3267 | if (xf) |
| 3268 | { |
| 3269 | // Set the frame flags, but then discard it |
| 3270 | // since we are not using it for display. |
| 3271 | xf->interlaced_frame = mpa_pic.interlaced_frame; |
| 3272 | xf->top_field_first = mpa_pic.top_field_first; |
| 3273 | xf->frameNumber = framesPlayed; |
| 3274 | GetNVP()->DiscardVideoFrame(xf); |
| 3275 | } |
| 3276 | } |
| 3277 | |
| 3278 | long long temppts = pts; |
| 3279 | |
| 3280 | // Validate the video pts against the last pts. If it's |
| 3281 | // a little bit smaller, equal or not available, compute |
| 3282 | // it from the last. Otherwise assume a wraparound. |
| 3283 | if (!ringBuffer->isDVD() && temppts <= lastvpts && |
| 3284 | (temppts + 10000 > lastvpts || temppts <= 0)) |
| 3285 | { |
| 3286 | temppts = lastvpts; |
| 3287 | temppts += (long long)(1000 / fps); |
| 3288 | // MPEG2/H264 frames can be repeated, update pts accordingly |
| 3289 | temppts += (long long)(mpa_pic.repeat_pict * 500 / fps); |
| 3290 | } |
| 3291 | |
| 3292 | VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + |
| 3293 | QString("video timecode %1 %2 %3 %4") |
| 3294 | .arg(pkt->pts).arg(pkt->dts).arg(temppts).arg(lastvpts)); |
| 3295 | |
| 3296 | /* XXX: Broken. |
| 3297 | if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && |
| 3298 | context->height == picframe->height) |
| 3299 | { |
| 3300 | int tblsize = mpa_pic.qstride * |
| 3301 | ((picframe->height + 15) / 16); |
| 3302 | |
| 3303 | if (picframe->qstride != mpa_pic.qstride || |
| 3304 | picframe->qscale_table == NULL) |
| 3305 | { |
| 3306 | picframe->qstride = mpa_pic.qstride; |
| 3307 | if (picframe->qscale_table) |
| 3308 | delete [] picframe->qscale_table; |
| 3309 | picframe->qscale_table = new unsigned char[tblsize]; |
| 3310 | } |
| 3311 | |
| 3312 | memcpy(picframe->qscale_table, mpa_pic.qscale_table, |
| 3313 | tblsize); |
| 3314 | } |
| 3315 | */ |
| 3316 | |
| 3317 | picframe->interlaced_frame = mpa_pic.interlaced_frame; |
| 3318 | picframe->top_field_first = mpa_pic.top_field_first; |
| 3319 | picframe->repeat_pict = mpa_pic.repeat_pict; |
| 3320 | picframe->frameNumber = framesPlayed; |
| 3321 | |
| 3322 | GetNVP()->ReleaseNextVideoFrame(picframe, temppts); |
| 3323 | if (d->HasMPEG2Dec() && mpa_pic.data[3]) |
| 3324 | ctx->release_buffer(ctx, &mpa_pic); |
| 3325 | |
| 3326 | decoded_video_frame = picframe; |
| 3327 | gotvideo = true; |
| 3328 | lastvpts = temppts; |
| 3329 | framesPlayed++; |
| 3330 | |
| 3331 | return ret; |
| 3332 | |
| 3333 | } |
| 3334 | |
| 3335 | static void extract_mono_channel(uint channel, AudioInfo *audioInfo, |
| 3336 | char *buffer, int bufsize) |
| 3337 | { |
| 3338 | // Only stereo -> mono (left or right) is supported |
| 3339 | if (audioInfo->channels != 2) |
| 3340 | return; |
| 3341 | |
| 3342 | if (channel >= (uint)audioInfo->channels) |
| 3343 | return; |
| 3344 | |
| 3345 | const uint samplesize = audioInfo->sample_size; |
| 3346 | const uint samples = bufsize / samplesize; |
| 3347 | const uint halfsample = samplesize >> 1; |
| 3348 | |
| 3349 | const char *from = (channel == 1) ? buffer + halfsample : buffer; |
| 3350 | char *to = (channel == 0) ? buffer + halfsample : buffer; |
| 3351 | |
| 3352 | for (uint sample = 0; sample < samples; |
| 3353 | (sample++), (from += samplesize), (to += samplesize)) |
| 3354 | { |
| 3355 | memmove(to, from, halfsample); |
| 3356 | } |
| 3357 | } |
| 3358 | |
| 3359 | int AvFormatDecoder::ProcessAudioPacket(const AVPacket *pkt, |
| 3360 | const AVStream *stream, |
| 3361 | uchar *ptr, int len, int &decoded, |
| 3362 | bool firstloop) |
| 3363 | { |
| 3364 | AVCodecContext *ctx = stream->codec; |
| 3365 | int ret = 0; |
| 3366 | bool reselectAudioTrack = false, dts = false; |
| 3367 | AC3HeaderInfo hdr; |
| 3368 | char *s; |
| 3369 | |
| 3370 | avcodeclock->lock(); |
| 3371 | int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; |
| 3372 | int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; |
| 3373 | avcodeclock->unlock(); |
| 3374 | /// HACK HACK HACK -- begin See #3731 |
| 3375 | if (!GetNVP()->HasAudioIn()) |
| 3376 | { |
| 3377 | VERBOSE(VB_AUDIO, LOC + "Audio is disabled - trying to restart it"); |
| 3378 | reselectAudioTrack = true; |
| 3379 | } |
| 3380 | /// HACK HACK HACK -- end |
| 3381 | |
| 3382 | // detect switches between stereo and dual languages |
| 3383 | bool wasDual = audSubIdx != -1; |
| 3384 | bool isDual = ctx->avcodec_dual_language; |
| 3385 | if ((wasDual && !isDual) || (!wasDual && isDual)) |
| 3386 | { |
| 3387 | SetupAudioStreamSubIndexes(audIdx); |
| 3388 | reselectAudioTrack = true; |
| 3389 | } |
| 3390 | |
| 3391 | // detect channels on streams that need |
| 3392 | // to be decoded before we can know this |
| 3393 | bool already_decoded = false; |
| 3394 | if (!ctx->channels) |
| 3395 | { |
| 3396 | QMutexLocker locker(avcodeclock); |
| 3397 | VERBOSE(VB_IMPORTANT, |
| 3398 | LOC + QString("Setting channels to %1") |
| 3399 | .arg(audioOut.channels)); |
| 3400 | |
| 3401 | if (DoPassThrough(ctx)) |
| 3402 | ctx->channels = ctx->request_channels = 0; |
| 3403 | else |
| 3404 | ctx->channels = ctx->request_channels = audioOut.channels; |
| 3405 | |
| 3406 | decoded = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
| 3407 | ret = avcodec_decode_audio2(ctx, audioSamples, &decoded, ptr, len); |
| 3408 | already_decoded = true; |
| 3409 | reselectAudioTrack |= ctx->channels; |
| 3410 | } |
| 3411 | |
| 3412 | if (ctx->codec_id == CODEC_ID_AC3) |
| 3413 | { |
| 3414 | GetBitContext gbc; |
| 3415 | init_get_bits(&gbc, ptr, len << 3); |
| 3416 | if (!ff_ac3_parse_header(&gbc, &hdr) && |
| 3417 | hdr.channels != last_ac3_channels) |
| 3418 | { |
| 3419 | VERBOSE(VB_AUDIO, LOC + |
| 3420 | QString("AC3 changed from %1 to %2 channels (frame %3)") |
| 3421 | .arg(last_ac3_channels).arg(hdr.channels).arg(framesRead)); |
| 3422 | |
| 3423 | if ((framesRead - last_framesRead) > AUDIOMAXFRAMES || |
| 3424 | hdr.channels < last_ac3_channels) |
| 3425 | { |
| 3426 | ctx->channels = hdr.channels; |
| 3427 | } |
| 3428 | |
| 3429 | last_ac3_channels = hdr.channels; |
| 3430 | last_framesRead = framesRead; |
| 3431 | SetupAudioStream(); |
| 3432 | } |
| 3433 | } |
| 3434 | |
| 3435 | if (reselectAudioTrack) |
| 3436 | { |
| 3437 | QMutexLocker locker(avcodeclock); |
| 3438 | currentTrack[kTrackTypeAudio] = -1; |
| 3439 | selectedTrack[kTrackTypeAudio].av_stream_index = -1; |
| 3440 | audIdx = audSubIdx = -1; |
| 3441 | AutoSelectAudioTrack(); |
| 3442 | audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; |
| 3443 | audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; |
| 3444 | } |
| 3445 | |
| 3446 | if (!wantaudio || pkt->stream_index != audIdx) |
| 3447 | { |
| 3448 | decoded = 0; |
| 3449 | return len; |
| 3450 | } |
| 3451 | |
| 3452 | if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) |
| 3453 | lastapts = (long long)(av_q2d(stream->time_base) * pkt->pts * 1000); |
| 3454 | |
| 3455 | if (skipaudio) |
| 3456 | { |
| 3457 | if ((lastapts < lastvpts - (10.0 / fps)) || lastvpts == 0) |
| 3458 | { |
| 3459 | decoded = 0; |
| 3460 | return len; |
| 3461 | } |
| 3462 | else |
| 3463 | skipaudio = false; |
| 3464 | } |
| 3465 | |
| 3466 | avcodeclock->lock(); |
| 3467 | decoded = 0; |
| 3468 | |
| 3469 | if (audioOut.do_passthru) |
| 3470 | { |
| 3471 | decoded = pkt->size; |
| 3472 | dts = CODEC_ID_DTS == ctx->codec_id; |
| 3473 | ret = encode_frame(dts, ptr, len, audioSamples, decoded); |
| 3474 | s = (char *)audioSamples; |
| 3475 | } |
| 3476 | else |
| 3477 | { |
| 3478 | if (!ctx->channels || ctx->channels > audioOut.channels) |
| 3479 | ctx->channels = audioOut.channels; |
| 3480 | |
| 3481 | if (!already_decoded) |
| 3482 | { |
| 3483 | ctx->request_channels = audioOut.channels; |
| 3484 | decoded = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
| 3485 | ret = avcodec_decode_audio2(ctx, audioSamples, &decoded, ptr, len); |
| 3486 | } |
| 3487 | |
| 3488 | // Convert sample format if required (Myth only handles 8 and 16 bits audio) |
| 3489 | if (ctx->sample_fmt == SAMPLE_FMT_S16 || |
| 3490 | ctx->sample_fmt == SAMPLE_FMT_U8 || |
| 3491 | (s = ConvertSampleFormat(ctx, decoded)) == NULL) |
| 3492 | { |
| 3493 | s = (char *)audioSamples; |
| 3494 | } |
| 3495 | // When decoding some audio streams the number of |
| 3496 | // channels, etc isn't known until we try decoding it. |
| 3497 | if ((ctx->sample_rate != audioOut.sample_rate) || |
| 3498 | (ctx->channels != audioOut.channels)) |
| 3499 | { |
| 3500 | VERBOSE(VB_IMPORTANT, LOC + "Audio stream changed"); |
| 3501 | currentTrack[kTrackTypeAudio] = -1; |
| 3502 | selectedTrack[kTrackTypeAudio].av_stream_index = -1; |
| 3503 | audIdx = -1; |
| 3504 | decoded = 0; |
| 3505 | AutoSelectAudioTrack(); |
| 3506 | } |
| 3507 | } |
| 3508 | avcodeclock->unlock(); |
| 3509 | |
| 3510 | if (ret < 0) |
| 3511 | { |
| 3512 | if (!dts) |
| 3513 | VERBOSE(VB_IMPORTANT, LOC_ERR + "Unknown audio decoding error"); |
| 3514 | decoded = 0; |
| 3515 | return len; |
| 3516 | } |
| 3517 | |
| 3518 | if (decoded <= 0) |
| 3519 | return ret; |
| 3520 | |
| 3521 | long long temppts = lastapts; |
| 3522 | |
| 3523 | // calc for next frame |
| 3524 | lastapts += (long long)((double)(decoded * 1000) / |
| 3525 | (ctx->sample_rate * ctx->channels * |
| 3526 | av_get_bits_per_sample_format(ctx->sample_fmt)>>3)); |
| 3527 | |
| 3528 | VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, |
| 3529 | LOC + QString("audio timecode %1 %2 %3 %4") |
| 3530 | .arg(pkt->pts).arg(pkt->dts).arg(temppts).arg(lastapts)); |
| 3531 | |
| 3532 | if (audSubIdx != -1) |
| 3533 | extract_mono_channel(audSubIdx, &audioOut, s, decoded); |
| 3534 | |
| 3535 | GetNVP()->AddAudioData(s, decoded, temppts); |
| 3536 | |
| 3537 | return ret; |
| 3538 | |
| 3539 | } |
| 3540 | |
| 3541 | bool AvFormatDecoder::TopUpAudioBuffer(int decoded, uint total_decoded, |
| 3542 | uint ofill, uint othresh) |
| 3543 | { |
| 3544 | uint fill, total; |
| 3545 | |
| 3546 | if (ofill + total_decoded > othresh) |
| 3547 | return true; |
| 3548 | |
| 3549 | if (!GetNVP()->GetAudioBufferStatus(fill, total)) |
| 3550 | { |
| 3551 | VERBOSE(VB_IMPORTANT, LOC_ERR + "GetFrame() : Failed to top off " |
| 3552 | "buffers in audio only mode"); |
| 3553 | return false; |
| 3554 | } |
| 3555 | |
| 3556 | total /= 6; // HACK needed for some audio files |
| 3557 | return (fill == 0) || (fill > (total>>1)) || |
| 3558 | ((total - fill) < (uint)decoded) || |
| 3559 | (ofill + total_decoded > (total>>2)) || |
| 3560 | ((total - fill) < (uint)decoded * 2); |
| 3561 | } |
| 3562 | |
3896 | | pts = (long long)(av_q2d(curstream->time_base) * pkt->dts * 1000); |
3897 | | |
3898 | | if (ringBuffer->isDVD() && |
3899 | | curstream->codec->codec_type == CODEC_TYPE_VIDEO) |
3900 | | { |
3901 | | MpegPreProcessPkt(curstream, pkt); |
| 4339 | pts = (long long)(av_q2d(stream->time_base) * pkt->dts * 1000); |
| 4340 | |
| 4341 | if (len <= 0) |
| 4342 | { |
| 4343 | av_free_packet(pkt); |
| 4344 | continue; |
| 4345 | } |
| 4346 | |
| 4347 | if (ctx->codec_type == CODEC_TYPE_VIDEO) |
| 4348 | { |
| 4349 | if (ringBuffer->isDVD() && !PreProcessDVDVideoPacket(pkt, stream)) |
| 4350 | continue; |
| 4351 | |
| 4352 | if (storevideoframes) |
| 4353 | { |
| 4354 | av_dup_packet(pkt); |
| 4355 | storedPackets.append(pkt); |
| 4356 | pkt = NULL; |
| 4357 | continue; |
| 4358 | } |
| 4359 | |
| 4360 | if (pkt->stream_index == selectedVideoIndex) |
| 4361 | { |
| 4362 | if (!PreProcessVideoPacket(pkt, stream)) |
| 4363 | continue; |
| 4364 | // If the resolution changed in XXXPreProcessPkt, we may |
| 4365 | // have a fatal error, so check for this before continuing. |
| 4366 | if (GetNVP()->IsErrored()) |
| 4367 | { |
| 4368 | av_free_packet(pkt); |
| 4369 | delete pkt; |
| 4370 | return false; |
| 4371 | } |
| 4372 | } |
| 4373 | } |
| 4374 | else if ((ctx->codec_type == CODEC_TYPE_DATA || |
| 4375 | ctx->codec_type == CODEC_TYPE_SUBTITLE) && |
| 4376 | ProcessDataPacket(pkt, stream)) |
| 4377 | continue; |
| 4378 | |
| 4379 | if (!ctx->codec) |
| 4380 | { |
| 4381 | VERBOSE(VB_PLAYBACK, LOC + |
| 4382 | QString("No codec for stream index %1, type(%2) id(%3:%4)") |
| 4383 | .arg(pkt->stream_index) |
| 4384 | .arg(codec_type_string(ctx->codec_type)) |
| 4385 | .arg(codec_id_string(ctx->codec_id)) |
| 4386 | .arg(ctx->codec_id)); |
| 4387 | av_free_packet(pkt); |
| 4388 | continue; |
| 4389 | } |
| 4390 | |
| 4391 | int ctype = ctx->codec_type; |
| 4392 | firstloop = true; |
| 4393 | |
| 4394 | while (len > 0) |
| 4395 | { |
| 4396 | switch (ctype) |
| 4397 | { |
| 4398 | case CODEC_TYPE_AUDIO: |
| 4399 | int decoded; |
| 4400 | ret = ProcessAudioPacket(pkt, stream, ptr, len, |
| 4401 | decoded, firstloop); |
| 4402 | if (decoded <= 0) |
| 4403 | break; |
| 4404 | |
| 4405 | total_decoded_audio += decoded; |
| 4406 | allowedquit |= ringBuffer->InDVDMenuOrStillFrame(); |
| 4407 | // top off audio buffers initially in audio only mode |
| 4408 | if (!allowedquit && !wantvideo) |
| 4409 | allowedquit = TopUpAudioBuffer(decoded, |
| 4410 | total_decoded_audio, |
| 4411 | ofill, othresh); |
| 4412 | break; |
| 4413 | case CODEC_TYPE_VIDEO: |
| 4414 | { |
| 4415 | ret = ProcessVideoPacket(pkt, stream, pts, firstloop); |
| 4416 | break; |
| 4417 | } |
| 4418 | case CODEC_TYPE_SUBTITLE: |
| 4419 | { |
| 4420 | ret = ProcessSubtitlePacket(pkt, stream, pts); |
| 4421 | break; |
| 4422 | } |
| 4423 | default: |
| 4424 | { |
| 4425 | VERBOSE(VB_IMPORTANT, LOC_ERR + |
| 4426 | QString("Decoding - id(%1) type(%2)") |
| 4427 | .arg(codec_id_string(ctx->codec_id)) |
| 4428 | .arg(codec_type_string(ctx->codec_type))); |
| 4429 | ret = len; |
| 4430 | break; |
| 4431 | } |
| 4432 | } |
| 4433 | ptr += ret; |
| 4434 | len -= ret; |
| 4435 | firstloop = false; |
| 4436 | } |
| 4437 | av_free_packet(pkt); |
| 4438 | } |
| 4439 | |
| 4440 | if (pkt) |
| 4441 | delete pkt; |
| 4442 | |
| 4443 | return true; |
| 4444 | } |
| 4445 | |
| 4446 | bool AvFormatDecoder::UpdateDVDStatus() |
| 4447 | { |
| 4448 | int dvdtitle = 0; |
| 4449 | int dvdpart = 0; |
| 4450 | bool cellChanged = ringBuffer->DVD()->CellChanged(); |
| 4451 | bool inDVDStill = ringBuffer->DVD()->InStillFrame(); |
| 4452 | bool inDVDMenu = ringBuffer->DVD()->IsInMenu(); |
| 4453 | int storedPktCount = storedPackets.count(); |
| 4454 | bool storevideoframes = false; |
| 4455 | selectedVideoIndex = 0; |
| 4456 | |
| 4457 | ringBuffer->DVD()->GetPartAndTitle(dvdpart, dvdtitle); |
| 4458 | |
| 4459 | if (dvdTitleChanged) |
| 4460 | { |
| 4461 | if ((storedPktCount > 10 && !decodeStillFrame) || decodeStillFrame) |
| 4462 | { |
| 4463 | storevideoframes = dvdTitleChanged = false; |
| 4464 | ScanStreams(true); |
| 4465 | } |
| 4466 | else |
| 4467 | storevideoframes = true; |
| 4468 | } |
| 4469 | else |
| 4470 | { |
| 4471 | storevideoframes = false; |
| 4472 | |
| 4473 | if (storedPktCount < 2 && !decodeStillFrame) |
| 4474 | storevideoframes = true; |
| 4475 | |
| 4476 | VERBOSE(VB_PLAYBACK+VB_EXTRA, QString("DVD Playback Debugging " |
| 4477 | "inDVDMenu %1 storedPacketcount %2 dvdstill %3") |
| 4478 | .arg(inDVDMenu).arg(storedPktCount).arg(inDVDStill)); |
| 4479 | |
| 4480 | if (inDVDStill && storedPktCount == 0 && |
| 4481 | GetNVP()->getVideoOutput()->ValidVideoFrames() == 0) |
| 4482 | { |
| 4483 | ringBuffer->DVD()->RunSeekCellStart(); |
| 4484 | } |
| 4485 | } |
| 4486 | |
| 4487 | if (GetNVP()->AtNormalSpeed() && (cellChanged || lastdvdtitle != dvdtitle)) |
| 4488 | { |
| 4489 | if (dvdtitle != lastdvdtitle) |
| 4490 | { |
| 4491 | VERBOSE(VB_PLAYBACK, LOC + "DVD Title Changed"); |
| 4492 | lastdvdtitle = dvdtitle; |
| 4493 | if (lastdvdtitle != -1) |
| 4494 | dvdTitleChanged = true; |
| 4495 | if (GetNVP() && GetNVP()->getVideoOutput()) |
| 4496 | { |
| 4497 | if (ringBuffer->DVD()->InStillFrame()) |
| 4498 | GetNVP()->getVideoOutput()->SetPrebuffering(false); |
| 4499 | else |
| 4500 | GetNVP()->getVideoOutput()->SetPrebuffering(true); |
| 4501 | } |
| 4502 | } |
| 4503 | |
| 4504 | if (ringBuffer->DVD()->PGCLengthChanged()) |
| 4505 | { |
| 4506 | { |
| 4507 | QMutexLocker locker(&m_positionMapLock); |
| 4508 | posmapStarted = false; |
| 4509 | m_positionMap.clear(); |
| 4510 | } |
| 4511 | SyncPositionMap(); |
| 4512 | } |
| 4513 | |
| 4514 | UpdateDVDFramesPlayed(); |
| 4515 | VERBOSE(VB_PLAYBACK, QString(LOC + "DVD Cell Changed. " |
| 4516 | "Update framesPlayed: %1") |
| 4517 | .arg(framesPlayed)); |
| 4518 | } |
| 4519 | |
| 4520 | return storevideoframes; |
| 4521 | } |
| 4522 | |
| 4523 | bool AvFormatDecoder::PreProcessDVDVideoPacket(AVPacket *pkt, AVStream *stream) |
| 4524 | { |
| 4525 | |
| 4526 | MpegPreProcessPkt(stream, pkt); |
4026 | | if (len > 0 && |
4027 | | curstream->codec->codec_type == CODEC_TYPE_DATA && |
4028 | | curstream->codec->codec_id == CODEC_ID_MPEG2VBI) |
4029 | | { |
4030 | | ProcessVBIDataPacket(curstream, pkt); |
4031 | | |
4032 | | av_free_packet(pkt); |
4033 | | continue; |
4034 | | } |
4035 | | |
4036 | | if (len > 0 && |
4037 | | ((curstream->codec->codec_type == CODEC_TYPE_DATA && |
4038 | | curstream->codec->codec_id == CODEC_ID_DVB_VBI) || |
4039 | | (curstream->codec->codec_type == CODEC_TYPE_SUBTITLE && |
4040 | | curstream->codec->codec_id == CODEC_ID_DVB_TELETEXT))) |
4041 | | { |
4042 | | ProcessDVBDataPacket(curstream, pkt); |
4043 | | |
4044 | | av_free_packet(pkt); |
4045 | | continue; |
4046 | | } |
4047 | | |
4048 | | #ifdef USING_MHEG |
4049 | | if (len > 0 && |
4050 | | curstream->codec->codec_type == CODEC_TYPE_DATA && |
4051 | | curstream->codec->codec_id == CODEC_ID_DSMCC_B) |
4052 | | { |
4053 | | ProcessDSMCCPacket(curstream, pkt); |
4054 | | |
4055 | | av_free_packet(pkt); |
4056 | | |
4057 | | // Have to return regularly to ensure that the OSD is updated. |
4058 | | // This applies both to MHEG and also channel browsing. |
4059 | | if (!(decodetype & kDecodeVideo)) |
4060 | | { |
4061 | | allowedquit |= (itv && itv->ImageHasChanged()); |
4062 | | OSD *osd = NULL; |
4063 | | if (!allowedquit && GetNVP() && (osd = GetNVP()->GetOSD())) |
4064 | | allowedquit |= osd->HasChanged(); |
4065 | | } |
4066 | | |
4067 | | continue; |
4068 | | } |
4069 | | #endif // USING_MHEG |
4070 | | |
4071 | | // we don't care about other data streams |
4072 | | if (curstream->codec->codec_type == CODEC_TYPE_DATA) |
4073 | | { |
4074 | | av_free_packet(pkt); |
4075 | | continue; |
4076 | | } |
4077 | | |
4078 | | if (!curstream->codec->codec) |
4079 | | { |
4080 | | VERBOSE(VB_PLAYBACK, LOC + |
4081 | | QString("No codec for stream index %1, type(%2) id(%3:%4)") |
4082 | | .arg(pkt->stream_index) |
4083 | | .arg(codec_type_string(curstream->codec->codec_type)) |
4084 | | .arg(codec_id_string(curstream->codec->codec_id)) |
4085 | | .arg(curstream->codec->codec_id)); |
4086 | | av_free_packet(pkt); |
4087 | | continue; |
4088 | | } |
4089 | | |
4090 | | firstloop = true; |
4091 | | have_err = false; |
4092 | | |
4093 | | avcodeclock->lock(); |
4094 | | int ctype = curstream->codec->codec_type; |
4095 | | int audIdx = selectedTrack[kTrackTypeAudio].av_stream_index; |
4096 | | int audSubIdx = selectedTrack[kTrackTypeAudio].av_substream_index; |
4097 | | int subIdx = selectedTrack[kTrackTypeSubtitle].av_stream_index; |
4098 | | avcodeclock->unlock(); |
4099 | | |
4100 | | while (!have_err && len > 0) |
4101 | | { |
4102 | | int ret = 0; |
4103 | | bool dts = false; |
4104 | | switch (ctype) |
4105 | | { |
4106 | | case CODEC_TYPE_AUDIO: |
4107 | | { |
4108 | | bool reselectAudioTrack = false; |
4109 | | char *s; |
4110 | | |
4111 | | /// HACK HACK HACK -- begin See #3731 |
4112 | | if (!GetNVP()->HasAudioIn()) |
4113 | | { |
4114 | | VERBOSE(VB_AUDIO, LOC + "Audio is disabled - trying to restart it"); |
4115 | | reselectAudioTrack = true; |
4116 | | } |
4117 | | /// HACK HACK HACK -- end |
4118 | | |
4119 | | // detect switches between stereo and dual languages |
4120 | | bool wasDual = audSubIdx != -1; |
4121 | | bool isDual = curstream->codec->avcodec_dual_language; |
4122 | | if ((wasDual && !isDual) || (!wasDual && isDual)) |
4123 | | { |
4124 | | SetupAudioStreamSubIndexes(audIdx); |
4125 | | reselectAudioTrack = true; |
4126 | | } |
4127 | | |
4128 | | // detect channels on streams that need |
4129 | | // to be decoded before we can know this |
4130 | | bool already_decoded = false; |
4131 | | if (!curstream->codec->channels) |
4132 | | { |
4133 | | QMutexLocker locker(avcodeclock); |
4134 | | VERBOSE(VB_IMPORTANT, LOC + |
4135 | | QString("Setting channels to %1") |
4136 | | .arg(audioOut.channels)); |
4137 | | |
4138 | | if (DoPassThrough(curstream->codec)) |
4139 | | { |
4140 | | // for passthru let it select the max number |
4141 | | // of channels |
4142 | | curstream->codec->channels = 0; |
4143 | | curstream->codec->request_channels = 0; |
4144 | | } |
4145 | | else |
4146 | | { |
4147 | | curstream->codec->channels = audioOut.channels; |
4148 | | curstream->codec->request_channels = |
4149 | | audioOut.channels; |
4150 | | } |
4151 | | data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
4152 | | ret = avcodec_decode_audio2(curstream->codec, |
4153 | | audioSamples, &data_size, |
4154 | | ptr, len); |
4155 | | already_decoded = true; |
4156 | | |
4157 | | reselectAudioTrack |= curstream->codec->channels; |
4158 | | } |
4159 | | |
4160 | | if (curstream->codec->codec_id == CODEC_ID_AC3) |
4161 | | { |
4162 | | GetBitContext gbc; |
4163 | | init_get_bits(&gbc, ptr, len * 8); |
4164 | | if (!ff_ac3_parse_header(&gbc, &hdr)) |
4165 | | { |
4166 | | if (hdr.channels != last_ac3_channels) |
4167 | | { |
4168 | | VERBOSE(VB_AUDIO, LOC + QString("AC3 changed from %1 to %2 channels (frame %3)") |
4169 | | .arg(last_ac3_channels).arg(hdr.channels).arg(framesRead)); |
4170 | | if ((framesRead - last_framesRead) > AUDIOMAXFRAMES || |
4171 | | hdr.channels < last_ac3_channels) |
4172 | | curstream->codec->channels = hdr.channels; |
4173 | | last_ac3_channels = hdr.channels; |
4174 | | last_framesRead = framesRead; |
4175 | | SetupAudioStream(); |
4176 | | } |
4177 | | } |
4178 | | } |
4179 | | |
4180 | | if (reselectAudioTrack) |
4181 | | { |
4182 | | QMutexLocker locker(avcodeclock); |
4183 | | currentTrack[kTrackTypeAudio] = -1; |
4184 | | selectedTrack[kTrackTypeAudio] |
4185 | | .av_stream_index = -1; |
4186 | | audIdx = -1; |
4187 | | audSubIdx = -1; |
4188 | | AutoSelectAudioTrack(); |
4189 | | audIdx = selectedTrack[kTrackTypeAudio] |
4190 | | .av_stream_index; |
4191 | | audSubIdx = selectedTrack[kTrackTypeAudio] |
4192 | | .av_substream_index; |
4193 | | } |
4194 | | |
4195 | | if (!(decodetype & kDecodeAudio) || |
4196 | | (pkt->stream_index != audIdx)) |
4197 | | { |
4198 | | ptr += len; |
4199 | | len = 0; |
4200 | | continue; |
4201 | | } |
4202 | | |
4203 | | if (firstloop && pkt->pts != (int64_t)AV_NOPTS_VALUE) |
4204 | | lastapts = (long long)(av_q2d(curstream->time_base) * |
4205 | | pkt->pts * 1000); |
4206 | | |
4207 | | if (skipaudio) |
4208 | | { |
4209 | | if ((lastapts < lastvpts - (10.0 / fps)) || |
4210 | | lastvpts == 0) |
4211 | | { |
4212 | | ptr += len; |
4213 | | len = 0; |
4214 | | continue; |
4215 | | } |
4216 | | else |
4217 | | skipaudio = false; |
4218 | | } |
4219 | | |
4220 | | avcodeclock->lock(); |
4221 | | data_size = 0; |
4222 | | |
4223 | | if (audioOut.do_passthru) |
4224 | | { |
4225 | | data_size = pkt->size; |
4226 | | dts = CODEC_ID_DTS == curstream->codec->codec_id; |
4227 | | ret = encode_frame(dts, ptr, len, |
4228 | | audioSamples, data_size); |
4229 | | s = (char *)audioSamples; |
4230 | | } |
4231 | | else |
4232 | | { |
4233 | | AVCodecContext *ctx = curstream->codec; |
4234 | | |
4235 | | if ((ctx->channels == 0) || |
4236 | | (ctx->channels > audioOut.channels)) |
4237 | | { |
4238 | | ctx->channels = audioOut.channels; |
4239 | | } |
4240 | | |
4241 | | if (!already_decoded) |
4242 | | { |
4243 | | curstream->codec->request_channels = |
4244 | | audioOut.channels; |
4245 | | data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
4246 | | ret = avcodec_decode_audio2(ctx, audioSamples, |
4247 | | &data_size, ptr, len); |
4248 | | } |
4249 | | |
4250 | | // Convert sample format if required (Myth only handles 8 and 16 bits audio) |
4251 | | if (ctx->sample_fmt != SAMPLE_FMT_S16 && ctx->sample_fmt != SAMPLE_FMT_U8) |
4252 | | { |
4253 | | if (audio_src_fmt != ctx->sample_fmt) |
4254 | | { |
4255 | | if (reformat_ctx) |
4256 | | av_audio_convert_free(reformat_ctx); |
4257 | | reformat_ctx = av_audio_convert_alloc(SAMPLE_FMT_S16, 1, |
4258 | | ctx->sample_fmt, 1, |
4259 | | NULL, 0); |
4260 | | if (!reformat_ctx || |
4261 | | (!audioSamplesResampled && |
4262 | | !(audioSamplesResampled = (short int *)av_mallocz(AVCODEC_MAX_AUDIO_FRAME_SIZE * |
4263 | | sizeof(*audioSamplesResampled))))) |
4264 | | { |
4265 | | VERBOSE(VB_PLAYBACK, QString("Cannot convert %1 sample format to %2 sample format") |
4266 | | .arg(avcodec_get_sample_fmt_name(ctx->sample_fmt)) |
4267 | | .arg(avcodec_get_sample_fmt_name(SAMPLE_FMT_S16))); |
4268 | | |
4269 | | avcodeclock->unlock(); |
4270 | | have_err = true; |
4271 | | continue; |
4272 | | } |
4273 | | audio_src_fmt = ctx->sample_fmt; |
4274 | | } |
4275 | | } |
4276 | | |
4277 | | if (reformat_ctx) |
4278 | | { |
4279 | | const void *ibuf[6] = {audioSamples}; |
4280 | | void *obuf[6] = {audioSamplesResampled}; |
4281 | | int istride[6] = {av_get_bits_per_sample_format(ctx->sample_fmt)/8}; |
4282 | | int ostride[6] = {2}; |
4283 | | int len = data_size/istride[0]; |
4284 | | if (av_audio_convert(reformat_ctx, obuf, ostride, |
4285 | | ibuf, istride, len) < 0) |
4286 | | { |
4287 | | VERBOSE(VB_PLAYBACK, "av_audio_convert() failed"); |
4288 | | |
4289 | | avcodeclock->unlock(); |
4290 | | have_err = true; |
4291 | | continue; |
4292 | | } |
4293 | | |
4294 | | data_size = len * 2; |
4295 | | s = (char *)audioSamplesResampled; |
4296 | | } |
4297 | | else |
4298 | | s = (char *)audioSamples; |
4299 | | |
4300 | | // When decoding some audio streams the number of |
4301 | | // channels, etc isn't known until we try decoding it. |
4302 | | if ((ctx->sample_rate != audioOut.sample_rate) || |
4303 | | (ctx->channels != audioOut.channels)) |
4304 | | { |
4305 | | VERBOSE(VB_IMPORTANT, "audio stream changed"); |
4306 | | currentTrack[kTrackTypeAudio] = -1; |
4307 | | selectedTrack[kTrackTypeAudio] |
4308 | | .av_stream_index = -1; |
4309 | | audIdx = -1; |
4310 | | AutoSelectAudioTrack(); |
4311 | | data_size = 0; |
4312 | | } |
4313 | | } |
4314 | | avcodeclock->unlock(); |
4315 | | |
4316 | | if (ret < 0) |
4317 | | { |
4318 | | if (!dts) |
4319 | | { |
4320 | | VERBOSE(VB_IMPORTANT, LOC_ERR + |
4321 | | "Unknown audio decoding error"); |
4322 | | } |
4323 | | have_err = true; |
4324 | | continue; |
4325 | | } |
4326 | | |
4327 | | if (data_size <= 0) |
4328 | | { |
4329 | | ptr += ret; |
4330 | | len -= ret; |
4331 | | continue; |
4332 | | } |
4333 | | |
4334 | | long long temppts = lastapts; |
4335 | | |
4336 | | // calc for next frame |
4337 | | lastapts += (long long)((double)(data_size * 1000) / |
4338 | | (curstream->codec->channels * 2) / |
4339 | | curstream->codec->sample_rate); |
4340 | | |
4341 | | VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, |
4342 | | LOC + QString("audio timecode %1 %2 %3 %4") |
4343 | | .arg(pkt->pts).arg(pkt->dts) |
4344 | | .arg(temppts).arg(lastapts)); |
4345 | | |
4346 | | if (audSubIdx != -1) |
4347 | | { |
4348 | | extract_mono_channel(audSubIdx, &audioOut, |
4349 | | s, data_size); |
4350 | | } |
4351 | | |
4352 | | GetNVP()->AddAudioData(s, data_size, temppts); |
4353 | | |
4354 | | total_decoded_audio += data_size; |
4355 | | |
4356 | | allowedquit |= ringBuffer->InDVDMenuOrStillFrame(); |
4357 | | allowedquit |= !(decodetype & kDecodeVideo) && |
4358 | | (ofill + total_decoded_audio > othresh); |
4359 | | |
4360 | | // top off audio buffers initially in audio only mode |
4361 | | if (!allowedquit && !(decodetype & kDecodeVideo)) |
4362 | | { |
4363 | | uint fill, total; |
4364 | | if (GetNVP()->GetAudioBufferStatus(fill, total)) |
4365 | | { |
4366 | | total /= 6; // HACK needed for some audio files |
4367 | | allowedquit = |
4368 | | (fill == 0) || (fill > (total>>1)) || |
4369 | | ((total - fill) < (uint) data_size) || |
4370 | | (ofill + total_decoded_audio > (total>>2)) || |
4371 | | ((total - fill) < (uint) data_size * 2); |
4372 | | } |
4373 | | else |
4374 | | { |
4375 | | VERBOSE(VB_IMPORTANT, LOC_ERR + |
4376 | | "GetFrame() : Failed to top off " |
4377 | | "buffers in audio only mode"); |
4378 | | } |
4379 | | } |
4380 | | |
4381 | | break; |
4382 | | } |
4383 | | case CODEC_TYPE_VIDEO: |
4384 | | { |
4385 | | if (pkt->stream_index != selectedVideoIndex) |
4386 | | { |
4387 | | ptr += pkt->size; |
4388 | | len -= pkt->size; |
4389 | | continue; |
4390 | | } |
4391 | | |
4392 | | if (firstloop && pts != (int64_t) AV_NOPTS_VALUE) |
4393 | | { |
4394 | | lastccptsu = (long long) |
4395 | | (av_q2d(curstream->time_base)*pkt->pts*1000000); |
4396 | | } |
4397 | | |
4398 | | if (!(decodetype & kDecodeVideo)) |
4399 | | { |
4400 | | framesPlayed++; |
4401 | | gotvideo = 1; |
4402 | | ptr += pkt->size; |
4403 | | len -= pkt->size; |
4404 | | continue; |
4405 | | } |
4406 | | |
4407 | | AVCodecContext *context = curstream->codec; |
4408 | | AVFrame mpa_pic; |
4409 | | bzero(&mpa_pic, sizeof(AVFrame)); |
4410 | | |
4411 | | int gotpicture = 0; |
4412 | | |
4413 | | avcodeclock->lock(); |
4414 | | if (d->HasDecoder()) |
4415 | | { |
4416 | | if (decodeStillFrame) |
4417 | | { |
4418 | | int count = 0; |
4419 | | // HACK |
4420 | | while (!gotpicture && count < 5) |
4421 | | { |
4422 | | ret = d->DecodeMPEG2Video(context, &mpa_pic, |
4423 | | &gotpicture, ptr, len); |
4424 | | count++; |
4425 | | } |
4426 | | } |
4427 | | else |
4428 | | { |
4429 | | ret = d->DecodeMPEG2Video(context, &mpa_pic, |
4430 | | &gotpicture, ptr, len); |
4431 | | } |
4432 | | } |
4433 | | else |
4434 | | { |
4435 | | ret = avcodec_decode_video(context, &mpa_pic, |
4436 | | &gotpicture, ptr, len); |
4437 | | // Reparse it to not drop the DVD still frame |
4438 | | if (decodeStillFrame) |
4439 | | ret = avcodec_decode_video(context, &mpa_pic, |
4440 | | &gotpicture, ptr, len); |
4441 | | } |
4442 | | avcodeclock->unlock(); |
4443 | | |
4444 | | if (ret < 0) |
4445 | | { |
4446 | | VERBOSE(VB_IMPORTANT, LOC_ERR + |
4447 | | "Unknown decoding error"); |
4448 | | have_err = true; |
4449 | | continue; |
4450 | | } |
4451 | | |
4452 | | if (!gotpicture) |
4453 | | { |
4454 | | ptr += ret; |
4455 | | len -= ret; |
4456 | | continue; |
4457 | | } |
4458 | | |
4459 | | // Decode CEA-608 and CEA-708 captions |
4460 | | for (uint i = 0; i < (uint)mpa_pic.atsc_cc_len; |
4461 | | i += ((mpa_pic.atsc_cc_buf[i] & 0x1f) * 3) + 2) |
4462 | | { |
4463 | | DecodeDTVCC(mpa_pic.atsc_cc_buf + i, |
4464 | | mpa_pic.atsc_cc_len - i); |
4465 | | } |
4466 | | |
4467 | | VideoFrame *picframe = (VideoFrame *)(mpa_pic.opaque); |
4468 | | |
4469 | | if (!directrendering) |
4470 | | { |
4471 | | AVPicture tmppicture; |
4472 | | |
4473 | | VideoFrame *xf = picframe; |
4474 | | picframe = GetNVP()->GetNextVideoFrame(false); |
4475 | | |
4476 | | unsigned char *buf = picframe->buf; |
4477 | | avpicture_fill(&tmppicture, buf, PIX_FMT_YUV420P, |
4478 | | context->width, context->height); |
4479 | | tmppicture.data[0] = buf + picframe->offsets[0]; |
4480 | | tmppicture.data[1] = buf + picframe->offsets[1]; |
4481 | | tmppicture.data[2] = buf + picframe->offsets[2]; |
4482 | | tmppicture.linesize[0] = picframe->pitches[0]; |
4483 | | tmppicture.linesize[1] = picframe->pitches[1]; |
4484 | | tmppicture.linesize[2] = picframe->pitches[2]; |
4485 | | |
4486 | | sws_ctx = sws_getCachedContext(sws_ctx, context->width, |
4487 | | context->height, context->pix_fmt, |
4488 | | context->width, context->height, |
4489 | | PIX_FMT_YUV420P, SWS_FAST_BILINEAR, |
4490 | | NULL, NULL, NULL); |
4491 | | if (!sws_ctx) |
4492 | | { |
4493 | | VERBOSE(VB_IMPORTANT, LOC_ERR + |
4494 | | "Failed to allocate sws context"); |
4495 | | have_err = true; |
4496 | | continue; |
4497 | | } |
4498 | | sws_scale(sws_ctx, mpa_pic.data, mpa_pic.linesize, |
4499 | | 0, context->height, tmppicture.data, |
4500 | | tmppicture.linesize); |
4501 | | |
4502 | | |
4503 | | if (xf) |
4504 | | { |
4505 | | // Set the frame flags, but then discard it |
4506 | | // since we are not using it for display. |
4507 | | xf->interlaced_frame = mpa_pic.interlaced_frame; |
4508 | | xf->top_field_first = mpa_pic.top_field_first; |
4509 | | xf->frameNumber = framesPlayed; |
4510 | | GetNVP()->DiscardVideoFrame(xf); |
4511 | | } |
4512 | | } |
4513 | | |
4514 | | long long temppts = pts; |
4515 | | |
4516 | | // Validate the video pts against the last pts. If it's |
4517 | | // a little bit smaller, equal or not available, compute |
4518 | | // it from the last. Otherwise assume a wraparound. |
4519 | | if (!ringBuffer->isDVD() && |
4520 | | temppts <= lastvpts && |
4521 | | (temppts + 10000 > lastvpts || temppts <= 0)) |
4522 | | { |
4523 | | temppts = lastvpts; |
4524 | | temppts += (long long)(1000 / fps); |
4525 | | // MPEG2/H264 frames can be repeated, update pts accordingly |
4526 | | temppts += (long long)(mpa_pic.repeat_pict * 500 / fps); |
4527 | | } |
4528 | | |
4529 | | VERBOSE(VB_PLAYBACK+VB_TIMESTAMP, LOC + |
4530 | | QString("video timecode %1 %2 %3 %4") |
4531 | | .arg(pkt->pts).arg(pkt->dts).arg(temppts) |
4532 | | .arg(lastvpts)); |
4533 | | |
4534 | | /* XXX: Broken. |
4535 | | if (mpa_pic.qscale_table != NULL && mpa_pic.qstride > 0 && |
4536 | | context->height == picframe->height) |
4537 | | { |
4538 | | int tblsize = mpa_pic.qstride * |
4539 | | ((picframe->height + 15) / 16); |
4540 | | |
4541 | | if (picframe->qstride != mpa_pic.qstride || |
4542 | | picframe->qscale_table == NULL) |
4543 | | { |
4544 | | picframe->qstride = mpa_pic.qstride; |
4545 | | if (picframe->qscale_table) |
4546 | | delete [] picframe->qscale_table; |
4547 | | picframe->qscale_table = new unsigned char[tblsize]; |
4548 | | } |
4549 | | |
4550 | | memcpy(picframe->qscale_table, mpa_pic.qscale_table, |
4551 | | tblsize); |
4552 | | } |
4553 | | */ |
4554 | | |
4555 | | picframe->interlaced_frame = mpa_pic.interlaced_frame; |
4556 | | picframe->top_field_first = mpa_pic.top_field_first; |
4557 | | picframe->repeat_pict = mpa_pic.repeat_pict; |
4558 | | |
4559 | | picframe->frameNumber = framesPlayed; |
4560 | | GetNVP()->ReleaseNextVideoFrame(picframe, temppts); |
4561 | | if (d->HasMPEG2Dec() && mpa_pic.data[3]) |
4562 | | context->release_buffer(context, &mpa_pic); |
4563 | | |
4564 | | decoded_video_frame = picframe; |
4565 | | gotvideo = 1; |
4566 | | framesPlayed++; |
4567 | | |
4568 | | lastvpts = temppts; |
4569 | | break; |
4570 | | } |
4571 | | case CODEC_TYPE_SUBTITLE: |
4572 | | { |
4573 | | int gotSubtitles = 0; |
4574 | | AVSubtitle subtitle; |
4575 | | memset(&subtitle, 0, sizeof(AVSubtitle)); |
4576 | | |
4577 | | if (ringBuffer->isDVD()) |
4578 | | { |
4579 | | if (ringBuffer->DVD()->NumMenuButtons() > 0) |
4580 | | { |
4581 | | ringBuffer->DVD()->GetMenuSPUPkt(ptr, len, |
4582 | | curstream->id); |
4583 | | } |
4584 | | else |
4585 | | { |
4586 | | if (pkt->stream_index == subIdx) |
4587 | | { |
4588 | | QMutexLocker locker(avcodeclock); |
4589 | | ringBuffer->DVD()->DecodeSubtitles(&subtitle, |
4590 | | &gotSubtitles, |
4591 | | ptr, len); |
4592 | | } |
4593 | | } |
4594 | | } |
4595 | | else if (pkt->stream_index == subIdx) |
4596 | | { |
4597 | | QMutexLocker locker(avcodeclock); |
4598 | | avcodec_decode_subtitle(curstream->codec, |
4599 | | &subtitle, &gotSubtitles, |
4600 | | ptr, len); |
4601 | | } |
4602 | | |
4603 | | // the subtitle decoder always consumes the whole packet |
4604 | | ptr += len; |
4605 | | len = 0; |
4606 | | |
4607 | | if (gotSubtitles) |
4608 | | { |
4609 | | subtitle.start_display_time += pts; |
4610 | | subtitle.end_display_time += pts; |
4611 | | GetNVP()->AddAVSubtitle(subtitle); |
4612 | | |
4613 | | VERBOSE(VB_PLAYBACK|VB_TIMESTAMP, LOC + |
4614 | | QString("subtl timecode %1 %2 %3 %4") |
4615 | | .arg(pkt->pts).arg(pkt->dts) |
4616 | | .arg(subtitle.start_display_time) |
4617 | | .arg(subtitle.end_display_time)); |
4618 | | } |
4619 | | |
4620 | | break; |
4621 | | } |
4622 | | default: |
4623 | | { |
4624 | | AVCodecContext *enc = curstream->codec; |
4625 | | VERBOSE(VB_IMPORTANT, LOC_ERR + |
4626 | | QString("Decoding - id(%1) type(%2)") |
4627 | | .arg(codec_id_string(enc->codec_id)) |
4628 | | .arg(codec_type_string(enc->codec_type))); |
4629 | | have_err = true; |
4630 | | break; |
4631 | | } |
4632 | | } |
4633 | | |
4634 | | if (!have_err) |
4635 | | { |
4636 | | ptr += ret; |
4637 | | len -= ret; |
4638 | | frame_decoded = 1; |
4639 | | firstloop = false; |
4640 | | } |
4641 | | } |
4642 | | |
4643 | | av_free_packet(pkt); |
4644 | | } |
4645 | | |
4646 | | if (pkt) |
4647 | | delete pkt; |
4648 | | |