سؤال

هل هناك طريقة لاكتشاف أن رسم مرشح DirectShow قد وصل إلى نهاية ملفه؟بنهاية ملفه، أعني أن رسم التصفية مع مرشح SampleGrabber لن يتلقى أبدًا استدعاء SampleCB آخر.

فيما يلي بعض الأشياء التي لا تعمل:

  • يثق IMediaDet::get_StreamLength (يُقال غالبًا أن عدد الإطارات في مقطع الفيديو أكبر من عدد الإطارات الموجودة بالفعل)
  • يثق IMediaSeeking::GetDuration (يتوافق مع IMediaDet، +/- إطار واحد)
  • يستخدم IMediaControl::GetState (يظل رسم التصفية قيد التشغيل حتى لو تمت معالجة كافة الإطارات من ملف بالفعل)

خلفية:

أقوم بمعالجة الفيديو ولدي فصل دراسي يقوم بإنشاء رسم بياني للتصفية باستخدام SampleGrabber.حينما SampleGrabber::SampleCB تم استدعاؤه، قمت بحظره باستخدام كائن المزامنة (mutex) حتى أتمكن من تشغيل رسم التصفية في وضع السحب.عندما أكون مستعدًا لإطار آخر، أقوم بإلغاء حظر كائن المزامنة (mutex) في خيطي الرئيسي وانتظر SampleGrabber::SampleCB لترسل لي إشارة بأن الأمر قد تم.بالنسبة لبعض مقاطع الفيديو، IMediaDet::get_StreamLength يخبرني أن الفيديو يحتوي على إطارات أكثر مما هو موجود بالفعل.بمجرد استخراج الإطار النهائي وطلب إطار أكثر مما هو موجود بالفعل، يتم حظر الخيط الرئيسي إلى الأبد بسبب SampleGrabber::SampleCB لن يتم الاتصال بك مرة أخرى.أود أن أكون قادرًا على اكتشاف متى SampleGrabber::SampleCB لن يتم استدعاؤها أبدًا لمصادر الملفات.تطبيقات مثل Windows Media Player قادرة على القيام بذلك بطريقة أو بأخرى لأن واجهة المستخدم الرسومية تشير إلى أن الفيديو قد انتهى بعد آخر إطار حقيقي، لذلك من الواضح أن هناك طريقة للقيام بذلك.

يحرر:

أنا استخدم WaitForSingleObject لتنفيذ حظر الموضوع الرئيسي.الحل البديل الذي كنت أستخدمه حتى الآن هو تنفيذ ما اقترحه جريج:لديك مهلة محدودة.لسوء الحظ، يصبح هذا الأمر صعبًا بعض الشيء.يمكن أن يفشل الانتظار لأسباب عديدة مثل حالة عدم اليقين الحقيقية، أو نظام ملفات الشبكة البطيء، أو فقدان الاتصال بالشبكة، أو وحدة فك الترميز البطيئة، وما إلى ذلك.

هل كانت مفيدة؟

المحلول

ربما باستخدام IMediaEventEx واجهه المستخدم؟أحد رموز الحدث هو EC_COMPLETE موثقة كـ "تم تقديم كافة البيانات من دفق معين."

نصائح أخرى

بافتراض أن الخيط الرئيسي محظور WaitForSingleObject, ، هل لا يمكنك تحديد مهلة للانتظار؟ثم إذا عاد الانتظار بسبب انتهاء المهلة وليس لأنه تلقى إشارة، فستعرف أنه الإطار الأخير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top